/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0

THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.

See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

"use strict";
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(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);
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __extends = (this && this.__extends) || (function () {
    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 (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
/* @internal */
var ts;
(function (ts) {
    function createMapShim() {
        /** Create a MapLike with good performance. */
        function createDictionaryObject() {
            var map = Object.create(/*prototype*/ null); // eslint-disable-line no-null/no-null
            // Using 'delete' on an object causes V8 to put the object in dictionary mode.
            // This disables creation of hidden classes, which are expensive when an object is
            // constantly changing shape.
            map.__ = undefined;
            delete map.__;
            return map;
        }
        var MapIterator = /** @class */ (function () {
            function MapIterator(currentEntry, selector) {
                this.currentEntry = currentEntry;
                this.selector = selector;
            }
            MapIterator.prototype.next = function () {
                // Navigate to the next entry.
                while (this.currentEntry) {
                    var skipNext = !!this.currentEntry.skipNext;
                    this.currentEntry = this.currentEntry.nextEntry;
                    if (!skipNext) {
                        break;
                    }
                }
                if (this.currentEntry) {
                    return { value: this.selector(this.currentEntry.key, this.currentEntry.value), done: false };
                }
                else {
                    return { value: undefined, done: true };
                }
            };
            return MapIterator;
        }());
        return /** @class */ (function () {
            function class_1() {
                this.data = createDictionaryObject();
                this.size = 0;
                // Create a first (stub) map entry that will not contain a key
                // and value but serves as starting point for iterators.
                this.firstEntry = {};
                // When the map is empty, the last entry is the same as the
                // first one.
                this.lastEntry = this.firstEntry;
            }
            class_1.prototype.get = function (key) {
                var entry = this.data[key];
                return entry && entry.value;
            };
            class_1.prototype.set = function (key, value) {
                if (!this.has(key)) {
                    this.size++;
                    // Create a new entry that will be appended at the
                    // end of the linked list.
                    var newEntry = {
                        key: key,
                        value: value
                    };
                    this.data[key] = newEntry;
                    // Adjust the references.
                    var previousLastEntry = this.lastEntry;
                    previousLastEntry.nextEntry = newEntry;
                    newEntry.previousEntry = previousLastEntry;
                    this.lastEntry = newEntry;
                }
                else {
                    this.data[key].value = value;
                }
                return this;
            };
            class_1.prototype.has = function (key) {
                // eslint-disable-next-line no-in-operator
                return key in this.data;
            };
            class_1.prototype.delete = function (key) {
                if (this.has(key)) {
                    this.size--;
                    var entry = this.data[key];
                    delete this.data[key];
                    // Adjust the linked list references of the neighbor entries.
                    var previousEntry = entry.previousEntry;
                    previousEntry.nextEntry = entry.nextEntry;
                    if (entry.nextEntry) {
                        entry.nextEntry.previousEntry = previousEntry;
                    }
                    // When the deleted entry was the last one, we need to
                    // adjust the lastEntry reference.
                    if (this.lastEntry === entry) {
                        this.lastEntry = previousEntry;
                    }
                    // Adjust the forward reference of the deleted entry
                    // in case an iterator still references it. This allows us
                    // to throw away the entry, but when an active iterator
                    // (which points to the current entry) continues, it will
                    // navigate to the entry that originally came before the
                    // current one and skip it.
                    entry.previousEntry = undefined;
                    entry.nextEntry = previousEntry;
                    entry.skipNext = true;
                    return true;
                }
                return false;
            };
            class_1.prototype.clear = function () {
                this.data = createDictionaryObject();
                this.size = 0;
                // Reset the linked list. Note that we must adjust the forward
                // references of the deleted entries to ensure iterators stuck
                // in the middle of the list don't continue with deleted entries,
                // but can continue with new entries added after the clear()
                // operation.
                var firstEntry = this.firstEntry;
                var currentEntry = firstEntry.nextEntry;
                while (currentEntry) {
                    var nextEntry = currentEntry.nextEntry;
                    currentEntry.previousEntry = undefined;
                    currentEntry.nextEntry = firstEntry;
                    currentEntry.skipNext = true;
                    currentEntry = nextEntry;
                }
                firstEntry.nextEntry = undefined;
                this.lastEntry = firstEntry;
            };
            class_1.prototype.keys = function () {
                return new MapIterator(this.firstEntry, function (key) { return key; });
            };
            class_1.prototype.values = function () {
                return new MapIterator(this.firstEntry, function (_key, value) { return value; });
            };
            class_1.prototype.entries = function () {
                return new MapIterator(this.firstEntry, function (key, value) { return [key, value]; });
            };
            class_1.prototype.forEach = function (action) {
                var iterator = this.entries();
                while (true) {
                    var iterResult = iterator.next();
                    if (iterResult.done) {
                        break;
                    }
                    var _a = iterResult.value, key = _a[0], value = _a[1];
                    action(value, key);
                }
            };
            return class_1;
        }());
    }
    ts.createMapShim = createMapShim;
})(ts || (ts = {}));
var ts;
(function (ts) {
    // WARNING: The script `configurePrerelease.ts` uses a regexp to parse out these values.
    // If changing the text in this section, be sure to test `configurePrerelease` too.
    ts.versionMajorMinor = "3.9";
    /** The version of the TypeScript compiler release */
    ts.version = "3.9.7";
    /**
     * Returns the native Map implementation if it is available and compatible (i.e. supports iteration).
     */
    /* @internal */
    function tryGetNativeMap() {
        // eslint-disable-next-line no-in-operator
        return typeof Map !== "undefined" && "entries" in Map.prototype ? Map : undefined;
    }
    ts.tryGetNativeMap = tryGetNativeMap;
    /* @internal */
    ts.Map = tryGetNativeMap() || (function () {
        // NOTE: createMapShim will be defined for typescriptServices.js but not for tsc.js, so we must test for it.
        if (typeof ts.createMapShim === "function") {
            return ts.createMapShim();
        }
        throw new Error("TypeScript requires an environment that provides a compatible native Map implementation.");
    })();
    /* @internal */
    var Comparison;
    (function (Comparison) {
        Comparison[Comparison["LessThan"] = -1] = "LessThan";
        Comparison[Comparison["EqualTo"] = 0] = "EqualTo";
        Comparison[Comparison["GreaterThan"] = 1] = "GreaterThan";
    })(Comparison = ts.Comparison || (ts.Comparison = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    ts.emptyArray = [];
    /** Create a new map. */
    function createMap() {
        return new ts.Map();
    }
    ts.createMap = createMap;
    /** Create a new map from an array of entries. */
    function createMapFromEntries(entries) {
        var map = createMap();
        for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
            var _a = entries_1[_i], key = _a[0], value = _a[1];
            map.set(key, value);
        }
        return map;
    }
    ts.createMapFromEntries = createMapFromEntries;
    /** Create a new map from a template object is provided, the map will copy entries from it. */
    function createMapFromTemplate(template) {
        var map = new ts.Map();
        // Copies keys/values from template. Note that for..in will not throw if
        // template is undefined, and instead will just exit the loop.
        for (var key in template) {
            if (hasOwnProperty.call(template, key)) {
                map.set(key, template[key]);
            }
        }
        return map;
    }
    ts.createMapFromTemplate = createMapFromTemplate;
    function length(array) {
        return array ? array.length : 0;
    }
    ts.length = length;
    /**
     * Iterates through 'array' by index and performs the callback on each element of array until the callback
     * returns a truthy value, then returns that value.
     * If no such value is found, the callback is applied to each element of array and undefined is returned.
     */
    function forEach(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var result = callback(array[i], i);
                if (result) {
                    return result;
                }
            }
        }
        return undefined;
    }
    ts.forEach = forEach;
    /**
     * Like `forEach`, but iterates in reverse order.
     */
    function forEachRight(array, callback) {
        if (array) {
            for (var i = array.length - 1; i >= 0; i--) {
                var result = callback(array[i], i);
                if (result) {
                    return result;
                }
            }
        }
        return undefined;
    }
    ts.forEachRight = forEachRight;
    /** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
    function firstDefined(array, callback) {
        if (array === undefined) {
            return undefined;
        }
        for (var i = 0; i < array.length; i++) {
            var result = callback(array[i], i);
            if (result !== undefined) {
                return result;
            }
        }
        return undefined;
    }
    ts.firstDefined = firstDefined;
    function firstDefinedIterator(iter, callback) {
        while (true) {
            var iterResult = iter.next();
            if (iterResult.done) {
                return undefined;
            }
            var result = callback(iterResult.value);
            if (result !== undefined) {
                return result;
            }
        }
    }
    ts.firstDefinedIterator = firstDefinedIterator;
    function zipWith(arrayA, arrayB, callback) {
        var result = [];
        ts.Debug.assertEqual(arrayA.length, arrayB.length);
        for (var i = 0; i < arrayA.length; i++) {
            result.push(callback(arrayA[i], arrayB[i], i));
        }
        return result;
    }
    ts.zipWith = zipWith;
    function zipToIterator(arrayA, arrayB) {
        ts.Debug.assertEqual(arrayA.length, arrayB.length);
        var i = 0;
        return {
            next: function () {
                if (i === arrayA.length) {
                    return { value: undefined, done: true };
                }
                i++;
                return { value: [arrayA[i - 1], arrayB[i - 1]], done: false };
            }
        };
    }
    ts.zipToIterator = zipToIterator;
    function zipToMap(keys, values) {
        ts.Debug.assert(keys.length === values.length);
        var map = createMap();
        for (var i = 0; i < keys.length; ++i) {
            map.set(keys[i], values[i]);
        }
        return map;
    }
    ts.zipToMap = zipToMap;
    /**
     * Iterates through `array` by index and performs the callback on each element of array until the callback
     * returns a falsey value, then returns false.
     * If no such value is found, the callback is applied to each element of array and `true` is returned.
     */
    function every(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                if (!callback(array[i], i)) {
                    return false;
                }
            }
        }
        return true;
    }
    ts.every = every;
    function find(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            var value = array[i];
            if (predicate(value, i)) {
                return value;
            }
        }
        return undefined;
    }
    ts.find = find;
    function findLast(array, predicate) {
        for (var i = array.length - 1; i >= 0; i--) {
            var value = array[i];
            if (predicate(value, i)) {
                return value;
            }
        }
        return undefined;
    }
    ts.findLast = findLast;
    /** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */
    function findIndex(array, predicate, startIndex) {
        for (var i = startIndex || 0; i < array.length; i++) {
            if (predicate(array[i], i)) {
                return i;
            }
        }
        return -1;
    }
    ts.findIndex = findIndex;
    function findLastIndex(array, predicate, startIndex) {
        for (var i = startIndex === undefined ? array.length - 1 : startIndex; i >= 0; i--) {
            if (predicate(array[i], i)) {
                return i;
            }
        }
        return -1;
    }
    ts.findLastIndex = findLastIndex;
    /**
     * Returns the first truthy result of `callback`, or else fails.
     * This is like `forEach`, but never returns undefined.
     */
    function findMap(array, callback) {
        for (var i = 0; i < array.length; i++) {
            var result = callback(array[i], i);
            if (result) {
                return result;
            }
        }
        return ts.Debug.fail();
    }
    ts.findMap = findMap;
    function contains(array, value, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (array) {
            for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
                var v = array_1[_i];
                if (equalityComparer(v, value)) {
                    return true;
                }
            }
        }
        return false;
    }
    ts.contains = contains;
    function arraysEqual(a, b, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        return a.length === b.length && a.every(function (x, i) { return equalityComparer(x, b[i]); });
    }
    ts.arraysEqual = arraysEqual;
    function indexOfAnyCharCode(text, charCodes, start) {
        for (var i = start || 0; i < text.length; i++) {
            if (contains(charCodes, text.charCodeAt(i))) {
                return i;
            }
        }
        return -1;
    }
    ts.indexOfAnyCharCode = indexOfAnyCharCode;
    function countWhere(array, predicate) {
        var count = 0;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = array[i];
                if (predicate(v, i)) {
                    count++;
                }
            }
        }
        return count;
    }
    ts.countWhere = countWhere;
    function filter(array, f) {
        if (array) {
            var len = array.length;
            var i = 0;
            while (i < len && f(array[i]))
                i++;
            if (i < len) {
                var result = array.slice(0, i);
                i++;
                while (i < len) {
                    var item = array[i];
                    if (f(item)) {
                        result.push(item);
                    }
                    i++;
                }
                return result;
            }
        }
        return array;
    }
    ts.filter = filter;
    function filterMutate(array, f) {
        var outIndex = 0;
        for (var i = 0; i < array.length; i++) {
            if (f(array[i], i, array)) {
                array[outIndex] = array[i];
                outIndex++;
            }
        }
        array.length = outIndex;
    }
    ts.filterMutate = filterMutate;
    function clear(array) {
        array.length = 0;
    }
    ts.clear = clear;
    function map(array, f) {
        var result;
        if (array) {
            result = [];
            for (var i = 0; i < array.length; i++) {
                result.push(f(array[i], i));
            }
        }
        return result;
    }
    ts.map = map;
    function mapIterator(iter, mapFn) {
        return {
            next: function () {
                var iterRes = iter.next();
                return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false };
            }
        };
    }
    ts.mapIterator = mapIterator;
    function sameMap(array, f) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var item = array[i];
                var mapped = f(item, i);
                if (item !== mapped) {
                    var result = array.slice(0, i);
                    result.push(mapped);
                    for (i++; i < array.length; i++) {
                        result.push(f(array[i], i));
                    }
                    return result;
                }
            }
        }
        return array;
    }
    ts.sameMap = sameMap;
    /**
     * Flattens an array containing a mix of array or non-array elements.
     *
     * @param array The array to flatten.
     */
    function flatten(array) {
        var result = [];
        for (var _i = 0, array_2 = array; _i < array_2.length; _i++) {
            var v = array_2[_i];
            if (v) {
                if (isArray(v)) {
                    addRange(result, v);
                }
                else {
                    result.push(v);
                }
            }
        }
        return result;
    }
    ts.flatten = flatten;
    /**
     * Maps an array. If the mapped value is an array, it is spread into the result.
     *
     * @param array The array to map.
     * @param mapfn The callback used to map the result into one or more values.
     */
    function flatMap(array, mapfn) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = mapfn(array[i], i);
                if (v) {
                    if (isArray(v)) {
                        result = addRange(result, v);
                    }
                    else {
                        result = append(result, v);
                    }
                }
            }
        }
        return result || ts.emptyArray;
    }
    ts.flatMap = flatMap;
    function flatMapToMutable(array, mapfn) {
        var result = [];
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = mapfn(array[i], i);
                if (v) {
                    if (isArray(v)) {
                        addRange(result, v);
                    }
                    else {
                        result.push(v);
                    }
                }
            }
        }
        return result;
    }
    ts.flatMapToMutable = flatMapToMutable;
    function flatMapIterator(iter, mapfn) {
        var first = iter.next();
        if (first.done) {
            return ts.emptyIterator;
        }
        var currentIter = getIterator(first.value);
        return {
            next: function () {
                while (true) {
                    var currentRes = currentIter.next();
                    if (!currentRes.done) {
                        return currentRes;
                    }
                    var iterRes = iter.next();
                    if (iterRes.done) {
                        return iterRes;
                    }
                    currentIter = getIterator(iterRes.value);
                }
            },
        };
        function getIterator(x) {
            var res = mapfn(x);
            return res === undefined ? ts.emptyIterator : isArray(res) ? arrayIterator(res) : res;
        }
    }
    ts.flatMapIterator = flatMapIterator;
    function sameFlatMap(array, mapfn) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var item = array[i];
                var mapped = mapfn(item, i);
                if (result || item !== mapped || isArray(mapped)) {
                    if (!result) {
                        result = array.slice(0, i);
                    }
                    if (isArray(mapped)) {
                        addRange(result, mapped);
                    }
                    else {
                        result.push(mapped);
                    }
                }
            }
        }
        return result || array;
    }
    ts.sameFlatMap = sameFlatMap;
    function mapAllOrFail(array, mapFn) {
        var result = [];
        for (var i = 0; i < array.length; i++) {
            var mapped = mapFn(array[i], i);
            if (mapped === undefined) {
                return undefined;
            }
            result.push(mapped);
        }
        return result;
    }
    ts.mapAllOrFail = mapAllOrFail;
    function mapDefined(array, mapFn) {
        var result = [];
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var mapped = mapFn(array[i], i);
                if (mapped !== undefined) {
                    result.push(mapped);
                }
            }
        }
        return result;
    }
    ts.mapDefined = mapDefined;
    function mapDefinedIterator(iter, mapFn) {
        return {
            next: function () {
                while (true) {
                    var res = iter.next();
                    if (res.done) {
                        return res;
                    }
                    var value = mapFn(res.value);
                    if (value !== undefined) {
                        return { value: value, done: false };
                    }
                }
            }
        };
    }
    ts.mapDefinedIterator = mapDefinedIterator;
    function mapDefinedMap(map, mapValue, mapKey) {
        if (mapKey === void 0) { mapKey = identity; }
        var result = createMap();
        map.forEach(function (value, key) {
            var mapped = mapValue(value, key);
            if (mapped !== undefined) {
                result.set(mapKey(key), mapped);
            }
        });
        return result;
    }
    ts.mapDefinedMap = mapDefinedMap;
    ts.emptyIterator = { next: function () { return ({ value: undefined, done: true }); } };
    function singleIterator(value) {
        var done = false;
        return {
            next: function () {
                var wasDone = done;
                done = true;
                return wasDone ? { value: undefined, done: true } : { value: value, done: false };
            }
        };
    }
    ts.singleIterator = singleIterator;
    function spanMap(array, keyfn, mapfn) {
        var result;
        if (array) {
            result = [];
            var len = array.length;
            var previousKey = void 0;
            var key = void 0;
            var start = 0;
            var pos = 0;
            while (start < len) {
                while (pos < len) {
                    var value = array[pos];
                    key = keyfn(value, pos);
                    if (pos === 0) {
                        previousKey = key;
                    }
                    else if (key !== previousKey) {
                        break;
                    }
                    pos++;
                }
                if (start < pos) {
                    var v = mapfn(array.slice(start, pos), previousKey, start, pos);
                    if (v) {
                        result.push(v);
                    }
                    start = pos;
                }
                previousKey = key;
                pos++;
            }
        }
        return result;
    }
    ts.spanMap = spanMap;
    function mapEntries(map, f) {
        if (!map) {
            return undefined;
        }
        var result = createMap();
        map.forEach(function (value, key) {
            var _a = f(key, value), newKey = _a[0], newValue = _a[1];
            result.set(newKey, newValue);
        });
        return result;
    }
    ts.mapEntries = mapEntries;
    function some(array, predicate) {
        if (array) {
            if (predicate) {
                for (var _i = 0, array_3 = array; _i < array_3.length; _i++) {
                    var v = array_3[_i];
                    if (predicate(v)) {
                        return true;
                    }
                }
            }
            else {
                return array.length > 0;
            }
        }
        return false;
    }
    ts.some = some;
    /** Calls the callback with (start, afterEnd) index pairs for each range where 'pred' is true. */
    function getRangesWhere(arr, pred, cb) {
        var start;
        for (var i = 0; i < arr.length; i++) {
            if (pred(arr[i])) {
                start = start === undefined ? i : start;
            }
            else {
                if (start !== undefined) {
                    cb(start, i);
                    start = undefined;
                }
            }
        }
        if (start !== undefined)
            cb(start, arr.length);
    }
    ts.getRangesWhere = getRangesWhere;
    function concatenate(array1, array2) {
        if (!some(array2))
            return array1;
        if (!some(array1))
            return array2;
        return __spreadArrays(array1, array2);
    }
    ts.concatenate = concatenate;
    function selectIndex(_, i) {
        return i;
    }
    function indicesOf(array) {
        return array.map(selectIndex);
    }
    ts.indicesOf = indicesOf;
    function deduplicateRelational(array, equalityComparer, comparer) {
        // Perform a stable sort of the array. This ensures the first entry in a list of
        // duplicates remains the first entry in the result.
        var indices = indicesOf(array);
        stableSortIndices(array, indices, comparer);
        var last = array[indices[0]];
        var deduplicated = [indices[0]];
        for (var i = 1; i < indices.length; i++) {
            var index = indices[i];
            var item = array[index];
            if (!equalityComparer(last, item)) {
                deduplicated.push(index);
                last = item;
            }
        }
        // restore original order
        deduplicated.sort();
        return deduplicated.map(function (i) { return array[i]; });
    }
    function deduplicateEquality(array, equalityComparer) {
        var result = [];
        for (var _i = 0, array_4 = array; _i < array_4.length; _i++) {
            var item = array_4[_i];
            pushIfUnique(result, item, equalityComparer);
        }
        return result;
    }
    /**
     * Deduplicates an unsorted array.
     * @param equalityComparer An `EqualityComparer` used to determine if two values are duplicates.
     * @param comparer An optional `Comparer` used to sort entries before comparison, though the
     * result will remain in the original order in `array`.
     */
    function deduplicate(array, equalityComparer, comparer) {
        return array.length === 0 ? [] :
            array.length === 1 ? array.slice() :
                comparer ? deduplicateRelational(array, equalityComparer, comparer) :
                    deduplicateEquality(array, equalityComparer);
    }
    ts.deduplicate = deduplicate;
    /**
     * Deduplicates an array that has already been sorted.
     */
    function deduplicateSorted(array, comparer) {
        if (array.length === 0)
            return ts.emptyArray;
        var last = array[0];
        var deduplicated = [last];
        for (var i = 1; i < array.length; i++) {
            var next = array[i];
            switch (comparer(next, last)) {
                // equality comparison
                case true:
                // relational comparison
                // falls through
                case 0 /* EqualTo */:
                    continue;
                case -1 /* LessThan */:
                    // If `array` is sorted, `next` should **never** be less than `last`.
                    return ts.Debug.fail("Array is unsorted.");
            }
            deduplicated.push(last = next);
        }
        return deduplicated;
    }
    function insertSorted(array, insert, compare) {
        if (array.length === 0) {
            array.push(insert);
            return;
        }
        var insertIndex = binarySearch(array, insert, identity, compare);
        if (insertIndex < 0) {
            array.splice(~insertIndex, 0, insert);
        }
    }
    ts.insertSorted = insertSorted;
    function sortAndDeduplicate(array, comparer, equalityComparer) {
        return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive);
    }
    ts.sortAndDeduplicate = sortAndDeduplicate;
    function arrayIsEqualTo(array1, array2, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (!array1 || !array2) {
            return array1 === array2;
        }
        if (array1.length !== array2.length) {
            return false;
        }
        for (var i = 0; i < array1.length; i++) {
            if (!equalityComparer(array1[i], array2[i], i)) {
                return false;
            }
        }
        return true;
    }
    ts.arrayIsEqualTo = arrayIsEqualTo;
    function compact(array) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = array[i];
                if (result || !v) {
                    if (!result) {
                        result = array.slice(0, i);
                    }
                    if (v) {
                        result.push(v);
                    }
                }
            }
        }
        return result || array;
    }
    ts.compact = compact;
    /**
     * Gets the relative complement of `arrayA` with respect to `arrayB`, returning the elements that
     * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted
     * based on the provided comparer.
     */
    function relativeComplement(arrayA, arrayB, comparer) {
        if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0)
            return arrayB;
        var result = [];
        loopB: for (var offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) {
            if (offsetB > 0) {
                // Ensure `arrayB` is properly sorted.
                ts.Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), 0 /* EqualTo */);
            }
            loopA: for (var startA = offsetA; offsetA < arrayA.length; offsetA++) {
                if (offsetA > startA) {
                    // Ensure `arrayA` is properly sorted. We only need to perform this check if
                    // `offsetA` has changed since we entered the loop.
                    ts.Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), 0 /* EqualTo */);
                }
                switch (comparer(arrayB[offsetB], arrayA[offsetA])) {
                    case -1 /* LessThan */:
                        // If B is less than A, B does not exist in arrayA. Add B to the result and
                        // move to the next element in arrayB without changing the current position
                        // in arrayA.
                        result.push(arrayB[offsetB]);
                        continue loopB;
                    case 0 /* EqualTo */:
                        // If B is equal to A, B exists in arrayA. Move to the next element in
                        // arrayB without adding B to the result or changing the current position
                        // in arrayA.
                        continue loopB;
                    case 1 /* GreaterThan */:
                        // If B is greater than A, we need to keep looking for B in arrayA. Move to
                        // the next element in arrayA and recheck.
                        continue loopA;
                }
            }
        }
        return result;
    }
    ts.relativeComplement = relativeComplement;
    function sum(array, prop) {
        var result = 0;
        for (var _i = 0, array_5 = array; _i < array_5.length; _i++) {
            var v = array_5[_i];
            result += v[prop];
        }
        return result;
    }
    ts.sum = sum;
    function append(to, value) {
        if (value === undefined)
            return to;
        if (to === undefined)
            return [value];
        to.push(value);
        return to;
    }
    ts.append = append;
    function combine(xs, ys) {
        if (xs === undefined)
            return ys;
        if (ys === undefined)
            return xs;
        if (isArray(xs))
            return isArray(ys) ? concatenate(xs, ys) : append(xs, ys);
        if (isArray(ys))
            return append(ys, xs);
        return [xs, ys];
    }
    ts.combine = combine;
    /**
     * Gets the actual offset into an array for a relative offset. Negative offsets indicate a
     * position offset from the end of the array.
     */
    function toOffset(array, offset) {
        return offset < 0 ? array.length + offset : offset;
    }
    function addRange(to, from, start, end) {
        if (from === undefined || from.length === 0)
            return to;
        if (to === undefined)
            return from.slice(start, end);
        start = start === undefined ? 0 : toOffset(from, start);
        end = end === undefined ? from.length : toOffset(from, end);
        for (var i = start; i < end && i < from.length; i++) {
            if (from[i] !== undefined) {
                to.push(from[i]);
            }
        }
        return to;
    }
    ts.addRange = addRange;
    /**
     * @return Whether the value was added.
     */
    function pushIfUnique(array, toAdd, equalityComparer) {
        if (contains(array, toAdd, equalityComparer)) {
            return false;
        }
        else {
            array.push(toAdd);
            return true;
        }
    }
    ts.pushIfUnique = pushIfUnique;
    /**
     * Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array.
     */
    function appendIfUnique(array, toAdd, equalityComparer) {
        if (array) {
            pushIfUnique(array, toAdd, equalityComparer);
            return array;
        }
        else {
            return [toAdd];
        }
    }
    ts.appendIfUnique = appendIfUnique;
    function stableSortIndices(array, indices, comparer) {
        // sort indices by value then position
        indices.sort(function (x, y) { return comparer(array[x], array[y]) || compareValues(x, y); });
    }
    /**
     * Returns a new sorted array.
     */
    function sort(array, comparer) {
        return (array.length === 0 ? array : array.slice().sort(comparer));
    }
    ts.sort = sort;
    function arrayIterator(array) {
        var i = 0;
        return { next: function () {
                if (i === array.length) {
                    return { value: undefined, done: true };
                }
                else {
                    i++;
                    return { value: array[i - 1], done: false };
                }
            } };
    }
    ts.arrayIterator = arrayIterator;
    function arrayReverseIterator(array) {
        var i = array.length;
        return {
            next: function () {
                if (i === 0) {
                    return { value: undefined, done: true };
                }
                else {
                    i--;
                    return { value: array[i], done: false };
                }
            }
        };
    }
    ts.arrayReverseIterator = arrayReverseIterator;
    /**
     * Stable sort of an array. Elements equal to each other maintain their relative position in the array.
     */
    function stableSort(array, comparer) {
        var indices = indicesOf(array);
        stableSortIndices(array, indices, comparer);
        return indices.map(function (i) { return array[i]; });
    }
    ts.stableSort = stableSort;
    function rangeEquals(array1, array2, pos, end) {
        while (pos < end) {
            if (array1[pos] !== array2[pos]) {
                return false;
            }
            pos++;
        }
        return true;
    }
    ts.rangeEquals = rangeEquals;
    /**
     * Returns the element at a specific offset in an array if non-empty, `undefined` otherwise.
     * A negative offset indicates the element should be retrieved from the end of the array.
     */
    function elementAt(array, offset) {
        if (array) {
            offset = toOffset(array, offset);
            if (offset < array.length) {
                return array[offset];
            }
        }
        return undefined;
    }
    ts.elementAt = elementAt;
    /**
     * Returns the first element of an array if non-empty, `undefined` otherwise.
     */
    function firstOrUndefined(array) {
        return array.length === 0 ? undefined : array[0];
    }
    ts.firstOrUndefined = firstOrUndefined;
    function first(array) {
        ts.Debug.assert(array.length !== 0);
        return array[0];
    }
    ts.first = first;
    /**
     * Returns the last element of an array if non-empty, `undefined` otherwise.
     */
    function lastOrUndefined(array) {
        return array.length === 0 ? undefined : array[array.length - 1];
    }
    ts.lastOrUndefined = lastOrUndefined;
    function last(array) {
        ts.Debug.assert(array.length !== 0);
        return array[array.length - 1];
    }
    ts.last = last;
    /**
     * Returns the only element of an array if it contains only one element, `undefined` otherwise.
     */
    function singleOrUndefined(array) {
        return array && array.length === 1
            ? array[0]
            : undefined;
    }
    ts.singleOrUndefined = singleOrUndefined;
    function singleOrMany(array) {
        return array && array.length === 1
            ? array[0]
            : array;
    }
    ts.singleOrMany = singleOrMany;
    function replaceElement(array, index, value) {
        var result = array.slice(0);
        result[index] = value;
        return result;
    }
    ts.replaceElement = replaceElement;
    /**
     * Performs a binary search, finding the index at which `value` occurs in `array`.
     * If no such index is found, returns the 2's-complement of first index at which
     * `array[index]` exceeds `value`.
     * @param array A sorted array whose first element must be no larger than number
     * @param value The value to be searched for in the array.
     * @param keySelector A callback used to select the search key from `value` and each element of
     * `array`.
     * @param keyComparer A callback used to compare two keys in a sorted array.
     * @param offset An offset into `array` at which to start the search.
     */
    function binarySearch(array, value, keySelector, keyComparer, offset) {
        return binarySearchKey(array, keySelector(value), keySelector, keyComparer, offset);
    }
    ts.binarySearch = binarySearch;
    /**
     * Performs a binary search, finding the index at which an object with `key` occurs in `array`.
     * If no such index is found, returns the 2's-complement of first index at which
     * `array[index]` exceeds `key`.
     * @param array A sorted array whose first element must be no larger than number
     * @param key The key to be searched for in the array.
     * @param keySelector A callback used to select the search key from each element of `array`.
     * @param keyComparer A callback used to compare two keys in a sorted array.
     * @param offset An offset into `array` at which to start the search.
     */
    function binarySearchKey(array, key, keySelector, keyComparer, offset) {
        if (!some(array)) {
            return -1;
        }
        var low = offset || 0;
        var high = array.length - 1;
        while (low <= high) {
            var middle = low + ((high - low) >> 1);
            var midKey = keySelector(array[middle]);
            switch (keyComparer(midKey, key)) {
                case -1 /* LessThan */:
                    low = middle + 1;
                    break;
                case 0 /* EqualTo */:
                    return middle;
                case 1 /* GreaterThan */:
                    high = middle - 1;
                    break;
            }
        }
        return ~low;
    }
    ts.binarySearchKey = binarySearchKey;
    function reduceLeft(array, f, initial, start, count) {
        if (array && array.length > 0) {
            var size = array.length;
            if (size > 0) {
                var pos = start === undefined || start < 0 ? 0 : start;
                var end = count === undefined || pos + count > size - 1 ? size - 1 : pos + count;
                var result = void 0;
                if (arguments.length <= 2) {
                    result = array[pos];
                    pos++;
                }
                else {
                    result = initial;
                }
                while (pos <= end) {
                    result = f(result, array[pos], pos);
                    pos++;
                }
                return result;
            }
        }
        return initial;
    }
    ts.reduceLeft = reduceLeft;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    /**
     * Indicates whether a map-like contains an own property with the specified key.
     *
     * @param map A map-like.
     * @param key A property key.
     */
    function hasProperty(map, key) {
        return hasOwnProperty.call(map, key);
    }
    ts.hasProperty = hasProperty;
    /**
     * Gets the value of an owned property in a map-like.
     *
     * @param map A map-like.
     * @param key A property key.
     */
    function getProperty(map, key) {
        return hasOwnProperty.call(map, key) ? map[key] : undefined;
    }
    ts.getProperty = getProperty;
    /**
     * Gets the owned, enumerable property keys of a map-like.
     */
    function getOwnKeys(map) {
        var keys = [];
        for (var key in map) {
            if (hasOwnProperty.call(map, key)) {
                keys.push(key);
            }
        }
        return keys;
    }
    ts.getOwnKeys = getOwnKeys;
    function getAllKeys(obj) {
        var result = [];
        do {
            var names = Object.getOwnPropertyNames(obj);
            for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
                var name = names_1[_i];
                pushIfUnique(result, name);
            }
        } while (obj = Object.getPrototypeOf(obj));
        return result;
    }
    ts.getAllKeys = getAllKeys;
    function getOwnValues(sparseArray) {
        var values = [];
        for (var key in sparseArray) {
            if (hasOwnProperty.call(sparseArray, key)) {
                values.push(sparseArray[key]);
            }
        }
        return values;
    }
    ts.getOwnValues = getOwnValues;
    function arrayFrom(iterator, map) {
        var result = [];
        for (var iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
            result.push(map ? map(iterResult.value) : iterResult.value);
        }
        return result;
    }
    ts.arrayFrom = arrayFrom;
    function assign(t) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
            var arg = args_1[_a];
            if (arg === undefined)
                continue;
            for (var p in arg) {
                if (hasProperty(arg, p)) {
                    t[p] = arg[p];
                }
            }
        }
        return t;
    }
    ts.assign = assign;
    /**
     * Performs a shallow equality comparison of the contents of two map-likes.
     *
     * @param left A map-like whose properties should be compared.
     * @param right A map-like whose properties should be compared.
     */
    function equalOwnProperties(left, right, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (left === right)
            return true;
        if (!left || !right)
            return false;
        for (var key in left) {
            if (hasOwnProperty.call(left, key)) {
                if (!hasOwnProperty.call(right, key))
                    return false;
                if (!equalityComparer(left[key], right[key]))
                    return false;
            }
        }
        for (var key in right) {
            if (hasOwnProperty.call(right, key)) {
                if (!hasOwnProperty.call(left, key))
                    return false;
            }
        }
        return true;
    }
    ts.equalOwnProperties = equalOwnProperties;
    function arrayToMap(array, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = createMap();
        for (var _i = 0, array_6 = array; _i < array_6.length; _i++) {
            var value = array_6[_i];
            var key = makeKey(value);
            if (key !== undefined)
                result.set(key, makeValue(value));
        }
        return result;
    }
    ts.arrayToMap = arrayToMap;
    function arrayToNumericMap(array, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = [];
        for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
            var value = array_7[_i];
            result[makeKey(value)] = makeValue(value);
        }
        return result;
    }
    ts.arrayToNumericMap = arrayToNumericMap;
    function arrayToMultiMap(values, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = createMultiMap();
        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
            var value = values_1[_i];
            result.add(makeKey(value), makeValue(value));
        }
        return result;
    }
    ts.arrayToMultiMap = arrayToMultiMap;
    function group(values, getGroupId, resultSelector) {
        if (resultSelector === void 0) { resultSelector = identity; }
        return arrayFrom(arrayToMultiMap(values, getGroupId).values(), resultSelector);
    }
    ts.group = group;
    function clone(object) {
        var result = {};
        for (var id in object) {
            if (hasOwnProperty.call(object, id)) {
                result[id] = object[id];
            }
        }
        return result;
    }
    ts.clone = clone;
    /**
     * Creates a new object by adding the own properties of `second`, then the own properties of `first`.
     *
     * NOTE: This means that if a property exists in both `first` and `second`, the property in `first` will be chosen.
     */
    function extend(first, second) {
        var result = {};
        for (var id in second) {
            if (hasOwnProperty.call(second, id)) {
                result[id] = second[id];
            }
        }
        for (var id in first) {
            if (hasOwnProperty.call(first, id)) {
                result[id] = first[id];
            }
        }
        return result;
    }
    ts.extend = extend;
    function copyProperties(first, second) {
        for (var id in second) {
            if (hasOwnProperty.call(second, id)) {
                first[id] = second[id];
            }
        }
    }
    ts.copyProperties = copyProperties;
    function maybeBind(obj, fn) {
        return fn ? fn.bind(obj) : undefined;
    }
    ts.maybeBind = maybeBind;
    function mapMap(map, f) {
        var result = createMap();
        map.forEach(function (t, key) { return result.set.apply(result, (f(t, key))); });
        return result;
    }
    ts.mapMap = mapMap;
    function createMultiMap() {
        var map = createMap();
        map.add = multiMapAdd;
        map.remove = multiMapRemove;
        return map;
    }
    ts.createMultiMap = createMultiMap;
    function multiMapAdd(key, value) {
        var values = this.get(key);
        if (values) {
            values.push(value);
        }
        else {
            this.set(key, values = [value]);
        }
        return values;
    }
    function multiMapRemove(key, value) {
        var values = this.get(key);
        if (values) {
            unorderedRemoveItem(values, value);
            if (!values.length) {
                this.delete(key);
            }
        }
    }
    function createUnderscoreEscapedMultiMap() {
        return createMultiMap();
    }
    ts.createUnderscoreEscapedMultiMap = createUnderscoreEscapedMultiMap;
    /**
     * Tests whether a value is an array.
     */
    function isArray(value) {
        return Array.isArray ? Array.isArray(value) : value instanceof Array;
    }
    ts.isArray = isArray;
    function toArray(value) {
        return isArray(value) ? value : [value];
    }
    ts.toArray = toArray;
    /**
     * Tests whether a value is string
     */
    function isString(text) {
        return typeof text === "string";
    }
    ts.isString = isString;
    function isNumber(x) {
        return typeof x === "number";
    }
    ts.isNumber = isNumber;
    function tryCast(value, test) {
        return value !== undefined && test(value) ? value : undefined;
    }
    ts.tryCast = tryCast;
    function cast(value, test) {
        if (value !== undefined && test(value))
            return value;
        return ts.Debug.fail("Invalid cast. The supplied value " + value + " did not pass the test '" + ts.Debug.getFunctionName(test) + "'.");
    }
    ts.cast = cast;
    /** Does nothing. */
    function noop(_) { }
    ts.noop = noop;
    /** Do nothing and return false */
    function returnFalse() { return false; }
    ts.returnFalse = returnFalse;
    /** Do nothing and return true */
    function returnTrue() { return true; }
    ts.returnTrue = returnTrue;
    /** Do nothing and return undefined */
    function returnUndefined() { return undefined; }
    ts.returnUndefined = returnUndefined;
    /** Returns its argument. */
    function identity(x) { return x; }
    ts.identity = identity;
    /** Returns lower case string */
    function toLowerCase(x) { return x.toLowerCase(); }
    ts.toLowerCase = toLowerCase;
    // We convert the file names to lower case as key for file name on case insensitive file system
    // While doing so we need to handle special characters (eg \u0130) to ensure that we dont convert
    // it to lower case, fileName with its lowercase form can exist along side it.
    // Handle special characters and make those case sensitive instead
    //
    // |-#--|-Unicode--|-Char code-|-Desc-------------------------------------------------------------------|
    // | 1. | i        | 105       | Ascii i                                                                |
    // | 2. | I        | 73        | Ascii I                                                                |
    // |-------- Special characters ------------------------------------------------------------------------|
    // | 3. | \u0130   | 304       | Uppper case I with dot above                                           |
    // | 4. | i,\u0307 | 105,775   | i, followed by 775: Lower case of (3rd item)                           |
    // | 5. | I,\u0307 | 73,775    | I, followed by 775: Upper case of (4th item), lower case is (4th item) |
    // | 6. | \u0131   | 305       | Lower case i without dot, upper case is I (2nd item)                   |
    // | 7. | \u00DF   | 223       | Lower case sharp s                                                     |
    //
    // Because item 3 is special where in its lowercase character has its own
    // upper case form we cant convert its case.
    // Rest special characters are either already in lower case format or
    // they have corresponding upper case character so they dont need special handling
    //
    // But to avoid having to do string building for most common cases, also ignore
    // a-z, 0-9, \u0131, \u00DF, \, /, ., : and space
    var fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_\. ]+/g;
    /**
     * Case insensitive file systems have descripencies in how they handle some characters (eg. turkish Upper case I with dot on top - \u0130)
     * This function is used in places where we want to make file name as a key on these systems
     * It is possible on mac to be able to refer to file name with I with dot on top as a fileName with its lower case form
     * But on windows we cannot. Windows can have fileName with I with dot on top next to its lower case and they can not each be referred with the lowercase forms
     * Technically we would want this function to be platform sepcific as well but
     * our api has till now only taken caseSensitive as the only input and just for some characters we dont want to update API and ensure all customers use those api
     * We could use upper case and we would still need to deal with the descripencies but
     * we want to continue using lower case since in most cases filenames are lowercasewe and wont need any case changes and avoid having to store another string for the key
     * So for this function purpose, we go ahead and assume character I with dot on top it as case sensitive since its very unlikely to use lower case form of that special character
     */
    function toFileNameLowerCase(x) {
        return fileNameLowerCaseRegExp.test(x) ?
            x.replace(fileNameLowerCaseRegExp, toLowerCase) :
            x;
    }
    ts.toFileNameLowerCase = toFileNameLowerCase;
    /** Throws an error because a function is not implemented. */
    function notImplemented() {
        throw new Error("Not implemented");
    }
    ts.notImplemented = notImplemented;
    function memoize(callback) {
        var value;
        return function () {
            if (callback) {
                value = callback();
                callback = undefined;
            }
            return value;
        };
    }
    ts.memoize = memoize;
    function compose(a, b, c, d, e) {
        if (!!e) {
            var args_2 = [];
            for (var i = 0; i < arguments.length; i++) {
                args_2[i] = arguments[i];
            }
            return function (t) { return reduceLeft(args_2, function (u, f) { return f(u); }, t); };
        }
        else if (d) {
            return function (t) { return d(c(b(a(t)))); };
        }
        else if (c) {
            return function (t) { return c(b(a(t))); };
        }
        else if (b) {
            return function (t) { return b(a(t)); };
        }
        else if (a) {
            return function (t) { return a(t); };
        }
        else {
            return function (t) { return t; };
        }
    }
    ts.compose = compose;
    var AssertionLevel;
    (function (AssertionLevel) {
        AssertionLevel[AssertionLevel["None"] = 0] = "None";
        AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal";
        AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive";
        AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive";
    })(AssertionLevel = ts.AssertionLevel || (ts.AssertionLevel = {}));
    function equateValues(a, b) {
        return a === b;
    }
    ts.equateValues = equateValues;
    /**
     * Compare the equality of two strings using a case-sensitive ordinal comparison.
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point after applying `toUpperCase` to each string. We always map both
     * strings to their upper-case form as some unicode characters do not properly round-trip to
     * lowercase (such as `ẞ` (German sharp capital s)).
     */
    function equateStringsCaseInsensitive(a, b) {
        return a === b
            || a !== undefined
                && b !== undefined
                && a.toUpperCase() === b.toUpperCase();
    }
    ts.equateStringsCaseInsensitive = equateStringsCaseInsensitive;
    /**
     * Compare the equality of two strings using a case-sensitive ordinal comparison.
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the
     * integer value of each code-point.
     */
    function equateStringsCaseSensitive(a, b) {
        return equateValues(a, b);
    }
    ts.equateStringsCaseSensitive = equateStringsCaseSensitive;
    function compareComparableValues(a, b) {
        return a === b ? 0 /* EqualTo */ :
            a === undefined ? -1 /* LessThan */ :
                b === undefined ? 1 /* GreaterThan */ :
                    a < b ? -1 /* LessThan */ :
                        1 /* GreaterThan */;
    }
    /**
     * Compare two numeric values for their order relative to each other.
     * To compare strings, use any of the `compareStrings` functions.
     */
    function compareValues(a, b) {
        return compareComparableValues(a, b);
    }
    ts.compareValues = compareValues;
    /**
     * Compare two TextSpans, first by `start`, then by `length`.
     */
    function compareTextSpans(a, b) {
        return compareValues(a === null || a === void 0 ? void 0 : a.start, b === null || b === void 0 ? void 0 : b.start) || compareValues(a === null || a === void 0 ? void 0 : a.length, b === null || b === void 0 ? void 0 : b.length);
    }
    ts.compareTextSpans = compareTextSpans;
    function min(a, b, compare) {
        return compare(a, b) === -1 /* LessThan */ ? a : b;
    }
    ts.min = min;
    /**
     * Compare two strings using a case-insensitive ordinal comparison.
     *
     * Ordinal comparisons are based on the difference between the unicode code points of both
     * strings. Characters with multiple unicode representations are considered unequal. Ordinal
     * comparisons provide predictable ordering, but place "a" after "B".
     *
     * Case-insensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point after applying `toUpperCase` to each string. We always map both
     * strings to their upper-case form as some unicode characters do not properly round-trip to
     * lowercase (such as `áºž` (German sharp capital s)).
     */
    function compareStringsCaseInsensitive(a, b) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        a = a.toUpperCase();
        b = b.toUpperCase();
        return a < b ? -1 /* LessThan */ : a > b ? 1 /* GreaterThan */ : 0 /* EqualTo */;
    }
    ts.compareStringsCaseInsensitive = compareStringsCaseInsensitive;
    /**
     * Compare two strings using a case-sensitive ordinal comparison.
     *
     * Ordinal comparisons are based on the difference between the unicode code points of both
     * strings. Characters with multiple unicode representations are considered unequal. Ordinal
     * comparisons provide predictable ordering, but place "a" after "B".
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point.
     */
    function compareStringsCaseSensitive(a, b) {
        return compareComparableValues(a, b);
    }
    ts.compareStringsCaseSensitive = compareStringsCaseSensitive;
    function getStringComparer(ignoreCase) {
        return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive;
    }
    ts.getStringComparer = getStringComparer;
    /**
     * Creates a string comparer for use with string collation in the UI.
     */
    var createUIStringComparer = (function () {
        var defaultComparer;
        var enUSComparer;
        var stringComparerFactory = getStringComparerFactory();
        return createStringComparer;
        function compareWithCallback(a, b, comparer) {
            if (a === b)
                return 0 /* EqualTo */;
            if (a === undefined)
                return -1 /* LessThan */;
            if (b === undefined)
                return 1 /* GreaterThan */;
            var value = comparer(a, b);
            return value < 0 ? -1 /* LessThan */ : value > 0 ? 1 /* GreaterThan */ : 0 /* EqualTo */;
        }
        function createIntlCollatorStringComparer(locale) {
            // Intl.Collator.prototype.compare is bound to the collator. See NOTE in
            // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare
            var comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: "variant" }).compare;
            return function (a, b) { return compareWithCallback(a, b, comparer); };
        }
        function createLocaleCompareStringComparer(locale) {
            // if the locale is not the default locale (`undefined`), use the fallback comparer.
            if (locale !== undefined)
                return createFallbackStringComparer();
            return function (a, b) { return compareWithCallback(a, b, compareStrings); };
            function compareStrings(a, b) {
                return a.localeCompare(b);
            }
        }
        function createFallbackStringComparer() {
            // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b".
            // We first sort case insensitively.  So "Aaa" will come before "baa".
            // Then we sort case sensitively, so "aaa" will come before "Aaa".
            //
            // For case insensitive comparisons we always map both strings to their
            // upper-case form as some unicode characters do not properly round-trip to
            // lowercase (such as `áºž` (German sharp capital s)).
            return function (a, b) { return compareWithCallback(a, b, compareDictionaryOrder); };
            function compareDictionaryOrder(a, b) {
                return compareStrings(a.toUpperCase(), b.toUpperCase()) || compareStrings(a, b);
            }
            function compareStrings(a, b) {
                return a < b ? -1 /* LessThan */ : a > b ? 1 /* GreaterThan */ : 0 /* EqualTo */;
            }
        }
        function getStringComparerFactory() {
            // If the host supports Intl, we use it for comparisons using the default locale.
            if (typeof Intl === "object" && typeof Intl.Collator === "function") {
                return createIntlCollatorStringComparer;
            }
            // If the host does not support Intl, we fall back to localeCompare.
            // localeCompare in Node v0.10 is just an ordinal comparison, so don't use it.
            if (typeof String.prototype.localeCompare === "function" &&
                typeof String.prototype.toLocaleUpperCase === "function" &&
                "a".localeCompare("B") < 0) {
                return createLocaleCompareStringComparer;
            }
            // Otherwise, fall back to ordinal comparison:
            return createFallbackStringComparer;
        }
        function createStringComparer(locale) {
            // Hold onto common string comparers. This avoids constantly reallocating comparers during
            // tests.
            if (locale === undefined) {
                return defaultComparer || (defaultComparer = stringComparerFactory(locale));
            }
            else if (locale === "en-US") {
                return enUSComparer || (enUSComparer = stringComparerFactory(locale));
            }
            else {
                return stringComparerFactory(locale);
            }
        }
    })();
    var uiComparerCaseSensitive;
    var uiLocale;
    function getUILocale() {
        return uiLocale;
    }
    ts.getUILocale = getUILocale;
    function setUILocale(value) {
        if (uiLocale !== value) {
            uiLocale = value;
            uiComparerCaseSensitive = undefined;
        }
    }
    ts.setUILocale = setUILocale;
    /**
     * Compare two strings in a using the case-sensitive sort behavior of the UI locale.
     *
     * Ordering is not predictable between different host locales, but is best for displaying
     * ordered data for UI presentation. Characters with multiple unicode representations may
     * be considered equal.
     *
     * Case-sensitive comparisons compare strings that differ in base characters, or
     * accents/diacritic marks, or case as unequal.
     */
    function compareStringsCaseSensitiveUI(a, b) {
        var comparer = uiComparerCaseSensitive || (uiComparerCaseSensitive = createUIStringComparer(uiLocale));
        return comparer(a, b);
    }
    ts.compareStringsCaseSensitiveUI = compareStringsCaseSensitiveUI;
    function compareProperties(a, b, key, comparer) {
        return a === b ? 0 /* EqualTo */ :
            a === undefined ? -1 /* LessThan */ :
                b === undefined ? 1 /* GreaterThan */ :
                    comparer(a[key], b[key]);
    }
    ts.compareProperties = compareProperties;
    /** True is greater than false. */
    function compareBooleans(a, b) {
        return compareValues(a ? 1 : 0, b ? 1 : 0);
    }
    ts.compareBooleans = compareBooleans;
    /**
     * Given a name and a list of names that are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
     * Names less than length 3 only check for case-insensitive equality, not Levenshtein distance.
     *
     * If there is a candidate that's the same except for case, return that.
     * If there is a candidate that's within one edit of the name, return that.
     * Otherwise, return the candidate with the smallest Levenshtein distance,
     *    except for candidates:
     *      * With no name
     *      * Whose length differs from the target name by more than 0.34 of the length of the name.
     *      * Whose levenshtein distance is more than 0.4 of the length of the name
     *        (0.4 allows 1 substitution/transposition for every 5 characters,
     *         and 1 insertion/deletion at 3 characters)
     */
    function getSpellingSuggestion(name, candidates, getName) {
        var maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34));
        var bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result isn't better than this, don't bother.
        var bestCandidate;
        var justCheckExactMatches = false;
        var nameLowerCase = name.toLowerCase();
        for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
            var candidate = candidates_1[_i];
            var candidateName = getName(candidate);
            if (candidateName !== undefined && Math.abs(candidateName.length - nameLowerCase.length) <= maximumLengthDifference) {
                var candidateNameLowerCase = candidateName.toLowerCase();
                if (candidateNameLowerCase === nameLowerCase) {
                    if (candidateName === name) {
                        continue;
                    }
                    return candidate;
                }
                if (justCheckExactMatches) {
                    continue;
                }
                if (candidateName.length < 3) {
                    // Don't bother, user would have noticed a 2-character name having an extra character
                    continue;
                }
                // Only care about a result better than the best so far.
                var distance = levenshteinWithMax(nameLowerCase, candidateNameLowerCase, bestDistance - 1);
                if (distance === undefined) {
                    continue;
                }
                if (distance < 3) {
                    justCheckExactMatches = true;
                    bestCandidate = candidate;
                }
                else {
                    ts.Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined
                    bestDistance = distance;
                    bestCandidate = candidate;
                }
            }
        }
        return bestCandidate;
    }
    ts.getSpellingSuggestion = getSpellingSuggestion;
    function levenshteinWithMax(s1, s2, max) {
        var previous = new Array(s2.length + 1);
        var current = new Array(s2.length + 1);
        /** Represents any value > max. We don't care about the particular value. */
        var big = max + 1;
        for (var i = 0; i <= s2.length; i++) {
            previous[i] = i;
        }
        for (var i = 1; i <= s1.length; i++) {
            var c1 = s1.charCodeAt(i - 1);
            var minJ = i > max ? i - max : 1;
            var maxJ = s2.length > max + i ? max + i : s2.length;
            current[0] = i;
            /** Smallest value of the matrix in the ith column. */
            var colMin = i;
            for (var j = 1; j < minJ; j++) {
                current[j] = big;
            }
            for (var j = minJ; j <= maxJ; j++) {
                var dist = c1 === s2.charCodeAt(j - 1)
                    ? previous[j - 1]
                    : Math.min(/*delete*/ previous[j] + 1, /*insert*/ current[j - 1] + 1, /*substitute*/ previous[j - 1] + 2);
                current[j] = dist;
                colMin = Math.min(colMin, dist);
            }
            for (var j = maxJ + 1; j <= s2.length; j++) {
                current[j] = big;
            }
            if (colMin > max) {
                // Give up -- everything in this column is > max and it can't get better in future columns.
                return undefined;
            }
            var temp = previous;
            previous = current;
            current = temp;
        }
        var res = previous[s2.length];
        return res > max ? undefined : res;
    }
    function endsWith(str, suffix) {
        var expectedPos = str.length - suffix.length;
        return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
    }
    ts.endsWith = endsWith;
    function removeSuffix(str, suffix) {
        return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : str;
    }
    ts.removeSuffix = removeSuffix;
    function tryRemoveSuffix(str, suffix) {
        return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : undefined;
    }
    ts.tryRemoveSuffix = tryRemoveSuffix;
    function stringContains(str, substring) {
        return str.indexOf(substring) !== -1;
    }
    ts.stringContains = stringContains;
    /**
     * Takes a string like "jquery-min.4.2.3" and returns "jquery"
     */
    function removeMinAndVersionNumbers(fileName) {
        // Match a "." or "-" followed by a version number or 'min' at the end of the name
        var trailingMinOrVersion = /[.-]((min)|(\d+(\.\d+)*))$/;
        // The "min" or version may both be present, in either order, so try applying the above twice.
        return fileName.replace(trailingMinOrVersion, "").replace(trailingMinOrVersion, "");
    }
    ts.removeMinAndVersionNumbers = removeMinAndVersionNumbers;
    /** Remove an item from an array, moving everything to its right one space left. */
    function orderedRemoveItem(array, item) {
        for (var i = 0; i < array.length; i++) {
            if (array[i] === item) {
                orderedRemoveItemAt(array, i);
                return true;
            }
        }
        return false;
    }
    ts.orderedRemoveItem = orderedRemoveItem;
    /** Remove an item by index from an array, moving everything to its right one space left. */
    function orderedRemoveItemAt(array, index) {
        // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
        for (var i = index; i < array.length - 1; i++) {
            array[i] = array[i + 1];
        }
        array.pop();
    }
    ts.orderedRemoveItemAt = orderedRemoveItemAt;
    function unorderedRemoveItemAt(array, index) {
        // Fill in the "hole" left at `index`.
        array[index] = array[array.length - 1];
        array.pop();
    }
    ts.unorderedRemoveItemAt = unorderedRemoveItemAt;
    /** Remove the *first* occurrence of `item` from the array. */
    function unorderedRemoveItem(array, item) {
        return unorderedRemoveFirstItemWhere(array, function (element) { return element === item; });
    }
    ts.unorderedRemoveItem = unorderedRemoveItem;
    /** Remove the *first* element satisfying `predicate`. */
    function unorderedRemoveFirstItemWhere(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                unorderedRemoveItemAt(array, i);
                return true;
            }
        }
        return false;
    }
    function createGetCanonicalFileName(useCaseSensitiveFileNames) {
        return useCaseSensitiveFileNames ? identity : toFileNameLowerCase;
    }
    ts.createGetCanonicalFileName = createGetCanonicalFileName;
    function patternText(_a) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return prefix + "*" + suffix;
    }
    ts.patternText = patternText;
    /**
     * Given that candidate matches pattern, returns the text matching the '*'.
     * E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
     */
    function matchedText(pattern, candidate) {
        ts.Debug.assert(isPatternMatch(pattern, candidate));
        return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length);
    }
    ts.matchedText = matchedText;
    /** Return the object corresponding to the best pattern to match `candidate`. */
    function findBestPatternMatch(values, getPattern, candidate) {
        var matchedValue;
        // use length of prefix as betterness criteria
        var longestMatchPrefixLength = -1;
        for (var _i = 0, values_2 = values; _i < values_2.length; _i++) {
            var v = values_2[_i];
            var pattern = getPattern(v);
            if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) {
                longestMatchPrefixLength = pattern.prefix.length;
                matchedValue = v;
            }
        }
        return matchedValue;
    }
    ts.findBestPatternMatch = findBestPatternMatch;
    function startsWith(str, prefix) {
        return str.lastIndexOf(prefix, 0) === 0;
    }
    ts.startsWith = startsWith;
    function removePrefix(str, prefix) {
        return startsWith(str, prefix) ? str.substr(prefix.length) : str;
    }
    ts.removePrefix = removePrefix;
    function tryRemovePrefix(str, prefix, getCanonicalFileName) {
        if (getCanonicalFileName === void 0) { getCanonicalFileName = identity; }
        return startsWith(getCanonicalFileName(str), getCanonicalFileName(prefix)) ? str.substring(prefix.length) : undefined;
    }
    ts.tryRemovePrefix = tryRemovePrefix;
    function isPatternMatch(_a, candidate) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return candidate.length >= prefix.length + suffix.length &&
            startsWith(candidate, prefix) &&
            endsWith(candidate, suffix);
    }
    function and(f, g) {
        return function (arg) { return f(arg) && g(arg); };
    }
    ts.and = and;
    function or() {
        var fs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            fs[_i] = arguments[_i];
        }
        return function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            for (var _a = 0, fs_1 = fs; _a < fs_1.length; _a++) {
                var f = fs_1[_a];
                if (f.apply(void 0, args)) {
                    return true;
                }
            }
            return false;
        };
    }
    ts.or = or;
    function not(fn) {
        return function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            return !fn.apply(void 0, args);
        };
    }
    ts.not = not;
    function assertType(_) { }
    ts.assertType = assertType;
    function singleElementArray(t) {
        return t === undefined ? undefined : [t];
    }
    ts.singleElementArray = singleElementArray;
    function enumerateInsertsAndDeletes(newItems, oldItems, comparer, inserted, deleted, unchanged) {
        unchanged = unchanged || noop;
        var newIndex = 0;
        var oldIndex = 0;
        var newLen = newItems.length;
        var oldLen = oldItems.length;
        while (newIndex < newLen && oldIndex < oldLen) {
            var newItem = newItems[newIndex];
            var oldItem = oldItems[oldIndex];
            var compareResult = comparer(newItem, oldItem);
            if (compareResult === -1 /* LessThan */) {
                inserted(newItem);
                newIndex++;
            }
            else if (compareResult === 1 /* GreaterThan */) {
                deleted(oldItem);
                oldIndex++;
            }
            else {
                unchanged(oldItem, newItem);
                newIndex++;
                oldIndex++;
            }
        }
        while (newIndex < newLen) {
            inserted(newItems[newIndex++]);
        }
        while (oldIndex < oldLen) {
            deleted(oldItems[oldIndex++]);
        }
    }
    ts.enumerateInsertsAndDeletes = enumerateInsertsAndDeletes;
    function fill(length, cb) {
        var result = Array(length);
        for (var i = 0; i < length; i++) {
            result[i] = cb(i);
        }
        return result;
    }
    ts.fill = fill;
    function cartesianProduct(arrays) {
        var result = [];
        cartesianProductWorker(arrays, result, /*outer*/ undefined, 0);
        return result;
    }
    ts.cartesianProduct = cartesianProduct;
    function cartesianProductWorker(arrays, result, outer, index) {
        for (var _i = 0, _a = arrays[index]; _i < _a.length; _i++) {
            var element = _a[_i];
            var inner = void 0;
            if (outer) {
                inner = outer.slice();
                inner.push(element);
            }
            else {
                inner = [element];
            }
            if (index === arrays.length - 1) {
                result.push(inner);
            }
            else {
                cartesianProductWorker(arrays, result, inner, index + 1);
            }
        }
    }
    function padLeft(s, length) {
        while (s.length < length) {
            s = " " + s;
        }
        return s;
    }
    ts.padLeft = padLeft;
    function padRight(s, length) {
        while (s.length < length) {
            s = s + " ";
        }
        return s;
    }
    ts.padRight = padRight;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Debug;
    (function (Debug) {
        var currentAssertionLevel = 0 /* None */;
        // eslint-disable-next-line prefer-const
        Debug.isDebugging = false;
        var assertionCache = {};
        function getAssertionLevel() {
            return currentAssertionLevel;
        }
        Debug.getAssertionLevel = getAssertionLevel;
        function setAssertionLevel(level) {
            var prevAssertionLevel = currentAssertionLevel;
            currentAssertionLevel = level;
            if (level > prevAssertionLevel) {
                // restore assertion functions for the current assertion level (see `shouldAssertFunction`).
                for (var _i = 0, _a = ts.getOwnKeys(assertionCache); _i < _a.length; _i++) {
                    var key = _a[_i];
                    var cachedFunc = assertionCache[key];
                    if (cachedFunc !== undefined && Debug[key] !== cachedFunc.assertion && level >= cachedFunc.level) {
                        Debug[key] = cachedFunc;
                        assertionCache[key] = undefined;
                    }
                }
            }
        }
        Debug.setAssertionLevel = setAssertionLevel;
        function shouldAssert(level) {
            return currentAssertionLevel >= level;
        }
        Debug.shouldAssert = shouldAssert;
        /**
         * Tests whether an assertion function should be executed. If it shouldn't, it is cached and replaced with `ts.noop`.
         * Replaced assertion functions are restored when `Debug.setAssertionLevel` is set to a high enough level.
         * @param level The minimum assertion level required.
         * @param name The name of the current assertion function.
         */
        function shouldAssertFunction(level, name) {
            if (!shouldAssert(level)) {
                assertionCache[name] = { level: level, assertion: Debug[name] };
                Debug[name] = ts.noop;
                return false;
            }
            return true;
        }
        function fail(message, stackCrawlMark) {
            debugger;
            var e = new Error(message ? "Debug Failure. " + message : "Debug Failure.");
            if (Error.captureStackTrace) {
                Error.captureStackTrace(e, stackCrawlMark || fail);
            }
            throw e;
        }
        Debug.fail = fail;
        function failBadSyntaxKind(node, message, stackCrawlMark) {
            return fail((message || "Unexpected node.") + "\r\nNode " + formatSyntaxKind(node.kind) + " was unexpected.", stackCrawlMark || failBadSyntaxKind);
        }
        Debug.failBadSyntaxKind = failBadSyntaxKind;
        function assert(expression, message, verboseDebugInfo, stackCrawlMark) {
            if (!expression) {
                message = message ? "False expression: " + message : "False expression.";
                if (verboseDebugInfo) {
                    message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo());
                }
                fail(message, stackCrawlMark || assert);
            }
        }
        Debug.assert = assert;
        function assertEqual(a, b, msg, msg2, stackCrawlMark) {
            if (a !== b) {
                var message = msg ? msg2 ? msg + " " + msg2 : msg : "";
                fail("Expected " + a + " === " + b + ". " + message, stackCrawlMark || assertEqual);
            }
        }
        Debug.assertEqual = assertEqual;
        function assertLessThan(a, b, msg, stackCrawlMark) {
            if (a >= b) {
                fail("Expected " + a + " < " + b + ". " + (msg || ""), stackCrawlMark || assertLessThan);
            }
        }
        Debug.assertLessThan = assertLessThan;
        function assertLessThanOrEqual(a, b, stackCrawlMark) {
            if (a > b) {
                fail("Expected " + a + " <= " + b, stackCrawlMark || assertLessThanOrEqual);
            }
        }
        Debug.assertLessThanOrEqual = assertLessThanOrEqual;
        function assertGreaterThanOrEqual(a, b, stackCrawlMark) {
            if (a < b) {
                fail("Expected " + a + " >= " + b, stackCrawlMark || assertGreaterThanOrEqual);
            }
        }
        Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual;
        function assertIsDefined(value, message, stackCrawlMark) {
            // eslint-disable-next-line no-null/no-null
            if (value === undefined || value === null) {
                fail(message, stackCrawlMark || assertIsDefined);
            }
        }
        Debug.assertIsDefined = assertIsDefined;
        function checkDefined(value, message, stackCrawlMark) {
            assertIsDefined(value, message, stackCrawlMark || checkDefined);
            return value;
        }
        Debug.checkDefined = checkDefined;
        /**
         * @deprecated Use `checkDefined` to check whether a value is defined inline. Use `assertIsDefined` to check whether
         * a value is defined at the statement level.
         */
        Debug.assertDefined = checkDefined;
        function assertEachIsDefined(value, message, stackCrawlMark) {
            for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
                var v = value_1[_i];
                assertIsDefined(v, message, stackCrawlMark || assertEachIsDefined);
            }
        }
        Debug.assertEachIsDefined = assertEachIsDefined;
        function checkEachDefined(value, message, stackCrawlMark) {
            assertEachIsDefined(value, message, stackCrawlMark || checkEachDefined);
            return value;
        }
        Debug.checkEachDefined = checkEachDefined;
        /**
         * @deprecated Use `checkEachDefined` to check whether the elements of an array are defined inline. Use `assertEachIsDefined` to check whether
         * the elements of an array are defined at the statement level.
         */
        Debug.assertEachDefined = checkEachDefined;
        function assertNever(member, message, stackCrawlMark) {
            if (message === void 0) { message = "Illegal value:"; }
            var detail = typeof member === "object" && ts.hasProperty(member, "kind") && ts.hasProperty(member, "pos") && formatSyntaxKind ? "SyntaxKind: " + formatSyntaxKind(member.kind) : JSON.stringify(member);
            return fail(message + " " + detail, stackCrawlMark || assertNever);
        }
        Debug.assertNever = assertNever;
        function assertEachNode(nodes, test, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertEachNode")) {
                assert(test === undefined || ts.every(nodes, test), message || "Unexpected node.", function () { return "Node array did not pass test '" + getFunctionName(test) + "'."; }, stackCrawlMark || assertEachNode);
            }
        }
        Debug.assertEachNode = assertEachNode;
        function assertNode(node, test, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertNode")) {
                assert(node !== undefined && (test === undefined || test(node)), message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " did not pass test '" + getFunctionName(test) + "'."; }, stackCrawlMark || assertNode);
            }
        }
        Debug.assertNode = assertNode;
        function assertNotNode(node, test, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertNotNode")) {
                assert(node === undefined || test === undefined || !test(node), message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " should not have passed test '" + getFunctionName(test) + "'."; }, stackCrawlMark || assertNotNode);
            }
        }
        Debug.assertNotNode = assertNotNode;
        function assertOptionalNode(node, test, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertOptionalNode")) {
                assert(test === undefined || node === undefined || test(node), message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " did not pass test '" + getFunctionName(test) + "'."; }, stackCrawlMark || assertOptionalNode);
            }
        }
        Debug.assertOptionalNode = assertOptionalNode;
        function assertOptionalToken(node, kind, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertOptionalToken")) {
                assert(kind === undefined || node === undefined || node.kind === kind, message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " was not a '" + formatSyntaxKind(kind) + "' token."; }, stackCrawlMark || assertOptionalToken);
            }
        }
        Debug.assertOptionalToken = assertOptionalToken;
        function assertMissingNode(node, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertMissingNode")) {
                assert(node === undefined, message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " was unexpected'."; }, stackCrawlMark || assertMissingNode);
            }
        }
        Debug.assertMissingNode = assertMissingNode;
        function getFunctionName(func) {
            if (typeof func !== "function") {
                return "";
            }
            else if (func.hasOwnProperty("name")) {
                return func.name;
            }
            else {
                var text = Function.prototype.toString.call(func);
                var match = /^function\s+([\w\$]+)\s*\(/.exec(text);
                return match ? match[1] : "";
            }
        }
        Debug.getFunctionName = getFunctionName;
        function formatSymbol(symbol) {
            return "{ name: " + ts.unescapeLeadingUnderscores(symbol.escapedName) + "; flags: " + formatSymbolFlags(symbol.flags) + "; declarations: " + ts.map(symbol.declarations, function (node) { return formatSyntaxKind(node.kind); }) + " }";
        }
        Debug.formatSymbol = formatSymbol;
        /**
         * Formats an enum value as a string for debugging and debug assertions.
         */
        function formatEnum(value, enumObject, isFlags) {
            if (value === void 0) { value = 0; }
            var members = getEnumMembers(enumObject);
            if (value === 0) {
                return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0";
            }
            if (isFlags) {
                var result = "";
                var remainingFlags = value;
                for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
                    var _a = members_1[_i], enumValue = _a[0], enumName = _a[1];
                    if (enumValue > value) {
                        break;
                    }
                    if (enumValue !== 0 && enumValue & value) {
                        result = "" + result + (result ? "|" : "") + enumName;
                        remainingFlags &= ~enumValue;
                    }
                }
                if (remainingFlags === 0) {
                    return result;
                }
            }
            else {
                for (var _b = 0, members_2 = members; _b < members_2.length; _b++) {
                    var _c = members_2[_b], enumValue = _c[0], enumName = _c[1];
                    if (enumValue === value) {
                        return enumName;
                    }
                }
            }
            return value.toString();
        }
        Debug.formatEnum = formatEnum;
        function getEnumMembers(enumObject) {
            var result = [];
            for (var name in enumObject) {
                var value = enumObject[name];
                if (typeof value === "number") {
                    result.push([value, name]);
                }
            }
            return ts.stableSort(result, function (x, y) { return ts.compareValues(x[0], y[0]); });
        }
        function formatSyntaxKind(kind) {
            return formatEnum(kind, ts.SyntaxKind, /*isFlags*/ false);
        }
        Debug.formatSyntaxKind = formatSyntaxKind;
        function formatNodeFlags(flags) {
            return formatEnum(flags, ts.NodeFlags, /*isFlags*/ true);
        }
        Debug.formatNodeFlags = formatNodeFlags;
        function formatModifierFlags(flags) {
            return formatEnum(flags, ts.ModifierFlags, /*isFlags*/ true);
        }
        Debug.formatModifierFlags = formatModifierFlags;
        function formatTransformFlags(flags) {
            return formatEnum(flags, ts.TransformFlags, /*isFlags*/ true);
        }
        Debug.formatTransformFlags = formatTransformFlags;
        function formatEmitFlags(flags) {
            return formatEnum(flags, ts.EmitFlags, /*isFlags*/ true);
        }
        Debug.formatEmitFlags = formatEmitFlags;
        function formatSymbolFlags(flags) {
            return formatEnum(flags, ts.SymbolFlags, /*isFlags*/ true);
        }
        Debug.formatSymbolFlags = formatSymbolFlags;
        function formatTypeFlags(flags) {
            return formatEnum(flags, ts.TypeFlags, /*isFlags*/ true);
        }
        Debug.formatTypeFlags = formatTypeFlags;
        function formatObjectFlags(flags) {
            return formatEnum(flags, ts.ObjectFlags, /*isFlags*/ true);
        }
        Debug.formatObjectFlags = formatObjectFlags;
        var isDebugInfoEnabled = false;
        var extendedDebugModule;
        function extendedDebug() {
            enableDebugInfo();
            if (!extendedDebugModule) {
                throw new Error("Debugging helpers could not be loaded.");
            }
            return extendedDebugModule;
        }
        function printControlFlowGraph(flowNode) {
            return console.log(formatControlFlowGraph(flowNode));
        }
        Debug.printControlFlowGraph = printControlFlowGraph;
        function formatControlFlowGraph(flowNode) {
            return extendedDebug().formatControlFlowGraph(flowNode);
        }
        Debug.formatControlFlowGraph = formatControlFlowGraph;
        function attachFlowNodeDebugInfo(flowNode) {
            if (isDebugInfoEnabled) {
                if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line no-in-operator
                    Object.defineProperties(flowNode, {
                        __debugFlowFlags: { get: function () { return formatEnum(this.flags, ts.FlowFlags, /*isFlags*/ true); } },
                        __debugToString: { value: function () { return formatControlFlowGraph(this); } }
                    });
                }
            }
        }
        Debug.attachFlowNodeDebugInfo = attachFlowNodeDebugInfo;
        /**
         * Injects debug information into frequently used types.
         */
        function enableDebugInfo() {
            if (isDebugInfoEnabled)
                return;
            // Add additional properties in debug mode to assist with debugging.
            Object.defineProperties(ts.objectAllocator.getSymbolConstructor().prototype, {
                __debugFlags: { get: function () { return formatSymbolFlags(this.flags); } }
            });
            Object.defineProperties(ts.objectAllocator.getTypeConstructor().prototype, {
                __debugFlags: { get: function () { return formatTypeFlags(this.flags); } },
                __debugObjectFlags: { get: function () { return this.flags & 524288 /* Object */ ? formatObjectFlags(this.objectFlags) : ""; } },
                __debugTypeToString: { value: function () { return this.checker.typeToString(this); } },
            });
            var nodeConstructors = [
                ts.objectAllocator.getNodeConstructor(),
                ts.objectAllocator.getIdentifierConstructor(),
                ts.objectAllocator.getTokenConstructor(),
                ts.objectAllocator.getSourceFileConstructor()
            ];
            for (var _i = 0, nodeConstructors_1 = nodeConstructors; _i < nodeConstructors_1.length; _i++) {
                var ctor = nodeConstructors_1[_i];
                if (!ctor.prototype.hasOwnProperty("__debugKind")) {
                    Object.defineProperties(ctor.prototype, {
                        __debugKind: { get: function () { return formatSyntaxKind(this.kind); } },
                        __debugNodeFlags: { get: function () { return formatNodeFlags(this.flags); } },
                        __debugModifierFlags: { get: function () { return formatModifierFlags(ts.getModifierFlagsNoCache(this)); } },
                        __debugTransformFlags: { get: function () { return formatTransformFlags(this.transformFlags); } },
                        __debugIsParseTreeNode: { get: function () { return ts.isParseTreeNode(this); } },
                        __debugEmitFlags: { get: function () { return formatEmitFlags(ts.getEmitFlags(this)); } },
                        __debugGetText: {
                            value: function (includeTrivia) {
                                if (ts.nodeIsSynthesized(this))
                                    return "";
                                var parseNode = ts.getParseTreeNode(this);
                                var sourceFile = parseNode && ts.getSourceFileOfNode(parseNode);
                                return sourceFile ? ts.getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
                            }
                        }
                    });
                }
            }
            // attempt to load extended debugging information
            try {
                if (ts.sys && ts.sys.require) {
                    var basePath = ts.getDirectoryPath(ts.resolvePath(ts.sys.getExecutingFilePath()));
                    var result = ts.sys.require(basePath, "./compiler-debug");
                    if (!result.error) {
                        result.module.init(ts);
                        extendedDebugModule = result.module;
                    }
                }
            }
            catch (_a) {
                // do nothing
            }
            isDebugInfoEnabled = true;
        }
        Debug.enableDebugInfo = enableDebugInfo;
    })(Debug = ts.Debug || (ts.Debug = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /** Gets a timestamp with (at least) ms resolution */
    ts.timestamp = typeof performance !== "undefined" && performance.now ? function () { return performance.now(); } : Date.now ? Date.now : function () { return +(new Date()); };
})(ts || (ts = {}));
/*@internal*/
/** Performance measurements for the compiler. */
var ts;
(function (ts) {
    var performance;
    (function (performance) {
        // NOTE: cannot use ts.noop as core.ts loads after this
        var profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : function () { };
        var enabled = false;
        var profilerStart = 0;
        var counts;
        var marks;
        var measures;
        function createTimerIf(condition, measureName, startMarkName, endMarkName) {
            return condition ? createTimer(measureName, startMarkName, endMarkName) : performance.nullTimer;
        }
        performance.createTimerIf = createTimerIf;
        function createTimer(measureName, startMarkName, endMarkName) {
            var enterCount = 0;
            return {
                enter: enter,
                exit: exit
            };
            function enter() {
                if (++enterCount === 1) {
                    mark(startMarkName);
                }
            }
            function exit() {
                if (--enterCount === 0) {
                    mark(endMarkName);
                    measure(measureName, startMarkName, endMarkName);
                }
                else if (enterCount < 0) {
                    ts.Debug.fail("enter/exit count does not match.");
                }
            }
        }
        performance.createTimer = createTimer;
        performance.nullTimer = { enter: ts.noop, exit: ts.noop };
        /**
         * Marks a performance event.
         *
         * @param markName The name of the mark.
         */
        function mark(markName) {
            if (enabled) {
                marks.set(markName, ts.timestamp());
                counts.set(markName, (counts.get(markName) || 0) + 1);
                profilerEvent(markName);
            }
        }
        performance.mark = mark;
        /**
         * Adds a performance measurement with the specified name.
         *
         * @param measureName The name of the performance measurement.
         * @param startMarkName The name of the starting mark. If not supplied, the point at which the
         *      profiler was enabled is used.
         * @param endMarkName The name of the ending mark. If not supplied, the current timestamp is
         *      used.
         */
        function measure(measureName, startMarkName, endMarkName) {
            if (enabled) {
                var end = endMarkName && marks.get(endMarkName) || ts.timestamp();
                var start = startMarkName && marks.get(startMarkName) || profilerStart;
                measures.set(measureName, (measures.get(measureName) || 0) + (end - start));
            }
        }
        performance.measure = measure;
        /**
         * Gets the number of times a marker was encountered.
         *
         * @param markName The name of the mark.
         */
        function getCount(markName) {
            return counts && counts.get(markName) || 0;
        }
        performance.getCount = getCount;
        /**
         * Gets the total duration of all measurements with the supplied name.
         *
         * @param measureName The name of the measure whose durations should be accumulated.
         */
        function getDuration(measureName) {
            return measures && measures.get(measureName) || 0;
        }
        performance.getDuration = getDuration;
        /**
         * Iterate over each measure, performing some action
         *
         * @param cb The action to perform for each measure
         */
        function forEachMeasure(cb) {
            measures.forEach(function (measure, key) {
                cb(key, measure);
            });
        }
        performance.forEachMeasure = forEachMeasure;
        /** Enables (and resets) performance measurements for the compiler. */
        function enable() {
            counts = ts.createMap();
            marks = ts.createMap();
            measures = ts.createMap();
            enabled = true;
            profilerStart = ts.timestamp();
        }
        performance.enable = enable;
        /** Disables performance measurements for the compiler. */
        function disable() {
            enabled = false;
        }
        performance.disable = disable;
    })(performance = ts.performance || (ts.performance = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var _a;
    var nullLogger = {
        logEvent: ts.noop,
        logErrEvent: ts.noop,
        logPerfEvent: ts.noop,
        logInfoEvent: ts.noop,
        logStartCommand: ts.noop,
        logStopCommand: ts.noop,
        logStartUpdateProgram: ts.noop,
        logStopUpdateProgram: ts.noop,
        logStartUpdateGraph: ts.noop,
        logStopUpdateGraph: ts.noop,
        logStartResolveModule: ts.noop,
        logStopResolveModule: ts.noop,
        logStartParseSourceFile: ts.noop,
        logStopParseSourceFile: ts.noop,
        logStartReadFile: ts.noop,
        logStopReadFile: ts.noop,
        logStartBindFile: ts.noop,
        logStopBindFile: ts.noop,
        logStartScheduledOperation: ts.noop,
        logStopScheduledOperation: ts.noop,
    };
    // Load optional module to enable Event Tracing for Windows
    // See https://github.com/microsoft/typescript-etw for more information
    var etwModule;
    try {
        var etwModulePath = (_a = process.env.TS_ETW_MODULE_PATH) !== null && _a !== void 0 ? _a : "./node_modules/@microsoft/typescript-etw";
        // require() will throw an exception if the module is not found
        // It may also return undefined if not installed properly
        etwModule = require(etwModulePath);
    }
    catch (e) {
        etwModule = undefined;
    }
    /** Performance logger that will generate ETW events if possible - check for `logEvent` member, as `etwModule` will be `{}` when browserified */
    ts.perfLogger = etwModule && etwModule.logEvent ? etwModule : nullLogger;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    // https://semver.org/#spec-item-2
    // > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative
    // > integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor
    // > version, and Z is the patch version. Each element MUST increase numerically.
    //
    // NOTE: We differ here in that we allow X and X.Y, with missing parts having the default
    // value of `0`.
    var versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
    // https://semver.org/#spec-item-9
    // > A pre-release version MAY be denoted by appending a hyphen and a series of dot separated
    // > identifiers immediately following the patch version. Identifiers MUST comprise only ASCII
    // > alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers
    // > MUST NOT include leading zeroes.
    var prereleaseRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)(?:\.(?:0|[1-9]\d*|[a-z-][a-z0-9-]*))*$/i;
    // https://semver.org/#spec-item-10
    // > Build metadata MAY be denoted by appending a plus sign and a series of dot separated
    // > identifiers immediately following the patch or pre-release version. Identifiers MUST
    // > comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty.
    var buildRegExp = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/i;
    // https://semver.org/#spec-item-9
    // > Numeric identifiers MUST NOT include leading zeroes.
    var numericIdentifierRegExp = /^(0|[1-9]\d*)$/;
    /**
     * Describes a precise semantic version number, https://semver.org
     */
    var Version = /** @class */ (function () {
        function Version(major, minor, patch, prerelease, build) {
            if (minor === void 0) { minor = 0; }
            if (patch === void 0) { patch = 0; }
            if (prerelease === void 0) { prerelease = ""; }
            if (build === void 0) { build = ""; }
            if (typeof major === "string") {
                var result = ts.Debug.checkDefined(tryParseComponents(major), "Invalid version");
                (major = result.major, minor = result.minor, patch = result.patch, prerelease = result.prerelease, build = result.build);
            }
            ts.Debug.assert(major >= 0, "Invalid argument: major");
            ts.Debug.assert(minor >= 0, "Invalid argument: minor");
            ts.Debug.assert(patch >= 0, "Invalid argument: patch");
            ts.Debug.assert(!prerelease || prereleaseRegExp.test(prerelease), "Invalid argument: prerelease");
            ts.Debug.assert(!build || buildRegExp.test(build), "Invalid argument: build");
            this.major = major;
            this.minor = minor;
            this.patch = patch;
            this.prerelease = prerelease ? prerelease.split(".") : ts.emptyArray;
            this.build = build ? build.split(".") : ts.emptyArray;
        }
        Version.tryParse = function (text) {
            var result = tryParseComponents(text);
            if (!result)
                return undefined;
            var major = result.major, minor = result.minor, patch = result.patch, prerelease = result.prerelease, build = result.build;
            return new Version(major, minor, patch, prerelease, build);
        };
        Version.prototype.compareTo = function (other) {
            // https://semver.org/#spec-item-11
            // > Precedence is determined by the first difference when comparing each of these
            // > identifiers from left to right as follows: Major, minor, and patch versions are
            // > always compared numerically.
            //
            // https://semver.org/#spec-item-11
            // > Precedence for two pre-release versions with the same major, minor, and patch version
            // > MUST be determined by comparing each dot separated identifier from left to right until
            // > a difference is found [...]
            //
            // https://semver.org/#spec-item-11
            // > Build metadata does not figure into precedence
            if (this === other)
                return 0 /* EqualTo */;
            if (other === undefined)
                return 1 /* GreaterThan */;
            return ts.compareValues(this.major, other.major)
                || ts.compareValues(this.minor, other.minor)
                || ts.compareValues(this.patch, other.patch)
                || comparePrerelaseIdentifiers(this.prerelease, other.prerelease);
        };
        Version.prototype.increment = function (field) {
            switch (field) {
                case "major": return new Version(this.major + 1, 0, 0);
                case "minor": return new Version(this.major, this.minor + 1, 0);
                case "patch": return new Version(this.major, this.minor, this.patch + 1);
                default: return ts.Debug.assertNever(field);
            }
        };
        Version.prototype.toString = function () {
            var result = this.major + "." + this.minor + "." + this.patch;
            if (ts.some(this.prerelease))
                result += "-" + this.prerelease.join(".");
            if (ts.some(this.build))
                result += "+" + this.build.join(".");
            return result;
        };
        Version.zero = new Version(0, 0, 0);
        return Version;
    }());
    ts.Version = Version;
    function tryParseComponents(text) {
        var match = versionRegExp.exec(text);
        if (!match)
            return undefined;
        var major = match[1], _a = match[2], minor = _a === void 0 ? "0" : _a, _b = match[3], patch = _b === void 0 ? "0" : _b, _c = match[4], prerelease = _c === void 0 ? "" : _c, _d = match[5], build = _d === void 0 ? "" : _d;
        if (prerelease && !prereleaseRegExp.test(prerelease))
            return undefined;
        if (build && !buildRegExp.test(build))
            return undefined;
        return {
            major: parseInt(major, 10),
            minor: parseInt(minor, 10),
            patch: parseInt(patch, 10),
            prerelease: prerelease,
            build: build
        };
    }
    function comparePrerelaseIdentifiers(left, right) {
        // https://semver.org/#spec-item-11
        // > When major, minor, and patch are equal, a pre-release version has lower precedence
        // > than a normal version.
        if (left === right)
            return 0 /* EqualTo */;
        if (left.length === 0)
            return right.length === 0 ? 0 /* EqualTo */ : 1 /* GreaterThan */;
        if (right.length === 0)
            return -1 /* LessThan */;
        // https://semver.org/#spec-item-11
        // > Precedence for two pre-release versions with the same major, minor, and patch version
        // > MUST be determined by comparing each dot separated identifier from left to right until
        // > a difference is found [...]
        var length = Math.min(left.length, right.length);
        for (var i = 0; i < length; i++) {
            var leftIdentifier = left[i];
            var rightIdentifier = right[i];
            if (leftIdentifier === rightIdentifier)
                continue;
            var leftIsNumeric = numericIdentifierRegExp.test(leftIdentifier);
            var rightIsNumeric = numericIdentifierRegExp.test(rightIdentifier);
            if (leftIsNumeric || rightIsNumeric) {
                // https://semver.org/#spec-item-11
                // > Numeric identifiers always have lower precedence than non-numeric identifiers.
                if (leftIsNumeric !== rightIsNumeric)
                    return leftIsNumeric ? -1 /* LessThan */ : 1 /* GreaterThan */;
                // https://semver.org/#spec-item-11
                // > identifiers consisting of only digits are compared numerically
                var result = ts.compareValues(+leftIdentifier, +rightIdentifier);
                if (result)
                    return result;
            }
            else {
                // https://semver.org/#spec-item-11
                // > identifiers with letters or hyphens are compared lexically in ASCII sort order.
                var result = ts.compareStringsCaseSensitive(leftIdentifier, rightIdentifier);
                if (result)
                    return result;
            }
        }
        // https://semver.org/#spec-item-11
        // > A larger set of pre-release fields has a higher precedence than a smaller set, if all
        // > of the preceding identifiers are equal.
        return ts.compareValues(left.length, right.length);
    }
    /**
     * Describes a semantic version range, per https://github.com/npm/node-semver#ranges
     */
    var VersionRange = /** @class */ (function () {
        function VersionRange(spec) {
            this._alternatives = spec ? ts.Debug.checkDefined(parseRange(spec), "Invalid range spec.") : ts.emptyArray;
        }
        VersionRange.tryParse = function (text) {
            var sets = parseRange(text);
            if (sets) {
                var range = new VersionRange("");
                range._alternatives = sets;
                return range;
            }
            return undefined;
        };
        VersionRange.prototype.test = function (version) {
            if (typeof version === "string")
                version = new Version(version);
            return testDisjunction(version, this._alternatives);
        };
        VersionRange.prototype.toString = function () {
            return formatDisjunction(this._alternatives);
        };
        return VersionRange;
    }());
    ts.VersionRange = VersionRange;
    // https://github.com/npm/node-semver#range-grammar
    //
    // range-set    ::= range ( logical-or range ) *
    // range        ::= hyphen | simple ( ' ' simple ) * | ''
    // logical-or   ::= ( ' ' ) * '||' ( ' ' ) *
    var logicalOrRegExp = /\s*\|\|\s*/g;
    var whitespaceRegExp = /\s+/g;
    // https://github.com/npm/node-semver#range-grammar
    //
    // partial      ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
    // xr           ::= 'x' | 'X' | '*' | nr
    // nr           ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
    // qualifier    ::= ( '-' pre )? ( '+' build )?
    // pre          ::= parts
    // build        ::= parts
    // parts        ::= part ( '.' part ) *
    // part         ::= nr | [-0-9A-Za-z]+
    var partialRegExp = /^([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
    // https://github.com/npm/node-semver#range-grammar
    //
    // hyphen       ::= partial ' - ' partial
    var hyphenRegExp = /^\s*([a-z0-9-+.*]+)\s+-\s+([a-z0-9-+.*]+)\s*$/i;
    // https://github.com/npm/node-semver#range-grammar
    //
    // simple       ::= primitive | partial | tilde | caret
    // primitive    ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
    // tilde        ::= '~' partial
    // caret        ::= '^' partial
    var rangeRegExp = /^\s*(~|\^|<|<=|>|>=|=)?\s*([a-z0-9-+.*]+)$/i;
    function parseRange(text) {
        var alternatives = [];
        for (var _i = 0, _a = text.trim().split(logicalOrRegExp); _i < _a.length; _i++) {
            var range = _a[_i];
            if (!range)
                continue;
            var comparators = [];
            var match = hyphenRegExp.exec(range);
            if (match) {
                if (!parseHyphen(match[1], match[2], comparators))
                    return undefined;
            }
            else {
                for (var _b = 0, _c = range.split(whitespaceRegExp); _b < _c.length; _b++) {
                    var simple = _c[_b];
                    var match_1 = rangeRegExp.exec(simple);
                    if (!match_1 || !parseComparator(match_1[1], match_1[2], comparators))
                        return undefined;
                }
            }
            alternatives.push(comparators);
        }
        return alternatives;
    }
    function parsePartial(text) {
        var match = partialRegExp.exec(text);
        if (!match)
            return undefined;
        var major = match[1], _a = match[2], minor = _a === void 0 ? "*" : _a, _b = match[3], patch = _b === void 0 ? "*" : _b, prerelease = match[4], build = match[5];
        var version = new Version(isWildcard(major) ? 0 : parseInt(major, 10), isWildcard(major) || isWildcard(minor) ? 0 : parseInt(minor, 10), isWildcard(major) || isWildcard(minor) || isWildcard(patch) ? 0 : parseInt(patch, 10), prerelease, build);
        return { version: version, major: major, minor: minor, patch: patch };
    }
    function parseHyphen(left, right, comparators) {
        var leftResult = parsePartial(left);
        if (!leftResult)
            return false;
        var rightResult = parsePartial(right);
        if (!rightResult)
            return false;
        if (!isWildcard(leftResult.major)) {
            comparators.push(createComparator(">=", leftResult.version));
        }
        if (!isWildcard(rightResult.major)) {
            comparators.push(isWildcard(rightResult.minor) ? createComparator("<", rightResult.version.increment("major")) :
                isWildcard(rightResult.patch) ? createComparator("<", rightResult.version.increment("minor")) :
                    createComparator("<=", rightResult.version));
        }
        return true;
    }
    function parseComparator(operator, text, comparators) {
        var result = parsePartial(text);
        if (!result)
            return false;
        var version = result.version, major = result.major, minor = result.minor, patch = result.patch;
        if (!isWildcard(major)) {
            switch (operator) {
                case "~":
                    comparators.push(createComparator(">=", version));
                    comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" :
                        "minor")));
                    break;
                case "^":
                    comparators.push(createComparator(">=", version));
                    comparators.push(createComparator("<", version.increment(version.major > 0 || isWildcard(minor) ? "major" :
                        version.minor > 0 || isWildcard(patch) ? "minor" :
                            "patch")));
                    break;
                case "<":
                case ">=":
                    comparators.push(createComparator(operator, version));
                    break;
                case "<=":
                case ">":
                    comparators.push(isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major")) :
                        isWildcard(patch) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("minor")) :
                            createComparator(operator, version));
                    break;
                case "=":
                case undefined:
                    if (isWildcard(minor) || isWildcard(patch)) {
                        comparators.push(createComparator(">=", version));
                        comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" : "minor")));
                    }
                    else {
                        comparators.push(createComparator("=", version));
                    }
                    break;
                default:
                    // unrecognized
                    return false;
            }
        }
        else if (operator === "<" || operator === ">") {
            comparators.push(createComparator("<", Version.zero));
        }
        return true;
    }
    function isWildcard(part) {
        return part === "*" || part === "x" || part === "X";
    }
    function createComparator(operator, operand) {
        return { operator: operator, operand: operand };
    }
    function testDisjunction(version, alternatives) {
        // an empty disjunction is treated as "*" (all versions)
        if (alternatives.length === 0)
            return true;
        for (var _i = 0, alternatives_1 = alternatives; _i < alternatives_1.length; _i++) {
            var alternative = alternatives_1[_i];
            if (testAlternative(version, alternative))
                return true;
        }
        return false;
    }
    function testAlternative(version, comparators) {
        for (var _i = 0, comparators_1 = comparators; _i < comparators_1.length; _i++) {
            var comparator = comparators_1[_i];
            if (!testComparator(version, comparator.operator, comparator.operand))
                return false;
        }
        return true;
    }
    function testComparator(version, operator, operand) {
        var cmp = version.compareTo(operand);
        switch (operator) {
            case "<": return cmp < 0;
            case "<=": return cmp <= 0;
            case ">": return cmp > 0;
            case ">=": return cmp >= 0;
            case "=": return cmp === 0;
            default: return ts.Debug.assertNever(operator);
        }
    }
    function formatDisjunction(alternatives) {
        return ts.map(alternatives, formatAlternative).join(" || ") || "*";
    }
    function formatAlternative(comparators) {
        return ts.map(comparators, formatComparator).join(" ");
    }
    function formatComparator(comparator) {
        return "" + comparator.operator + comparator.operand;
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    // token > SyntaxKind.Identifier => token is a keyword
    // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync
    var SyntaxKind;
    (function (SyntaxKind) {
        SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown";
        SyntaxKind[SyntaxKind["EndOfFileToken"] = 1] = "EndOfFileToken";
        SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
        SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 3] = "MultiLineCommentTrivia";
        SyntaxKind[SyntaxKind["NewLineTrivia"] = 4] = "NewLineTrivia";
        SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 5] = "WhitespaceTrivia";
        // We detect and preserve #! on the first line
        SyntaxKind[SyntaxKind["ShebangTrivia"] = 6] = "ShebangTrivia";
        // We detect and provide better error recovery when we encounter a git merge marker.  This
        // allows us to edit files with git-conflict markers in them in a much more pleasant manner.
        SyntaxKind[SyntaxKind["ConflictMarkerTrivia"] = 7] = "ConflictMarkerTrivia";
        // Literals
        SyntaxKind[SyntaxKind["NumericLiteral"] = 8] = "NumericLiteral";
        SyntaxKind[SyntaxKind["BigIntLiteral"] = 9] = "BigIntLiteral";
        SyntaxKind[SyntaxKind["StringLiteral"] = 10] = "StringLiteral";
        SyntaxKind[SyntaxKind["JsxText"] = 11] = "JsxText";
        SyntaxKind[SyntaxKind["JsxTextAllWhiteSpaces"] = 12] = "JsxTextAllWhiteSpaces";
        SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 13] = "RegularExpressionLiteral";
        SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 14] = "NoSubstitutionTemplateLiteral";
        // Pseudo-literals
        SyntaxKind[SyntaxKind["TemplateHead"] = 15] = "TemplateHead";
        SyntaxKind[SyntaxKind["TemplateMiddle"] = 16] = "TemplateMiddle";
        SyntaxKind[SyntaxKind["TemplateTail"] = 17] = "TemplateTail";
        // Punctuation
        SyntaxKind[SyntaxKind["OpenBraceToken"] = 18] = "OpenBraceToken";
        SyntaxKind[SyntaxKind["CloseBraceToken"] = 19] = "CloseBraceToken";
        SyntaxKind[SyntaxKind["OpenParenToken"] = 20] = "OpenParenToken";
        SyntaxKind[SyntaxKind["CloseParenToken"] = 21] = "CloseParenToken";
        SyntaxKind[SyntaxKind["OpenBracketToken"] = 22] = "OpenBracketToken";
        SyntaxKind[SyntaxKind["CloseBracketToken"] = 23] = "CloseBracketToken";
        SyntaxKind[SyntaxKind["DotToken"] = 24] = "DotToken";
        SyntaxKind[SyntaxKind["DotDotDotToken"] = 25] = "DotDotDotToken";
        SyntaxKind[SyntaxKind["SemicolonToken"] = 26] = "SemicolonToken";
        SyntaxKind[SyntaxKind["CommaToken"] = 27] = "CommaToken";
        SyntaxKind[SyntaxKind["QuestionDotToken"] = 28] = "QuestionDotToken";
        SyntaxKind[SyntaxKind["LessThanToken"] = 29] = "LessThanToken";
        SyntaxKind[SyntaxKind["LessThanSlashToken"] = 30] = "LessThanSlashToken";
        SyntaxKind[SyntaxKind["GreaterThanToken"] = 31] = "GreaterThanToken";
        SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 32] = "LessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 33] = "GreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 34] = "EqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 35] = "ExclamationEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 36] = "EqualsEqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 37] = "ExclamationEqualsEqualsToken";
        SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 38] = "EqualsGreaterThanToken";
        SyntaxKind[SyntaxKind["PlusToken"] = 39] = "PlusToken";
        SyntaxKind[SyntaxKind["MinusToken"] = 40] = "MinusToken";
        SyntaxKind[SyntaxKind["AsteriskToken"] = 41] = "AsteriskToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskToken"] = 42] = "AsteriskAsteriskToken";
        SyntaxKind[SyntaxKind["SlashToken"] = 43] = "SlashToken";
        SyntaxKind[SyntaxKind["PercentToken"] = 44] = "PercentToken";
        SyntaxKind[SyntaxKind["PlusPlusToken"] = 45] = "PlusPlusToken";
        SyntaxKind[SyntaxKind["MinusMinusToken"] = 46] = "MinusMinusToken";
        SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 47] = "LessThanLessThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 48] = "GreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 49] = "GreaterThanGreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["AmpersandToken"] = 50] = "AmpersandToken";
        SyntaxKind[SyntaxKind["BarToken"] = 51] = "BarToken";
        SyntaxKind[SyntaxKind["CaretToken"] = 52] = "CaretToken";
        SyntaxKind[SyntaxKind["ExclamationToken"] = 53] = "ExclamationToken";
        SyntaxKind[SyntaxKind["TildeToken"] = 54] = "TildeToken";
        SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 55] = "AmpersandAmpersandToken";
        SyntaxKind[SyntaxKind["BarBarToken"] = 56] = "BarBarToken";
        SyntaxKind[SyntaxKind["QuestionToken"] = 57] = "QuestionToken";
        SyntaxKind[SyntaxKind["ColonToken"] = 58] = "ColonToken";
        SyntaxKind[SyntaxKind["AtToken"] = 59] = "AtToken";
        SyntaxKind[SyntaxKind["QuestionQuestionToken"] = 60] = "QuestionQuestionToken";
        /** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */
        SyntaxKind[SyntaxKind["BacktickToken"] = 61] = "BacktickToken";
        // Assignments
        SyntaxKind[SyntaxKind["EqualsToken"] = 62] = "EqualsToken";
        SyntaxKind[SyntaxKind["PlusEqualsToken"] = 63] = "PlusEqualsToken";
        SyntaxKind[SyntaxKind["MinusEqualsToken"] = 64] = "MinusEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 65] = "AsteriskEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskEqualsToken"] = 66] = "AsteriskAsteriskEqualsToken";
        SyntaxKind[SyntaxKind["SlashEqualsToken"] = 67] = "SlashEqualsToken";
        SyntaxKind[SyntaxKind["PercentEqualsToken"] = 68] = "PercentEqualsToken";
        SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 69] = "LessThanLessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 70] = "GreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 71] = "GreaterThanGreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 72] = "AmpersandEqualsToken";
        SyntaxKind[SyntaxKind["BarEqualsToken"] = 73] = "BarEqualsToken";
        SyntaxKind[SyntaxKind["CaretEqualsToken"] = 74] = "CaretEqualsToken";
        // Identifiers and PrivateIdentifiers
        SyntaxKind[SyntaxKind["Identifier"] = 75] = "Identifier";
        SyntaxKind[SyntaxKind["PrivateIdentifier"] = 76] = "PrivateIdentifier";
        // Reserved words
        SyntaxKind[SyntaxKind["BreakKeyword"] = 77] = "BreakKeyword";
        SyntaxKind[SyntaxKind["CaseKeyword"] = 78] = "CaseKeyword";
        SyntaxKind[SyntaxKind["CatchKeyword"] = 79] = "CatchKeyword";
        SyntaxKind[SyntaxKind["ClassKeyword"] = 80] = "ClassKeyword";
        SyntaxKind[SyntaxKind["ConstKeyword"] = 81] = "ConstKeyword";
        SyntaxKind[SyntaxKind["ContinueKeyword"] = 82] = "ContinueKeyword";
        SyntaxKind[SyntaxKind["DebuggerKeyword"] = 83] = "DebuggerKeyword";
        SyntaxKind[SyntaxKind["DefaultKeyword"] = 84] = "DefaultKeyword";
        SyntaxKind[SyntaxKind["DeleteKeyword"] = 85] = "DeleteKeyword";
        SyntaxKind[SyntaxKind["DoKeyword"] = 86] = "DoKeyword";
        SyntaxKind[SyntaxKind["ElseKeyword"] = 87] = "ElseKeyword";
        SyntaxKind[SyntaxKind["EnumKeyword"] = 88] = "EnumKeyword";
        SyntaxKind[SyntaxKind["ExportKeyword"] = 89] = "ExportKeyword";
        SyntaxKind[SyntaxKind["ExtendsKeyword"] = 90] = "ExtendsKeyword";
        SyntaxKind[SyntaxKind["FalseKeyword"] = 91] = "FalseKeyword";
        SyntaxKind[SyntaxKind["FinallyKeyword"] = 92] = "FinallyKeyword";
        SyntaxKind[SyntaxKind["ForKeyword"] = 93] = "ForKeyword";
        SyntaxKind[SyntaxKind["FunctionKeyword"] = 94] = "FunctionKeyword";
        SyntaxKind[SyntaxKind["IfKeyword"] = 95] = "IfKeyword";
        SyntaxKind[SyntaxKind["ImportKeyword"] = 96] = "ImportKeyword";
        SyntaxKind[SyntaxKind["InKeyword"] = 97] = "InKeyword";
        SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 98] = "InstanceOfKeyword";
        SyntaxKind[SyntaxKind["NewKeyword"] = 99] = "NewKeyword";
        SyntaxKind[SyntaxKind["NullKeyword"] = 100] = "NullKeyword";
        SyntaxKind[SyntaxKind["ReturnKeyword"] = 101] = "ReturnKeyword";
        SyntaxKind[SyntaxKind["SuperKeyword"] = 102] = "SuperKeyword";
        SyntaxKind[SyntaxKind["SwitchKeyword"] = 103] = "SwitchKeyword";
        SyntaxKind[SyntaxKind["ThisKeyword"] = 104] = "ThisKeyword";
        SyntaxKind[SyntaxKind["ThrowKeyword"] = 105] = "ThrowKeyword";
        SyntaxKind[SyntaxKind["TrueKeyword"] = 106] = "TrueKeyword";
        SyntaxKind[SyntaxKind["TryKeyword"] = 107] = "TryKeyword";
        SyntaxKind[SyntaxKind["TypeOfKeyword"] = 108] = "TypeOfKeyword";
        SyntaxKind[SyntaxKind["VarKeyword"] = 109] = "VarKeyword";
        SyntaxKind[SyntaxKind["VoidKeyword"] = 110] = "VoidKeyword";
        SyntaxKind[SyntaxKind["WhileKeyword"] = 111] = "WhileKeyword";
        SyntaxKind[SyntaxKind["WithKeyword"] = 112] = "WithKeyword";
        // Strict mode reserved words
        SyntaxKind[SyntaxKind["ImplementsKeyword"] = 113] = "ImplementsKeyword";
        SyntaxKind[SyntaxKind["InterfaceKeyword"] = 114] = "InterfaceKeyword";
        SyntaxKind[SyntaxKind["LetKeyword"] = 115] = "LetKeyword";
        SyntaxKind[SyntaxKind["PackageKeyword"] = 116] = "PackageKeyword";
        SyntaxKind[SyntaxKind["PrivateKeyword"] = 117] = "PrivateKeyword";
        SyntaxKind[SyntaxKind["ProtectedKeyword"] = 118] = "ProtectedKeyword";
        SyntaxKind[SyntaxKind["PublicKeyword"] = 119] = "PublicKeyword";
        SyntaxKind[SyntaxKind["StaticKeyword"] = 120] = "StaticKeyword";
        SyntaxKind[SyntaxKind["YieldKeyword"] = 121] = "YieldKeyword";
        // Contextual keywords
        SyntaxKind[SyntaxKind["AbstractKeyword"] = 122] = "AbstractKeyword";
        SyntaxKind[SyntaxKind["AsKeyword"] = 123] = "AsKeyword";
        SyntaxKind[SyntaxKind["AssertsKeyword"] = 124] = "AssertsKeyword";
        SyntaxKind[SyntaxKind["AnyKeyword"] = 125] = "AnyKeyword";
        SyntaxKind[SyntaxKind["AsyncKeyword"] = 126] = "AsyncKeyword";
        SyntaxKind[SyntaxKind["AwaitKeyword"] = 127] = "AwaitKeyword";
        SyntaxKind[SyntaxKind["BooleanKeyword"] = 128] = "BooleanKeyword";
        SyntaxKind[SyntaxKind["ConstructorKeyword"] = 129] = "ConstructorKeyword";
        SyntaxKind[SyntaxKind["DeclareKeyword"] = 130] = "DeclareKeyword";
        SyntaxKind[SyntaxKind["GetKeyword"] = 131] = "GetKeyword";
        SyntaxKind[SyntaxKind["InferKeyword"] = 132] = "InferKeyword";
        SyntaxKind[SyntaxKind["IsKeyword"] = 133] = "IsKeyword";
        SyntaxKind[SyntaxKind["KeyOfKeyword"] = 134] = "KeyOfKeyword";
        SyntaxKind[SyntaxKind["ModuleKeyword"] = 135] = "ModuleKeyword";
        SyntaxKind[SyntaxKind["NamespaceKeyword"] = 136] = "NamespaceKeyword";
        SyntaxKind[SyntaxKind["NeverKeyword"] = 137] = "NeverKeyword";
        SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 138] = "ReadonlyKeyword";
        SyntaxKind[SyntaxKind["RequireKeyword"] = 139] = "RequireKeyword";
        SyntaxKind[SyntaxKind["NumberKeyword"] = 140] = "NumberKeyword";
        SyntaxKind[SyntaxKind["ObjectKeyword"] = 141] = "ObjectKeyword";
        SyntaxKind[SyntaxKind["SetKeyword"] = 142] = "SetKeyword";
        SyntaxKind[SyntaxKind["StringKeyword"] = 143] = "StringKeyword";
        SyntaxKind[SyntaxKind["SymbolKeyword"] = 144] = "SymbolKeyword";
        SyntaxKind[SyntaxKind["TypeKeyword"] = 145] = "TypeKeyword";
        SyntaxKind[SyntaxKind["UndefinedKeyword"] = 146] = "UndefinedKeyword";
        SyntaxKind[SyntaxKind["UniqueKeyword"] = 147] = "UniqueKeyword";
        SyntaxKind[SyntaxKind["UnknownKeyword"] = 148] = "UnknownKeyword";
        SyntaxKind[SyntaxKind["FromKeyword"] = 149] = "FromKeyword";
        SyntaxKind[SyntaxKind["GlobalKeyword"] = 150] = "GlobalKeyword";
        SyntaxKind[SyntaxKind["BigIntKeyword"] = 151] = "BigIntKeyword";
        SyntaxKind[SyntaxKind["OfKeyword"] = 152] = "OfKeyword";
        // Parse tree nodes
        // Names
        SyntaxKind[SyntaxKind["QualifiedName"] = 153] = "QualifiedName";
        SyntaxKind[SyntaxKind["ComputedPropertyName"] = 154] = "ComputedPropertyName";
        // Signature elements
        SyntaxKind[SyntaxKind["TypeParameter"] = 155] = "TypeParameter";
        SyntaxKind[SyntaxKind["Parameter"] = 156] = "Parameter";
        SyntaxKind[SyntaxKind["Decorator"] = 157] = "Decorator";
        // TypeMember
        SyntaxKind[SyntaxKind["PropertySignature"] = 158] = "PropertySignature";
        SyntaxKind[SyntaxKind["PropertyDeclaration"] = 159] = "PropertyDeclaration";
        SyntaxKind[SyntaxKind["MethodSignature"] = 160] = "MethodSignature";
        SyntaxKind[SyntaxKind["MethodDeclaration"] = 161] = "MethodDeclaration";
        SyntaxKind[SyntaxKind["Constructor"] = 162] = "Constructor";
        SyntaxKind[SyntaxKind["GetAccessor"] = 163] = "GetAccessor";
        SyntaxKind[SyntaxKind["SetAccessor"] = 164] = "SetAccessor";
        SyntaxKind[SyntaxKind["CallSignature"] = 165] = "CallSignature";
        SyntaxKind[SyntaxKind["ConstructSignature"] = 166] = "ConstructSignature";
        SyntaxKind[SyntaxKind["IndexSignature"] = 167] = "IndexSignature";
        // Type
        SyntaxKind[SyntaxKind["TypePredicate"] = 168] = "TypePredicate";
        SyntaxKind[SyntaxKind["TypeReference"] = 169] = "TypeReference";
        SyntaxKind[SyntaxKind["FunctionType"] = 170] = "FunctionType";
        SyntaxKind[SyntaxKind["ConstructorType"] = 171] = "ConstructorType";
        SyntaxKind[SyntaxKind["TypeQuery"] = 172] = "TypeQuery";
        SyntaxKind[SyntaxKind["TypeLiteral"] = 173] = "TypeLiteral";
        SyntaxKind[SyntaxKind["ArrayType"] = 174] = "ArrayType";
        SyntaxKind[SyntaxKind["TupleType"] = 175] = "TupleType";
        SyntaxKind[SyntaxKind["OptionalType"] = 176] = "OptionalType";
        SyntaxKind[SyntaxKind["RestType"] = 177] = "RestType";
        SyntaxKind[SyntaxKind["UnionType"] = 178] = "UnionType";
        SyntaxKind[SyntaxKind["IntersectionType"] = 179] = "IntersectionType";
        SyntaxKind[SyntaxKind["ConditionalType"] = 180] = "ConditionalType";
        SyntaxKind[SyntaxKind["InferType"] = 181] = "InferType";
        SyntaxKind[SyntaxKind["ParenthesizedType"] = 182] = "ParenthesizedType";
        SyntaxKind[SyntaxKind["ThisType"] = 183] = "ThisType";
        SyntaxKind[SyntaxKind["TypeOperator"] = 184] = "TypeOperator";
        SyntaxKind[SyntaxKind["IndexedAccessType"] = 185] = "IndexedAccessType";
        SyntaxKind[SyntaxKind["MappedType"] = 186] = "MappedType";
        SyntaxKind[SyntaxKind["LiteralType"] = 187] = "LiteralType";
        SyntaxKind[SyntaxKind["ImportType"] = 188] = "ImportType";
        // Binding patterns
        SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 189] = "ObjectBindingPattern";
        SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 190] = "ArrayBindingPattern";
        SyntaxKind[SyntaxKind["BindingElement"] = 191] = "BindingElement";
        // Expression
        SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 192] = "ArrayLiteralExpression";
        SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 193] = "ObjectLiteralExpression";
        SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 194] = "PropertyAccessExpression";
        SyntaxKind[SyntaxKind["ElementAccessExpression"] = 195] = "ElementAccessExpression";
        SyntaxKind[SyntaxKind["CallExpression"] = 196] = "CallExpression";
        SyntaxKind[SyntaxKind["NewExpression"] = 197] = "NewExpression";
        SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 198] = "TaggedTemplateExpression";
        SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 199] = "TypeAssertionExpression";
        SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 200] = "ParenthesizedExpression";
        SyntaxKind[SyntaxKind["FunctionExpression"] = 201] = "FunctionExpression";
        SyntaxKind[SyntaxKind["ArrowFunction"] = 202] = "ArrowFunction";
        SyntaxKind[SyntaxKind["DeleteExpression"] = 203] = "DeleteExpression";
        SyntaxKind[SyntaxKind["TypeOfExpression"] = 204] = "TypeOfExpression";
        SyntaxKind[SyntaxKind["VoidExpression"] = 205] = "VoidExpression";
        SyntaxKind[SyntaxKind["AwaitExpression"] = 206] = "AwaitExpression";
        SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 207] = "PrefixUnaryExpression";
        SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 208] = "PostfixUnaryExpression";
        SyntaxKind[SyntaxKind["BinaryExpression"] = 209] = "BinaryExpression";
        SyntaxKind[SyntaxKind["ConditionalExpression"] = 210] = "ConditionalExpression";
        SyntaxKind[SyntaxKind["TemplateExpression"] = 211] = "TemplateExpression";
        SyntaxKind[SyntaxKind["YieldExpression"] = 212] = "YieldExpression";
        SyntaxKind[SyntaxKind["SpreadElement"] = 213] = "SpreadElement";
        SyntaxKind[SyntaxKind["ClassExpression"] = 214] = "ClassExpression";
        SyntaxKind[SyntaxKind["OmittedExpression"] = 215] = "OmittedExpression";
        SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 216] = "ExpressionWithTypeArguments";
        SyntaxKind[SyntaxKind["AsExpression"] = 217] = "AsExpression";
        SyntaxKind[SyntaxKind["NonNullExpression"] = 218] = "NonNullExpression";
        SyntaxKind[SyntaxKind["MetaProperty"] = 219] = "MetaProperty";
        SyntaxKind[SyntaxKind["SyntheticExpression"] = 220] = "SyntheticExpression";
        // Misc
        SyntaxKind[SyntaxKind["TemplateSpan"] = 221] = "TemplateSpan";
        SyntaxKind[SyntaxKind["SemicolonClassElement"] = 222] = "SemicolonClassElement";
        // Element
        SyntaxKind[SyntaxKind["Block"] = 223] = "Block";
        SyntaxKind[SyntaxKind["EmptyStatement"] = 224] = "EmptyStatement";
        SyntaxKind[SyntaxKind["VariableStatement"] = 225] = "VariableStatement";
        SyntaxKind[SyntaxKind["ExpressionStatement"] = 226] = "ExpressionStatement";
        SyntaxKind[SyntaxKind["IfStatement"] = 227] = "IfStatement";
        SyntaxKind[SyntaxKind["DoStatement"] = 228] = "DoStatement";
        SyntaxKind[SyntaxKind["WhileStatement"] = 229] = "WhileStatement";
        SyntaxKind[SyntaxKind["ForStatement"] = 230] = "ForStatement";
        SyntaxKind[SyntaxKind["ForInStatement"] = 231] = "ForInStatement";
        SyntaxKind[SyntaxKind["ForOfStatement"] = 232] = "ForOfStatement";
        SyntaxKind[SyntaxKind["ContinueStatement"] = 233] = "ContinueStatement";
        SyntaxKind[SyntaxKind["BreakStatement"] = 234] = "BreakStatement";
        SyntaxKind[SyntaxKind["ReturnStatement"] = 235] = "ReturnStatement";
        SyntaxKind[SyntaxKind["WithStatement"] = 236] = "WithStatement";
        SyntaxKind[SyntaxKind["SwitchStatement"] = 237] = "SwitchStatement";
        SyntaxKind[SyntaxKind["LabeledStatement"] = 238] = "LabeledStatement";
        SyntaxKind[SyntaxKind["ThrowStatement"] = 239] = "ThrowStatement";
        SyntaxKind[SyntaxKind["TryStatement"] = 240] = "TryStatement";
        SyntaxKind[SyntaxKind["DebuggerStatement"] = 241] = "DebuggerStatement";
        SyntaxKind[SyntaxKind["VariableDeclaration"] = 242] = "VariableDeclaration";
        SyntaxKind[SyntaxKind["VariableDeclarationList"] = 243] = "VariableDeclarationList";
        SyntaxKind[SyntaxKind["FunctionDeclaration"] = 244] = "FunctionDeclaration";
        SyntaxKind[SyntaxKind["ClassDeclaration"] = 245] = "ClassDeclaration";
        SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 246] = "InterfaceDeclaration";
        SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 247] = "TypeAliasDeclaration";
        SyntaxKind[SyntaxKind["EnumDeclaration"] = 248] = "EnumDeclaration";
        SyntaxKind[SyntaxKind["ModuleDeclaration"] = 249] = "ModuleDeclaration";
        SyntaxKind[SyntaxKind["ModuleBlock"] = 250] = "ModuleBlock";
        SyntaxKind[SyntaxKind["CaseBlock"] = 251] = "CaseBlock";
        SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 252] = "NamespaceExportDeclaration";
        SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 253] = "ImportEqualsDeclaration";
        SyntaxKind[SyntaxKind["ImportDeclaration"] = 254] = "ImportDeclaration";
        SyntaxKind[SyntaxKind["ImportClause"] = 255] = "ImportClause";
        SyntaxKind[SyntaxKind["NamespaceImport"] = 256] = "NamespaceImport";
        SyntaxKind[SyntaxKind["NamedImports"] = 257] = "NamedImports";
        SyntaxKind[SyntaxKind["ImportSpecifier"] = 258] = "ImportSpecifier";
        SyntaxKind[SyntaxKind["ExportAssignment"] = 259] = "ExportAssignment";
        SyntaxKind[SyntaxKind["ExportDeclaration"] = 260] = "ExportDeclaration";
        SyntaxKind[SyntaxKind["NamedExports"] = 261] = "NamedExports";
        SyntaxKind[SyntaxKind["NamespaceExport"] = 262] = "NamespaceExport";
        SyntaxKind[SyntaxKind["ExportSpecifier"] = 263] = "ExportSpecifier";
        SyntaxKind[SyntaxKind["MissingDeclaration"] = 264] = "MissingDeclaration";
        // Module references
        SyntaxKind[SyntaxKind["ExternalModuleReference"] = 265] = "ExternalModuleReference";
        // JSX
        SyntaxKind[SyntaxKind["JsxElement"] = 266] = "JsxElement";
        SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 267] = "JsxSelfClosingElement";
        SyntaxKind[SyntaxKind["JsxOpeningElement"] = 268] = "JsxOpeningElement";
        SyntaxKind[SyntaxKind["JsxClosingElement"] = 269] = "JsxClosingElement";
        SyntaxKind[SyntaxKind["JsxFragment"] = 270] = "JsxFragment";
        SyntaxKind[SyntaxKind["JsxOpeningFragment"] = 271] = "JsxOpeningFragment";
        SyntaxKind[SyntaxKind["JsxClosingFragment"] = 272] = "JsxClosingFragment";
        SyntaxKind[SyntaxKind["JsxAttribute"] = 273] = "JsxAttribute";
        SyntaxKind[SyntaxKind["JsxAttributes"] = 274] = "JsxAttributes";
        SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 275] = "JsxSpreadAttribute";
        SyntaxKind[SyntaxKind["JsxExpression"] = 276] = "JsxExpression";
        // Clauses
        SyntaxKind[SyntaxKind["CaseClause"] = 277] = "CaseClause";
        SyntaxKind[SyntaxKind["DefaultClause"] = 278] = "DefaultClause";
        SyntaxKind[SyntaxKind["HeritageClause"] = 279] = "HeritageClause";
        SyntaxKind[SyntaxKind["CatchClause"] = 280] = "CatchClause";
        // Property assignments
        SyntaxKind[SyntaxKind["PropertyAssignment"] = 281] = "PropertyAssignment";
        SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 282] = "ShorthandPropertyAssignment";
        SyntaxKind[SyntaxKind["SpreadAssignment"] = 283] = "SpreadAssignment";
        // Enum
        SyntaxKind[SyntaxKind["EnumMember"] = 284] = "EnumMember";
        // Unparsed
        SyntaxKind[SyntaxKind["UnparsedPrologue"] = 285] = "UnparsedPrologue";
        SyntaxKind[SyntaxKind["UnparsedPrepend"] = 286] = "UnparsedPrepend";
        SyntaxKind[SyntaxKind["UnparsedText"] = 287] = "UnparsedText";
        SyntaxKind[SyntaxKind["UnparsedInternalText"] = 288] = "UnparsedInternalText";
        SyntaxKind[SyntaxKind["UnparsedSyntheticReference"] = 289] = "UnparsedSyntheticReference";
        // Top-level nodes
        SyntaxKind[SyntaxKind["SourceFile"] = 290] = "SourceFile";
        SyntaxKind[SyntaxKind["Bundle"] = 291] = "Bundle";
        SyntaxKind[SyntaxKind["UnparsedSource"] = 292] = "UnparsedSource";
        SyntaxKind[SyntaxKind["InputFiles"] = 293] = "InputFiles";
        // JSDoc nodes
        SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 294] = "JSDocTypeExpression";
        // The * type
        SyntaxKind[SyntaxKind["JSDocAllType"] = 295] = "JSDocAllType";
        // The ? type
        SyntaxKind[SyntaxKind["JSDocUnknownType"] = 296] = "JSDocUnknownType";
        SyntaxKind[SyntaxKind["JSDocNullableType"] = 297] = "JSDocNullableType";
        SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 298] = "JSDocNonNullableType";
        SyntaxKind[SyntaxKind["JSDocOptionalType"] = 299] = "JSDocOptionalType";
        SyntaxKind[SyntaxKind["JSDocFunctionType"] = 300] = "JSDocFunctionType";
        SyntaxKind[SyntaxKind["JSDocVariadicType"] = 301] = "JSDocVariadicType";
        // https://jsdoc.app/about-namepaths.html
        SyntaxKind[SyntaxKind["JSDocNamepathType"] = 302] = "JSDocNamepathType";
        SyntaxKind[SyntaxKind["JSDocComment"] = 303] = "JSDocComment";
        SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 304] = "JSDocTypeLiteral";
        SyntaxKind[SyntaxKind["JSDocSignature"] = 305] = "JSDocSignature";
        SyntaxKind[SyntaxKind["JSDocTag"] = 306] = "JSDocTag";
        SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 307] = "JSDocAugmentsTag";
        SyntaxKind[SyntaxKind["JSDocImplementsTag"] = 308] = "JSDocImplementsTag";
        SyntaxKind[SyntaxKind["JSDocAuthorTag"] = 309] = "JSDocAuthorTag";
        SyntaxKind[SyntaxKind["JSDocClassTag"] = 310] = "JSDocClassTag";
        SyntaxKind[SyntaxKind["JSDocPublicTag"] = 311] = "JSDocPublicTag";
        SyntaxKind[SyntaxKind["JSDocPrivateTag"] = 312] = "JSDocPrivateTag";
        SyntaxKind[SyntaxKind["JSDocProtectedTag"] = 313] = "JSDocProtectedTag";
        SyntaxKind[SyntaxKind["JSDocReadonlyTag"] = 314] = "JSDocReadonlyTag";
        SyntaxKind[SyntaxKind["JSDocCallbackTag"] = 315] = "JSDocCallbackTag";
        SyntaxKind[SyntaxKind["JSDocEnumTag"] = 316] = "JSDocEnumTag";
        SyntaxKind[SyntaxKind["JSDocParameterTag"] = 317] = "JSDocParameterTag";
        SyntaxKind[SyntaxKind["JSDocReturnTag"] = 318] = "JSDocReturnTag";
        SyntaxKind[SyntaxKind["JSDocThisTag"] = 319] = "JSDocThisTag";
        SyntaxKind[SyntaxKind["JSDocTypeTag"] = 320] = "JSDocTypeTag";
        SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 321] = "JSDocTemplateTag";
        SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 322] = "JSDocTypedefTag";
        SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 323] = "JSDocPropertyTag";
        // Synthesized list
        SyntaxKind[SyntaxKind["SyntaxList"] = 324] = "SyntaxList";
        // Transformation nodes
        SyntaxKind[SyntaxKind["NotEmittedStatement"] = 325] = "NotEmittedStatement";
        SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 326] = "PartiallyEmittedExpression";
        SyntaxKind[SyntaxKind["CommaListExpression"] = 327] = "CommaListExpression";
        SyntaxKind[SyntaxKind["MergeDeclarationMarker"] = 328] = "MergeDeclarationMarker";
        SyntaxKind[SyntaxKind["EndOfDeclarationMarker"] = 329] = "EndOfDeclarationMarker";
        SyntaxKind[SyntaxKind["SyntheticReferenceExpression"] = 330] = "SyntheticReferenceExpression";
        // Enum value count
        SyntaxKind[SyntaxKind["Count"] = 331] = "Count";
        // Markers
        SyntaxKind[SyntaxKind["FirstAssignment"] = 62] = "FirstAssignment";
        SyntaxKind[SyntaxKind["LastAssignment"] = 74] = "LastAssignment";
        SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 63] = "FirstCompoundAssignment";
        SyntaxKind[SyntaxKind["LastCompoundAssignment"] = 74] = "LastCompoundAssignment";
        SyntaxKind[SyntaxKind["FirstReservedWord"] = 77] = "FirstReservedWord";
        SyntaxKind[SyntaxKind["LastReservedWord"] = 112] = "LastReservedWord";
        SyntaxKind[SyntaxKind["FirstKeyword"] = 77] = "FirstKeyword";
        SyntaxKind[SyntaxKind["LastKeyword"] = 152] = "LastKeyword";
        SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 113] = "FirstFutureReservedWord";
        SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 121] = "LastFutureReservedWord";
        SyntaxKind[SyntaxKind["FirstTypeNode"] = 168] = "FirstTypeNode";
        SyntaxKind[SyntaxKind["LastTypeNode"] = 188] = "LastTypeNode";
        SyntaxKind[SyntaxKind["FirstPunctuation"] = 18] = "FirstPunctuation";
        SyntaxKind[SyntaxKind["LastPunctuation"] = 74] = "LastPunctuation";
        SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken";
        SyntaxKind[SyntaxKind["LastToken"] = 152] = "LastToken";
        SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken";
        SyntaxKind[SyntaxKind["LastTriviaToken"] = 7] = "LastTriviaToken";
        SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken";
        SyntaxKind[SyntaxKind["LastLiteralToken"] = 14] = "LastLiteralToken";
        SyntaxKind[SyntaxKind["FirstTemplateToken"] = 14] = "FirstTemplateToken";
        SyntaxKind[SyntaxKind["LastTemplateToken"] = 17] = "LastTemplateToken";
        SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 29] = "FirstBinaryOperator";
        SyntaxKind[SyntaxKind["LastBinaryOperator"] = 74] = "LastBinaryOperator";
        SyntaxKind[SyntaxKind["FirstStatement"] = 225] = "FirstStatement";
        SyntaxKind[SyntaxKind["LastStatement"] = 241] = "LastStatement";
        SyntaxKind[SyntaxKind["FirstNode"] = 153] = "FirstNode";
        SyntaxKind[SyntaxKind["FirstJSDocNode"] = 294] = "FirstJSDocNode";
        SyntaxKind[SyntaxKind["LastJSDocNode"] = 323] = "LastJSDocNode";
        SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 306] = "FirstJSDocTagNode";
        SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 323] = "LastJSDocTagNode";
        /* @internal */ SyntaxKind[SyntaxKind["FirstContextualKeyword"] = 122] = "FirstContextualKeyword";
        /* @internal */ SyntaxKind[SyntaxKind["LastContextualKeyword"] = 152] = "LastContextualKeyword";
    })(SyntaxKind = ts.SyntaxKind || (ts.SyntaxKind = {}));
    var NodeFlags;
    (function (NodeFlags) {
        NodeFlags[NodeFlags["None"] = 0] = "None";
        NodeFlags[NodeFlags["Let"] = 1] = "Let";
        NodeFlags[NodeFlags["Const"] = 2] = "Const";
        NodeFlags[NodeFlags["NestedNamespace"] = 4] = "NestedNamespace";
        NodeFlags[NodeFlags["Synthesized"] = 8] = "Synthesized";
        NodeFlags[NodeFlags["Namespace"] = 16] = "Namespace";
        NodeFlags[NodeFlags["OptionalChain"] = 32] = "OptionalChain";
        NodeFlags[NodeFlags["ExportContext"] = 64] = "ExportContext";
        NodeFlags[NodeFlags["ContainsThis"] = 128] = "ContainsThis";
        NodeFlags[NodeFlags["HasImplicitReturn"] = 256] = "HasImplicitReturn";
        NodeFlags[NodeFlags["HasExplicitReturn"] = 512] = "HasExplicitReturn";
        NodeFlags[NodeFlags["GlobalAugmentation"] = 1024] = "GlobalAugmentation";
        NodeFlags[NodeFlags["HasAsyncFunctions"] = 2048] = "HasAsyncFunctions";
        NodeFlags[NodeFlags["DisallowInContext"] = 4096] = "DisallowInContext";
        NodeFlags[NodeFlags["YieldContext"] = 8192] = "YieldContext";
        NodeFlags[NodeFlags["DecoratorContext"] = 16384] = "DecoratorContext";
        NodeFlags[NodeFlags["AwaitContext"] = 32768] = "AwaitContext";
        NodeFlags[NodeFlags["ThisNodeHasError"] = 65536] = "ThisNodeHasError";
        NodeFlags[NodeFlags["JavaScriptFile"] = 131072] = "JavaScriptFile";
        NodeFlags[NodeFlags["ThisNodeOrAnySubNodesHasError"] = 262144] = "ThisNodeOrAnySubNodesHasError";
        NodeFlags[NodeFlags["HasAggregatedChildData"] = 524288] = "HasAggregatedChildData";
        // These flags will be set when the parser encounters a dynamic import expression or 'import.meta' to avoid
        // walking the tree if the flags are not set. However, these flags are just a approximation
        // (hence why it's named "PossiblyContainsDynamicImport") because once set, the flags never get cleared.
        // During editing, if a dynamic import is removed, incremental parsing will *NOT* clear this flag.
        // This means that the tree will always be traversed during module resolution, or when looking for external module indicators.
        // However, the removal operation should not occur often and in the case of the
        // removal, it is likely that users will add the import anyway.
        // The advantage of this approach is its simplicity. For the case of batch compilation,
        // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
        /* @internal */ NodeFlags[NodeFlags["PossiblyContainsDynamicImport"] = 1048576] = "PossiblyContainsDynamicImport";
        /* @internal */ NodeFlags[NodeFlags["PossiblyContainsImportMeta"] = 2097152] = "PossiblyContainsImportMeta";
        NodeFlags[NodeFlags["JSDoc"] = 4194304] = "JSDoc";
        /* @internal */ NodeFlags[NodeFlags["Ambient"] = 8388608] = "Ambient";
        /* @internal */ NodeFlags[NodeFlags["InWithStatement"] = 16777216] = "InWithStatement";
        NodeFlags[NodeFlags["JsonFile"] = 33554432] = "JsonFile";
        /* @internal */ NodeFlags[NodeFlags["TypeCached"] = 67108864] = "TypeCached";
        NodeFlags[NodeFlags["BlockScoped"] = 3] = "BlockScoped";
        NodeFlags[NodeFlags["ReachabilityCheckFlags"] = 768] = "ReachabilityCheckFlags";
        NodeFlags[NodeFlags["ReachabilityAndEmitFlags"] = 2816] = "ReachabilityAndEmitFlags";
        // Parsing context flags
        NodeFlags[NodeFlags["ContextFlags"] = 25358336] = "ContextFlags";
        // Exclude these flags when parsing a Type
        NodeFlags[NodeFlags["TypeExcludesFlags"] = 40960] = "TypeExcludesFlags";
        // Represents all flags that are potentially set once and
        // never cleared on SourceFiles which get re-used in between incremental parses.
        // See the comment above on `PossiblyContainsDynamicImport` and `PossiblyContainsImportMeta`.
        /* @internal */ NodeFlags[NodeFlags["PermanentlySetIncrementalFlags"] = 3145728] = "PermanentlySetIncrementalFlags";
    })(NodeFlags = ts.NodeFlags || (ts.NodeFlags = {}));
    var ModifierFlags;
    (function (ModifierFlags) {
        ModifierFlags[ModifierFlags["None"] = 0] = "None";
        ModifierFlags[ModifierFlags["Export"] = 1] = "Export";
        ModifierFlags[ModifierFlags["Ambient"] = 2] = "Ambient";
        ModifierFlags[ModifierFlags["Public"] = 4] = "Public";
        ModifierFlags[ModifierFlags["Private"] = 8] = "Private";
        ModifierFlags[ModifierFlags["Protected"] = 16] = "Protected";
        ModifierFlags[ModifierFlags["Static"] = 32] = "Static";
        ModifierFlags[ModifierFlags["Readonly"] = 64] = "Readonly";
        ModifierFlags[ModifierFlags["Abstract"] = 128] = "Abstract";
        ModifierFlags[ModifierFlags["Async"] = 256] = "Async";
        ModifierFlags[ModifierFlags["Default"] = 512] = "Default";
        ModifierFlags[ModifierFlags["Const"] = 2048] = "Const";
        ModifierFlags[ModifierFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
        ModifierFlags[ModifierFlags["AccessibilityModifier"] = 28] = "AccessibilityModifier";
        // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
        ModifierFlags[ModifierFlags["ParameterPropertyModifier"] = 92] = "ParameterPropertyModifier";
        ModifierFlags[ModifierFlags["NonPublicAccessibilityModifier"] = 24] = "NonPublicAccessibilityModifier";
        ModifierFlags[ModifierFlags["TypeScriptModifier"] = 2270] = "TypeScriptModifier";
        ModifierFlags[ModifierFlags["ExportDefault"] = 513] = "ExportDefault";
        ModifierFlags[ModifierFlags["All"] = 3071] = "All";
    })(ModifierFlags = ts.ModifierFlags || (ts.ModifierFlags = {}));
    var JsxFlags;
    (function (JsxFlags) {
        JsxFlags[JsxFlags["None"] = 0] = "None";
        /** An element from a named property of the JSX.IntrinsicElements interface */
        JsxFlags[JsxFlags["IntrinsicNamedElement"] = 1] = "IntrinsicNamedElement";
        /** An element inferred from the string index signature of the JSX.IntrinsicElements interface */
        JsxFlags[JsxFlags["IntrinsicIndexedElement"] = 2] = "IntrinsicIndexedElement";
        JsxFlags[JsxFlags["IntrinsicElement"] = 3] = "IntrinsicElement";
    })(JsxFlags = ts.JsxFlags || (ts.JsxFlags = {}));
    /* @internal */
    var RelationComparisonResult;
    (function (RelationComparisonResult) {
        RelationComparisonResult[RelationComparisonResult["Succeeded"] = 1] = "Succeeded";
        RelationComparisonResult[RelationComparisonResult["Failed"] = 2] = "Failed";
        RelationComparisonResult[RelationComparisonResult["Reported"] = 4] = "Reported";
        RelationComparisonResult[RelationComparisonResult["ReportsUnmeasurable"] = 8] = "ReportsUnmeasurable";
        RelationComparisonResult[RelationComparisonResult["ReportsUnreliable"] = 16] = "ReportsUnreliable";
        RelationComparisonResult[RelationComparisonResult["ReportsMask"] = 24] = "ReportsMask";
    })(RelationComparisonResult = ts.RelationComparisonResult || (ts.RelationComparisonResult = {}));
    /*@internal*/
    var GeneratedIdentifierFlags;
    (function (GeneratedIdentifierFlags) {
        // Kinds
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["None"] = 0] = "None";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Auto"] = 1] = "Auto";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Loop"] = 2] = "Loop";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Unique"] = 3] = "Unique";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Node"] = 4] = "Node";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["KindMask"] = 7] = "KindMask";
        // Flags
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["ReservedInNestedScopes"] = 8] = "ReservedInNestedScopes";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Optimistic"] = 16] = "Optimistic";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["FileLevel"] = 32] = "FileLevel";
    })(GeneratedIdentifierFlags = ts.GeneratedIdentifierFlags || (ts.GeneratedIdentifierFlags = {}));
    var TokenFlags;
    (function (TokenFlags) {
        TokenFlags[TokenFlags["None"] = 0] = "None";
        /* @internal */
        TokenFlags[TokenFlags["PrecedingLineBreak"] = 1] = "PrecedingLineBreak";
        /* @internal */
        TokenFlags[TokenFlags["PrecedingJSDocComment"] = 2] = "PrecedingJSDocComment";
        /* @internal */
        TokenFlags[TokenFlags["Unterminated"] = 4] = "Unterminated";
        /* @internal */
        TokenFlags[TokenFlags["ExtendedUnicodeEscape"] = 8] = "ExtendedUnicodeEscape";
        TokenFlags[TokenFlags["Scientific"] = 16] = "Scientific";
        TokenFlags[TokenFlags["Octal"] = 32] = "Octal";
        TokenFlags[TokenFlags["HexSpecifier"] = 64] = "HexSpecifier";
        TokenFlags[TokenFlags["BinarySpecifier"] = 128] = "BinarySpecifier";
        TokenFlags[TokenFlags["OctalSpecifier"] = 256] = "OctalSpecifier";
        /* @internal */
        TokenFlags[TokenFlags["ContainsSeparator"] = 512] = "ContainsSeparator";
        /* @internal */
        TokenFlags[TokenFlags["UnicodeEscape"] = 1024] = "UnicodeEscape";
        /* @internal */
        TokenFlags[TokenFlags["ContainsInvalidEscape"] = 2048] = "ContainsInvalidEscape";
        /* @internal */
        TokenFlags[TokenFlags["BinaryOrOctalSpecifier"] = 384] = "BinaryOrOctalSpecifier";
        /* @internal */
        TokenFlags[TokenFlags["NumericLiteralFlags"] = 1008] = "NumericLiteralFlags";
    })(TokenFlags = ts.TokenFlags || (ts.TokenFlags = {}));
    // NOTE: Ensure this is up-to-date with src/debug/debug.ts
    var FlowFlags;
    (function (FlowFlags) {
        FlowFlags[FlowFlags["Unreachable"] = 1] = "Unreachable";
        FlowFlags[FlowFlags["Start"] = 2] = "Start";
        FlowFlags[FlowFlags["BranchLabel"] = 4] = "BranchLabel";
        FlowFlags[FlowFlags["LoopLabel"] = 8] = "LoopLabel";
        FlowFlags[FlowFlags["Assignment"] = 16] = "Assignment";
        FlowFlags[FlowFlags["TrueCondition"] = 32] = "TrueCondition";
        FlowFlags[FlowFlags["FalseCondition"] = 64] = "FalseCondition";
        FlowFlags[FlowFlags["SwitchClause"] = 128] = "SwitchClause";
        FlowFlags[FlowFlags["ArrayMutation"] = 256] = "ArrayMutation";
        FlowFlags[FlowFlags["Call"] = 512] = "Call";
        FlowFlags[FlowFlags["ReduceLabel"] = 1024] = "ReduceLabel";
        FlowFlags[FlowFlags["Referenced"] = 2048] = "Referenced";
        FlowFlags[FlowFlags["Shared"] = 4096] = "Shared";
        FlowFlags[FlowFlags["Label"] = 12] = "Label";
        FlowFlags[FlowFlags["Condition"] = 96] = "Condition";
    })(FlowFlags = ts.FlowFlags || (ts.FlowFlags = {}));
    /* @internal */
    var CommentDirectiveType;
    (function (CommentDirectiveType) {
        CommentDirectiveType[CommentDirectiveType["ExpectError"] = 0] = "ExpectError";
        CommentDirectiveType[CommentDirectiveType["Ignore"] = 1] = "Ignore";
    })(CommentDirectiveType = ts.CommentDirectiveType || (ts.CommentDirectiveType = {}));
    var OperationCanceledException = /** @class */ (function () {
        function OperationCanceledException() {
        }
        return OperationCanceledException;
    }());
    ts.OperationCanceledException = OperationCanceledException;
    /*@internal*/
    var RefFileKind;
    (function (RefFileKind) {
        RefFileKind[RefFileKind["Import"] = 0] = "Import";
        RefFileKind[RefFileKind["ReferenceFile"] = 1] = "ReferenceFile";
        RefFileKind[RefFileKind["TypeReferenceDirective"] = 2] = "TypeReferenceDirective";
    })(RefFileKind = ts.RefFileKind || (ts.RefFileKind = {}));
    /* @internal */
    var StructureIsReused;
    (function (StructureIsReused) {
        StructureIsReused[StructureIsReused["Not"] = 0] = "Not";
        StructureIsReused[StructureIsReused["SafeModules"] = 1] = "SafeModules";
        StructureIsReused[StructureIsReused["Completely"] = 2] = "Completely";
    })(StructureIsReused = ts.StructureIsReused || (ts.StructureIsReused = {}));
    /** Return code used by getEmitOutput function to indicate status of the function */
    var ExitStatus;
    (function (ExitStatus) {
        // Compiler ran successfully.  Either this was a simple do-nothing compilation (for example,
        // when -version or -help was provided, or this was a normal compilation, no diagnostics
        // were produced, and all outputs were generated successfully.
        ExitStatus[ExitStatus["Success"] = 0] = "Success";
        // Diagnostics were produced and because of them no code was generated.
        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsSkipped"] = 1] = "DiagnosticsPresent_OutputsSkipped";
        // Diagnostics were produced and outputs were generated in spite of them.
        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsGenerated"] = 2] = "DiagnosticsPresent_OutputsGenerated";
        // When build skipped because passed in project is invalid
        ExitStatus[ExitStatus["InvalidProject_OutputsSkipped"] = 3] = "InvalidProject_OutputsSkipped";
        // When build is skipped because project references form cycle
        ExitStatus[ExitStatus["ProjectReferenceCycle_OutputsSkipped"] = 4] = "ProjectReferenceCycle_OutputsSkipped";
        /** @deprecated Use ProjectReferenceCycle_OutputsSkipped instead. */
        ExitStatus[ExitStatus["ProjectReferenceCycle_OutputsSkupped"] = 4] = "ProjectReferenceCycle_OutputsSkupped";
    })(ExitStatus = ts.ExitStatus || (ts.ExitStatus = {}));
    /* @internal */
    var UnionReduction;
    (function (UnionReduction) {
        UnionReduction[UnionReduction["None"] = 0] = "None";
        UnionReduction[UnionReduction["Literal"] = 1] = "Literal";
        UnionReduction[UnionReduction["Subtype"] = 2] = "Subtype";
    })(UnionReduction = ts.UnionReduction || (ts.UnionReduction = {}));
    /* @internal */
    var ContextFlags;
    (function (ContextFlags) {
        ContextFlags[ContextFlags["None"] = 0] = "None";
        ContextFlags[ContextFlags["Signature"] = 1] = "Signature";
        ContextFlags[ContextFlags["NoConstraints"] = 2] = "NoConstraints";
        ContextFlags[ContextFlags["Completions"] = 4] = "Completions";
    })(ContextFlags = ts.ContextFlags || (ts.ContextFlags = {}));
    // NOTE: If modifying this enum, must modify `TypeFormatFlags` too!
    var NodeBuilderFlags;
    (function (NodeBuilderFlags) {
        NodeBuilderFlags[NodeBuilderFlags["None"] = 0] = "None";
        // Options
        NodeBuilderFlags[NodeBuilderFlags["NoTruncation"] = 1] = "NoTruncation";
        NodeBuilderFlags[NodeBuilderFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType";
        NodeBuilderFlags[NodeBuilderFlags["GenerateNamesForShadowedTypeParams"] = 4] = "GenerateNamesForShadowedTypeParams";
        NodeBuilderFlags[NodeBuilderFlags["UseStructuralFallback"] = 8] = "UseStructuralFallback";
        NodeBuilderFlags[NodeBuilderFlags["ForbidIndexedAccessSymbolReferences"] = 16] = "ForbidIndexedAccessSymbolReferences";
        NodeBuilderFlags[NodeBuilderFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
        NodeBuilderFlags[NodeBuilderFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType";
        NodeBuilderFlags[NodeBuilderFlags["UseOnlyExternalAliasing"] = 128] = "UseOnlyExternalAliasing";
        NodeBuilderFlags[NodeBuilderFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType";
        NodeBuilderFlags[NodeBuilderFlags["WriteTypeParametersInQualifiedName"] = 512] = "WriteTypeParametersInQualifiedName";
        NodeBuilderFlags[NodeBuilderFlags["MultilineObjectLiterals"] = 1024] = "MultilineObjectLiterals";
        NodeBuilderFlags[NodeBuilderFlags["WriteClassExpressionAsTypeLiteral"] = 2048] = "WriteClassExpressionAsTypeLiteral";
        NodeBuilderFlags[NodeBuilderFlags["UseTypeOfFunction"] = 4096] = "UseTypeOfFunction";
        NodeBuilderFlags[NodeBuilderFlags["OmitParameterModifiers"] = 8192] = "OmitParameterModifiers";
        NodeBuilderFlags[NodeBuilderFlags["UseAliasDefinedOutsideCurrentScope"] = 16384] = "UseAliasDefinedOutsideCurrentScope";
        NodeBuilderFlags[NodeBuilderFlags["UseSingleQuotesForStringLiteralType"] = 268435456] = "UseSingleQuotesForStringLiteralType";
        NodeBuilderFlags[NodeBuilderFlags["NoTypeReduction"] = 536870912] = "NoTypeReduction";
        // Error handling
        NodeBuilderFlags[NodeBuilderFlags["AllowThisInObjectLiteral"] = 32768] = "AllowThisInObjectLiteral";
        NodeBuilderFlags[NodeBuilderFlags["AllowQualifedNameInPlaceOfIdentifier"] = 65536] = "AllowQualifedNameInPlaceOfIdentifier";
        NodeBuilderFlags[NodeBuilderFlags["AllowAnonymousIdentifier"] = 131072] = "AllowAnonymousIdentifier";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyUnionOrIntersection"] = 262144] = "AllowEmptyUnionOrIntersection";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyTuple"] = 524288] = "AllowEmptyTuple";
        NodeBuilderFlags[NodeBuilderFlags["AllowUniqueESSymbolType"] = 1048576] = "AllowUniqueESSymbolType";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyIndexInfoType"] = 2097152] = "AllowEmptyIndexInfoType";
        // Errors (cont.)
        NodeBuilderFlags[NodeBuilderFlags["AllowNodeModulesRelativePaths"] = 67108864] = "AllowNodeModulesRelativePaths";
        /* @internal */ NodeBuilderFlags[NodeBuilderFlags["DoNotIncludeSymbolChain"] = 134217728] = "DoNotIncludeSymbolChain";
        NodeBuilderFlags[NodeBuilderFlags["IgnoreErrors"] = 70221824] = "IgnoreErrors";
        // State
        NodeBuilderFlags[NodeBuilderFlags["InObjectTypeLiteral"] = 4194304] = "InObjectTypeLiteral";
        NodeBuilderFlags[NodeBuilderFlags["InTypeAlias"] = 8388608] = "InTypeAlias";
        NodeBuilderFlags[NodeBuilderFlags["InInitialEntityName"] = 16777216] = "InInitialEntityName";
        NodeBuilderFlags[NodeBuilderFlags["InReverseMappedType"] = 33554432] = "InReverseMappedType";
    })(NodeBuilderFlags = ts.NodeBuilderFlags || (ts.NodeBuilderFlags = {}));
    // Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment
    var TypeFormatFlags;
    (function (TypeFormatFlags) {
        TypeFormatFlags[TypeFormatFlags["None"] = 0] = "None";
        TypeFormatFlags[TypeFormatFlags["NoTruncation"] = 1] = "NoTruncation";
        TypeFormatFlags[TypeFormatFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType";
        // hole because there's a hole in node builder flags
        TypeFormatFlags[TypeFormatFlags["UseStructuralFallback"] = 8] = "UseStructuralFallback";
        // hole because there's a hole in node builder flags
        TypeFormatFlags[TypeFormatFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
        TypeFormatFlags[TypeFormatFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType";
        // hole because `UseOnlyExternalAliasing` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` instead
        TypeFormatFlags[TypeFormatFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType";
        // hole because `WriteTypeParametersInQualifiedName` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` for this instead
        TypeFormatFlags[TypeFormatFlags["MultilineObjectLiterals"] = 1024] = "MultilineObjectLiterals";
        TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 2048] = "WriteClassExpressionAsTypeLiteral";
        TypeFormatFlags[TypeFormatFlags["UseTypeOfFunction"] = 4096] = "UseTypeOfFunction";
        TypeFormatFlags[TypeFormatFlags["OmitParameterModifiers"] = 8192] = "OmitParameterModifiers";
        TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 16384] = "UseAliasDefinedOutsideCurrentScope";
        TypeFormatFlags[TypeFormatFlags["UseSingleQuotesForStringLiteralType"] = 268435456] = "UseSingleQuotesForStringLiteralType";
        TypeFormatFlags[TypeFormatFlags["NoTypeReduction"] = 536870912] = "NoTypeReduction";
        // Error Handling
        TypeFormatFlags[TypeFormatFlags["AllowUniqueESSymbolType"] = 1048576] = "AllowUniqueESSymbolType";
        // TypeFormatFlags exclusive
        TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 131072] = "AddUndefined";
        TypeFormatFlags[TypeFormatFlags["WriteArrowStyleSignature"] = 262144] = "WriteArrowStyleSignature";
        // State
        TypeFormatFlags[TypeFormatFlags["InArrayType"] = 524288] = "InArrayType";
        TypeFormatFlags[TypeFormatFlags["InElementType"] = 2097152] = "InElementType";
        TypeFormatFlags[TypeFormatFlags["InFirstTypeArgument"] = 4194304] = "InFirstTypeArgument";
        TypeFormatFlags[TypeFormatFlags["InTypeAlias"] = 8388608] = "InTypeAlias";
        /** @deprecated */ TypeFormatFlags[TypeFormatFlags["WriteOwnNameForAnyLike"] = 0] = "WriteOwnNameForAnyLike";
        TypeFormatFlags[TypeFormatFlags["NodeBuilderFlagsMask"] = 814775659] = "NodeBuilderFlagsMask";
    })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {}));
    var SymbolFormatFlags;
    (function (SymbolFormatFlags) {
        SymbolFormatFlags[SymbolFormatFlags["None"] = 0] = "None";
        // Write symbols's type argument if it is instantiated symbol
        // eg. class C<T> { p: T }   <-- Show p as C<T>.p here
        //     var a: C<number>;
        //     var p = a.p; <--- Here p is property of C<number> so show it as C<number>.p instead of just C.p
        SymbolFormatFlags[SymbolFormatFlags["WriteTypeParametersOrArguments"] = 1] = "WriteTypeParametersOrArguments";
        // Use only external alias information to get the symbol name in the given context
        // eg.  module m { export class c { } } import x = m.c;
        // When this flag is specified m.c will be used to refer to the class instead of alias symbol x
        SymbolFormatFlags[SymbolFormatFlags["UseOnlyExternalAliasing"] = 2] = "UseOnlyExternalAliasing";
        // Build symbol name using any nodes needed, instead of just components of an entity name
        SymbolFormatFlags[SymbolFormatFlags["AllowAnyNodeKind"] = 4] = "AllowAnyNodeKind";
        // Prefer aliases which are not directly visible
        SymbolFormatFlags[SymbolFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 8] = "UseAliasDefinedOutsideCurrentScope";
        // Skip building an accessible symbol chain
        /* @internal */ SymbolFormatFlags[SymbolFormatFlags["DoNotIncludeSymbolChain"] = 16] = "DoNotIncludeSymbolChain";
    })(SymbolFormatFlags = ts.SymbolFormatFlags || (ts.SymbolFormatFlags = {}));
    /* @internal */
    var SymbolAccessibility;
    (function (SymbolAccessibility) {
        SymbolAccessibility[SymbolAccessibility["Accessible"] = 0] = "Accessible";
        SymbolAccessibility[SymbolAccessibility["NotAccessible"] = 1] = "NotAccessible";
        SymbolAccessibility[SymbolAccessibility["CannotBeNamed"] = 2] = "CannotBeNamed";
    })(SymbolAccessibility = ts.SymbolAccessibility || (ts.SymbolAccessibility = {}));
    /* @internal */
    var SyntheticSymbolKind;
    (function (SyntheticSymbolKind) {
        SyntheticSymbolKind[SyntheticSymbolKind["UnionOrIntersection"] = 0] = "UnionOrIntersection";
        SyntheticSymbolKind[SyntheticSymbolKind["Spread"] = 1] = "Spread";
    })(SyntheticSymbolKind = ts.SyntheticSymbolKind || (ts.SyntheticSymbolKind = {}));
    var TypePredicateKind;
    (function (TypePredicateKind) {
        TypePredicateKind[TypePredicateKind["This"] = 0] = "This";
        TypePredicateKind[TypePredicateKind["Identifier"] = 1] = "Identifier";
        TypePredicateKind[TypePredicateKind["AssertsThis"] = 2] = "AssertsThis";
        TypePredicateKind[TypePredicateKind["AssertsIdentifier"] = 3] = "AssertsIdentifier";
    })(TypePredicateKind = ts.TypePredicateKind || (ts.TypePredicateKind = {}));
    /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */
    /* @internal */
    var TypeReferenceSerializationKind;
    (function (TypeReferenceSerializationKind) {
        // The TypeReferenceNode could not be resolved.
        // The type name should be emitted using a safe fallback.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Unknown"] = 0] = "Unknown";
        // The TypeReferenceNode resolves to a type with a constructor
        // function that can be reached at runtime (e.g. a `class`
        // declaration or a `var` declaration for the static side
        // of a type, such as the global `Promise` type in lib.d.ts).
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithConstructSignatureAndValue"] = 1] = "TypeWithConstructSignatureAndValue";
        // The TypeReferenceNode resolves to a Void-like, Nullable, or Never type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["VoidNullableOrNeverType"] = 2] = "VoidNullableOrNeverType";
        // The TypeReferenceNode resolves to a Number-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["NumberLikeType"] = 3] = "NumberLikeType";
        // The TypeReferenceNode resolves to a BigInt-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["BigIntLikeType"] = 4] = "BigIntLikeType";
        // The TypeReferenceNode resolves to a String-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["StringLikeType"] = 5] = "StringLikeType";
        // The TypeReferenceNode resolves to a Boolean-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["BooleanType"] = 6] = "BooleanType";
        // The TypeReferenceNode resolves to an Array-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ArrayLikeType"] = 7] = "ArrayLikeType";
        // The TypeReferenceNode resolves to the ESSymbol type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ESSymbolType"] = 8] = "ESSymbolType";
        // The TypeReferenceNode resolved to the global Promise constructor symbol.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Promise"] = 9] = "Promise";
        // The TypeReferenceNode resolves to a Function type or a type with call signatures.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithCallSignature"] = 10] = "TypeWithCallSignature";
        // The TypeReferenceNode resolves to any other type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ObjectType"] = 11] = "ObjectType";
    })(TypeReferenceSerializationKind = ts.TypeReferenceSerializationKind || (ts.TypeReferenceSerializationKind = {}));
    var SymbolFlags;
    (function (SymbolFlags) {
        SymbolFlags[SymbolFlags["None"] = 0] = "None";
        SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable";
        SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable";
        SymbolFlags[SymbolFlags["Property"] = 4] = "Property";
        SymbolFlags[SymbolFlags["EnumMember"] = 8] = "EnumMember";
        SymbolFlags[SymbolFlags["Function"] = 16] = "Function";
        SymbolFlags[SymbolFlags["Class"] = 32] = "Class";
        SymbolFlags[SymbolFlags["Interface"] = 64] = "Interface";
        SymbolFlags[SymbolFlags["ConstEnum"] = 128] = "ConstEnum";
        SymbolFlags[SymbolFlags["RegularEnum"] = 256] = "RegularEnum";
        SymbolFlags[SymbolFlags["ValueModule"] = 512] = "ValueModule";
        SymbolFlags[SymbolFlags["NamespaceModule"] = 1024] = "NamespaceModule";
        SymbolFlags[SymbolFlags["TypeLiteral"] = 2048] = "TypeLiteral";
        SymbolFlags[SymbolFlags["ObjectLiteral"] = 4096] = "ObjectLiteral";
        SymbolFlags[SymbolFlags["Method"] = 8192] = "Method";
        SymbolFlags[SymbolFlags["Constructor"] = 16384] = "Constructor";
        SymbolFlags[SymbolFlags["GetAccessor"] = 32768] = "GetAccessor";
        SymbolFlags[SymbolFlags["SetAccessor"] = 65536] = "SetAccessor";
        SymbolFlags[SymbolFlags["Signature"] = 131072] = "Signature";
        SymbolFlags[SymbolFlags["TypeParameter"] = 262144] = "TypeParameter";
        SymbolFlags[SymbolFlags["TypeAlias"] = 524288] = "TypeAlias";
        SymbolFlags[SymbolFlags["ExportValue"] = 1048576] = "ExportValue";
        SymbolFlags[SymbolFlags["Alias"] = 2097152] = "Alias";
        SymbolFlags[SymbolFlags["Prototype"] = 4194304] = "Prototype";
        SymbolFlags[SymbolFlags["ExportStar"] = 8388608] = "ExportStar";
        SymbolFlags[SymbolFlags["Optional"] = 16777216] = "Optional";
        SymbolFlags[SymbolFlags["Transient"] = 33554432] = "Transient";
        SymbolFlags[SymbolFlags["Assignment"] = 67108864] = "Assignment";
        SymbolFlags[SymbolFlags["ModuleExports"] = 134217728] = "ModuleExports";
        /* @internal */
        SymbolFlags[SymbolFlags["All"] = 67108863] = "All";
        SymbolFlags[SymbolFlags["Enum"] = 384] = "Enum";
        SymbolFlags[SymbolFlags["Variable"] = 3] = "Variable";
        SymbolFlags[SymbolFlags["Value"] = 111551] = "Value";
        SymbolFlags[SymbolFlags["Type"] = 788968] = "Type";
        SymbolFlags[SymbolFlags["Namespace"] = 1920] = "Namespace";
        SymbolFlags[SymbolFlags["Module"] = 1536] = "Module";
        SymbolFlags[SymbolFlags["Accessor"] = 98304] = "Accessor";
        // Variables can be redeclared, but can not redeclare a block-scoped declaration with the
        // same name, or any other value that is not a variable, e.g. ValueModule or Class
        SymbolFlags[SymbolFlags["FunctionScopedVariableExcludes"] = 111550] = "FunctionScopedVariableExcludes";
        // Block-scoped declarations are not allowed to be re-declared
        // they can not merge with anything in the value space
        SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 111551] = "BlockScopedVariableExcludes";
        SymbolFlags[SymbolFlags["ParameterExcludes"] = 111551] = "ParameterExcludes";
        SymbolFlags[SymbolFlags["PropertyExcludes"] = 0] = "PropertyExcludes";
        SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 900095] = "EnumMemberExcludes";
        SymbolFlags[SymbolFlags["FunctionExcludes"] = 110991] = "FunctionExcludes";
        SymbolFlags[SymbolFlags["ClassExcludes"] = 899503] = "ClassExcludes";
        SymbolFlags[SymbolFlags["InterfaceExcludes"] = 788872] = "InterfaceExcludes";
        SymbolFlags[SymbolFlags["RegularEnumExcludes"] = 899327] = "RegularEnumExcludes";
        SymbolFlags[SymbolFlags["ConstEnumExcludes"] = 899967] = "ConstEnumExcludes";
        SymbolFlags[SymbolFlags["ValueModuleExcludes"] = 110735] = "ValueModuleExcludes";
        SymbolFlags[SymbolFlags["NamespaceModuleExcludes"] = 0] = "NamespaceModuleExcludes";
        SymbolFlags[SymbolFlags["MethodExcludes"] = 103359] = "MethodExcludes";
        SymbolFlags[SymbolFlags["GetAccessorExcludes"] = 46015] = "GetAccessorExcludes";
        SymbolFlags[SymbolFlags["SetAccessorExcludes"] = 78783] = "SetAccessorExcludes";
        SymbolFlags[SymbolFlags["TypeParameterExcludes"] = 526824] = "TypeParameterExcludes";
        SymbolFlags[SymbolFlags["TypeAliasExcludes"] = 788968] = "TypeAliasExcludes";
        SymbolFlags[SymbolFlags["AliasExcludes"] = 2097152] = "AliasExcludes";
        SymbolFlags[SymbolFlags["ModuleMember"] = 2623475] = "ModuleMember";
        SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal";
        SymbolFlags[SymbolFlags["BlockScoped"] = 418] = "BlockScoped";
        SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor";
        SymbolFlags[SymbolFlags["ClassMember"] = 106500] = "ClassMember";
        /* @internal */
        SymbolFlags[SymbolFlags["ExportSupportsDefaultModifier"] = 112] = "ExportSupportsDefaultModifier";
        /* @internal */
        SymbolFlags[SymbolFlags["ExportDoesNotSupportDefaultModifier"] = -113] = "ExportDoesNotSupportDefaultModifier";
        /* @internal */
        // The set of things we consider semantically classifiable.  Used to speed up the LS during
        // classification.
        SymbolFlags[SymbolFlags["Classifiable"] = 2885600] = "Classifiable";
        /* @internal */
        SymbolFlags[SymbolFlags["LateBindingContainer"] = 6256] = "LateBindingContainer";
    })(SymbolFlags = ts.SymbolFlags || (ts.SymbolFlags = {}));
    /* @internal */
    var EnumKind;
    (function (EnumKind) {
        EnumKind[EnumKind["Numeric"] = 0] = "Numeric";
        EnumKind[EnumKind["Literal"] = 1] = "Literal"; // Literal enum (each member has a TypeFlags.EnumLiteral type)
    })(EnumKind = ts.EnumKind || (ts.EnumKind = {}));
    /* @internal */
    var CheckFlags;
    (function (CheckFlags) {
        CheckFlags[CheckFlags["Instantiated"] = 1] = "Instantiated";
        CheckFlags[CheckFlags["SyntheticProperty"] = 2] = "SyntheticProperty";
        CheckFlags[CheckFlags["SyntheticMethod"] = 4] = "SyntheticMethod";
        CheckFlags[CheckFlags["Readonly"] = 8] = "Readonly";
        CheckFlags[CheckFlags["ReadPartial"] = 16] = "ReadPartial";
        CheckFlags[CheckFlags["WritePartial"] = 32] = "WritePartial";
        CheckFlags[CheckFlags["HasNonUniformType"] = 64] = "HasNonUniformType";
        CheckFlags[CheckFlags["HasLiteralType"] = 128] = "HasLiteralType";
        CheckFlags[CheckFlags["ContainsPublic"] = 256] = "ContainsPublic";
        CheckFlags[CheckFlags["ContainsProtected"] = 512] = "ContainsProtected";
        CheckFlags[CheckFlags["ContainsPrivate"] = 1024] = "ContainsPrivate";
        CheckFlags[CheckFlags["ContainsStatic"] = 2048] = "ContainsStatic";
        CheckFlags[CheckFlags["Late"] = 4096] = "Late";
        CheckFlags[CheckFlags["ReverseMapped"] = 8192] = "ReverseMapped";
        CheckFlags[CheckFlags["OptionalParameter"] = 16384] = "OptionalParameter";
        CheckFlags[CheckFlags["RestParameter"] = 32768] = "RestParameter";
        CheckFlags[CheckFlags["DeferredType"] = 65536] = "DeferredType";
        CheckFlags[CheckFlags["HasNeverType"] = 131072] = "HasNeverType";
        CheckFlags[CheckFlags["Mapped"] = 262144] = "Mapped";
        CheckFlags[CheckFlags["StripOptional"] = 524288] = "StripOptional";
        CheckFlags[CheckFlags["Synthetic"] = 6] = "Synthetic";
        CheckFlags[CheckFlags["Discriminant"] = 192] = "Discriminant";
        CheckFlags[CheckFlags["Partial"] = 48] = "Partial";
    })(CheckFlags = ts.CheckFlags || (ts.CheckFlags = {}));
    var InternalSymbolName;
    (function (InternalSymbolName) {
        InternalSymbolName["Call"] = "__call";
        InternalSymbolName["Constructor"] = "__constructor";
        InternalSymbolName["New"] = "__new";
        InternalSymbolName["Index"] = "__index";
        InternalSymbolName["ExportStar"] = "__export";
        InternalSymbolName["Global"] = "__global";
        InternalSymbolName["Missing"] = "__missing";
        InternalSymbolName["Type"] = "__type";
        InternalSymbolName["Object"] = "__object";
        InternalSymbolName["JSXAttributes"] = "__jsxAttributes";
        InternalSymbolName["Class"] = "__class";
        InternalSymbolName["Function"] = "__function";
        InternalSymbolName["Computed"] = "__computed";
        InternalSymbolName["Resolving"] = "__resolving__";
        InternalSymbolName["ExportEquals"] = "export=";
        InternalSymbolName["Default"] = "default";
        InternalSymbolName["This"] = "this";
    })(InternalSymbolName = ts.InternalSymbolName || (ts.InternalSymbolName = {}));
    /* @internal */
    var NodeCheckFlags;
    (function (NodeCheckFlags) {
        NodeCheckFlags[NodeCheckFlags["TypeChecked"] = 1] = "TypeChecked";
        NodeCheckFlags[NodeCheckFlags["LexicalThis"] = 2] = "LexicalThis";
        NodeCheckFlags[NodeCheckFlags["CaptureThis"] = 4] = "CaptureThis";
        NodeCheckFlags[NodeCheckFlags["CaptureNewTarget"] = 8] = "CaptureNewTarget";
        NodeCheckFlags[NodeCheckFlags["SuperInstance"] = 256] = "SuperInstance";
        NodeCheckFlags[NodeCheckFlags["SuperStatic"] = 512] = "SuperStatic";
        NodeCheckFlags[NodeCheckFlags["ContextChecked"] = 1024] = "ContextChecked";
        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuper"] = 2048] = "AsyncMethodWithSuper";
        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuperBinding"] = 4096] = "AsyncMethodWithSuperBinding";
        NodeCheckFlags[NodeCheckFlags["CaptureArguments"] = 8192] = "CaptureArguments";
        NodeCheckFlags[NodeCheckFlags["EnumValuesComputed"] = 16384] = "EnumValuesComputed";
        NodeCheckFlags[NodeCheckFlags["LexicalModuleMergesWithClass"] = 32768] = "LexicalModuleMergesWithClass";
        NodeCheckFlags[NodeCheckFlags["LoopWithCapturedBlockScopedBinding"] = 65536] = "LoopWithCapturedBlockScopedBinding";
        NodeCheckFlags[NodeCheckFlags["ContainsCapturedBlockScopeBinding"] = 131072] = "ContainsCapturedBlockScopeBinding";
        NodeCheckFlags[NodeCheckFlags["CapturedBlockScopedBinding"] = 262144] = "CapturedBlockScopedBinding";
        NodeCheckFlags[NodeCheckFlags["BlockScopedBindingInLoop"] = 524288] = "BlockScopedBindingInLoop";
        NodeCheckFlags[NodeCheckFlags["ClassWithBodyScopedClassBinding"] = 1048576] = "ClassWithBodyScopedClassBinding";
        NodeCheckFlags[NodeCheckFlags["BodyScopedClassBinding"] = 2097152] = "BodyScopedClassBinding";
        NodeCheckFlags[NodeCheckFlags["NeedsLoopOutParameter"] = 4194304] = "NeedsLoopOutParameter";
        NodeCheckFlags[NodeCheckFlags["AssignmentsMarked"] = 8388608] = "AssignmentsMarked";
        NodeCheckFlags[NodeCheckFlags["ClassWithConstructorReference"] = 16777216] = "ClassWithConstructorReference";
        NodeCheckFlags[NodeCheckFlags["ConstructorReferenceInClass"] = 33554432] = "ConstructorReferenceInClass";
        NodeCheckFlags[NodeCheckFlags["ContainsClassWithPrivateIdentifiers"] = 67108864] = "ContainsClassWithPrivateIdentifiers";
    })(NodeCheckFlags = ts.NodeCheckFlags || (ts.NodeCheckFlags = {}));
    var TypeFlags;
    (function (TypeFlags) {
        TypeFlags[TypeFlags["Any"] = 1] = "Any";
        TypeFlags[TypeFlags["Unknown"] = 2] = "Unknown";
        TypeFlags[TypeFlags["String"] = 4] = "String";
        TypeFlags[TypeFlags["Number"] = 8] = "Number";
        TypeFlags[TypeFlags["Boolean"] = 16] = "Boolean";
        TypeFlags[TypeFlags["Enum"] = 32] = "Enum";
        TypeFlags[TypeFlags["BigInt"] = 64] = "BigInt";
        TypeFlags[TypeFlags["StringLiteral"] = 128] = "StringLiteral";
        TypeFlags[TypeFlags["NumberLiteral"] = 256] = "NumberLiteral";
        TypeFlags[TypeFlags["BooleanLiteral"] = 512] = "BooleanLiteral";
        TypeFlags[TypeFlags["EnumLiteral"] = 1024] = "EnumLiteral";
        TypeFlags[TypeFlags["BigIntLiteral"] = 2048] = "BigIntLiteral";
        TypeFlags[TypeFlags["ESSymbol"] = 4096] = "ESSymbol";
        TypeFlags[TypeFlags["UniqueESSymbol"] = 8192] = "UniqueESSymbol";
        TypeFlags[TypeFlags["Void"] = 16384] = "Void";
        TypeFlags[TypeFlags["Undefined"] = 32768] = "Undefined";
        TypeFlags[TypeFlags["Null"] = 65536] = "Null";
        TypeFlags[TypeFlags["Never"] = 131072] = "Never";
        TypeFlags[TypeFlags["TypeParameter"] = 262144] = "TypeParameter";
        TypeFlags[TypeFlags["Object"] = 524288] = "Object";
        TypeFlags[TypeFlags["Union"] = 1048576] = "Union";
        TypeFlags[TypeFlags["Intersection"] = 2097152] = "Intersection";
        TypeFlags[TypeFlags["Index"] = 4194304] = "Index";
        TypeFlags[TypeFlags["IndexedAccess"] = 8388608] = "IndexedAccess";
        TypeFlags[TypeFlags["Conditional"] = 16777216] = "Conditional";
        TypeFlags[TypeFlags["Substitution"] = 33554432] = "Substitution";
        TypeFlags[TypeFlags["NonPrimitive"] = 67108864] = "NonPrimitive";
        /* @internal */
        TypeFlags[TypeFlags["AnyOrUnknown"] = 3] = "AnyOrUnknown";
        /* @internal */
        TypeFlags[TypeFlags["Nullable"] = 98304] = "Nullable";
        TypeFlags[TypeFlags["Literal"] = 2944] = "Literal";
        TypeFlags[TypeFlags["Unit"] = 109440] = "Unit";
        TypeFlags[TypeFlags["StringOrNumberLiteral"] = 384] = "StringOrNumberLiteral";
        /* @internal */
        TypeFlags[TypeFlags["StringOrNumberLiteralOrUnique"] = 8576] = "StringOrNumberLiteralOrUnique";
        /* @internal */
        TypeFlags[TypeFlags["DefinitelyFalsy"] = 117632] = "DefinitelyFalsy";
        TypeFlags[TypeFlags["PossiblyFalsy"] = 117724] = "PossiblyFalsy";
        /* @internal */
        TypeFlags[TypeFlags["Intrinsic"] = 67359327] = "Intrinsic";
        /* @internal */
        TypeFlags[TypeFlags["Primitive"] = 131068] = "Primitive";
        TypeFlags[TypeFlags["StringLike"] = 132] = "StringLike";
        TypeFlags[TypeFlags["NumberLike"] = 296] = "NumberLike";
        TypeFlags[TypeFlags["BigIntLike"] = 2112] = "BigIntLike";
        TypeFlags[TypeFlags["BooleanLike"] = 528] = "BooleanLike";
        TypeFlags[TypeFlags["EnumLike"] = 1056] = "EnumLike";
        TypeFlags[TypeFlags["ESSymbolLike"] = 12288] = "ESSymbolLike";
        TypeFlags[TypeFlags["VoidLike"] = 49152] = "VoidLike";
        /* @internal */
        TypeFlags[TypeFlags["DisjointDomains"] = 67238908] = "DisjointDomains";
        TypeFlags[TypeFlags["UnionOrIntersection"] = 3145728] = "UnionOrIntersection";
        TypeFlags[TypeFlags["StructuredType"] = 3670016] = "StructuredType";
        TypeFlags[TypeFlags["TypeVariable"] = 8650752] = "TypeVariable";
        TypeFlags[TypeFlags["InstantiableNonPrimitive"] = 58982400] = "InstantiableNonPrimitive";
        TypeFlags[TypeFlags["InstantiablePrimitive"] = 4194304] = "InstantiablePrimitive";
        TypeFlags[TypeFlags["Instantiable"] = 63176704] = "Instantiable";
        TypeFlags[TypeFlags["StructuredOrInstantiable"] = 66846720] = "StructuredOrInstantiable";
        /* @internal */
        TypeFlags[TypeFlags["ObjectFlagsType"] = 3899393] = "ObjectFlagsType";
        /* @internal */
        TypeFlags[TypeFlags["Simplifiable"] = 25165824] = "Simplifiable";
        /* @internal */
        TypeFlags[TypeFlags["Substructure"] = 66584576] = "Substructure";
        // 'Narrowable' types are types where narrowing actually narrows.
        // This *should* be every type other than null, undefined, void, and never
        TypeFlags[TypeFlags["Narrowable"] = 133970943] = "Narrowable";
        TypeFlags[TypeFlags["NotUnionOrUnit"] = 67637251] = "NotUnionOrUnit";
        /* @internal */
        TypeFlags[TypeFlags["NotPrimitiveUnion"] = 66994211] = "NotPrimitiveUnion";
        // The following flags are aggregated during union and intersection type construction
        /* @internal */
        TypeFlags[TypeFlags["IncludesMask"] = 71041023] = "IncludesMask";
        // The following flags are used for different purposes during union and intersection type construction
        /* @internal */
        TypeFlags[TypeFlags["IncludesStructuredOrInstantiable"] = 262144] = "IncludesStructuredOrInstantiable";
        /* @internal */
        TypeFlags[TypeFlags["IncludesNonWideningType"] = 4194304] = "IncludesNonWideningType";
        /* @internal */
        TypeFlags[TypeFlags["IncludesWildcard"] = 8388608] = "IncludesWildcard";
        /* @internal */
        TypeFlags[TypeFlags["IncludesEmptyObject"] = 16777216] = "IncludesEmptyObject";
    })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {}));
    var ObjectFlags;
    (function (ObjectFlags) {
        ObjectFlags[ObjectFlags["Class"] = 1] = "Class";
        ObjectFlags[ObjectFlags["Interface"] = 2] = "Interface";
        ObjectFlags[ObjectFlags["Reference"] = 4] = "Reference";
        ObjectFlags[ObjectFlags["Tuple"] = 8] = "Tuple";
        ObjectFlags[ObjectFlags["Anonymous"] = 16] = "Anonymous";
        ObjectFlags[ObjectFlags["Mapped"] = 32] = "Mapped";
        ObjectFlags[ObjectFlags["Instantiated"] = 64] = "Instantiated";
        ObjectFlags[ObjectFlags["ObjectLiteral"] = 128] = "ObjectLiteral";
        ObjectFlags[ObjectFlags["EvolvingArray"] = 256] = "EvolvingArray";
        ObjectFlags[ObjectFlags["ObjectLiteralPatternWithComputedProperties"] = 512] = "ObjectLiteralPatternWithComputedProperties";
        ObjectFlags[ObjectFlags["ContainsSpread"] = 1024] = "ContainsSpread";
        ObjectFlags[ObjectFlags["ReverseMapped"] = 2048] = "ReverseMapped";
        ObjectFlags[ObjectFlags["JsxAttributes"] = 4096] = "JsxAttributes";
        ObjectFlags[ObjectFlags["MarkerType"] = 8192] = "MarkerType";
        ObjectFlags[ObjectFlags["JSLiteral"] = 16384] = "JSLiteral";
        ObjectFlags[ObjectFlags["FreshLiteral"] = 32768] = "FreshLiteral";
        ObjectFlags[ObjectFlags["ArrayLiteral"] = 65536] = "ArrayLiteral";
        ObjectFlags[ObjectFlags["ObjectRestType"] = 131072] = "ObjectRestType";
        /* @internal */
        ObjectFlags[ObjectFlags["PrimitiveUnion"] = 262144] = "PrimitiveUnion";
        /* @internal */
        ObjectFlags[ObjectFlags["ContainsWideningType"] = 524288] = "ContainsWideningType";
        /* @internal */
        ObjectFlags[ObjectFlags["ContainsObjectOrArrayLiteral"] = 1048576] = "ContainsObjectOrArrayLiteral";
        /* @internal */
        ObjectFlags[ObjectFlags["NonInferrableType"] = 2097152] = "NonInferrableType";
        /* @internal */
        ObjectFlags[ObjectFlags["IsGenericObjectTypeComputed"] = 4194304] = "IsGenericObjectTypeComputed";
        /* @internal */
        ObjectFlags[ObjectFlags["IsGenericObjectType"] = 8388608] = "IsGenericObjectType";
        /* @internal */
        ObjectFlags[ObjectFlags["IsGenericIndexTypeComputed"] = 16777216] = "IsGenericIndexTypeComputed";
        /* @internal */
        ObjectFlags[ObjectFlags["IsGenericIndexType"] = 33554432] = "IsGenericIndexType";
        /* @internal */
        ObjectFlags[ObjectFlags["CouldContainTypeVariablesComputed"] = 67108864] = "CouldContainTypeVariablesComputed";
        /* @internal */
        ObjectFlags[ObjectFlags["CouldContainTypeVariables"] = 134217728] = "CouldContainTypeVariables";
        /* @internal */
        ObjectFlags[ObjectFlags["ContainsIntersections"] = 268435456] = "ContainsIntersections";
        /* @internal */
        ObjectFlags[ObjectFlags["IsNeverIntersectionComputed"] = 268435456] = "IsNeverIntersectionComputed";
        /* @internal */
        ObjectFlags[ObjectFlags["IsNeverIntersection"] = 536870912] = "IsNeverIntersection";
        ObjectFlags[ObjectFlags["ClassOrInterface"] = 3] = "ClassOrInterface";
        /* @internal */
        ObjectFlags[ObjectFlags["RequiresWidening"] = 1572864] = "RequiresWidening";
        /* @internal */
        ObjectFlags[ObjectFlags["PropagatingFlags"] = 3670016] = "PropagatingFlags";
    })(ObjectFlags = ts.ObjectFlags || (ts.ObjectFlags = {}));
    /* @internal */
    var VarianceFlags;
    (function (VarianceFlags) {
        VarianceFlags[VarianceFlags["Invariant"] = 0] = "Invariant";
        VarianceFlags[VarianceFlags["Covariant"] = 1] = "Covariant";
        VarianceFlags[VarianceFlags["Contravariant"] = 2] = "Contravariant";
        VarianceFlags[VarianceFlags["Bivariant"] = 3] = "Bivariant";
        VarianceFlags[VarianceFlags["Independent"] = 4] = "Independent";
        VarianceFlags[VarianceFlags["VarianceMask"] = 7] = "VarianceMask";
        VarianceFlags[VarianceFlags["Unmeasurable"] = 8] = "Unmeasurable";
        VarianceFlags[VarianceFlags["Unreliable"] = 16] = "Unreliable";
        VarianceFlags[VarianceFlags["AllowsStructuralFallback"] = 24] = "AllowsStructuralFallback";
    })(VarianceFlags = ts.VarianceFlags || (ts.VarianceFlags = {}));
    /* @internal */
    var JsxReferenceKind;
    (function (JsxReferenceKind) {
        JsxReferenceKind[JsxReferenceKind["Component"] = 0] = "Component";
        JsxReferenceKind[JsxReferenceKind["Function"] = 1] = "Function";
        JsxReferenceKind[JsxReferenceKind["Mixed"] = 2] = "Mixed";
    })(JsxReferenceKind = ts.JsxReferenceKind || (ts.JsxReferenceKind = {}));
    var SignatureKind;
    (function (SignatureKind) {
        SignatureKind[SignatureKind["Call"] = 0] = "Call";
        SignatureKind[SignatureKind["Construct"] = 1] = "Construct";
    })(SignatureKind = ts.SignatureKind || (ts.SignatureKind = {}));
    /* @internal */
    var SignatureFlags;
    (function (SignatureFlags) {
        SignatureFlags[SignatureFlags["None"] = 0] = "None";
        SignatureFlags[SignatureFlags["HasRestParameter"] = 1] = "HasRestParameter";
        SignatureFlags[SignatureFlags["HasLiteralTypes"] = 2] = "HasLiteralTypes";
        SignatureFlags[SignatureFlags["IsInnerCallChain"] = 4] = "IsInnerCallChain";
        SignatureFlags[SignatureFlags["IsOuterCallChain"] = 8] = "IsOuterCallChain";
        SignatureFlags[SignatureFlags["IsUntypedSignatureInJSFile"] = 16] = "IsUntypedSignatureInJSFile";
        // We do not propagate `IsInnerCallChain` to instantiated signatures, as that would result in us
        // attempting to add `| undefined` on each recursive call to `getReturnTypeOfSignature` when
        // instantiating the return type.
        SignatureFlags[SignatureFlags["PropagatingFlags"] = 3] = "PropagatingFlags";
        SignatureFlags[SignatureFlags["CallChainFlags"] = 12] = "CallChainFlags";
    })(SignatureFlags = ts.SignatureFlags || (ts.SignatureFlags = {}));
    var IndexKind;
    (function (IndexKind) {
        IndexKind[IndexKind["String"] = 0] = "String";
        IndexKind[IndexKind["Number"] = 1] = "Number";
    })(IndexKind = ts.IndexKind || (ts.IndexKind = {}));
    /* @internal */
    var TypeMapKind;
    (function (TypeMapKind) {
        TypeMapKind[TypeMapKind["Simple"] = 0] = "Simple";
        TypeMapKind[TypeMapKind["Array"] = 1] = "Array";
        TypeMapKind[TypeMapKind["Function"] = 2] = "Function";
        TypeMapKind[TypeMapKind["Composite"] = 3] = "Composite";
        TypeMapKind[TypeMapKind["Merged"] = 4] = "Merged";
    })(TypeMapKind = ts.TypeMapKind || (ts.TypeMapKind = {}));
    var InferencePriority;
    (function (InferencePriority) {
        InferencePriority[InferencePriority["NakedTypeVariable"] = 1] = "NakedTypeVariable";
        InferencePriority[InferencePriority["HomomorphicMappedType"] = 2] = "HomomorphicMappedType";
        InferencePriority[InferencePriority["PartialHomomorphicMappedType"] = 4] = "PartialHomomorphicMappedType";
        InferencePriority[InferencePriority["MappedTypeConstraint"] = 8] = "MappedTypeConstraint";
        InferencePriority[InferencePriority["ContravariantConditional"] = 16] = "ContravariantConditional";
        InferencePriority[InferencePriority["ReturnType"] = 32] = "ReturnType";
        InferencePriority[InferencePriority["LiteralKeyof"] = 64] = "LiteralKeyof";
        InferencePriority[InferencePriority["NoConstraints"] = 128] = "NoConstraints";
        InferencePriority[InferencePriority["AlwaysStrict"] = 256] = "AlwaysStrict";
        InferencePriority[InferencePriority["MaxValue"] = 512] = "MaxValue";
        InferencePriority[InferencePriority["PriorityImpliesCombination"] = 104] = "PriorityImpliesCombination";
        InferencePriority[InferencePriority["Circularity"] = -1] = "Circularity";
    })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {}));
    /* @internal */
    var InferenceFlags;
    (function (InferenceFlags) {
        InferenceFlags[InferenceFlags["None"] = 0] = "None";
        InferenceFlags[InferenceFlags["NoDefault"] = 1] = "NoDefault";
        InferenceFlags[InferenceFlags["AnyDefault"] = 2] = "AnyDefault";
        InferenceFlags[InferenceFlags["SkippedGenericFunction"] = 4] = "SkippedGenericFunction";
    })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {}));
    /**
     * Ternary values are defined such that
     * x & y is False if either x or y is False.
     * x & y is Maybe if either x or y is Maybe, but neither x or y is False.
     * x & y is True if both x and y are True.
     * x | y is False if both x and y are False.
     * x | y is Maybe if either x or y is Maybe, but neither x or y is True.
     * x | y is True if either x or y is True.
     */
    /* @internal */
    var Ternary;
    (function (Ternary) {
        Ternary[Ternary["False"] = 0] = "False";
        Ternary[Ternary["Maybe"] = 1] = "Maybe";
        Ternary[Ternary["True"] = -1] = "True";
    })(Ternary = ts.Ternary || (ts.Ternary = {}));
    /* @internal */
    var AssignmentDeclarationKind;
    (function (AssignmentDeclarationKind) {
        AssignmentDeclarationKind[AssignmentDeclarationKind["None"] = 0] = "None";
        /// exports.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ExportsProperty"] = 1] = "ExportsProperty";
        /// module.exports = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ModuleExports"] = 2] = "ModuleExports";
        /// className.prototype.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["PrototypeProperty"] = 3] = "PrototypeProperty";
        /// this.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ThisProperty"] = 4] = "ThisProperty";
        // F.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["Property"] = 5] = "Property";
        // F.prototype = { ... }
        AssignmentDeclarationKind[AssignmentDeclarationKind["Prototype"] = 6] = "Prototype";
        // Object.defineProperty(x, 'name', { value: any, writable?: boolean (false by default) });
        // Object.defineProperty(x, 'name', { get: Function, set: Function });
        // Object.defineProperty(x, 'name', { get: Function });
        // Object.defineProperty(x, 'name', { set: Function });
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePropertyValue"] = 7] = "ObjectDefinePropertyValue";
        // Object.defineProperty(exports || module.exports, 'name', ...);
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePropertyExports"] = 8] = "ObjectDefinePropertyExports";
        // Object.defineProperty(Foo.prototype, 'name', ...);
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePrototypeProperty"] = 9] = "ObjectDefinePrototypeProperty";
    })(AssignmentDeclarationKind = ts.AssignmentDeclarationKind || (ts.AssignmentDeclarationKind = {}));
    var DiagnosticCategory;
    (function (DiagnosticCategory) {
        DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
        DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
        DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion";
        DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message";
    })(DiagnosticCategory = ts.DiagnosticCategory || (ts.DiagnosticCategory = {}));
    /* @internal */
    function diagnosticCategoryName(d, lowerCase) {
        if (lowerCase === void 0) { lowerCase = true; }
        var name = DiagnosticCategory[d.category];
        return lowerCase ? name.toLowerCase() : name;
    }
    ts.diagnosticCategoryName = diagnosticCategoryName;
    var ModuleResolutionKind;
    (function (ModuleResolutionKind) {
        ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic";
        ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs";
    })(ModuleResolutionKind = ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {}));
    var WatchFileKind;
    (function (WatchFileKind) {
        WatchFileKind[WatchFileKind["FixedPollingInterval"] = 0] = "FixedPollingInterval";
        WatchFileKind[WatchFileKind["PriorityPollingInterval"] = 1] = "PriorityPollingInterval";
        WatchFileKind[WatchFileKind["DynamicPriorityPolling"] = 2] = "DynamicPriorityPolling";
        WatchFileKind[WatchFileKind["UseFsEvents"] = 3] = "UseFsEvents";
        WatchFileKind[WatchFileKind["UseFsEventsOnParentDirectory"] = 4] = "UseFsEventsOnParentDirectory";
    })(WatchFileKind = ts.WatchFileKind || (ts.WatchFileKind = {}));
    var WatchDirectoryKind;
    (function (WatchDirectoryKind) {
        WatchDirectoryKind[WatchDirectoryKind["UseFsEvents"] = 0] = "UseFsEvents";
        WatchDirectoryKind[WatchDirectoryKind["FixedPollingInterval"] = 1] = "FixedPollingInterval";
        WatchDirectoryKind[WatchDirectoryKind["DynamicPriorityPolling"] = 2] = "DynamicPriorityPolling";
    })(WatchDirectoryKind = ts.WatchDirectoryKind || (ts.WatchDirectoryKind = {}));
    var PollingWatchKind;
    (function (PollingWatchKind) {
        PollingWatchKind[PollingWatchKind["FixedInterval"] = 0] = "FixedInterval";
        PollingWatchKind[PollingWatchKind["PriorityInterval"] = 1] = "PriorityInterval";
        PollingWatchKind[PollingWatchKind["DynamicPriority"] = 2] = "DynamicPriority";
    })(PollingWatchKind = ts.PollingWatchKind || (ts.PollingWatchKind = {}));
    var ModuleKind;
    (function (ModuleKind) {
        ModuleKind[ModuleKind["None"] = 0] = "None";
        ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS";
        ModuleKind[ModuleKind["AMD"] = 2] = "AMD";
        ModuleKind[ModuleKind["UMD"] = 3] = "UMD";
        ModuleKind[ModuleKind["System"] = 4] = "System";
        // NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind.
        //       Non-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES
        //       module kind).
        ModuleKind[ModuleKind["ES2015"] = 5] = "ES2015";
        ModuleKind[ModuleKind["ES2020"] = 6] = "ES2020";
        ModuleKind[ModuleKind["ESNext"] = 99] = "ESNext";
    })(ModuleKind = ts.ModuleKind || (ts.ModuleKind = {}));
    var JsxEmit;
    (function (JsxEmit) {
        JsxEmit[JsxEmit["None"] = 0] = "None";
        JsxEmit[JsxEmit["Preserve"] = 1] = "Preserve";
        JsxEmit[JsxEmit["React"] = 2] = "React";
        JsxEmit[JsxEmit["ReactNative"] = 3] = "ReactNative";
    })(JsxEmit = ts.JsxEmit || (ts.JsxEmit = {}));
    var ImportsNotUsedAsValues;
    (function (ImportsNotUsedAsValues) {
        ImportsNotUsedAsValues[ImportsNotUsedAsValues["Remove"] = 0] = "Remove";
        ImportsNotUsedAsValues[ImportsNotUsedAsValues["Preserve"] = 1] = "Preserve";
        ImportsNotUsedAsValues[ImportsNotUsedAsValues["Error"] = 2] = "Error";
    })(ImportsNotUsedAsValues = ts.ImportsNotUsedAsValues || (ts.ImportsNotUsedAsValues = {}));
    var NewLineKind;
    (function (NewLineKind) {
        NewLineKind[NewLineKind["CarriageReturnLineFeed"] = 0] = "CarriageReturnLineFeed";
        NewLineKind[NewLineKind["LineFeed"] = 1] = "LineFeed";
    })(NewLineKind = ts.NewLineKind || (ts.NewLineKind = {}));
    var ScriptKind;
    (function (ScriptKind) {
        ScriptKind[ScriptKind["Unknown"] = 0] = "Unknown";
        ScriptKind[ScriptKind["JS"] = 1] = "JS";
        ScriptKind[ScriptKind["JSX"] = 2] = "JSX";
        ScriptKind[ScriptKind["TS"] = 3] = "TS";
        ScriptKind[ScriptKind["TSX"] = 4] = "TSX";
        ScriptKind[ScriptKind["External"] = 5] = "External";
        ScriptKind[ScriptKind["JSON"] = 6] = "JSON";
        /**
         * Used on extensions that doesn't define the ScriptKind but the content defines it.
         * Deferred extensions are going to be included in all project contexts.
         */
        ScriptKind[ScriptKind["Deferred"] = 7] = "Deferred";
    })(ScriptKind = ts.ScriptKind || (ts.ScriptKind = {}));
    var ScriptTarget;
    (function (ScriptTarget) {
        ScriptTarget[ScriptTarget["ES3"] = 0] = "ES3";
        ScriptTarget[ScriptTarget["ES5"] = 1] = "ES5";
        ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015";
        ScriptTarget[ScriptTarget["ES2016"] = 3] = "ES2016";
        ScriptTarget[ScriptTarget["ES2017"] = 4] = "ES2017";
        ScriptTarget[ScriptTarget["ES2018"] = 5] = "ES2018";
        ScriptTarget[ScriptTarget["ES2019"] = 6] = "ES2019";
        ScriptTarget[ScriptTarget["ES2020"] = 7] = "ES2020";
        ScriptTarget[ScriptTarget["ESNext"] = 99] = "ESNext";
        ScriptTarget[ScriptTarget["JSON"] = 100] = "JSON";
        ScriptTarget[ScriptTarget["Latest"] = 99] = "Latest";
    })(ScriptTarget = ts.ScriptTarget || (ts.ScriptTarget = {}));
    var LanguageVariant;
    (function (LanguageVariant) {
        LanguageVariant[LanguageVariant["Standard"] = 0] = "Standard";
        LanguageVariant[LanguageVariant["JSX"] = 1] = "JSX";
    })(LanguageVariant = ts.LanguageVariant || (ts.LanguageVariant = {}));
    var WatchDirectoryFlags;
    (function (WatchDirectoryFlags) {
        WatchDirectoryFlags[WatchDirectoryFlags["None"] = 0] = "None";
        WatchDirectoryFlags[WatchDirectoryFlags["Recursive"] = 1] = "Recursive";
    })(WatchDirectoryFlags = ts.WatchDirectoryFlags || (ts.WatchDirectoryFlags = {}));
    /* @internal */
    var CharacterCodes;
    (function (CharacterCodes) {
        CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter";
        CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter";
        CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
        CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
        CharacterCodes[CharacterCodes["lineSeparator"] = 8232] = "lineSeparator";
        CharacterCodes[CharacterCodes["paragraphSeparator"] = 8233] = "paragraphSeparator";
        CharacterCodes[CharacterCodes["nextLine"] = 133] = "nextLine";
        // Unicode 3.0 space characters
        CharacterCodes[CharacterCodes["space"] = 32] = "space";
        CharacterCodes[CharacterCodes["nonBreakingSpace"] = 160] = "nonBreakingSpace";
        CharacterCodes[CharacterCodes["enQuad"] = 8192] = "enQuad";
        CharacterCodes[CharacterCodes["emQuad"] = 8193] = "emQuad";
        CharacterCodes[CharacterCodes["enSpace"] = 8194] = "enSpace";
        CharacterCodes[CharacterCodes["emSpace"] = 8195] = "emSpace";
        CharacterCodes[CharacterCodes["threePerEmSpace"] = 8196] = "threePerEmSpace";
        CharacterCodes[CharacterCodes["fourPerEmSpace"] = 8197] = "fourPerEmSpace";
        CharacterCodes[CharacterCodes["sixPerEmSpace"] = 8198] = "sixPerEmSpace";
        CharacterCodes[CharacterCodes["figureSpace"] = 8199] = "figureSpace";
        CharacterCodes[CharacterCodes["punctuationSpace"] = 8200] = "punctuationSpace";
        CharacterCodes[CharacterCodes["thinSpace"] = 8201] = "thinSpace";
        CharacterCodes[CharacterCodes["hairSpace"] = 8202] = "hairSpace";
        CharacterCodes[CharacterCodes["zeroWidthSpace"] = 8203] = "zeroWidthSpace";
        CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 8239] = "narrowNoBreakSpace";
        CharacterCodes[CharacterCodes["ideographicSpace"] = 12288] = "ideographicSpace";
        CharacterCodes[CharacterCodes["mathematicalSpace"] = 8287] = "mathematicalSpace";
        CharacterCodes[CharacterCodes["ogham"] = 5760] = "ogham";
        CharacterCodes[CharacterCodes["_"] = 95] = "_";
        CharacterCodes[CharacterCodes["$"] = 36] = "$";
        CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
        CharacterCodes[CharacterCodes["_1"] = 49] = "_1";
        CharacterCodes[CharacterCodes["_2"] = 50] = "_2";
        CharacterCodes[CharacterCodes["_3"] = 51] = "_3";
        CharacterCodes[CharacterCodes["_4"] = 52] = "_4";
        CharacterCodes[CharacterCodes["_5"] = 53] = "_5";
        CharacterCodes[CharacterCodes["_6"] = 54] = "_6";
        CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
        CharacterCodes[CharacterCodes["_8"] = 56] = "_8";
        CharacterCodes[CharacterCodes["_9"] = 57] = "_9";
        CharacterCodes[CharacterCodes["a"] = 97] = "a";
        CharacterCodes[CharacterCodes["b"] = 98] = "b";
        CharacterCodes[CharacterCodes["c"] = 99] = "c";
        CharacterCodes[CharacterCodes["d"] = 100] = "d";
        CharacterCodes[CharacterCodes["e"] = 101] = "e";
        CharacterCodes[CharacterCodes["f"] = 102] = "f";
        CharacterCodes[CharacterCodes["g"] = 103] = "g";
        CharacterCodes[CharacterCodes["h"] = 104] = "h";
        CharacterCodes[CharacterCodes["i"] = 105] = "i";
        CharacterCodes[CharacterCodes["j"] = 106] = "j";
        CharacterCodes[CharacterCodes["k"] = 107] = "k";
        CharacterCodes[CharacterCodes["l"] = 108] = "l";
        CharacterCodes[CharacterCodes["m"] = 109] = "m";
        CharacterCodes[CharacterCodes["n"] = 110] = "n";
        CharacterCodes[CharacterCodes["o"] = 111] = "o";
        CharacterCodes[CharacterCodes["p"] = 112] = "p";
        CharacterCodes[CharacterCodes["q"] = 113] = "q";
        CharacterCodes[CharacterCodes["r"] = 114] = "r";
        CharacterCodes[CharacterCodes["s"] = 115] = "s";
        CharacterCodes[CharacterCodes["t"] = 116] = "t";
        CharacterCodes[CharacterCodes["u"] = 117] = "u";
        CharacterCodes[CharacterCodes["v"] = 118] = "v";
        CharacterCodes[CharacterCodes["w"] = 119] = "w";
        CharacterCodes[CharacterCodes["x"] = 120] = "x";
        CharacterCodes[CharacterCodes["y"] = 121] = "y";
        CharacterCodes[CharacterCodes["z"] = 122] = "z";
        CharacterCodes[CharacterCodes["A"] = 65] = "A";
        CharacterCodes[CharacterCodes["B"] = 66] = "B";
        CharacterCodes[CharacterCodes["C"] = 67] = "C";
        CharacterCodes[CharacterCodes["D"] = 68] = "D";
        CharacterCodes[CharacterCodes["E"] = 69] = "E";
        CharacterCodes[CharacterCodes["F"] = 70] = "F";
        CharacterCodes[CharacterCodes["G"] = 71] = "G";
        CharacterCodes[CharacterCodes["H"] = 72] = "H";
        CharacterCodes[CharacterCodes["I"] = 73] = "I";
        CharacterCodes[CharacterCodes["J"] = 74] = "J";
        CharacterCodes[CharacterCodes["K"] = 75] = "K";
        CharacterCodes[CharacterCodes["L"] = 76] = "L";
        CharacterCodes[CharacterCodes["M"] = 77] = "M";
        CharacterCodes[CharacterCodes["N"] = 78] = "N";
        CharacterCodes[CharacterCodes["O"] = 79] = "O";
        CharacterCodes[CharacterCodes["P"] = 80] = "P";
        CharacterCodes[CharacterCodes["Q"] = 81] = "Q";
        CharacterCodes[CharacterCodes["R"] = 82] = "R";
        CharacterCodes[CharacterCodes["S"] = 83] = "S";
        CharacterCodes[CharacterCodes["T"] = 84] = "T";
        CharacterCodes[CharacterCodes["U"] = 85] = "U";
        CharacterCodes[CharacterCodes["V"] = 86] = "V";
        CharacterCodes[CharacterCodes["W"] = 87] = "W";
        CharacterCodes[CharacterCodes["X"] = 88] = "X";
        CharacterCodes[CharacterCodes["Y"] = 89] = "Y";
        CharacterCodes[CharacterCodes["Z"] = 90] = "Z";
        CharacterCodes[CharacterCodes["ampersand"] = 38] = "ampersand";
        CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk";
        CharacterCodes[CharacterCodes["at"] = 64] = "at";
        CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
        CharacterCodes[CharacterCodes["backtick"] = 96] = "backtick";
        CharacterCodes[CharacterCodes["bar"] = 124] = "bar";
        CharacterCodes[CharacterCodes["caret"] = 94] = "caret";
        CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
        CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
        CharacterCodes[CharacterCodes["closeParen"] = 41] = "closeParen";
        CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
        CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
        CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
        CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
        CharacterCodes[CharacterCodes["equals"] = 61] = "equals";
        CharacterCodes[CharacterCodes["exclamation"] = 33] = "exclamation";
        CharacterCodes[CharacterCodes["greaterThan"] = 62] = "greaterThan";
        CharacterCodes[CharacterCodes["hash"] = 35] = "hash";
        CharacterCodes[CharacterCodes["lessThan"] = 60] = "lessThan";
        CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
        CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
        CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
        CharacterCodes[CharacterCodes["openParen"] = 40] = "openParen";
        CharacterCodes[CharacterCodes["percent"] = 37] = "percent";
        CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
        CharacterCodes[CharacterCodes["question"] = 63] = "question";
        CharacterCodes[CharacterCodes["semicolon"] = 59] = "semicolon";
        CharacterCodes[CharacterCodes["singleQuote"] = 39] = "singleQuote";
        CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
        CharacterCodes[CharacterCodes["tilde"] = 126] = "tilde";
        CharacterCodes[CharacterCodes["backspace"] = 8] = "backspace";
        CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
        CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark";
        CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
        CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab";
    })(CharacterCodes = ts.CharacterCodes || (ts.CharacterCodes = {}));
    var Extension;
    (function (Extension) {
        Extension["Ts"] = ".ts";
        Extension["Tsx"] = ".tsx";
        Extension["Dts"] = ".d.ts";
        Extension["Js"] = ".js";
        Extension["Jsx"] = ".jsx";
        Extension["Json"] = ".json";
        Extension["TsBuildInfo"] = ".tsbuildinfo";
    })(Extension = ts.Extension || (ts.Extension = {}));
    /* @internal */
    var TransformFlags;
    (function (TransformFlags) {
        TransformFlags[TransformFlags["None"] = 0] = "None";
        // Facts
        // - Flags used to indicate that a node or subtree contains syntax that requires transformation.
        TransformFlags[TransformFlags["ContainsTypeScript"] = 1] = "ContainsTypeScript";
        TransformFlags[TransformFlags["ContainsJsx"] = 2] = "ContainsJsx";
        TransformFlags[TransformFlags["ContainsESNext"] = 4] = "ContainsESNext";
        TransformFlags[TransformFlags["ContainsES2020"] = 8] = "ContainsES2020";
        TransformFlags[TransformFlags["ContainsES2019"] = 16] = "ContainsES2019";
        TransformFlags[TransformFlags["ContainsES2018"] = 32] = "ContainsES2018";
        TransformFlags[TransformFlags["ContainsES2017"] = 64] = "ContainsES2017";
        TransformFlags[TransformFlags["ContainsES2016"] = 128] = "ContainsES2016";
        TransformFlags[TransformFlags["ContainsES2015"] = 256] = "ContainsES2015";
        TransformFlags[TransformFlags["ContainsGenerator"] = 512] = "ContainsGenerator";
        TransformFlags[TransformFlags["ContainsDestructuringAssignment"] = 1024] = "ContainsDestructuringAssignment";
        // Markers
        // - Flags used to indicate that a subtree contains a specific transformation.
        TransformFlags[TransformFlags["ContainsTypeScriptClassSyntax"] = 2048] = "ContainsTypeScriptClassSyntax";
        TransformFlags[TransformFlags["ContainsLexicalThis"] = 4096] = "ContainsLexicalThis";
        TransformFlags[TransformFlags["ContainsRestOrSpread"] = 8192] = "ContainsRestOrSpread";
        TransformFlags[TransformFlags["ContainsObjectRestOrSpread"] = 16384] = "ContainsObjectRestOrSpread";
        TransformFlags[TransformFlags["ContainsComputedPropertyName"] = 32768] = "ContainsComputedPropertyName";
        TransformFlags[TransformFlags["ContainsBlockScopedBinding"] = 65536] = "ContainsBlockScopedBinding";
        TransformFlags[TransformFlags["ContainsBindingPattern"] = 131072] = "ContainsBindingPattern";
        TransformFlags[TransformFlags["ContainsYield"] = 262144] = "ContainsYield";
        TransformFlags[TransformFlags["ContainsAwait"] = 524288] = "ContainsAwait";
        TransformFlags[TransformFlags["ContainsHoistedDeclarationOrCompletion"] = 1048576] = "ContainsHoistedDeclarationOrCompletion";
        TransformFlags[TransformFlags["ContainsDynamicImport"] = 2097152] = "ContainsDynamicImport";
        TransformFlags[TransformFlags["ContainsClassFields"] = 4194304] = "ContainsClassFields";
        // Please leave this as 1 << 29.
        // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
        // It is a good reminder of how much room we have left
        TransformFlags[TransformFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
        // Assertions
        // - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
        TransformFlags[TransformFlags["AssertTypeScript"] = 1] = "AssertTypeScript";
        TransformFlags[TransformFlags["AssertJsx"] = 2] = "AssertJsx";
        TransformFlags[TransformFlags["AssertESNext"] = 4] = "AssertESNext";
        TransformFlags[TransformFlags["AssertES2020"] = 8] = "AssertES2020";
        TransformFlags[TransformFlags["AssertES2019"] = 16] = "AssertES2019";
        TransformFlags[TransformFlags["AssertES2018"] = 32] = "AssertES2018";
        TransformFlags[TransformFlags["AssertES2017"] = 64] = "AssertES2017";
        TransformFlags[TransformFlags["AssertES2016"] = 128] = "AssertES2016";
        TransformFlags[TransformFlags["AssertES2015"] = 256] = "AssertES2015";
        TransformFlags[TransformFlags["AssertGenerator"] = 512] = "AssertGenerator";
        TransformFlags[TransformFlags["AssertDestructuringAssignment"] = 1024] = "AssertDestructuringAssignment";
        // Scope Exclusions
        // - Bitmasks that exclude flags from propagating out of a specific context
        //   into the subtree flags of their container.
        TransformFlags[TransformFlags["OuterExpressionExcludes"] = 536870912] = "OuterExpressionExcludes";
        TransformFlags[TransformFlags["PropertyAccessExcludes"] = 536870912] = "PropertyAccessExcludes";
        TransformFlags[TransformFlags["NodeExcludes"] = 536870912] = "NodeExcludes";
        TransformFlags[TransformFlags["ArrowFunctionExcludes"] = 538920960] = "ArrowFunctionExcludes";
        TransformFlags[TransformFlags["FunctionExcludes"] = 538925056] = "FunctionExcludes";
        TransformFlags[TransformFlags["ConstructorExcludes"] = 538923008] = "ConstructorExcludes";
        TransformFlags[TransformFlags["MethodOrAccessorExcludes"] = 538923008] = "MethodOrAccessorExcludes";
        TransformFlags[TransformFlags["PropertyExcludes"] = 536875008] = "PropertyExcludes";
        TransformFlags[TransformFlags["ClassExcludes"] = 536905728] = "ClassExcludes";
        TransformFlags[TransformFlags["ModuleExcludes"] = 537991168] = "ModuleExcludes";
        TransformFlags[TransformFlags["TypeExcludes"] = -2] = "TypeExcludes";
        TransformFlags[TransformFlags["ObjectLiteralExcludes"] = 536922112] = "ObjectLiteralExcludes";
        TransformFlags[TransformFlags["ArrayLiteralOrCallOrNewExcludes"] = 536879104] = "ArrayLiteralOrCallOrNewExcludes";
        TransformFlags[TransformFlags["VariableDeclarationListExcludes"] = 537018368] = "VariableDeclarationListExcludes";
        TransformFlags[TransformFlags["ParameterExcludes"] = 536870912] = "ParameterExcludes";
        TransformFlags[TransformFlags["CatchClauseExcludes"] = 536887296] = "CatchClauseExcludes";
        TransformFlags[TransformFlags["BindingPatternExcludes"] = 536879104] = "BindingPatternExcludes";
        // Propagating flags
        // - Bitmasks for flags that should propagate from a child
        TransformFlags[TransformFlags["PropertyNamePropagatingFlags"] = 4096] = "PropertyNamePropagatingFlags";
        // Masks
        // - Additional bitmasks
    })(TransformFlags = ts.TransformFlags || (ts.TransformFlags = {}));
    var EmitFlags;
    (function (EmitFlags) {
        EmitFlags[EmitFlags["None"] = 0] = "None";
        EmitFlags[EmitFlags["SingleLine"] = 1] = "SingleLine";
        EmitFlags[EmitFlags["AdviseOnEmitNode"] = 2] = "AdviseOnEmitNode";
        EmitFlags[EmitFlags["NoSubstitution"] = 4] = "NoSubstitution";
        EmitFlags[EmitFlags["CapturesThis"] = 8] = "CapturesThis";
        EmitFlags[EmitFlags["NoLeadingSourceMap"] = 16] = "NoLeadingSourceMap";
        EmitFlags[EmitFlags["NoTrailingSourceMap"] = 32] = "NoTrailingSourceMap";
        EmitFlags[EmitFlags["NoSourceMap"] = 48] = "NoSourceMap";
        EmitFlags[EmitFlags["NoNestedSourceMaps"] = 64] = "NoNestedSourceMaps";
        EmitFlags[EmitFlags["NoTokenLeadingSourceMaps"] = 128] = "NoTokenLeadingSourceMaps";
        EmitFlags[EmitFlags["NoTokenTrailingSourceMaps"] = 256] = "NoTokenTrailingSourceMaps";
        EmitFlags[EmitFlags["NoTokenSourceMaps"] = 384] = "NoTokenSourceMaps";
        EmitFlags[EmitFlags["NoLeadingComments"] = 512] = "NoLeadingComments";
        EmitFlags[EmitFlags["NoTrailingComments"] = 1024] = "NoTrailingComments";
        EmitFlags[EmitFlags["NoComments"] = 1536] = "NoComments";
        EmitFlags[EmitFlags["NoNestedComments"] = 2048] = "NoNestedComments";
        EmitFlags[EmitFlags["HelperName"] = 4096] = "HelperName";
        EmitFlags[EmitFlags["ExportName"] = 8192] = "ExportName";
        EmitFlags[EmitFlags["LocalName"] = 16384] = "LocalName";
        EmitFlags[EmitFlags["InternalName"] = 32768] = "InternalName";
        EmitFlags[EmitFlags["Indented"] = 65536] = "Indented";
        EmitFlags[EmitFlags["NoIndentation"] = 131072] = "NoIndentation";
        EmitFlags[EmitFlags["AsyncFunctionBody"] = 262144] = "AsyncFunctionBody";
        EmitFlags[EmitFlags["ReuseTempVariableScope"] = 524288] = "ReuseTempVariableScope";
        EmitFlags[EmitFlags["CustomPrologue"] = 1048576] = "CustomPrologue";
        EmitFlags[EmitFlags["NoHoisting"] = 2097152] = "NoHoisting";
        EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
        EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
        EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
        /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
        /*@internal*/ EmitFlags[EmitFlags["NeverApplyImportHelper"] = 67108864] = "NeverApplyImportHelper";
        /*@internal*/ EmitFlags[EmitFlags["IgnoreSourceNewlines"] = 134217728] = "IgnoreSourceNewlines";
    })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
    /**
     * Used by the checker, this enum keeps track of external emit helpers that should be type
     * checked.
     */
    /* @internal */
    var ExternalEmitHelpers;
    (function (ExternalEmitHelpers) {
        ExternalEmitHelpers[ExternalEmitHelpers["Extends"] = 1] = "Extends";
        ExternalEmitHelpers[ExternalEmitHelpers["Assign"] = 2] = "Assign";
        ExternalEmitHelpers[ExternalEmitHelpers["Rest"] = 4] = "Rest";
        ExternalEmitHelpers[ExternalEmitHelpers["Decorate"] = 8] = "Decorate";
        ExternalEmitHelpers[ExternalEmitHelpers["Metadata"] = 16] = "Metadata";
        ExternalEmitHelpers[ExternalEmitHelpers["Param"] = 32] = "Param";
        ExternalEmitHelpers[ExternalEmitHelpers["Awaiter"] = 64] = "Awaiter";
        ExternalEmitHelpers[ExternalEmitHelpers["Generator"] = 128] = "Generator";
        ExternalEmitHelpers[ExternalEmitHelpers["Values"] = 256] = "Values";
        ExternalEmitHelpers[ExternalEmitHelpers["Read"] = 512] = "Read";
        ExternalEmitHelpers[ExternalEmitHelpers["Spread"] = 1024] = "Spread";
        ExternalEmitHelpers[ExternalEmitHelpers["SpreadArrays"] = 2048] = "SpreadArrays";
        ExternalEmitHelpers[ExternalEmitHelpers["Await"] = 4096] = "Await";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGenerator"] = 8192] = "AsyncGenerator";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegator"] = 16384] = "AsyncDelegator";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncValues"] = 32768] = "AsyncValues";
        ExternalEmitHelpers[ExternalEmitHelpers["ExportStar"] = 65536] = "ExportStar";
        ExternalEmitHelpers[ExternalEmitHelpers["MakeTemplateObject"] = 131072] = "MakeTemplateObject";
        ExternalEmitHelpers[ExternalEmitHelpers["ClassPrivateFieldGet"] = 262144] = "ClassPrivateFieldGet";
        ExternalEmitHelpers[ExternalEmitHelpers["ClassPrivateFieldSet"] = 524288] = "ClassPrivateFieldSet";
        ExternalEmitHelpers[ExternalEmitHelpers["CreateBinding"] = 1048576] = "CreateBinding";
        ExternalEmitHelpers[ExternalEmitHelpers["FirstEmitHelper"] = 1] = "FirstEmitHelper";
        ExternalEmitHelpers[ExternalEmitHelpers["LastEmitHelper"] = 1048576] = "LastEmitHelper";
        // Helpers included by ES2015 for..of
        ExternalEmitHelpers[ExternalEmitHelpers["ForOfIncludes"] = 256] = "ForOfIncludes";
        // Helpers included by ES2017 for..await..of
        ExternalEmitHelpers[ExternalEmitHelpers["ForAwaitOfIncludes"] = 32768] = "ForAwaitOfIncludes";
        // Helpers included by ES2017 async generators
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGeneratorIncludes"] = 12288] = "AsyncGeneratorIncludes";
        // Helpers included by yield* in ES2017 async generators
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegatorIncludes"] = 53248] = "AsyncDelegatorIncludes";
        // Helpers included by ES2015 spread
        ExternalEmitHelpers[ExternalEmitHelpers["SpreadIncludes"] = 1536] = "SpreadIncludes";
    })(ExternalEmitHelpers = ts.ExternalEmitHelpers || (ts.ExternalEmitHelpers = {}));
    var EmitHint;
    (function (EmitHint) {
        EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile";
        EmitHint[EmitHint["Expression"] = 1] = "Expression";
        EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName";
        EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter";
        EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified";
        EmitHint[EmitHint["EmbeddedStatement"] = 5] = "EmbeddedStatement";
        EmitHint[EmitHint["JsxAttributeValue"] = 6] = "JsxAttributeValue";
    })(EmitHint = ts.EmitHint || (ts.EmitHint = {}));
    /* @internal */
    var LexicalEnvironmentFlags;
    (function (LexicalEnvironmentFlags) {
        LexicalEnvironmentFlags[LexicalEnvironmentFlags["None"] = 0] = "None";
        LexicalEnvironmentFlags[LexicalEnvironmentFlags["InParameters"] = 1] = "InParameters";
        LexicalEnvironmentFlags[LexicalEnvironmentFlags["VariablesHoistedInParameters"] = 2] = "VariablesHoistedInParameters"; // a temp variable was hoisted while visiting a parameter list
    })(LexicalEnvironmentFlags = ts.LexicalEnvironmentFlags || (ts.LexicalEnvironmentFlags = {}));
    /*@internal*/
    var BundleFileSectionKind;
    (function (BundleFileSectionKind) {
        BundleFileSectionKind["Prologue"] = "prologue";
        BundleFileSectionKind["EmitHelpers"] = "emitHelpers";
        BundleFileSectionKind["NoDefaultLib"] = "no-default-lib";
        BundleFileSectionKind["Reference"] = "reference";
        BundleFileSectionKind["Type"] = "type";
        BundleFileSectionKind["Lib"] = "lib";
        BundleFileSectionKind["Prepend"] = "prepend";
        BundleFileSectionKind["Text"] = "text";
        BundleFileSectionKind["Internal"] = "internal";
        // comments?
    })(BundleFileSectionKind = ts.BundleFileSectionKind || (ts.BundleFileSectionKind = {}));
    var ListFormat;
    (function (ListFormat) {
        ListFormat[ListFormat["None"] = 0] = "None";
        // Line separators
        ListFormat[ListFormat["SingleLine"] = 0] = "SingleLine";
        ListFormat[ListFormat["MultiLine"] = 1] = "MultiLine";
        ListFormat[ListFormat["PreserveLines"] = 2] = "PreserveLines";
        ListFormat[ListFormat["LinesMask"] = 3] = "LinesMask";
        // Delimiters
        ListFormat[ListFormat["NotDelimited"] = 0] = "NotDelimited";
        ListFormat[ListFormat["BarDelimited"] = 4] = "BarDelimited";
        ListFormat[ListFormat["AmpersandDelimited"] = 8] = "AmpersandDelimited";
        ListFormat[ListFormat["CommaDelimited"] = 16] = "CommaDelimited";
        ListFormat[ListFormat["AsteriskDelimited"] = 32] = "AsteriskDelimited";
        ListFormat[ListFormat["DelimitersMask"] = 60] = "DelimitersMask";
        ListFormat[ListFormat["AllowTrailingComma"] = 64] = "AllowTrailingComma";
        // Whitespace
        ListFormat[ListFormat["Indented"] = 128] = "Indented";
        ListFormat[ListFormat["SpaceBetweenBraces"] = 256] = "SpaceBetweenBraces";
        ListFormat[ListFormat["SpaceBetweenSiblings"] = 512] = "SpaceBetweenSiblings";
        // Brackets/Braces
        ListFormat[ListFormat["Braces"] = 1024] = "Braces";
        ListFormat[ListFormat["Parenthesis"] = 2048] = "Parenthesis";
        ListFormat[ListFormat["AngleBrackets"] = 4096] = "AngleBrackets";
        ListFormat[ListFormat["SquareBrackets"] = 8192] = "SquareBrackets";
        ListFormat[ListFormat["BracketsMask"] = 15360] = "BracketsMask";
        ListFormat[ListFormat["OptionalIfUndefined"] = 16384] = "OptionalIfUndefined";
        ListFormat[ListFormat["OptionalIfEmpty"] = 32768] = "OptionalIfEmpty";
        ListFormat[ListFormat["Optional"] = 49152] = "Optional";
        // Other
        ListFormat[ListFormat["PreferNewLine"] = 65536] = "PreferNewLine";
        ListFormat[ListFormat["NoTrailingNewLine"] = 131072] = "NoTrailingNewLine";
        ListFormat[ListFormat["NoInterveningComments"] = 262144] = "NoInterveningComments";
        ListFormat[ListFormat["NoSpaceIfEmpty"] = 524288] = "NoSpaceIfEmpty";
        ListFormat[ListFormat["SingleElement"] = 1048576] = "SingleElement";
        ListFormat[ListFormat["SpaceAfterList"] = 2097152] = "SpaceAfterList";
        // Precomputed Formats
        ListFormat[ListFormat["Modifiers"] = 262656] = "Modifiers";
        ListFormat[ListFormat["HeritageClauses"] = 512] = "HeritageClauses";
        ListFormat[ListFormat["SingleLineTypeLiteralMembers"] = 768] = "SingleLineTypeLiteralMembers";
        ListFormat[ListFormat["MultiLineTypeLiteralMembers"] = 32897] = "MultiLineTypeLiteralMembers";
        ListFormat[ListFormat["TupleTypeElements"] = 528] = "TupleTypeElements";
        ListFormat[ListFormat["UnionTypeConstituents"] = 516] = "UnionTypeConstituents";
        ListFormat[ListFormat["IntersectionTypeConstituents"] = 520] = "IntersectionTypeConstituents";
        ListFormat[ListFormat["ObjectBindingPatternElements"] = 525136] = "ObjectBindingPatternElements";
        ListFormat[ListFormat["ArrayBindingPatternElements"] = 524880] = "ArrayBindingPatternElements";
        ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 526226] = "ObjectLiteralExpressionProperties";
        ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 8914] = "ArrayLiteralExpressionElements";
        ListFormat[ListFormat["CommaListElements"] = 528] = "CommaListElements";
        ListFormat[ListFormat["CallExpressionArguments"] = 2576] = "CallExpressionArguments";
        ListFormat[ListFormat["NewExpressionArguments"] = 18960] = "NewExpressionArguments";
        ListFormat[ListFormat["TemplateExpressionSpans"] = 262144] = "TemplateExpressionSpans";
        ListFormat[ListFormat["SingleLineBlockStatements"] = 768] = "SingleLineBlockStatements";
        ListFormat[ListFormat["MultiLineBlockStatements"] = 129] = "MultiLineBlockStatements";
        ListFormat[ListFormat["VariableDeclarationList"] = 528] = "VariableDeclarationList";
        ListFormat[ListFormat["SingleLineFunctionBodyStatements"] = 768] = "SingleLineFunctionBodyStatements";
        ListFormat[ListFormat["MultiLineFunctionBodyStatements"] = 1] = "MultiLineFunctionBodyStatements";
        ListFormat[ListFormat["ClassHeritageClauses"] = 0] = "ClassHeritageClauses";
        ListFormat[ListFormat["ClassMembers"] = 129] = "ClassMembers";
        ListFormat[ListFormat["InterfaceMembers"] = 129] = "InterfaceMembers";
        ListFormat[ListFormat["EnumMembers"] = 145] = "EnumMembers";
        ListFormat[ListFormat["CaseBlockClauses"] = 129] = "CaseBlockClauses";
        ListFormat[ListFormat["NamedImportsOrExportsElements"] = 525136] = "NamedImportsOrExportsElements";
        ListFormat[ListFormat["JsxElementOrFragmentChildren"] = 262144] = "JsxElementOrFragmentChildren";
        ListFormat[ListFormat["JsxElementAttributes"] = 262656] = "JsxElementAttributes";
        ListFormat[ListFormat["CaseOrDefaultClauseStatements"] = 163969] = "CaseOrDefaultClauseStatements";
        ListFormat[ListFormat["HeritageClauseTypes"] = 528] = "HeritageClauseTypes";
        ListFormat[ListFormat["SourceFileStatements"] = 131073] = "SourceFileStatements";
        ListFormat[ListFormat["Decorators"] = 2146305] = "Decorators";
        ListFormat[ListFormat["TypeArguments"] = 53776] = "TypeArguments";
        ListFormat[ListFormat["TypeParameters"] = 53776] = "TypeParameters";
        ListFormat[ListFormat["Parameters"] = 2576] = "Parameters";
        ListFormat[ListFormat["IndexSignatureParameters"] = 8848] = "IndexSignatureParameters";
        ListFormat[ListFormat["JSDocComment"] = 33] = "JSDocComment";
    })(ListFormat = ts.ListFormat || (ts.ListFormat = {}));
    /* @internal */
    var PragmaKindFlags;
    (function (PragmaKindFlags) {
        PragmaKindFlags[PragmaKindFlags["None"] = 0] = "None";
        /**
         * Triple slash comment of the form
         * /// <pragma-name argname="value" />
         */
        PragmaKindFlags[PragmaKindFlags["TripleSlashXML"] = 1] = "TripleSlashXML";
        /**
         * Single line comment of the form
         * // @pragma-name argval1 argval2
         * or
         * /// @pragma-name argval1 argval2
         */
        PragmaKindFlags[PragmaKindFlags["SingleLine"] = 2] = "SingleLine";
        /**
         * Multiline non-jsdoc pragma of the form
         * /* @pragma-name argval1 argval2 * /
         */
        PragmaKindFlags[PragmaKindFlags["MultiLine"] = 4] = "MultiLine";
        PragmaKindFlags[PragmaKindFlags["All"] = 7] = "All";
        PragmaKindFlags[PragmaKindFlags["Default"] = 7] = "Default";
    })(PragmaKindFlags = ts.PragmaKindFlags || (ts.PragmaKindFlags = {}));
    // While not strictly a type, this is here because `PragmaMap` needs to be here to be used with `SourceFile`, and we don't
    //  fancy effectively defining it twice, once in value-space and once in type-space
    /* @internal */
    ts.commentPragmas = {
        "reference": {
            args: [
                { name: "types", optional: true, captureSpan: true },
                { name: "lib", optional: true, captureSpan: true },
                { name: "path", optional: true, captureSpan: true },
                { name: "no-default-lib", optional: true }
            ],
            kind: 1 /* TripleSlashXML */
        },
        "amd-dependency": {
            args: [{ name: "path" }, { name: "name", optional: true }],
            kind: 1 /* TripleSlashXML */
        },
        "amd-module": {
            args: [{ name: "name" }],
            kind: 1 /* TripleSlashXML */
        },
        "ts-check": {
            kind: 2 /* SingleLine */
        },
        "ts-nocheck": {
            kind: 2 /* SingleLine */
        },
        "jsx": {
            args: [{ name: "factory" }],
            kind: 4 /* MultiLine */
        },
    };
})(ts || (ts = {}));
var ts;
(function (ts) {
    /**
     * djb2 hashing algorithm
     * http://www.cse.yorku.ca/~oz/hash.html
     */
    /* @internal */
    function generateDjb2Hash(data) {
        var acc = 5381;
        for (var i = 0; i < data.length; i++) {
            acc = ((acc << 5) + acc) + data.charCodeAt(i);
        }
        return acc.toString();
    }
    ts.generateDjb2Hash = generateDjb2Hash;
    /**
     * Set a high stack trace limit to provide more information in case of an error.
     * Called for command-line and server use cases.
     * Not called if TypeScript is used as a library.
     */
    /* @internal */
    function setStackTraceLimit() {
        if (Error.stackTraceLimit < 100) { // Also tests that we won't set the property if it doesn't exist.
            Error.stackTraceLimit = 100;
        }
    }
    ts.setStackTraceLimit = setStackTraceLimit;
    var FileWatcherEventKind;
    (function (FileWatcherEventKind) {
        FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created";
        FileWatcherEventKind[FileWatcherEventKind["Changed"] = 1] = "Changed";
        FileWatcherEventKind[FileWatcherEventKind["Deleted"] = 2] = "Deleted";
    })(FileWatcherEventKind = ts.FileWatcherEventKind || (ts.FileWatcherEventKind = {}));
    /* @internal */
    var PollingInterval;
    (function (PollingInterval) {
        PollingInterval[PollingInterval["High"] = 2000] = "High";
        PollingInterval[PollingInterval["Medium"] = 500] = "Medium";
        PollingInterval[PollingInterval["Low"] = 250] = "Low";
    })(PollingInterval = ts.PollingInterval || (ts.PollingInterval = {}));
    /* @internal */
    ts.missingFileModifiedTime = new Date(0); // Any subsequent modification will occur after this time
    function createPollingIntervalBasedLevels(levels) {
        var _a;
        return _a = {},
            _a[PollingInterval.Low] = levels.Low,
            _a[PollingInterval.Medium] = levels.Medium,
            _a[PollingInterval.High] = levels.High,
            _a;
    }
    var defaultChunkLevels = { Low: 32, Medium: 64, High: 256 };
    var pollingChunkSize = createPollingIntervalBasedLevels(defaultChunkLevels);
    /* @internal */
    ts.unchangedPollThresholds = createPollingIntervalBasedLevels(defaultChunkLevels);
    /* @internal */
    function setCustomPollingValues(system) {
        if (!system.getEnvironmentVariable) {
            return;
        }
        var pollingIntervalChanged = setCustomLevels("TSC_WATCH_POLLINGINTERVAL", PollingInterval);
        pollingChunkSize = getCustomPollingBasedLevels("TSC_WATCH_POLLINGCHUNKSIZE", defaultChunkLevels) || pollingChunkSize;
        ts.unchangedPollThresholds = getCustomPollingBasedLevels("TSC_WATCH_UNCHANGEDPOLLTHRESHOLDS", defaultChunkLevels) || ts.unchangedPollThresholds;
        function getLevel(envVar, level) {
            return system.getEnvironmentVariable(envVar + "_" + level.toUpperCase());
        }
        function getCustomLevels(baseVariable) {
            var customLevels;
            setCustomLevel("Low");
            setCustomLevel("Medium");
            setCustomLevel("High");
            return customLevels;
            function setCustomLevel(level) {
                var customLevel = getLevel(baseVariable, level);
                if (customLevel) {
                    (customLevels || (customLevels = {}))[level] = Number(customLevel);
                }
            }
        }
        function setCustomLevels(baseVariable, levels) {
            var customLevels = getCustomLevels(baseVariable);
            if (customLevels) {
                setLevel("Low");
                setLevel("Medium");
                setLevel("High");
                return true;
            }
            return false;
            function setLevel(level) {
                levels[level] = customLevels[level] || levels[level];
            }
        }
        function getCustomPollingBasedLevels(baseVariable, defaultLevels) {
            var customLevels = getCustomLevels(baseVariable);
            return (pollingIntervalChanged || customLevels) &&
                createPollingIntervalBasedLevels(customLevels ? __assign(__assign({}, defaultLevels), customLevels) : defaultLevels);
        }
    }
    ts.setCustomPollingValues = setCustomPollingValues;
    /* @internal */
    function createDynamicPriorityPollingWatchFile(host) {
        var watchedFiles = [];
        var changedFilesInLastPoll = [];
        var lowPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.Low);
        var mediumPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.Medium);
        var highPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.High);
        return watchFile;
        function watchFile(fileName, callback, defaultPollingInterval) {
            var file = {
                fileName: fileName,
                callback: callback,
                unchangedPolls: 0,
                mtime: getModifiedTime(fileName)
            };
            watchedFiles.push(file);
            addToPollingIntervalQueue(file, defaultPollingInterval);
            return {
                close: function () {
                    file.isClosed = true;
                    // Remove from watchedFiles
                    ts.unorderedRemoveItem(watchedFiles, file);
                    // Do not update polling interval queue since that will happen as part of polling
                }
            };
        }
        function createPollingIntervalQueue(pollingInterval) {
            var queue = [];
            queue.pollingInterval = pollingInterval;
            queue.pollIndex = 0;
            queue.pollScheduled = false;
            return queue;
        }
        function pollPollingIntervalQueue(queue) {
            queue.pollIndex = pollQueue(queue, queue.pollingInterval, queue.pollIndex, pollingChunkSize[queue.pollingInterval]);
            // Set the next polling index and timeout
            if (queue.length) {
                scheduleNextPoll(queue.pollingInterval);
            }
            else {
                ts.Debug.assert(queue.pollIndex === 0);
                queue.pollScheduled = false;
            }
        }
        function pollLowPollingIntervalQueue(queue) {
            // Always poll complete list of changedFilesInLastPoll
            pollQueue(changedFilesInLastPoll, PollingInterval.Low, /*pollIndex*/ 0, changedFilesInLastPoll.length);
            // Finally do the actual polling of the queue
            pollPollingIntervalQueue(queue);
            // Schedule poll if there are files in changedFilesInLastPoll but no files in the actual queue
            // as pollPollingIntervalQueue wont schedule for next poll
            if (!queue.pollScheduled && changedFilesInLastPoll.length) {
                scheduleNextPoll(PollingInterval.Low);
            }
        }
        function pollQueue(queue, pollingInterval, pollIndex, chunkSize) {
            // Max visit would be all elements of the queue
            var needsVisit = queue.length;
            var definedValueCopyToIndex = pollIndex;
            for (var polled = 0; polled < chunkSize && needsVisit > 0; nextPollIndex(), needsVisit--) {
                var watchedFile = queue[pollIndex];
                if (!watchedFile) {
                    continue;
                }
                else if (watchedFile.isClosed) {
                    queue[pollIndex] = undefined;
                    continue;
                }
                polled++;
                var fileChanged = onWatchedFileStat(watchedFile, getModifiedTime(watchedFile.fileName));
                if (watchedFile.isClosed) {
                    // Closed watcher as part of callback
                    queue[pollIndex] = undefined;
                }
                else if (fileChanged) {
                    watchedFile.unchangedPolls = 0;
                    // Changed files go to changedFilesInLastPoll queue
                    if (queue !== changedFilesInLastPoll) {
                        queue[pollIndex] = undefined;
                        addChangedFileToLowPollingIntervalQueue(watchedFile);
                    }
                }
                else if (watchedFile.unchangedPolls !== ts.unchangedPollThresholds[pollingInterval]) {
                    watchedFile.unchangedPolls++;
                }
                else if (queue === changedFilesInLastPoll) {
                    // Restart unchangedPollCount for unchanged file and move to low polling interval queue
                    watchedFile.unchangedPolls = 1;
                    queue[pollIndex] = undefined;
                    addToPollingIntervalQueue(watchedFile, PollingInterval.Low);
                }
                else if (pollingInterval !== PollingInterval.High) {
                    watchedFile.unchangedPolls++;
                    queue[pollIndex] = undefined;
                    addToPollingIntervalQueue(watchedFile, pollingInterval === PollingInterval.Low ? PollingInterval.Medium : PollingInterval.High);
                }
                if (queue[pollIndex]) {
                    // Copy this file to the non hole location
                    if (definedValueCopyToIndex < pollIndex) {
                        queue[definedValueCopyToIndex] = watchedFile;
                        queue[pollIndex] = undefined;
                    }
                    definedValueCopyToIndex++;
                }
            }
            // Return next poll index
            return pollIndex;
            function nextPollIndex() {
                pollIndex++;
                if (pollIndex === queue.length) {
                    if (definedValueCopyToIndex < pollIndex) {
                        // There are holes from nextDefinedValueIndex to end of queue, change queue size
                        queue.length = definedValueCopyToIndex;
                    }
                    pollIndex = 0;
                    definedValueCopyToIndex = 0;
                }
            }
        }
        function pollingIntervalQueue(pollingInterval) {
            switch (pollingInterval) {
                case PollingInterval.Low:
                    return lowPollingIntervalQueue;
                case PollingInterval.Medium:
                    return mediumPollingIntervalQueue;
                case PollingInterval.High:
                    return highPollingIntervalQueue;
            }
        }
        function addToPollingIntervalQueue(file, pollingInterval) {
            pollingIntervalQueue(pollingInterval).push(file);
            scheduleNextPollIfNotAlreadyScheduled(pollingInterval);
        }
        function addChangedFileToLowPollingIntervalQueue(file) {
            changedFilesInLastPoll.push(file);
            scheduleNextPollIfNotAlreadyScheduled(PollingInterval.Low);
        }
        function scheduleNextPollIfNotAlreadyScheduled(pollingInterval) {
            if (!pollingIntervalQueue(pollingInterval).pollScheduled) {
                scheduleNextPoll(pollingInterval);
            }
        }
        function scheduleNextPoll(pollingInterval) {
            pollingIntervalQueue(pollingInterval).pollScheduled = host.setTimeout(pollingInterval === PollingInterval.Low ? pollLowPollingIntervalQueue : pollPollingIntervalQueue, pollingInterval, pollingIntervalQueue(pollingInterval));
        }
        function getModifiedTime(fileName) {
            return host.getModifiedTime(fileName) || ts.missingFileModifiedTime;
        }
    }
    ts.createDynamicPriorityPollingWatchFile = createDynamicPriorityPollingWatchFile;
    function createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames) {
        // One file can have multiple watchers
        var fileWatcherCallbacks = ts.createMultiMap();
        var dirWatchers = ts.createMap();
        var toCanonicalName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        return nonPollingWatchFile;
        function nonPollingWatchFile(fileName, callback, _pollingInterval, fallbackOptions) {
            var filePath = toCanonicalName(fileName);
            fileWatcherCallbacks.add(filePath, callback);
            var dirPath = ts.getDirectoryPath(filePath) || ".";
            var watcher = dirWatchers.get(dirPath) ||
                createDirectoryWatcher(ts.getDirectoryPath(fileName) || ".", dirPath, fallbackOptions);
            watcher.referenceCount++;
            return {
                close: function () {
                    if (watcher.referenceCount === 1) {
                        watcher.close();
                        dirWatchers.delete(dirPath);
                    }
                    else {
                        watcher.referenceCount--;
                    }
                    fileWatcherCallbacks.remove(filePath, callback);
                }
            };
        }
        function createDirectoryWatcher(dirName, dirPath, fallbackOptions) {
            var watcher = fsWatch(dirName, 1 /* Directory */, function (_eventName, relativeFileName) {
                // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
                if (!ts.isString(relativeFileName)) {
                    return;
                }
                var fileName = ts.getNormalizedAbsolutePath(relativeFileName, dirName);
                // Some applications save a working file via rename operations
                var callbacks = fileName && fileWatcherCallbacks.get(toCanonicalName(fileName));
                if (callbacks) {
                    for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) {
                        var fileCallback = callbacks_1[_i];
                        fileCallback(fileName, FileWatcherEventKind.Changed);
                    }
                }
            }, 
            /*recursive*/ false, PollingInterval.Medium, fallbackOptions);
            watcher.referenceCount = 0;
            dirWatchers.set(dirPath, watcher);
            return watcher;
        }
    }
    /* @internal */
    function createSingleFileWatcherPerName(watchFile, useCaseSensitiveFileNames) {
        var cache = ts.createMap();
        var callbacksCache = ts.createMultiMap();
        var toCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        return function (fileName, callback, pollingInterval, options) {
            var path = toCanonicalFileName(fileName);
            var existing = cache.get(path);
            if (existing) {
                existing.refCount++;
            }
            else {
                cache.set(path, {
                    watcher: watchFile(fileName, function (fileName, eventKind) { return ts.forEach(callbacksCache.get(path), function (cb) { return cb(fileName, eventKind); }); }, pollingInterval, options),
                    refCount: 1
                });
            }
            callbacksCache.add(path, callback);
            return {
                close: function () {
                    var watcher = ts.Debug.checkDefined(cache.get(path));
                    callbacksCache.remove(path, callback);
                    watcher.refCount--;
                    if (watcher.refCount)
                        return;
                    cache.delete(path);
                    ts.closeFileWatcherOf(watcher);
                }
            };
        };
    }
    ts.createSingleFileWatcherPerName = createSingleFileWatcherPerName;
    /**
     * Returns true if file status changed
     */
    /*@internal*/
    function onWatchedFileStat(watchedFile, modifiedTime) {
        var oldTime = watchedFile.mtime.getTime();
        var newTime = modifiedTime.getTime();
        if (oldTime !== newTime) {
            watchedFile.mtime = modifiedTime;
            watchedFile.callback(watchedFile.fileName, getFileWatcherEventKind(oldTime, newTime));
            return true;
        }
        return false;
    }
    ts.onWatchedFileStat = onWatchedFileStat;
    /*@internal*/
    function getFileWatcherEventKind(oldTime, newTime) {
        return oldTime === 0
            ? FileWatcherEventKind.Created
            : newTime === 0
                ? FileWatcherEventKind.Deleted
                : FileWatcherEventKind.Changed;
    }
    ts.getFileWatcherEventKind = getFileWatcherEventKind;
    /*@internal*/
    ts.ignoredPaths = ["/node_modules/.", "/.git", "/.#"];
    /*@internal*/
    ts.sysLog = ts.noop; // eslint-disable-line prefer-const
    /*@internal*/
    function setSysLog(logger) {
        ts.sysLog = logger;
    }
    ts.setSysLog = setSysLog;
    /**
     * Watch the directory recursively using host provided method to watch child directories
     * that means if this is recursive watcher, watch the children directories as well
     * (eg on OS that dont support recursive watch using fs.watch use fs.watchFile)
     */
    /*@internal*/
    function createDirectoryWatcherSupportingRecursive(host) {
        var cache = ts.createMap();
        var callbackCache = ts.createMultiMap();
        var cacheToUpdateChildWatches = ts.createMap();
        var timerToUpdateChildWatches;
        var filePathComparer = ts.getStringComparer(!host.useCaseSensitiveFileNames);
        var toCanonicalFilePath = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        return function (dirName, callback, recursive, options) { return recursive ?
            createDirectoryWatcher(dirName, options, callback) :
            host.watchDirectory(dirName, callback, recursive, options); };
        /**
         * Create the directory watcher for the dirPath.
         */
        function createDirectoryWatcher(dirName, options, callback) {
            var dirPath = toCanonicalFilePath(dirName);
            var directoryWatcher = cache.get(dirPath);
            if (directoryWatcher) {
                directoryWatcher.refCount++;
            }
            else {
                directoryWatcher = {
                    watcher: host.watchDirectory(dirName, function (fileName) {
                        if (isIgnoredPath(fileName))
                            return;
                        if (options === null || options === void 0 ? void 0 : options.synchronousWatchDirectory) {
                            // Call the actual callback
                            invokeCallbacks(dirPath, fileName);
                            // Iterate through existing children and update the watches if needed
                            updateChildWatches(dirName, dirPath, options);
                        }
                        else {
                            nonSyncUpdateChildWatches(dirName, dirPath, fileName, options);
                        }
                    }, /*recursive*/ false, options),
                    refCount: 1,
                    childWatches: ts.emptyArray
                };
                cache.set(dirPath, directoryWatcher);
                updateChildWatches(dirName, dirPath, options);
            }
            var callbackToAdd = callback && { dirName: dirName, callback: callback };
            if (callbackToAdd) {
                callbackCache.add(dirPath, callbackToAdd);
            }
            return {
                dirName: dirName,
                close: function () {
                    var directoryWatcher = ts.Debug.checkDefined(cache.get(dirPath));
                    if (callbackToAdd)
                        callbackCache.remove(dirPath, callbackToAdd);
                    directoryWatcher.refCount--;
                    if (directoryWatcher.refCount)
                        return;
                    cache.delete(dirPath);
                    ts.closeFileWatcherOf(directoryWatcher);
                    directoryWatcher.childWatches.forEach(ts.closeFileWatcher);
                }
            };
        }
        function invokeCallbacks(dirPath, fileNameOrInvokeMap) {
            var fileName;
            var invokeMap;
            if (ts.isString(fileNameOrInvokeMap)) {
                fileName = fileNameOrInvokeMap;
            }
            else {
                invokeMap = fileNameOrInvokeMap;
            }
            // Call the actual callback
            callbackCache.forEach(function (callbacks, rootDirName) {
                if (invokeMap && invokeMap.has(rootDirName))
                    return;
                if (rootDirName === dirPath || (ts.startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === ts.directorySeparator)) {
                    if (invokeMap) {
                        invokeMap.set(rootDirName, true);
                    }
                    else {
                        callbacks.forEach(function (_a) {
                            var callback = _a.callback;
                            return callback(fileName);
                        });
                    }
                }
            });
        }
        function nonSyncUpdateChildWatches(dirName, dirPath, fileName, options) {
            // Iterate through existing children and update the watches if needed
            var parentWatcher = cache.get(dirPath);
            if (parentWatcher && host.directoryExists(dirName)) {
                // Schedule the update and postpone invoke for callbacks
                scheduleUpdateChildWatches(dirName, dirPath, options);
                return;
            }
            // Call the actual callbacks and remove child watches
            invokeCallbacks(dirPath, fileName);
            removeChildWatches(parentWatcher);
        }
        function scheduleUpdateChildWatches(dirName, dirPath, options) {
            if (!cacheToUpdateChildWatches.has(dirPath)) {
                cacheToUpdateChildWatches.set(dirPath, { dirName: dirName, options: options });
            }
            if (timerToUpdateChildWatches) {
                host.clearTimeout(timerToUpdateChildWatches);
                timerToUpdateChildWatches = undefined;
            }
            timerToUpdateChildWatches = host.setTimeout(onTimerToUpdateChildWatches, 1000);
        }
        function onTimerToUpdateChildWatches() {
            timerToUpdateChildWatches = undefined;
            ts.sysLog("sysLog:: onTimerToUpdateChildWatches:: " + cacheToUpdateChildWatches.size);
            var start = ts.timestamp();
            var invokeMap = ts.createMap();
            while (!timerToUpdateChildWatches && cacheToUpdateChildWatches.size) {
                var _a = cacheToUpdateChildWatches.entries().next(), _b = _a.value, dirPath = _b[0], _c = _b[1], dirName = _c.dirName, options = _c.options, done = _a.done;
                ts.Debug.assert(!done);
                cacheToUpdateChildWatches.delete(dirPath);
                // Because the child refresh is fresh, we would need to invalidate whole root directory being watched
                // to ensure that all the changes are reflected at this time
                invokeCallbacks(dirPath, invokeMap);
                updateChildWatches(dirName, dirPath, options);
            }
            ts.sysLog("sysLog:: invokingWatchers:: " + (ts.timestamp() - start) + "ms:: " + cacheToUpdateChildWatches.size);
            callbackCache.forEach(function (callbacks, rootDirName) {
                if (invokeMap.has(rootDirName)) {
                    callbacks.forEach(function (_a) {
                        var callback = _a.callback, dirName = _a.dirName;
                        return callback(dirName);
                    });
                }
            });
            var elapsed = ts.timestamp() - start;
            ts.sysLog("sysLog:: Elapsed " + elapsed + "ms:: onTimerToUpdateChildWatches:: " + cacheToUpdateChildWatches.size + " " + timerToUpdateChildWatches);
        }
        function removeChildWatches(parentWatcher) {
            if (!parentWatcher)
                return;
            var existingChildWatches = parentWatcher.childWatches;
            parentWatcher.childWatches = ts.emptyArray;
            for (var _i = 0, existingChildWatches_1 = existingChildWatches; _i < existingChildWatches_1.length; _i++) {
                var childWatcher = existingChildWatches_1[_i];
                childWatcher.close();
                removeChildWatches(cache.get(toCanonicalFilePath(childWatcher.dirName)));
            }
        }
        function updateChildWatches(dirName, dirPath, options) {
            // Iterate through existing children and update the watches if needed
            var parentWatcher = cache.get(dirPath);
            if (parentWatcher) {
                parentWatcher.childWatches = watchChildDirectories(dirName, parentWatcher.childWatches, options);
            }
        }
        /**
         * Watch the directories in the parentDir
         */
        function watchChildDirectories(parentDir, existingChildWatches, options) {
            var newChildWatches;
            ts.enumerateInsertsAndDeletes(host.directoryExists(parentDir) ? ts.mapDefined(host.getAccessibleSortedChildDirectories(parentDir), function (child) {
                var childFullName = ts.getNormalizedAbsolutePath(child, parentDir);
                // Filter our the symbolic link directories since those arent included in recursive watch
                // which is same behaviour when recursive: true is passed to fs.watch
                return !isIgnoredPath(childFullName) && filePathComparer(childFullName, ts.normalizePath(host.realpath(childFullName))) === 0 /* EqualTo */ ? childFullName : undefined;
            }) : ts.emptyArray, existingChildWatches, function (child, childWatcher) { return filePathComparer(child, childWatcher.dirName); }, createAndAddChildDirectoryWatcher, ts.closeFileWatcher, addChildDirectoryWatcher);
            return newChildWatches || ts.emptyArray;
            /**
             * Create new childDirectoryWatcher and add it to the new ChildDirectoryWatcher list
             */
            function createAndAddChildDirectoryWatcher(childName) {
                var result = createDirectoryWatcher(childName, options);
                addChildDirectoryWatcher(result);
            }
            /**
             * Add child directory watcher to the new ChildDirectoryWatcher list
             */
            function addChildDirectoryWatcher(childWatcher) {
                (newChildWatches || (newChildWatches = [])).push(childWatcher);
            }
        }
        function isIgnoredPath(path) {
            return ts.some(ts.ignoredPaths, function (searchPath) { return isInPath(path, searchPath); });
        }
        function isInPath(path, searchPath) {
            if (ts.stringContains(path, searchPath))
                return true;
            if (host.useCaseSensitiveFileNames)
                return false;
            return ts.stringContains(toCanonicalFilePath(path), searchPath);
        }
    }
    ts.createDirectoryWatcherSupportingRecursive = createDirectoryWatcherSupportingRecursive;
    /*@internal*/
    var FileSystemEntryKind;
    (function (FileSystemEntryKind) {
        FileSystemEntryKind[FileSystemEntryKind["File"] = 0] = "File";
        FileSystemEntryKind[FileSystemEntryKind["Directory"] = 1] = "Directory";
    })(FileSystemEntryKind = ts.FileSystemEntryKind || (ts.FileSystemEntryKind = {}));
    /*@internal*/
    function createFileWatcherCallback(callback) {
        return function (_fileName, eventKind) { return callback(eventKind === FileWatcherEventKind.Changed ? "change" : "rename", ""); };
    }
    ts.createFileWatcherCallback = createFileWatcherCallback;
    function createFsWatchCallbackForFileWatcherCallback(fileName, callback, fileExists) {
        return function (eventName) {
            if (eventName === "rename") {
                callback(fileName, fileExists(fileName) ? FileWatcherEventKind.Created : FileWatcherEventKind.Deleted);
            }
            else {
                // Change
                callback(fileName, FileWatcherEventKind.Changed);
            }
        };
    }
    function createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback) {
        return function (eventName, relativeFileName) {
            // In watchDirectory we only care about adding and removing files (when event name is
            // "rename"); changes made within files are handled by corresponding fileWatchers (when
            // event name is "change")
            if (eventName === "rename") {
                // When deleting a file, the passed baseFileName is null
                callback(!relativeFileName ? directoryName : ts.normalizePath(ts.combinePaths(directoryName, relativeFileName)));
            }
        };
    }
    /*@internal*/
    function createSystemWatchFunctions(_a) {
        var pollingWatchFile = _a.pollingWatchFile, getModifiedTime = _a.getModifiedTime, setTimeout = _a.setTimeout, clearTimeout = _a.clearTimeout, fsWatch = _a.fsWatch, fileExists = _a.fileExists, useCaseSensitiveFileNames = _a.useCaseSensitiveFileNames, fsSupportsRecursiveFsWatch = _a.fsSupportsRecursiveFsWatch, directoryExists = _a.directoryExists, getAccessibleSortedChildDirectories = _a.getAccessibleSortedChildDirectories, realpath = _a.realpath, tscWatchFile = _a.tscWatchFile, useNonPollingWatchers = _a.useNonPollingWatchers, tscWatchDirectory = _a.tscWatchDirectory;
        var dynamicPollingWatchFile;
        var nonPollingWatchFile;
        var hostRecursiveDirectoryWatcher;
        return {
            watchFile: watchFile,
            watchDirectory: watchDirectory
        };
        function watchFile(fileName, callback, pollingInterval, options) {
            options = updateOptionsForWatchFile(options, useNonPollingWatchers);
            var watchFileKind = ts.Debug.checkDefined(options.watchFile);
            switch (watchFileKind) {
                case ts.WatchFileKind.FixedPollingInterval:
                    return pollingWatchFile(fileName, callback, PollingInterval.Low, /*options*/ undefined);
                case ts.WatchFileKind.PriorityPollingInterval:
                    return pollingWatchFile(fileName, callback, pollingInterval, /*options*/ undefined);
                case ts.WatchFileKind.DynamicPriorityPolling:
                    return ensureDynamicPollingWatchFile()(fileName, callback, pollingInterval, /*options*/ undefined);
                case ts.WatchFileKind.UseFsEvents:
                    return fsWatch(fileName, 0 /* File */, createFsWatchCallbackForFileWatcherCallback(fileName, callback, fileExists), 
                    /*recursive*/ false, pollingInterval, ts.getFallbackOptions(options));
                case ts.WatchFileKind.UseFsEventsOnParentDirectory:
                    if (!nonPollingWatchFile) {
                        nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames);
                    }
                    return nonPollingWatchFile(fileName, callback, pollingInterval, ts.getFallbackOptions(options));
                default:
                    ts.Debug.assertNever(watchFileKind);
            }
        }
        function ensureDynamicPollingWatchFile() {
            return dynamicPollingWatchFile ||
                (dynamicPollingWatchFile = createDynamicPriorityPollingWatchFile({ getModifiedTime: getModifiedTime, setTimeout: setTimeout }));
        }
        function updateOptionsForWatchFile(options, useNonPollingWatchers) {
            if (options && options.watchFile !== undefined)
                return options;
            switch (tscWatchFile) {
                case "PriorityPollingInterval":
                    // Use polling interval based on priority when create watch using host.watchFile
                    return { watchFile: ts.WatchFileKind.PriorityPollingInterval };
                case "DynamicPriorityPolling":
                    // Use polling interval but change the interval depending on file changes and their default polling interval
                    return { watchFile: ts.WatchFileKind.DynamicPriorityPolling };
                case "UseFsEvents":
                    // Use notifications from FS to watch with falling back to fs.watchFile
                    return generateWatchFileOptions(ts.WatchFileKind.UseFsEvents, ts.PollingWatchKind.PriorityInterval, options);
                case "UseFsEventsWithFallbackDynamicPolling":
                    // Use notifications from FS to watch with falling back to dynamic watch file
                    return generateWatchFileOptions(ts.WatchFileKind.UseFsEvents, ts.PollingWatchKind.DynamicPriority, options);
                case "UseFsEventsOnParentDirectory":
                    useNonPollingWatchers = true;
                // fall through
                default:
                    return useNonPollingWatchers ?
                        // Use notifications from FS to watch with falling back to fs.watchFile
                        generateWatchFileOptions(ts.WatchFileKind.UseFsEventsOnParentDirectory, ts.PollingWatchKind.PriorityInterval, options) :
                        // Default to do not use fixed polling interval
                        { watchFile: ts.WatchFileKind.FixedPollingInterval };
            }
        }
        function generateWatchFileOptions(watchFile, fallbackPolling, options) {
            var defaultFallbackPolling = options === null || options === void 0 ? void 0 : options.fallbackPolling;
            return {
                watchFile: watchFile,
                fallbackPolling: defaultFallbackPolling === undefined ?
                    fallbackPolling :
                    defaultFallbackPolling
            };
        }
        function watchDirectory(directoryName, callback, recursive, options) {
            if (fsSupportsRecursiveFsWatch) {
                return fsWatch(directoryName, 1 /* Directory */, createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback), recursive, PollingInterval.Medium, ts.getFallbackOptions(options));
            }
            if (!hostRecursiveDirectoryWatcher) {
                hostRecursiveDirectoryWatcher = createDirectoryWatcherSupportingRecursive({
                    useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                    directoryExists: directoryExists,
                    getAccessibleSortedChildDirectories: getAccessibleSortedChildDirectories,
                    watchDirectory: nonRecursiveWatchDirectory,
                    realpath: realpath,
                    setTimeout: setTimeout,
                    clearTimeout: clearTimeout
                });
            }
            return hostRecursiveDirectoryWatcher(directoryName, callback, recursive, options);
        }
        function nonRecursiveWatchDirectory(directoryName, callback, recursive, options) {
            ts.Debug.assert(!recursive);
            options = updateOptionsForWatchDirectory(options);
            var watchDirectoryKind = ts.Debug.checkDefined(options.watchDirectory);
            switch (watchDirectoryKind) {
                case ts.WatchDirectoryKind.FixedPollingInterval:
                    return pollingWatchFile(directoryName, function () { return callback(directoryName); }, PollingInterval.Medium, 
                    /*options*/ undefined);
                case ts.WatchDirectoryKind.DynamicPriorityPolling:
                    return ensureDynamicPollingWatchFile()(directoryName, function () { return callback(directoryName); }, PollingInterval.Medium, 
                    /*options*/ undefined);
                case ts.WatchDirectoryKind.UseFsEvents:
                    return fsWatch(directoryName, 1 /* Directory */, createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback), recursive, PollingInterval.Medium, ts.getFallbackOptions(options));
                default:
                    ts.Debug.assertNever(watchDirectoryKind);
            }
        }
        function updateOptionsForWatchDirectory(options) {
            if (options && options.watchDirectory !== undefined)
                return options;
            switch (tscWatchDirectory) {
                case "RecursiveDirectoryUsingFsWatchFile":
                    // Use polling interval based on priority when create watch using host.watchFile
                    return { watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval };
                case "RecursiveDirectoryUsingDynamicPriorityPolling":
                    // Use polling interval but change the interval depending on file changes and their default polling interval
                    return { watchDirectory: ts.WatchDirectoryKind.DynamicPriorityPolling };
                default:
                    var defaultFallbackPolling = options === null || options === void 0 ? void 0 : options.fallbackPolling;
                    return {
                        watchDirectory: ts.WatchDirectoryKind.UseFsEvents,
                        fallbackPolling: defaultFallbackPolling !== undefined ?
                            defaultFallbackPolling :
                            undefined
                    };
            }
        }
    }
    ts.createSystemWatchFunctions = createSystemWatchFunctions;
    /**
     * patch writefile to create folder before writing the file
     */
    /*@internal*/
    function patchWriteFileEnsuringDirectory(sys) {
        // patch writefile to create folder before writing the file
        var originalWriteFile = sys.writeFile;
        sys.writeFile = function (path, data, writeBom) {
            return ts.writeFileEnsuringDirectories(path, data, !!writeBom, function (path, data, writeByteOrderMark) { return originalWriteFile.call(sys, path, data, writeByteOrderMark); }, function (path) { return sys.createDirectory(path); }, function (path) { return sys.directoryExists(path); });
        };
    }
    ts.patchWriteFileEnsuringDirectory = patchWriteFileEnsuringDirectory;
    function getNodeMajorVersion() {
        if (typeof process === "undefined") {
            return undefined;
        }
        var version = process.version;
        if (!version) {
            return undefined;
        }
        var dot = version.indexOf(".");
        if (dot === -1) {
            return undefined;
        }
        return parseInt(version.substring(1, dot));
    }
    ts.getNodeMajorVersion = getNodeMajorVersion;
    // TODO: GH#18217 this is used as if it's certainly defined in many places.
    // eslint-disable-next-line prefer-const
    ts.sys = (function () {
        // NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
        // byte order mark from the specified encoding. Using any other byte order mark does
        // not actually work.
        var byteOrderMarkIndicator = "\uFEFF";
        function getNodeSystem() {
            var nativePattern = /^native |^\([^)]+\)$|^(internal[\\/]|[a-zA-Z0-9_\s]+(\.js)?$)/;
            var _fs = require("fs");
            var _path = require("path");
            var _os = require("os");
            // crypto can be absent on reduced node installations
            var _crypto;
            try {
                _crypto = require("crypto");
            }
            catch (_a) {
                _crypto = undefined;
            }
            var activeSession;
            var profilePath = "./profile.cpuprofile";
            var Buffer = require("buffer").Buffer;
            var nodeVersion = getNodeMajorVersion();
            var isNode4OrLater = nodeVersion >= 4;
            var isLinuxOrMacOs = process.platform === "linux" || process.platform === "darwin";
            var platform = _os.platform();
            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
            var fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
            var _b = createSystemWatchFunctions({
                pollingWatchFile: createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames),
                getModifiedTime: getModifiedTime,
                setTimeout: setTimeout,
                clearTimeout: clearTimeout,
                fsWatch: fsWatch,
                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                fileExists: fileExists,
                // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
                // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
                fsSupportsRecursiveFsWatch: fsSupportsRecursiveFsWatch,
                directoryExists: directoryExists,
                getAccessibleSortedChildDirectories: function (path) { return getAccessibleFileSystemEntries(path).directories; },
                realpath: realpath,
                tscWatchFile: process.env.TSC_WATCHFILE,
                useNonPollingWatchers: process.env.TSC_NONPOLLING_WATCHER,
                tscWatchDirectory: process.env.TSC_WATCHDIRECTORY,
            }), watchFile = _b.watchFile, watchDirectory = _b.watchDirectory;
            var nodeSystem = {
                args: process.argv.slice(2),
                newLine: _os.EOL,
                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                write: function (s) {
                    process.stdout.write(s);
                },
                writeOutputIsTTY: function () {
                    return process.stdout.isTTY;
                },
                readFile: readFile,
                writeFile: writeFile,
                watchFile: watchFile,
                watchDirectory: watchDirectory,
                resolvePath: function (path) { return _path.resolve(path); },
                fileExists: fileExists,
                directoryExists: directoryExists,
                createDirectory: function (directoryName) {
                    if (!nodeSystem.directoryExists(directoryName)) {
                        // Wrapped in a try-catch to prevent crashing if we are in a race
                        // with another copy of ourselves to create the same directory
                        try {
                            _fs.mkdirSync(directoryName);
                        }
                        catch (e) {
                            if (e.code !== "EEXIST") {
                                // Failed for some other reason (access denied?); still throw
                                throw e;
                            }
                        }
                    }
                },
                getExecutingFilePath: function () {
                    return __filename;
                },
                getCurrentDirectory: function () {
                    return process.cwd();
                },
                getDirectories: getDirectories,
                getEnvironmentVariable: function (name) {
                    return process.env[name] || "";
                },
                readDirectory: readDirectory,
                getModifiedTime: getModifiedTime,
                setModifiedTime: setModifiedTime,
                deleteFile: deleteFile,
                createHash: _crypto ? createSHA256Hash : generateDjb2Hash,
                createSHA256Hash: _crypto ? createSHA256Hash : undefined,
                getMemoryUsage: function () {
                    if (global.gc) {
                        global.gc();
                    }
                    return process.memoryUsage().heapUsed;
                },
                getFileSize: function (path) {
                    try {
                        var stat = _fs.statSync(path);
                        if (stat.isFile()) {
                            return stat.size;
                        }
                    }
                    catch ( /*ignore*/_a) { /*ignore*/ }
                    return 0;
                },
                exit: function (exitCode) {
                    disableCPUProfiler(function () { return process.exit(exitCode); });
                },
                enableCPUProfiler: enableCPUProfiler,
                disableCPUProfiler: disableCPUProfiler,
                realpath: realpath,
                debugMode: !!process.env.NODE_INSPECTOR_IPC || ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
                tryEnableSourceMapsForHost: function () {
                    try {
                        require("source-map-support").install();
                    }
                    catch (_a) {
                        // Could not enable source maps.
                    }
                },
                setTimeout: setTimeout,
                clearTimeout: clearTimeout,
                clearScreen: function () {
                    process.stdout.write("\x1Bc");
                },
                setBlocking: function () {
                    if (process.stdout && process.stdout._handle && process.stdout._handle.setBlocking) {
                        process.stdout._handle.setBlocking(true);
                    }
                },
                bufferFrom: bufferFrom,
                base64decode: function (input) { return bufferFrom(input, "base64").toString("utf8"); },
                base64encode: function (input) { return bufferFrom(input).toString("base64"); },
                require: function (baseDir, moduleName) {
                    try {
                        var modulePath = ts.resolveJSModule(moduleName, baseDir, nodeSystem);
                        return { module: require(modulePath), modulePath: modulePath, error: undefined };
                    }
                    catch (error) {
                        return { module: undefined, modulePath: undefined, error: error };
                    }
                }
            };
            return nodeSystem;
            /**
             * Uses the builtin inspector APIs to capture a CPU profile
             * See https://nodejs.org/api/inspector.html#inspector_example_usage for details
             */
            function enableCPUProfiler(path, cb) {
                if (activeSession) {
                    cb();
                    return false;
                }
                var inspector = require("inspector");
                if (!inspector || !inspector.Session) {
                    cb();
                    return false;
                }
                var session = new inspector.Session();
                session.connect();
                session.post("Profiler.enable", function () {
                    session.post("Profiler.start", function () {
                        activeSession = session;
                        profilePath = path;
                        cb();
                    });
                });
                return true;
            }
            /**
             * Strips non-TS paths from the profile, so users with private projects shouldn't
             * need to worry about leaking paths by submitting a cpu profile to us
             */
            function cleanupPaths(profile) {
                var externalFileCounter = 0;
                var remappedPaths = ts.createMap();
                var normalizedDir = ts.normalizeSlashes(__dirname);
                // Windows rooted dir names need an extra `/` prepended to be valid file:/// urls
                var fileUrlRoot = "file://" + (ts.getRootLength(normalizedDir) === 1 ? "" : "/") + normalizedDir;
                for (var _i = 0, _a = profile.nodes; _i < _a.length; _i++) {
                    var node = _a[_i];
                    if (node.callFrame.url) {
                        var url = ts.normalizeSlashes(node.callFrame.url);
                        if (ts.containsPath(fileUrlRoot, url, useCaseSensitiveFileNames)) {
                            node.callFrame.url = ts.getRelativePathToDirectoryOrUrl(fileUrlRoot, url, fileUrlRoot, ts.createGetCanonicalFileName(useCaseSensitiveFileNames), /*isAbsolutePathAnUrl*/ true);
                        }
                        else if (!nativePattern.test(url)) {
                            node.callFrame.url = (remappedPaths.has(url) ? remappedPaths : remappedPaths.set(url, "external" + externalFileCounter + ".js")).get(url);
                            externalFileCounter++;
                        }
                    }
                }
                return profile;
            }
            function disableCPUProfiler(cb) {
                if (activeSession && activeSession !== "stopping") {
                    var s_1 = activeSession;
                    activeSession.post("Profiler.stop", function (err, _a) {
                        var profile = _a.profile;
                        if (!err) {
                            try {
                                if (_fs.statSync(profilePath).isDirectory()) {
                                    profilePath = _path.join(profilePath, (new Date()).toISOString().replace(/:/g, "-") + "+P" + process.pid + ".cpuprofile");
                                }
                            }
                            catch (_b) {
                                // do nothing and ignore fallible fs operation
                            }
                            try {
                                _fs.mkdirSync(_path.dirname(profilePath), { recursive: true });
                            }
                            catch (_c) {
                                // do nothing and ignore fallible fs operation
                            }
                            _fs.writeFileSync(profilePath, JSON.stringify(cleanupPaths(profile)));
                        }
                        activeSession = undefined;
                        s_1.disconnect();
                        cb();
                    });
                    activeSession = "stopping";
                    return true;
                }
                else {
                    cb();
                    return false;
                }
            }
            function bufferFrom(input, encoding) {
                // See https://github.com/Microsoft/TypeScript/issues/25652
                return Buffer.from && Buffer.from !== Int8Array.from
                    ? Buffer.from(input, encoding)
                    : new Buffer(input, encoding);
            }
            function isFileSystemCaseSensitive() {
                // win32\win64 are case insensitive platforms
                if (platform === "win32" || platform === "win64") {
                    return false;
                }
                // If this file exists under a different case, we must be case-insensitve.
                return !fileExists(swapCase(__filename));
            }
            /** Convert all lowercase chars to uppercase, and vice-versa */
            function swapCase(s) {
                return s.replace(/\w/g, function (ch) {
                    var up = ch.toUpperCase();
                    return ch === up ? ch.toLowerCase() : up;
                });
            }
            function fsWatchFileWorker(fileName, callback, pollingInterval) {
                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval }, fileChanged);
                var eventKind;
                return {
                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
                };
                function fileChanged(curr, prev) {
                    // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears)
                    // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation
                    var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted;
                    if (+curr.mtime === 0) {
                        if (isPreviouslyDeleted) {
                            // Already deleted file, no need to callback again
                            return;
                        }
                        eventKind = FileWatcherEventKind.Deleted;
                    }
                    else if (isPreviouslyDeleted) {
                        eventKind = FileWatcherEventKind.Created;
                    }
                    // If there is no change in modified time, ignore the event
                    else if (+curr.mtime === +prev.mtime) {
                        return;
                    }
                    else {
                        // File changed
                        eventKind = FileWatcherEventKind.Changed;
                    }
                    callback(fileName, eventKind);
                }
            }
            function fsWatch(fileOrDirectory, entryKind, callback, recursive, fallbackPollingInterval, fallbackOptions) {
                var options;
                var lastDirectoryPartWithDirectorySeparator;
                var lastDirectoryPart;
                if (isLinuxOrMacOs) {
                    lastDirectoryPartWithDirectorySeparator = fileOrDirectory.substr(fileOrDirectory.lastIndexOf(ts.directorySeparator));
                    lastDirectoryPart = lastDirectoryPartWithDirectorySeparator.slice(ts.directorySeparator.length);
                }
                /** Watcher for the file system entry depending on whether it is missing or present */
                var watcher = !fileSystemEntryExists(fileOrDirectory, entryKind) ?
                    watchMissingFileSystemEntry() :
                    watchPresentFileSystemEntry();
                return {
                    close: function () {
                        // Close the watcher (either existing file system entry watcher or missing file system entry watcher)
                        watcher.close();
                        watcher = undefined;
                    }
                };
                /**
                 * Invoke the callback with rename and update the watcher if not closed
                 * @param createWatcher
                 */
                function invokeCallbackAndUpdateWatcher(createWatcher) {
                    ts.sysLog("sysLog:: " + fileOrDirectory + ":: Changing watcher to " + (createWatcher === watchPresentFileSystemEntry ? "Present" : "Missing") + "FileSystemEntryWatcher");
                    // Call the callback for current directory
                    callback("rename", "");
                    // If watcher is not closed, update it
                    if (watcher) {
                        watcher.close();
                        watcher = createWatcher();
                    }
                }
                /**
                 * Watch the file or directory that is currently present
                 * and when the watched file or directory is deleted, switch to missing file system entry watcher
                 */
                function watchPresentFileSystemEntry() {
                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
                    if (options === undefined) {
                        if (fsSupportsRecursiveFsWatch) {
                            options = { persistent: true, recursive: !!recursive };
                        }
                        else {
                            options = { persistent: true };
                        }
                    }
                    try {
                        var presentWatcher = _fs.watch(fileOrDirectory, options, isLinuxOrMacOs ?
                            callbackChangingToMissingFileSystemEntry :
                            callback);
                        // Watch the missing file or directory or error
                        presentWatcher.on("error", function () { return invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry); });
                        return presentWatcher;
                    }
                    catch (e) {
                        // Catch the exception and use polling instead
                        // Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
                        // so instead of throwing error, use fs.watchFile
                        return watchPresentFileSystemEntryWithFsWatchFile();
                    }
                }
                function callbackChangingToMissingFileSystemEntry(event, relativeName) {
                    // because relativeName is not guaranteed to be correct we need to check on each rename with few combinations
                    // Eg on ubuntu while watching app/node_modules the relativeName is "node_modules" which is neither relative nor full path
                    return event === "rename" &&
                        (!relativeName ||
                            relativeName === lastDirectoryPart ||
                            relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) === relativeName.length - lastDirectoryPartWithDirectorySeparator.length) &&
                        !fileSystemEntryExists(fileOrDirectory, entryKind) ?
                        invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry) :
                        callback(event, relativeName);
                }
                /**
                 * Watch the file or directory using fs.watchFile since fs.watch threw exception
                 * Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
                 */
                function watchPresentFileSystemEntryWithFsWatchFile() {
                    ts.sysLog("sysLog:: " + fileOrDirectory + ":: Changing to fsWatchFile");
                    return watchFile(fileOrDirectory, createFileWatcherCallback(callback), fallbackPollingInterval, fallbackOptions);
                }
                /**
                 * Watch the file or directory that is missing
                 * and switch to existing file or directory when the missing filesystem entry is created
                 */
                function watchMissingFileSystemEntry() {
                    return watchFile(fileOrDirectory, function (_fileName, eventKind) {
                        if (eventKind === FileWatcherEventKind.Created && fileSystemEntryExists(fileOrDirectory, entryKind)) {
                            // Call the callback for current file or directory
                            // For now it could be callback for the inner directory creation,
                            // but just return current directory, better than current no-op
                            invokeCallbackAndUpdateWatcher(watchPresentFileSystemEntry);
                        }
                    }, fallbackPollingInterval, fallbackOptions);
                }
            }
            function readFileWorker(fileName, _encoding) {
                var buffer;
                try {
                    buffer = _fs.readFileSync(fileName);
                }
                catch (e) {
                    return undefined;
                }
                var len = buffer.length;
                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
                    // flip all byte pairs and treat as little endian.
                    len &= ~1; // Round down to a multiple of 2
                    for (var i = 0; i < len; i += 2) {
                        var temp = buffer[i];
                        buffer[i] = buffer[i + 1];
                        buffer[i + 1] = temp;
                    }
                    return buffer.toString("utf16le", 2);
                }
                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
                    // Little endian UTF-16 byte order mark detected
                    return buffer.toString("utf16le", 2);
                }
                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
                    // UTF-8 byte order mark detected
                    return buffer.toString("utf8", 3);
                }
                // Default is UTF-8 with no byte order mark
                return buffer.toString("utf8");
            }
            function readFile(fileName, _encoding) {
                ts.perfLogger.logStartReadFile(fileName);
                var file = readFileWorker(fileName, _encoding);
                ts.perfLogger.logStopReadFile();
                return file;
            }
            function writeFile(fileName, data, writeByteOrderMark) {
                ts.perfLogger.logEvent("WriteFile: " + fileName);
                // If a BOM is required, emit one
                if (writeByteOrderMark) {
                    data = byteOrderMarkIndicator + data;
                }
                var fd;
                try {
                    fd = _fs.openSync(fileName, "w");
                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
                }
                finally {
                    if (fd !== undefined) {
                        _fs.closeSync(fd);
                    }
                }
            }
            function getAccessibleFileSystemEntries(path) {
                ts.perfLogger.logEvent("ReadDir: " + (path || "."));
                try {
                    var entries = _fs.readdirSync(path || ".", { withFileTypes: true });
                    var files = [];
                    var directories = [];
                    for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) {
                        var dirent = entries_2[_i];
                        // withFileTypes is not supported before Node 10.10.
                        var entry = typeof dirent === "string" ? dirent : dirent.name;
                        // This is necessary because on some file system node fails to exclude
                        // "." and "..". See https://github.com/nodejs/node/issues/4002
                        if (entry === "." || entry === "..") {
                            continue;
                        }
                        var stat = void 0;
                        if (typeof dirent === "string" || dirent.isSymbolicLink()) {
                            var name = ts.combinePaths(path, entry);
                            try {
                                stat = _fs.statSync(name);
                            }
                            catch (e) {
                                continue;
                            }
                        }
                        else {
                            stat = dirent;
                        }
                        if (stat.isFile()) {
                            files.push(entry);
                        }
                        else if (stat.isDirectory()) {
                            directories.push(entry);
                        }
                    }
                    files.sort();
                    directories.sort();
                    return { files: files, directories: directories };
                }
                catch (e) {
                    return ts.emptyFileSystemEntries;
                }
            }
            function readDirectory(path, extensions, excludes, includes, depth) {
                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
            }
            function fileSystemEntryExists(path, entryKind) {
                try {
                    var stat = _fs.statSync(path);
                    switch (entryKind) {
                        case 0 /* File */: return stat.isFile();
                        case 1 /* Directory */: return stat.isDirectory();
                        default: return false;
                    }
                }
                catch (e) {
                    return false;
                }
            }
            function fileExists(path) {
                return fileSystemEntryExists(path, 0 /* File */);
            }
            function directoryExists(path) {
                return fileSystemEntryExists(path, 1 /* Directory */);
            }
            function getDirectories(path) {
                return getAccessibleFileSystemEntries(path).directories.slice();
            }
            function realpath(path) {
                try {
                    return _fs.realpathSync(path);
                }
                catch (_a) {
                    return path;
                }
            }
            function getModifiedTime(path) {
                try {
                    return _fs.statSync(path).mtime;
                }
                catch (e) {
                    return undefined;
                }
            }
            function setModifiedTime(path, time) {
                try {
                    _fs.utimesSync(path, time, time);
                }
                catch (e) {
                    return;
                }
            }
            function deleteFile(path) {
                try {
                    return _fs.unlinkSync(path);
                }
                catch (e) {
                    return;
                }
            }
            function createSHA256Hash(data) {
                var hash = _crypto.createHash("sha256");
                hash.update(data);
                return hash.digest("hex");
            }
        }
        var sys;
        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
            // process and process.nextTick checks if current environment is node-like
            // process.browser check excludes webpack and browserify
            sys = getNodeSystem();
        }
        if (sys) {
            // patch writefile to create folder before writing the file
            patchWriteFileEnsuringDirectory(sys);
        }
        return sys;
    })();
    if (ts.sys && ts.sys.getEnvironmentVariable) {
        setCustomPollingValues(ts.sys);
        ts.Debug.setAssertionLevel(/^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))
            ? 1 /* Normal */
            : 0 /* None */);
    }
    if (ts.sys && ts.sys.debugMode) {
        ts.Debug.isDebugging = true;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    /**
     * Internally, we represent paths as strings with '/' as the directory separator.
     * When we make system calls (eg: LanguageServiceHost.getDirectory()),
     * we expect the host to correctly handle paths in our specified format.
     */
    ts.directorySeparator = "/";
    var altDirectorySeparator = "\\";
    var urlSchemeSeparator = "://";
    var backslashRegExp = /\\/g;
    //// Path Tests
    /**
     * Determines whether a charCode corresponds to `/` or `\`.
     */
    function isAnyDirectorySeparator(charCode) {
        return charCode === 47 /* slash */ || charCode === 92 /* backslash */;
    }
    ts.isAnyDirectorySeparator = isAnyDirectorySeparator;
    /**
     * Determines whether a path starts with a URL scheme (e.g. starts with `http://`, `ftp://`, `file://`, etc.).
     */
    function isUrl(path) {
        return getEncodedRootLength(path) < 0;
    }
    ts.isUrl = isUrl;
    /**
     * Determines whether a path is an absolute disk path (e.g. starts with `/`, or a dos path
     * like `c:`, `c:\` or `c:/`).
     */
    function isRootedDiskPath(path) {
        return getEncodedRootLength(path) > 0;
    }
    ts.isRootedDiskPath = isRootedDiskPath;
    /**
     * Determines whether a path consists only of a path root.
     */
    function isDiskPathRoot(path) {
        var rootLength = getEncodedRootLength(path);
        return rootLength > 0 && rootLength === path.length;
    }
    ts.isDiskPathRoot = isDiskPathRoot;
    /**
     * Determines whether a path starts with an absolute path component (i.e. `/`, `c:/`, `file://`, etc.).
     *
     * ```ts
     * // POSIX
     * pathIsAbsolute("/path/to/file.ext") === true
     * // DOS
     * pathIsAbsolute("c:/path/to/file.ext") === true
     * // URL
     * pathIsAbsolute("file:///path/to/file.ext") === true
     * // Non-absolute
     * pathIsAbsolute("path/to/file.ext") === false
     * pathIsAbsolute("./path/to/file.ext") === false
     * ```
     */
    function pathIsAbsolute(path) {
        return getEncodedRootLength(path) !== 0;
    }
    ts.pathIsAbsolute = pathIsAbsolute;
    /**
     * Determines whether a path starts with a relative path component (i.e. `.` or `..`).
     */
    function pathIsRelative(path) {
        return /^\.\.?($|[\\/])/.test(path);
    }
    ts.pathIsRelative = pathIsRelative;
    function hasExtension(fileName) {
        return ts.stringContains(getBaseFileName(fileName), ".");
    }
    ts.hasExtension = hasExtension;
    function fileExtensionIs(path, extension) {
        return path.length > extension.length && ts.endsWith(path, extension);
    }
    ts.fileExtensionIs = fileExtensionIs;
    function fileExtensionIsOneOf(path, extensions) {
        for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
            var extension = extensions_1[_i];
            if (fileExtensionIs(path, extension)) {
                return true;
            }
        }
        return false;
    }
    ts.fileExtensionIsOneOf = fileExtensionIsOneOf;
    /**
     * Determines whether a path has a trailing separator (`/` or `\\`).
     */
    function hasTrailingDirectorySeparator(path) {
        return path.length > 0 && isAnyDirectorySeparator(path.charCodeAt(path.length - 1));
    }
    ts.hasTrailingDirectorySeparator = hasTrailingDirectorySeparator;
    //// Path Parsing
    function isVolumeCharacter(charCode) {
        return (charCode >= 97 /* a */ && charCode <= 122 /* z */) ||
            (charCode >= 65 /* A */ && charCode <= 90 /* Z */);
    }
    function getFileUrlVolumeSeparatorEnd(url, start) {
        var ch0 = url.charCodeAt(start);
        if (ch0 === 58 /* colon */)
            return start + 1;
        if (ch0 === 37 /* percent */ && url.charCodeAt(start + 1) === 51 /* _3 */) {
            var ch2 = url.charCodeAt(start + 2);
            if (ch2 === 97 /* a */ || ch2 === 65 /* A */)
                return start + 3;
        }
        return -1;
    }
    /**
     * Returns length of the root part of a path or URL (i.e. length of "/", "x:/", "//server/share/, file:///user/files").
     * If the root is part of a URL, the twos-complement of the root length is returned.
     */
    function getEncodedRootLength(path) {
        if (!path)
            return 0;
        var ch0 = path.charCodeAt(0);
        // POSIX or UNC
        if (ch0 === 47 /* slash */ || ch0 === 92 /* backslash */) {
            if (path.charCodeAt(1) !== ch0)
                return 1; // POSIX: "/" (or non-normalized "\")
            var p1 = path.indexOf(ch0 === 47 /* slash */ ? ts.directorySeparator : altDirectorySeparator, 2);
            if (p1 < 0)
                return path.length; // UNC: "//server" or "\\server"
            return p1 + 1; // UNC: "//server/" or "\\server\"
        }
        // DOS
        if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* colon */) {
            var ch2 = path.charCodeAt(2);
            if (ch2 === 47 /* slash */ || ch2 === 92 /* backslash */)
                return 3; // DOS: "c:/" or "c:\"
            if (path.length === 2)
                return 2; // DOS: "c:" (but not "c:d")
        }
        // URL
        var schemeEnd = path.indexOf(urlSchemeSeparator);
        if (schemeEnd !== -1) {
            var authorityStart = schemeEnd + urlSchemeSeparator.length;
            var authorityEnd = path.indexOf(ts.directorySeparator, authorityStart);
            if (authorityEnd !== -1) { // URL: "file:///", "file://server/", "file://server/path"
                // For local "file" URLs, include the leading DOS volume (if present).
                // Per https://www.ietf.org/rfc/rfc1738.txt, a host of "" or "localhost" is a
                // special case interpreted as "the machine from which the URL is being interpreted".
                var scheme = path.slice(0, schemeEnd);
                var authority = path.slice(authorityStart, authorityEnd);
                if (scheme === "file" && (authority === "" || authority === "localhost") &&
                    isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) {
                    var volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2);
                    if (volumeSeparatorEnd !== -1) {
                        if (path.charCodeAt(volumeSeparatorEnd) === 47 /* slash */) {
                            // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/"
                            return ~(volumeSeparatorEnd + 1);
                        }
                        if (volumeSeparatorEnd === path.length) {
                            // URL: "file:///c:", "file://localhost/c:", "file:///c$3a", "file://localhost/c%3a"
                            // but not "file:///c:d" or "file:///c%3ad"
                            return ~volumeSeparatorEnd;
                        }
                    }
                }
                return ~(authorityEnd + 1); // URL: "file://server/", "http://server/"
            }
            return ~path.length; // URL: "file://server", "http://server"
        }
        // relative
        return 0;
    }
    /**
     * Returns length of the root part of a path or URL (i.e. length of "/", "x:/", "//server/share/, file:///user/files").
     *
     * For example:
     * ```ts
     * getRootLength("a") === 0                   // ""
     * getRootLength("/") === 1                   // "/"
     * getRootLength("c:") === 2                  // "c:"
     * getRootLength("c:d") === 0                 // ""
     * getRootLength("c:/") === 3                 // "c:/"
     * getRootLength("c:\\") === 3                // "c:\\"
     * getRootLength("//server") === 7            // "//server"
     * getRootLength("//server/share") === 8      // "//server/"
     * getRootLength("\\\\server") === 7          // "\\\\server"
     * getRootLength("\\\\server\\share") === 8   // "\\\\server\\"
     * getRootLength("file:///path") === 8        // "file:///"
     * getRootLength("file:///c:") === 10         // "file:///c:"
     * getRootLength("file:///c:d") === 8         // "file:///"
     * getRootLength("file:///c:/path") === 11    // "file:///c:/"
     * getRootLength("file://server") === 13      // "file://server"
     * getRootLength("file://server/path") === 14 // "file://server/"
     * getRootLength("http://server") === 13      // "http://server"
     * getRootLength("http://server/path") === 14 // "http://server/"
     * ```
     */
    function getRootLength(path) {
        var rootLength = getEncodedRootLength(path);
        return rootLength < 0 ? ~rootLength : rootLength;
    }
    ts.getRootLength = getRootLength;
    function getDirectoryPath(path) {
        path = normalizeSlashes(path);
        // If the path provided is itself the root, then return it.
        var rootLength = getRootLength(path);
        if (rootLength === path.length)
            return path;
        // return the leading portion of the path up to the last (non-terminal) directory separator
        // but not including any trailing directory separator.
        path = removeTrailingDirectorySeparator(path);
        return path.slice(0, Math.max(rootLength, path.lastIndexOf(ts.directorySeparator)));
    }
    ts.getDirectoryPath = getDirectoryPath;
    function getBaseFileName(path, extensions, ignoreCase) {
        path = normalizeSlashes(path);
        // if the path provided is itself the root, then it has not file name.
        var rootLength = getRootLength(path);
        if (rootLength === path.length)
            return "";
        // return the trailing portion of the path starting after the last (non-terminal) directory
        // separator but not including any trailing directory separator.
        path = removeTrailingDirectorySeparator(path);
        var name = path.slice(Math.max(getRootLength(path), path.lastIndexOf(ts.directorySeparator) + 1));
        var extension = extensions !== undefined && ignoreCase !== undefined ? getAnyExtensionFromPath(name, extensions, ignoreCase) : undefined;
        return extension ? name.slice(0, name.length - extension.length) : name;
    }
    ts.getBaseFileName = getBaseFileName;
    function tryGetExtensionFromPath(path, extension, stringEqualityComparer) {
        if (!ts.startsWith(extension, "."))
            extension = "." + extension;
        if (path.length >= extension.length && path.charCodeAt(path.length - extension.length) === 46 /* dot */) {
            var pathExtension = path.slice(path.length - extension.length);
            if (stringEqualityComparer(pathExtension, extension)) {
                return pathExtension;
            }
        }
    }
    function getAnyExtensionFromPathWorker(path, extensions, stringEqualityComparer) {
        if (typeof extensions === "string") {
            return tryGetExtensionFromPath(path, extensions, stringEqualityComparer) || "";
        }
        for (var _i = 0, extensions_2 = extensions; _i < extensions_2.length; _i++) {
            var extension = extensions_2[_i];
            var result = tryGetExtensionFromPath(path, extension, stringEqualityComparer);
            if (result)
                return result;
        }
        return "";
    }
    function getAnyExtensionFromPath(path, extensions, ignoreCase) {
        // Retrieves any string from the final "." onwards from a base file name.
        // Unlike extensionFromPath, which throws an exception on unrecognized extensions.
        if (extensions) {
            return getAnyExtensionFromPathWorker(removeTrailingDirectorySeparator(path), extensions, ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive);
        }
        var baseFileName = getBaseFileName(path);
        var extensionIndex = baseFileName.lastIndexOf(".");
        if (extensionIndex >= 0) {
            return baseFileName.substring(extensionIndex);
        }
        return "";
    }
    ts.getAnyExtensionFromPath = getAnyExtensionFromPath;
    function pathComponents(path, rootLength) {
        var root = path.substring(0, rootLength);
        var rest = path.substring(rootLength).split(ts.directorySeparator);
        if (rest.length && !ts.lastOrUndefined(rest))
            rest.pop();
        return __spreadArrays([root], rest);
    }
    /**
     * Parse a path into an array containing a root component (at index 0) and zero or more path
     * components (at indices > 0). The result is not normalized.
     * If the path is relative, the root component is `""`.
     * If the path is absolute, the root component includes the first path separator (`/`).
     *
     * ```ts
     * // POSIX
     * getPathComponents("/path/to/file.ext") === ["/", "path", "to", "file.ext"]
     * getPathComponents("/path/to/") === ["/", "path", "to"]
     * getPathComponents("/") === ["/"]
     * // DOS
     * getPathComponents("c:/path/to/file.ext") === ["c:/", "path", "to", "file.ext"]
     * getPathComponents("c:/path/to/") === ["c:/", "path", "to"]
     * getPathComponents("c:/") === ["c:/"]
     * getPathComponents("c:") === ["c:"]
     * // URL
     * getPathComponents("http://typescriptlang.org/path/to/file.ext") === ["http://typescriptlang.org/", "path", "to", "file.ext"]
     * getPathComponents("http://typescriptlang.org/path/to/") === ["http://typescriptlang.org/", "path", "to"]
     * getPathComponents("http://typescriptlang.org/") === ["http://typescriptlang.org/"]
     * getPathComponents("http://typescriptlang.org") === ["http://typescriptlang.org"]
     * getPathComponents("file://server/path/to/file.ext") === ["file://server/", "path", "to", "file.ext"]
     * getPathComponents("file://server/path/to/") === ["file://server/", "path", "to"]
     * getPathComponents("file://server/") === ["file://server/"]
     * getPathComponents("file://server") === ["file://server"]
     * getPathComponents("file:///path/to/file.ext") === ["file:///", "path", "to", "file.ext"]
     * getPathComponents("file:///path/to/") === ["file:///", "path", "to"]
     * getPathComponents("file:///") === ["file:///"]
     * getPathComponents("file://") === ["file://"]
     */
    function getPathComponents(path, currentDirectory) {
        if (currentDirectory === void 0) { currentDirectory = ""; }
        path = combinePaths(currentDirectory, path);
        return pathComponents(path, getRootLength(path));
    }
    ts.getPathComponents = getPathComponents;
    //// Path Formatting
    /**
     * Formats a parsed path consisting of a root component (at index 0) and zero or more path
     * segments (at indices > 0).
     *
     * ```ts
     * getPathFromPathComponents(["/", "path", "to", "file.ext"]) === "/path/to/file.ext"
     * ```
     */
    function getPathFromPathComponents(pathComponents) {
        if (pathComponents.length === 0)
            return "";
        var root = pathComponents[0] && ensureTrailingDirectorySeparator(pathComponents[0]);
        return root + pathComponents.slice(1).join(ts.directorySeparator);
    }
    ts.getPathFromPathComponents = getPathFromPathComponents;
    //// Path Normalization
    /**
     * Normalize path separators, converting `\` into `/`.
     */
    function normalizeSlashes(path) {
        return path.replace(backslashRegExp, ts.directorySeparator);
    }
    ts.normalizeSlashes = normalizeSlashes;
    /**
     * Reduce an array of path components to a more simplified path by navigating any
     * `"."` or `".."` entries in the path.
     */
    function reducePathComponents(components) {
        if (!ts.some(components))
            return [];
        var reduced = [components[0]];
        for (var i = 1; i < components.length; i++) {
            var component = components[i];
            if (!component)
                continue;
            if (component === ".")
                continue;
            if (component === "..") {
                if (reduced.length > 1) {
                    if (reduced[reduced.length - 1] !== "..") {
                        reduced.pop();
                        continue;
                    }
                }
                else if (reduced[0])
                    continue;
            }
            reduced.push(component);
        }
        return reduced;
    }
    ts.reducePathComponents = reducePathComponents;
    /**
     * Combines paths. If a path is absolute, it replaces any previous path. Relative paths are not simplified.
     *
     * ```ts
     * // Non-rooted
     * combinePaths("path", "to", "file.ext") === "path/to/file.ext"
     * combinePaths("path", "dir", "..", "to", "file.ext") === "path/dir/../to/file.ext"
     * // POSIX
     * combinePaths("/path", "to", "file.ext") === "/path/to/file.ext"
     * combinePaths("/path", "/to", "file.ext") === "/to/file.ext"
     * // DOS
     * combinePaths("c:/path", "to", "file.ext") === "c:/path/to/file.ext"
     * combinePaths("c:/path", "c:/to", "file.ext") === "c:/to/file.ext"
     * // URL
     * combinePaths("file:///path", "to", "file.ext") === "file:///path/to/file.ext"
     * combinePaths("file:///path", "file:///to", "file.ext") === "file:///to/file.ext"
     * ```
     */
    function combinePaths(path) {
        var paths = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            paths[_i - 1] = arguments[_i];
        }
        if (path)
            path = normalizeSlashes(path);
        for (var _a = 0, paths_1 = paths; _a < paths_1.length; _a++) {
            var relativePath = paths_1[_a];
            if (!relativePath)
                continue;
            relativePath = normalizeSlashes(relativePath);
            if (!path || getRootLength(relativePath) !== 0) {
                path = relativePath;
            }
            else {
                path = ensureTrailingDirectorySeparator(path) + relativePath;
            }
        }
        return path;
    }
    ts.combinePaths = combinePaths;
    /**
     * Combines and resolves paths. If a path is absolute, it replaces any previous path. Any
     * `.` and `..` path components are resolved. Trailing directory separators are preserved.
     *
     * ```ts
     * resolvePath("/path", "to", "file.ext") === "path/to/file.ext"
     * resolvePath("/path", "to", "file.ext/") === "path/to/file.ext/"
     * resolvePath("/path", "dir", "..", "to", "file.ext") === "path/to/file.ext"
     * ```
     */
    function resolvePath(path) {
        var paths = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            paths[_i - 1] = arguments[_i];
        }
        return normalizePath(ts.some(paths) ? combinePaths.apply(void 0, __spreadArrays([path], paths)) : normalizeSlashes(path));
    }
    ts.resolvePath = resolvePath;
    /**
     * Parse a path into an array containing a root component (at index 0) and zero or more path
     * components (at indices > 0). The result is normalized.
     * If the path is relative, the root component is `""`.
     * If the path is absolute, the root component includes the first path separator (`/`).
     *
     * ```ts
     * getNormalizedPathComponents("to/dir/../file.ext", "/path/") === ["/", "path", "to", "file.ext"]
     * ```
     */
    function getNormalizedPathComponents(path, currentDirectory) {
        return reducePathComponents(getPathComponents(path, currentDirectory));
    }
    ts.getNormalizedPathComponents = getNormalizedPathComponents;
    function getNormalizedAbsolutePath(fileName, currentDirectory) {
        return getPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
    }
    ts.getNormalizedAbsolutePath = getNormalizedAbsolutePath;
    function normalizePath(path) {
        path = normalizeSlashes(path);
        var normalized = getPathFromPathComponents(reducePathComponents(getPathComponents(path)));
        return normalized && hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalized) : normalized;
    }
    ts.normalizePath = normalizePath;
    function getPathWithoutRoot(pathComponents) {
        if (pathComponents.length === 0)
            return "";
        return pathComponents.slice(1).join(ts.directorySeparator);
    }
    function getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory) {
        return getPathWithoutRoot(getNormalizedPathComponents(fileName, currentDirectory));
    }
    ts.getNormalizedAbsolutePathWithoutRoot = getNormalizedAbsolutePathWithoutRoot;
    function toPath(fileName, basePath, getCanonicalFileName) {
        var nonCanonicalizedPath = isRootedDiskPath(fileName)
            ? normalizePath(fileName)
            : getNormalizedAbsolutePath(fileName, basePath);
        return getCanonicalFileName(nonCanonicalizedPath);
    }
    ts.toPath = toPath;
    function normalizePathAndParts(path) {
        path = normalizeSlashes(path);
        var _a = reducePathComponents(getPathComponents(path)), root = _a[0], parts = _a.slice(1);
        if (parts.length) {
            var joinedParts = root + parts.join(ts.directorySeparator);
            return { path: hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(joinedParts) : joinedParts, parts: parts };
        }
        else {
            return { path: root, parts: parts };
        }
    }
    ts.normalizePathAndParts = normalizePathAndParts;
    function removeTrailingDirectorySeparator(path) {
        if (hasTrailingDirectorySeparator(path)) {
            return path.substr(0, path.length - 1);
        }
        return path;
    }
    ts.removeTrailingDirectorySeparator = removeTrailingDirectorySeparator;
    function ensureTrailingDirectorySeparator(path) {
        if (!hasTrailingDirectorySeparator(path)) {
            return path + ts.directorySeparator;
        }
        return path;
    }
    ts.ensureTrailingDirectorySeparator = ensureTrailingDirectorySeparator;
    /**
     * Ensures a path is either absolute (prefixed with `/` or `c:`) or dot-relative (prefixed
     * with `./` or `../`) so as not to be confused with an unprefixed module name.
     *
     * ```ts
     * ensurePathIsNonModuleName("/path/to/file.ext") === "/path/to/file.ext"
     * ensurePathIsNonModuleName("./path/to/file.ext") === "./path/to/file.ext"
     * ensurePathIsNonModuleName("../path/to/file.ext") === "../path/to/file.ext"
     * ensurePathIsNonModuleName("path/to/file.ext") === "./path/to/file.ext"
     * ```
     */
    function ensurePathIsNonModuleName(path) {
        return !pathIsAbsolute(path) && !pathIsRelative(path) ? "./" + path : path;
    }
    ts.ensurePathIsNonModuleName = ensurePathIsNonModuleName;
    function changeAnyExtension(path, ext, extensions, ignoreCase) {
        var pathext = extensions !== undefined && ignoreCase !== undefined ? getAnyExtensionFromPath(path, extensions, ignoreCase) : getAnyExtensionFromPath(path);
        return pathext ? path.slice(0, path.length - pathext.length) + (ts.startsWith(ext, ".") ? ext : "." + ext) : path;
    }
    ts.changeAnyExtension = changeAnyExtension;
    //// Path Comparisons
    // check path for these segments: '', '.'. '..'
    var relativePathSegmentRegExp = /(^|\/)\.{0,2}($|\/)/;
    function comparePathsWorker(a, b, componentComparer) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        // NOTE: Performance optimization - shortcut if the root segments differ as there would be no
        //       need to perform path reduction.
        var aRoot = a.substring(0, getRootLength(a));
        var bRoot = b.substring(0, getRootLength(b));
        var result = ts.compareStringsCaseInsensitive(aRoot, bRoot);
        if (result !== 0 /* EqualTo */) {
            return result;
        }
        // NOTE: Performance optimization - shortcut if there are no relative path segments in
        //       the non-root portion of the path
        var aRest = a.substring(aRoot.length);
        var bRest = b.substring(bRoot.length);
        if (!relativePathSegmentRegExp.test(aRest) && !relativePathSegmentRegExp.test(bRest)) {
            return componentComparer(aRest, bRest);
        }
        // The path contains a relative path segment. Normalize the paths and perform a slower component
        // by component comparison.
        var aComponents = reducePathComponents(getPathComponents(a));
        var bComponents = reducePathComponents(getPathComponents(b));
        var sharedLength = Math.min(aComponents.length, bComponents.length);
        for (var i = 1; i < sharedLength; i++) {
            var result_1 = componentComparer(aComponents[i], bComponents[i]);
            if (result_1 !== 0 /* EqualTo */) {
                return result_1;
            }
        }
        return ts.compareValues(aComponents.length, bComponents.length);
    }
    /**
     * Performs a case-sensitive comparison of two paths. Path roots are always compared case-insensitively.
     */
    function comparePathsCaseSensitive(a, b) {
        return comparePathsWorker(a, b, ts.compareStringsCaseSensitive);
    }
    ts.comparePathsCaseSensitive = comparePathsCaseSensitive;
    /**
     * Performs a case-insensitive comparison of two paths.
     */
    function comparePathsCaseInsensitive(a, b) {
        return comparePathsWorker(a, b, ts.compareStringsCaseInsensitive);
    }
    ts.comparePathsCaseInsensitive = comparePathsCaseInsensitive;
    function comparePaths(a, b, currentDirectory, ignoreCase) {
        if (typeof currentDirectory === "string") {
            a = combinePaths(currentDirectory, a);
            b = combinePaths(currentDirectory, b);
        }
        else if (typeof currentDirectory === "boolean") {
            ignoreCase = currentDirectory;
        }
        return comparePathsWorker(a, b, ts.getStringComparer(ignoreCase));
    }
    ts.comparePaths = comparePaths;
    function containsPath(parent, child, currentDirectory, ignoreCase) {
        if (typeof currentDirectory === "string") {
            parent = combinePaths(currentDirectory, parent);
            child = combinePaths(currentDirectory, child);
        }
        else if (typeof currentDirectory === "boolean") {
            ignoreCase = currentDirectory;
        }
        if (parent === undefined || child === undefined)
            return false;
        if (parent === child)
            return true;
        var parentComponents = reducePathComponents(getPathComponents(parent));
        var childComponents = reducePathComponents(getPathComponents(child));
        if (childComponents.length < parentComponents.length) {
            return false;
        }
        var componentEqualityComparer = ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive;
        for (var i = 0; i < parentComponents.length; i++) {
            var equalityComparer = i === 0 ? ts.equateStringsCaseInsensitive : componentEqualityComparer;
            if (!equalityComparer(parentComponents[i], childComponents[i])) {
                return false;
            }
        }
        return true;
    }
    ts.containsPath = containsPath;
    /**
     * Determines whether `fileName` starts with the specified `directoryName` using the provided path canonicalization callback.
     * Comparison is case-sensitive between the canonical paths.
     *
     * @deprecated Use `containsPath` if possible.
     */
    function startsWithDirectory(fileName, directoryName, getCanonicalFileName) {
        var canonicalFileName = getCanonicalFileName(fileName);
        var canonicalDirectoryName = getCanonicalFileName(directoryName);
        return ts.startsWith(canonicalFileName, canonicalDirectoryName + "/") || ts.startsWith(canonicalFileName, canonicalDirectoryName + "\\");
    }
    ts.startsWithDirectory = startsWithDirectory;
    //// Relative Paths
    function getPathComponentsRelativeTo(from, to, stringEqualityComparer, getCanonicalFileName) {
        var fromComponents = reducePathComponents(getPathComponents(from));
        var toComponents = reducePathComponents(getPathComponents(to));
        var start;
        for (start = 0; start < fromComponents.length && start < toComponents.length; start++) {
            var fromComponent = getCanonicalFileName(fromComponents[start]);
            var toComponent = getCanonicalFileName(toComponents[start]);
            var comparer = start === 0 ? ts.equateStringsCaseInsensitive : stringEqualityComparer;
            if (!comparer(fromComponent, toComponent))
                break;
        }
        if (start === 0) {
            return toComponents;
        }
        var components = toComponents.slice(start);
        var relative = [];
        for (; start < fromComponents.length; start++) {
            relative.push("..");
        }
        return __spreadArrays([""], relative, components);
    }
    ts.getPathComponentsRelativeTo = getPathComponentsRelativeTo;
    function getRelativePathFromDirectory(fromDirectory, to, getCanonicalFileNameOrIgnoreCase) {
        ts.Debug.assert((getRootLength(fromDirectory) > 0) === (getRootLength(to) > 0), "Paths must either both be absolute or both be relative");
        var getCanonicalFileName = typeof getCanonicalFileNameOrIgnoreCase === "function" ? getCanonicalFileNameOrIgnoreCase : ts.identity;
        var ignoreCase = typeof getCanonicalFileNameOrIgnoreCase === "boolean" ? getCanonicalFileNameOrIgnoreCase : false;
        var pathComponents = getPathComponentsRelativeTo(fromDirectory, to, ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive, getCanonicalFileName);
        return getPathFromPathComponents(pathComponents);
    }
    ts.getRelativePathFromDirectory = getRelativePathFromDirectory;
    function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) {
        return !isRootedDiskPath(absoluteOrRelativePath)
            ? absoluteOrRelativePath
            : getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
    }
    ts.convertToRelativePath = convertToRelativePath;
    function getRelativePathFromFile(from, to, getCanonicalFileName) {
        return ensurePathIsNonModuleName(getRelativePathFromDirectory(getDirectoryPath(from), to, getCanonicalFileName));
    }
    ts.getRelativePathFromFile = getRelativePathFromFile;
    function getRelativePathToDirectoryOrUrl(directoryPathOrUrl, relativeOrAbsolutePath, currentDirectory, getCanonicalFileName, isAbsolutePathAnUrl) {
        var pathComponents = getPathComponentsRelativeTo(resolvePath(currentDirectory, directoryPathOrUrl), resolvePath(currentDirectory, relativeOrAbsolutePath), ts.equateStringsCaseSensitive, getCanonicalFileName);
        var firstComponent = pathComponents[0];
        if (isAbsolutePathAnUrl && isRootedDiskPath(firstComponent)) {
            var prefix = firstComponent.charAt(0) === ts.directorySeparator ? "file://" : "file:///";
            pathComponents[0] = prefix + firstComponent;
        }
        return getPathFromPathComponents(pathComponents);
    }
    ts.getRelativePathToDirectoryOrUrl = getRelativePathToDirectoryOrUrl;
    function forEachAncestorDirectory(directory, callback) {
        while (true) {
            var result = callback(directory);
            if (result !== undefined) {
                return result;
            }
            var parentPath = getDirectoryPath(directory);
            if (parentPath === directory) {
                return undefined;
            }
            directory = parentPath;
        }
    }
    ts.forEachAncestorDirectory = forEachAncestorDirectory;
    function isNodeModulesDirectory(dirPath) {
        return ts.endsWith(dirPath, "/node_modules");
    }
    ts.isNodeModulesDirectory = isNodeModulesDirectory;
})(ts || (ts = {}));
// <auto-generated />
// generated from './diagnosticInformationMap.generated.ts' by 'src/compiler'
/* @internal */
var ts;
(function (ts) {
    function diag(code, category, key, message, reportsUnnecessary, elidedInCompatabilityPyramid) {
        return { code: code, category: category, key: key, message: message, reportsUnnecessary: reportsUnnecessary, elidedInCompatabilityPyramid: elidedInCompatabilityPyramid };
    }
    ts.Diagnostics = {
        Unterminated_string_literal: diag(1002, ts.DiagnosticCategory.Error, "Unterminated_string_literal_1002", "Unterminated string literal."),
        Identifier_expected: diag(1003, ts.DiagnosticCategory.Error, "Identifier_expected_1003", "Identifier expected."),
        _0_expected: diag(1005, ts.DiagnosticCategory.Error, "_0_expected_1005", "'{0}' expected."),
        A_file_cannot_have_a_reference_to_itself: diag(1006, ts.DiagnosticCategory.Error, "A_file_cannot_have_a_reference_to_itself_1006", "A file cannot have a reference to itself."),
        The_parser_expected_to_find_a_to_match_the_token_here: diag(1007, ts.DiagnosticCategory.Error, "The_parser_expected_to_find_a_to_match_the_token_here_1007", "The parser expected to find a '}' to match the '{' token here."),
        Trailing_comma_not_allowed: diag(1009, ts.DiagnosticCategory.Error, "Trailing_comma_not_allowed_1009", "Trailing comma not allowed."),
        Asterisk_Slash_expected: diag(1010, ts.DiagnosticCategory.Error, "Asterisk_Slash_expected_1010", "'*/' expected."),
        An_element_access_expression_should_take_an_argument: diag(1011, ts.DiagnosticCategory.Error, "An_element_access_expression_should_take_an_argument_1011", "An element access expression should take an argument."),
        Unexpected_token: diag(1012, ts.DiagnosticCategory.Error, "Unexpected_token_1012", "Unexpected token."),
        A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma: diag(1013, ts.DiagnosticCategory.Error, "A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013", "A rest parameter or binding pattern may not have a trailing comma."),
        A_rest_parameter_must_be_last_in_a_parameter_list: diag(1014, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_last_in_a_parameter_list_1014", "A rest parameter must be last in a parameter list."),
        Parameter_cannot_have_question_mark_and_initializer: diag(1015, ts.DiagnosticCategory.Error, "Parameter_cannot_have_question_mark_and_initializer_1015", "Parameter cannot have question mark and initializer."),
        A_required_parameter_cannot_follow_an_optional_parameter: diag(1016, ts.DiagnosticCategory.Error, "A_required_parameter_cannot_follow_an_optional_parameter_1016", "A required parameter cannot follow an optional parameter."),
        An_index_signature_cannot_have_a_rest_parameter: diag(1017, ts.DiagnosticCategory.Error, "An_index_signature_cannot_have_a_rest_parameter_1017", "An index signature cannot have a rest parameter."),
        An_index_signature_parameter_cannot_have_an_accessibility_modifier: diag(1018, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018", "An index signature parameter cannot have an accessibility modifier."),
        An_index_signature_parameter_cannot_have_a_question_mark: diag(1019, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_a_question_mark_1019", "An index signature parameter cannot have a question mark."),
        An_index_signature_parameter_cannot_have_an_initializer: diag(1020, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_initializer_1020", "An index signature parameter cannot have an initializer."),
        An_index_signature_must_have_a_type_annotation: diag(1021, ts.DiagnosticCategory.Error, "An_index_signature_must_have_a_type_annotation_1021", "An index signature must have a type annotation."),
        An_index_signature_parameter_must_have_a_type_annotation: diag(1022, ts.DiagnosticCategory.Error, "An_index_signature_parameter_must_have_a_type_annotation_1022", "An index signature parameter must have a type annotation."),
        An_index_signature_parameter_type_must_be_either_string_or_number: diag(1023, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_must_be_either_string_or_number_1023", "An index signature parameter type must be either 'string' or 'number'."),
        readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature: diag(1024, ts.DiagnosticCategory.Error, "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024", "'readonly' modifier can only appear on a property declaration or index signature."),
        An_index_signature_cannot_have_a_trailing_comma: diag(1025, ts.DiagnosticCategory.Error, "An_index_signature_cannot_have_a_trailing_comma_1025", "An index signature cannot have a trailing comma."),
        Accessibility_modifier_already_seen: diag(1028, ts.DiagnosticCategory.Error, "Accessibility_modifier_already_seen_1028", "Accessibility modifier already seen."),
        _0_modifier_must_precede_1_modifier: diag(1029, ts.DiagnosticCategory.Error, "_0_modifier_must_precede_1_modifier_1029", "'{0}' modifier must precede '{1}' modifier."),
        _0_modifier_already_seen: diag(1030, ts.DiagnosticCategory.Error, "_0_modifier_already_seen_1030", "'{0}' modifier already seen."),
        _0_modifier_cannot_appear_on_a_class_element: diag(1031, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_class_element_1031", "'{0}' modifier cannot appear on a class element."),
        super_must_be_followed_by_an_argument_list_or_member_access: diag(1034, ts.DiagnosticCategory.Error, "super_must_be_followed_by_an_argument_list_or_member_access_1034", "'super' must be followed by an argument list or member access."),
        Only_ambient_modules_can_use_quoted_names: diag(1035, ts.DiagnosticCategory.Error, "Only_ambient_modules_can_use_quoted_names_1035", "Only ambient modules can use quoted names."),
        Statements_are_not_allowed_in_ambient_contexts: diag(1036, ts.DiagnosticCategory.Error, "Statements_are_not_allowed_in_ambient_contexts_1036", "Statements are not allowed in ambient contexts."),
        A_declare_modifier_cannot_be_used_in_an_already_ambient_context: diag(1038, ts.DiagnosticCategory.Error, "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038", "A 'declare' modifier cannot be used in an already ambient context."),
        Initializers_are_not_allowed_in_ambient_contexts: diag(1039, ts.DiagnosticCategory.Error, "Initializers_are_not_allowed_in_ambient_contexts_1039", "Initializers are not allowed in ambient contexts."),
        _0_modifier_cannot_be_used_in_an_ambient_context: diag(1040, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_in_an_ambient_context_1040", "'{0}' modifier cannot be used in an ambient context."),
        _0_modifier_cannot_be_used_with_a_class_declaration: diag(1041, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_a_class_declaration_1041", "'{0}' modifier cannot be used with a class declaration."),
        _0_modifier_cannot_be_used_here: diag(1042, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_here_1042", "'{0}' modifier cannot be used here."),
        _0_modifier_cannot_appear_on_a_data_property: diag(1043, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_data_property_1043", "'{0}' modifier cannot appear on a data property."),
        _0_modifier_cannot_appear_on_a_module_or_namespace_element: diag(1044, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044", "'{0}' modifier cannot appear on a module or namespace element."),
        A_0_modifier_cannot_be_used_with_an_interface_declaration: diag(1045, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_interface_declaration_1045", "A '{0}' modifier cannot be used with an interface declaration."),
        Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier: diag(1046, ts.DiagnosticCategory.Error, "Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier_1046", "Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier."),
        A_rest_parameter_cannot_be_optional: diag(1047, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_be_optional_1047", "A rest parameter cannot be optional."),
        A_rest_parameter_cannot_have_an_initializer: diag(1048, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_have_an_initializer_1048", "A rest parameter cannot have an initializer."),
        A_set_accessor_must_have_exactly_one_parameter: diag(1049, ts.DiagnosticCategory.Error, "A_set_accessor_must_have_exactly_one_parameter_1049", "A 'set' accessor must have exactly one parameter."),
        A_set_accessor_cannot_have_an_optional_parameter: diag(1051, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_an_optional_parameter_1051", "A 'set' accessor cannot have an optional parameter."),
        A_set_accessor_parameter_cannot_have_an_initializer: diag(1052, ts.DiagnosticCategory.Error, "A_set_accessor_parameter_cannot_have_an_initializer_1052", "A 'set' accessor parameter cannot have an initializer."),
        A_set_accessor_cannot_have_rest_parameter: diag(1053, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_rest_parameter_1053", "A 'set' accessor cannot have rest parameter."),
        A_get_accessor_cannot_have_parameters: diag(1054, ts.DiagnosticCategory.Error, "A_get_accessor_cannot_have_parameters_1054", "A 'get' accessor cannot have parameters."),
        Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value: diag(1055, ts.DiagnosticCategory.Error, "Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Prom_1055", "Type '{0}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value."),
        Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: diag(1056, ts.DiagnosticCategory.Error, "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056", "Accessors are only available when targeting ECMAScript 5 and higher."),
        An_async_function_or_method_must_have_a_valid_awaitable_return_type: diag(1057, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_have_a_valid_awaitable_return_type_1057", "An async function or method must have a valid awaitable return type."),
        The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1058, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_t_1058", "The return type of an async function must either be a valid promise or must not contain a callable 'then' member."),
        A_promise_must_have_a_then_method: diag(1059, ts.DiagnosticCategory.Error, "A_promise_must_have_a_then_method_1059", "A promise must have a 'then' method."),
        The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback: diag(1060, ts.DiagnosticCategory.Error, "The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback_1060", "The first parameter of the 'then' method of a promise must be a callback."),
        Enum_member_must_have_initializer: diag(1061, ts.DiagnosticCategory.Error, "Enum_member_must_have_initializer_1061", "Enum member must have initializer."),
        Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method: diag(1062, ts.DiagnosticCategory.Error, "Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062", "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method."),
        An_export_assignment_cannot_be_used_in_a_namespace: diag(1063, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_namespace_1063", "An export assignment cannot be used in a namespace."),
        The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type: diag(1064, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1064", "The return type of an async function or method must be the global Promise<T> type."),
        In_ambient_enum_declarations_member_initializer_must_be_constant_expression: diag(1066, ts.DiagnosticCategory.Error, "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066", "In ambient enum declarations member initializer must be constant expression."),
        Unexpected_token_A_constructor_method_accessor_or_property_was_expected: diag(1068, ts.DiagnosticCategory.Error, "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068", "Unexpected token. A constructor, method, accessor, or property was expected."),
        Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces: diag(1069, ts.DiagnosticCategory.Error, "Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces_1069", "Unexpected token. A type parameter name was expected without curly braces."),
        _0_modifier_cannot_appear_on_a_type_member: diag(1070, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_type_member_1070", "'{0}' modifier cannot appear on a type member."),
        _0_modifier_cannot_appear_on_an_index_signature: diag(1071, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_an_index_signature_1071", "'{0}' modifier cannot appear on an index signature."),
        A_0_modifier_cannot_be_used_with_an_import_declaration: diag(1079, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_import_declaration_1079", "A '{0}' modifier cannot be used with an import declaration."),
        Invalid_reference_directive_syntax: diag(1084, ts.DiagnosticCategory.Error, "Invalid_reference_directive_syntax_1084", "Invalid 'reference' directive syntax."),
        Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0: diag(1085, ts.DiagnosticCategory.Error, "Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0_1085", "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'."),
        _0_modifier_cannot_appear_on_a_constructor_declaration: diag(1089, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_constructor_declaration_1089", "'{0}' modifier cannot appear on a constructor declaration."),
        _0_modifier_cannot_appear_on_a_parameter: diag(1090, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_parameter_1090", "'{0}' modifier cannot appear on a parameter."),
        Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: diag(1091, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091", "Only a single variable declaration is allowed in a 'for...in' statement."),
        Type_parameters_cannot_appear_on_a_constructor_declaration: diag(1092, ts.DiagnosticCategory.Error, "Type_parameters_cannot_appear_on_a_constructor_declaration_1092", "Type parameters cannot appear on a constructor declaration."),
        Type_annotation_cannot_appear_on_a_constructor_declaration: diag(1093, ts.DiagnosticCategory.Error, "Type_annotation_cannot_appear_on_a_constructor_declaration_1093", "Type annotation cannot appear on a constructor declaration."),
        An_accessor_cannot_have_type_parameters: diag(1094, ts.DiagnosticCategory.Error, "An_accessor_cannot_have_type_parameters_1094", "An accessor cannot have type parameters."),
        A_set_accessor_cannot_have_a_return_type_annotation: diag(1095, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_a_return_type_annotation_1095", "A 'set' accessor cannot have a return type annotation."),
        An_index_signature_must_have_exactly_one_parameter: diag(1096, ts.DiagnosticCategory.Error, "An_index_signature_must_have_exactly_one_parameter_1096", "An index signature must have exactly one parameter."),
        _0_list_cannot_be_empty: diag(1097, ts.DiagnosticCategory.Error, "_0_list_cannot_be_empty_1097", "'{0}' list cannot be empty."),
        Type_parameter_list_cannot_be_empty: diag(1098, ts.DiagnosticCategory.Error, "Type_parameter_list_cannot_be_empty_1098", "Type parameter list cannot be empty."),
        Type_argument_list_cannot_be_empty: diag(1099, ts.DiagnosticCategory.Error, "Type_argument_list_cannot_be_empty_1099", "Type argument list cannot be empty."),
        Invalid_use_of_0_in_strict_mode: diag(1100, ts.DiagnosticCategory.Error, "Invalid_use_of_0_in_strict_mode_1100", "Invalid use of '{0}' in strict mode."),
        with_statements_are_not_allowed_in_strict_mode: diag(1101, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_strict_mode_1101", "'with' statements are not allowed in strict mode."),
        delete_cannot_be_called_on_an_identifier_in_strict_mode: diag(1102, ts.DiagnosticCategory.Error, "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102", "'delete' cannot be called on an identifier in strict mode."),
        A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator: diag(1103, ts.DiagnosticCategory.Error, "A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator_1103", "A 'for-await-of' statement is only allowed within an async function or async generator."),
        A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: diag(1104, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104", "A 'continue' statement can only be used within an enclosing iteration statement."),
        A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: diag(1105, ts.DiagnosticCategory.Error, "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105", "A 'break' statement can only be used within an enclosing iteration or switch statement."),
        Jump_target_cannot_cross_function_boundary: diag(1107, ts.DiagnosticCategory.Error, "Jump_target_cannot_cross_function_boundary_1107", "Jump target cannot cross function boundary."),
        A_return_statement_can_only_be_used_within_a_function_body: diag(1108, ts.DiagnosticCategory.Error, "A_return_statement_can_only_be_used_within_a_function_body_1108", "A 'return' statement can only be used within a function body."),
        Expression_expected: diag(1109, ts.DiagnosticCategory.Error, "Expression_expected_1109", "Expression expected."),
        Type_expected: diag(1110, ts.DiagnosticCategory.Error, "Type_expected_1110", "Type expected."),
        A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: diag(1113, ts.DiagnosticCategory.Error, "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113", "A 'default' clause cannot appear more than once in a 'switch' statement."),
        Duplicate_label_0: diag(1114, ts.DiagnosticCategory.Error, "Duplicate_label_0_1114", "Duplicate label '{0}'."),
        A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: diag(1115, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115", "A 'continue' statement can only jump to a label of an enclosing iteration statement."),
        A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement: diag(1116, ts.DiagnosticCategory.Error, "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116", "A 'break' statement can only jump to a label of an enclosing statement."),
        An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: diag(1117, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode_1117", "An object literal cannot have multiple properties with the same name in strict mode."),
        An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: diag(1118, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118", "An object literal cannot have multiple get/set accessors with the same name."),
        An_object_literal_cannot_have_property_and_accessor_with_the_same_name: diag(1119, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119", "An object literal cannot have property and accessor with the same name."),
        An_export_assignment_cannot_have_modifiers: diag(1120, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_have_modifiers_1120", "An export assignment cannot have modifiers."),
        Octal_literals_are_not_allowed_in_strict_mode: diag(1121, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_strict_mode_1121", "Octal literals are not allowed in strict mode."),
        Variable_declaration_list_cannot_be_empty: diag(1123, ts.DiagnosticCategory.Error, "Variable_declaration_list_cannot_be_empty_1123", "Variable declaration list cannot be empty."),
        Digit_expected: diag(1124, ts.DiagnosticCategory.Error, "Digit_expected_1124", "Digit expected."),
        Hexadecimal_digit_expected: diag(1125, ts.DiagnosticCategory.Error, "Hexadecimal_digit_expected_1125", "Hexadecimal digit expected."),
        Unexpected_end_of_text: diag(1126, ts.DiagnosticCategory.Error, "Unexpected_end_of_text_1126", "Unexpected end of text."),
        Invalid_character: diag(1127, ts.DiagnosticCategory.Error, "Invalid_character_1127", "Invalid character."),
        Declaration_or_statement_expected: diag(1128, ts.DiagnosticCategory.Error, "Declaration_or_statement_expected_1128", "Declaration or statement expected."),
        Statement_expected: diag(1129, ts.DiagnosticCategory.Error, "Statement_expected_1129", "Statement expected."),
        case_or_default_expected: diag(1130, ts.DiagnosticCategory.Error, "case_or_default_expected_1130", "'case' or 'default' expected."),
        Property_or_signature_expected: diag(1131, ts.DiagnosticCategory.Error, "Property_or_signature_expected_1131", "Property or signature expected."),
        Enum_member_expected: diag(1132, ts.DiagnosticCategory.Error, "Enum_member_expected_1132", "Enum member expected."),
        Variable_declaration_expected: diag(1134, ts.DiagnosticCategory.Error, "Variable_declaration_expected_1134", "Variable declaration expected."),
        Argument_expression_expected: diag(1135, ts.DiagnosticCategory.Error, "Argument_expression_expected_1135", "Argument expression expected."),
        Property_assignment_expected: diag(1136, ts.DiagnosticCategory.Error, "Property_assignment_expected_1136", "Property assignment expected."),
        Expression_or_comma_expected: diag(1137, ts.DiagnosticCategory.Error, "Expression_or_comma_expected_1137", "Expression or comma expected."),
        Parameter_declaration_expected: diag(1138, ts.DiagnosticCategory.Error, "Parameter_declaration_expected_1138", "Parameter declaration expected."),
        Type_parameter_declaration_expected: diag(1139, ts.DiagnosticCategory.Error, "Type_parameter_declaration_expected_1139", "Type parameter declaration expected."),
        Type_argument_expected: diag(1140, ts.DiagnosticCategory.Error, "Type_argument_expected_1140", "Type argument expected."),
        String_literal_expected: diag(1141, ts.DiagnosticCategory.Error, "String_literal_expected_1141", "String literal expected."),
        Line_break_not_permitted_here: diag(1142, ts.DiagnosticCategory.Error, "Line_break_not_permitted_here_1142", "Line break not permitted here."),
        or_expected: diag(1144, ts.DiagnosticCategory.Error, "or_expected_1144", "'{' or ';' expected."),
        Declaration_expected: diag(1146, ts.DiagnosticCategory.Error, "Declaration_expected_1146", "Declaration expected."),
        Import_declarations_in_a_namespace_cannot_reference_a_module: diag(1147, ts.DiagnosticCategory.Error, "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", "Import declarations in a namespace cannot reference a module."),
        Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: diag(1148, ts.DiagnosticCategory.Error, "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", "Cannot use imports, exports, or module augmentations when '--module' is 'none'."),
        File_name_0_differs_from_already_included_file_name_1_only_in_casing: diag(1149, ts.DiagnosticCategory.Error, "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", "File name '{0}' differs from already included file name '{1}' only in casing."),
        const_declarations_must_be_initialized: diag(1155, ts.DiagnosticCategory.Error, "const_declarations_must_be_initialized_1155", "'const' declarations must be initialized."),
        const_declarations_can_only_be_declared_inside_a_block: diag(1156, ts.DiagnosticCategory.Error, "const_declarations_can_only_be_declared_inside_a_block_1156", "'const' declarations can only be declared inside a block."),
        let_declarations_can_only_be_declared_inside_a_block: diag(1157, ts.DiagnosticCategory.Error, "let_declarations_can_only_be_declared_inside_a_block_1157", "'let' declarations can only be declared inside a block."),
        Unterminated_template_literal: diag(1160, ts.DiagnosticCategory.Error, "Unterminated_template_literal_1160", "Unterminated template literal."),
        Unterminated_regular_expression_literal: diag(1161, ts.DiagnosticCategory.Error, "Unterminated_regular_expression_literal_1161", "Unterminated regular expression literal."),
        An_object_member_cannot_be_declared_optional: diag(1162, ts.DiagnosticCategory.Error, "An_object_member_cannot_be_declared_optional_1162", "An object member cannot be declared optional."),
        A_yield_expression_is_only_allowed_in_a_generator_body: diag(1163, ts.DiagnosticCategory.Error, "A_yield_expression_is_only_allowed_in_a_generator_body_1163", "A 'yield' expression is only allowed in a generator body."),
        Computed_property_names_are_not_allowed_in_enums: diag(1164, ts.DiagnosticCategory.Error, "Computed_property_names_are_not_allowed_in_enums_1164", "Computed property names are not allowed in enums."),
        A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1165, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_t_1165", "A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1166, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_1166", "A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1168, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_ty_1168", "A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1169, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_1169", "A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1170, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type__1170", "A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_comma_expression_is_not_allowed_in_a_computed_property_name: diag(1171, ts.DiagnosticCategory.Error, "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171", "A comma expression is not allowed in a computed property name."),
        extends_clause_already_seen: diag(1172, ts.DiagnosticCategory.Error, "extends_clause_already_seen_1172", "'extends' clause already seen."),
        extends_clause_must_precede_implements_clause: diag(1173, ts.DiagnosticCategory.Error, "extends_clause_must_precede_implements_clause_1173", "'extends' clause must precede 'implements' clause."),
        Classes_can_only_extend_a_single_class: diag(1174, ts.DiagnosticCategory.Error, "Classes_can_only_extend_a_single_class_1174", "Classes can only extend a single class."),
        implements_clause_already_seen: diag(1175, ts.DiagnosticCategory.Error, "implements_clause_already_seen_1175", "'implements' clause already seen."),
        Interface_declaration_cannot_have_implements_clause: diag(1176, ts.DiagnosticCategory.Error, "Interface_declaration_cannot_have_implements_clause_1176", "Interface declaration cannot have 'implements' clause."),
        Binary_digit_expected: diag(1177, ts.DiagnosticCategory.Error, "Binary_digit_expected_1177", "Binary digit expected."),
        Octal_digit_expected: diag(1178, ts.DiagnosticCategory.Error, "Octal_digit_expected_1178", "Octal digit expected."),
        Unexpected_token_expected: diag(1179, ts.DiagnosticCategory.Error, "Unexpected_token_expected_1179", "Unexpected token. '{' expected."),
        Property_destructuring_pattern_expected: diag(1180, ts.DiagnosticCategory.Error, "Property_destructuring_pattern_expected_1180", "Property destructuring pattern expected."),
        Array_element_destructuring_pattern_expected: diag(1181, ts.DiagnosticCategory.Error, "Array_element_destructuring_pattern_expected_1181", "Array element destructuring pattern expected."),
        A_destructuring_declaration_must_have_an_initializer: diag(1182, ts.DiagnosticCategory.Error, "A_destructuring_declaration_must_have_an_initializer_1182", "A destructuring declaration must have an initializer."),
        An_implementation_cannot_be_declared_in_ambient_contexts: diag(1183, ts.DiagnosticCategory.Error, "An_implementation_cannot_be_declared_in_ambient_contexts_1183", "An implementation cannot be declared in ambient contexts."),
        Modifiers_cannot_appear_here: diag(1184, ts.DiagnosticCategory.Error, "Modifiers_cannot_appear_here_1184", "Modifiers cannot appear here."),
        Merge_conflict_marker_encountered: diag(1185, ts.DiagnosticCategory.Error, "Merge_conflict_marker_encountered_1185", "Merge conflict marker encountered."),
        A_rest_element_cannot_have_an_initializer: diag(1186, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_an_initializer_1186", "A rest element cannot have an initializer."),
        A_parameter_property_may_not_be_declared_using_a_binding_pattern: diag(1187, ts.DiagnosticCategory.Error, "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187", "A parameter property may not be declared using a binding pattern."),
        Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: diag(1188, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188", "Only a single variable declaration is allowed in a 'for...of' statement."),
        The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: diag(1189, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189", "The variable declaration of a 'for...in' statement cannot have an initializer."),
        The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: diag(1190, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190", "The variable declaration of a 'for...of' statement cannot have an initializer."),
        An_import_declaration_cannot_have_modifiers: diag(1191, ts.DiagnosticCategory.Error, "An_import_declaration_cannot_have_modifiers_1191", "An import declaration cannot have modifiers."),
        Module_0_has_no_default_export: diag(1192, ts.DiagnosticCategory.Error, "Module_0_has_no_default_export_1192", "Module '{0}' has no default export."),
        An_export_declaration_cannot_have_modifiers: diag(1193, ts.DiagnosticCategory.Error, "An_export_declaration_cannot_have_modifiers_1193", "An export declaration cannot have modifiers."),
        Export_declarations_are_not_permitted_in_a_namespace: diag(1194, ts.DiagnosticCategory.Error, "Export_declarations_are_not_permitted_in_a_namespace_1194", "Export declarations are not permitted in a namespace."),
        export_Asterisk_does_not_re_export_a_default: diag(1195, ts.DiagnosticCategory.Error, "export_Asterisk_does_not_re_export_a_default_1195", "'export *' does not re-export a default."),
        Catch_clause_variable_cannot_have_a_type_annotation: diag(1196, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_a_type_annotation_1196", "Catch clause variable cannot have a type annotation."),
        Catch_clause_variable_cannot_have_an_initializer: diag(1197, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_an_initializer_1197", "Catch clause variable cannot have an initializer."),
        An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: diag(1198, ts.DiagnosticCategory.Error, "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198", "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive."),
        Unterminated_Unicode_escape_sequence: diag(1199, ts.DiagnosticCategory.Error, "Unterminated_Unicode_escape_sequence_1199", "Unterminated Unicode escape sequence."),
        Line_terminator_not_permitted_before_arrow: diag(1200, ts.DiagnosticCategory.Error, "Line_terminator_not_permitted_before_arrow_1200", "Line terminator not permitted before arrow."),
        Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead: diag(1202, ts.DiagnosticCategory.Error, "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202", "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead."),
        Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead: diag(1203, ts.DiagnosticCategory.Error, "Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or__1203", "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead."),
        Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type: diag(1205, ts.DiagnosticCategory.Error, "Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type_1205", "Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'."),
        Decorators_are_not_valid_here: diag(1206, ts.DiagnosticCategory.Error, "Decorators_are_not_valid_here_1206", "Decorators are not valid here."),
        Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: diag(1207, ts.DiagnosticCategory.Error, "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207", "Decorators cannot be applied to multiple get/set accessors of the same name."),
        All_files_must_be_modules_when_the_isolatedModules_flag_is_provided: diag(1208, ts.DiagnosticCategory.Error, "All_files_must_be_modules_when_the_isolatedModules_flag_is_provided_1208", "All files must be modules when the '--isolatedModules' flag is provided."),
        Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: diag(1210, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode_1210", "Invalid use of '{0}'. Class definitions are automatically in strict mode."),
        A_class_declaration_without_the_default_modifier_must_have_a_name: diag(1211, ts.DiagnosticCategory.Error, "A_class_declaration_without_the_default_modifier_must_have_a_name_1211", "A class declaration without the 'default' modifier must have a name."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode: diag(1212, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212", "Identifier expected. '{0}' is a reserved word in strict mode."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: diag(1213, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213", "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode: diag(1214, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214", "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode."),
        Invalid_use_of_0_Modules_are_automatically_in_strict_mode: diag(1215, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215", "Invalid use of '{0}'. Modules are automatically in strict mode."),
        Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules: diag(1216, ts.DiagnosticCategory.Error, "Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules_1216", "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules."),
        Export_assignment_is_not_supported_when_module_flag_is_system: diag(1218, ts.DiagnosticCategory.Error, "Export_assignment_is_not_supported_when_module_flag_is_system_1218", "Export assignment is not supported when '--module' flag is 'system'."),
        Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning: diag(1219, ts.DiagnosticCategory.Error, "Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_t_1219", "Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning."),
        Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher: diag(1220, ts.DiagnosticCategory.Error, "Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher_1220", "Generators are only available when targeting ECMAScript 2015 or higher."),
        Generators_are_not_allowed_in_an_ambient_context: diag(1221, ts.DiagnosticCategory.Error, "Generators_are_not_allowed_in_an_ambient_context_1221", "Generators are not allowed in an ambient context."),
        An_overload_signature_cannot_be_declared_as_a_generator: diag(1222, ts.DiagnosticCategory.Error, "An_overload_signature_cannot_be_declared_as_a_generator_1222", "An overload signature cannot be declared as a generator."),
        _0_tag_already_specified: diag(1223, ts.DiagnosticCategory.Error, "_0_tag_already_specified_1223", "'{0}' tag already specified."),
        Signature_0_must_be_a_type_predicate: diag(1224, ts.DiagnosticCategory.Error, "Signature_0_must_be_a_type_predicate_1224", "Signature '{0}' must be a type predicate."),
        Cannot_find_parameter_0: diag(1225, ts.DiagnosticCategory.Error, "Cannot_find_parameter_0_1225", "Cannot find parameter '{0}'."),
        Type_predicate_0_is_not_assignable_to_1: diag(1226, ts.DiagnosticCategory.Error, "Type_predicate_0_is_not_assignable_to_1_1226", "Type predicate '{0}' is not assignable to '{1}'."),
        Parameter_0_is_not_in_the_same_position_as_parameter_1: diag(1227, ts.DiagnosticCategory.Error, "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227", "Parameter '{0}' is not in the same position as parameter '{1}'."),
        A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: diag(1228, ts.DiagnosticCategory.Error, "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228", "A type predicate is only allowed in return type position for functions and methods."),
        A_type_predicate_cannot_reference_a_rest_parameter: diag(1229, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_a_rest_parameter_1229", "A type predicate cannot reference a rest parameter."),
        A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: diag(1230, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230", "A type predicate cannot reference element '{0}' in a binding pattern."),
        An_export_assignment_can_only_be_used_in_a_module: diag(1231, ts.DiagnosticCategory.Error, "An_export_assignment_can_only_be_used_in_a_module_1231", "An export assignment can only be used in a module."),
        An_import_declaration_can_only_be_used_in_a_namespace_or_module: diag(1232, ts.DiagnosticCategory.Error, "An_import_declaration_can_only_be_used_in_a_namespace_or_module_1232", "An import declaration can only be used in a namespace or module."),
        An_export_declaration_can_only_be_used_in_a_module: diag(1233, ts.DiagnosticCategory.Error, "An_export_declaration_can_only_be_used_in_a_module_1233", "An export declaration can only be used in a module."),
        An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: diag(1234, ts.DiagnosticCategory.Error, "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234", "An ambient module declaration is only allowed at the top level in a file."),
        A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: diag(1235, ts.DiagnosticCategory.Error, "A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235", "A namespace declaration is only allowed in a namespace or module."),
        The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: diag(1236, ts.DiagnosticCategory.Error, "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236", "The return type of a property decorator function must be either 'void' or 'any'."),
        The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: diag(1237, ts.DiagnosticCategory.Error, "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237", "The return type of a parameter decorator function must be either 'void' or 'any'."),
        Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: diag(1238, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238", "Unable to resolve signature of class decorator when called as an expression."),
        Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: diag(1239, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239", "Unable to resolve signature of parameter decorator when called as an expression."),
        Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: diag(1240, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240", "Unable to resolve signature of property decorator when called as an expression."),
        Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: diag(1241, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241", "Unable to resolve signature of method decorator when called as an expression."),
        abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration: diag(1242, ts.DiagnosticCategory.Error, "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242", "'abstract' modifier can only appear on a class, method, or property declaration."),
        _0_modifier_cannot_be_used_with_1_modifier: diag(1243, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_1_modifier_1243", "'{0}' modifier cannot be used with '{1}' modifier."),
        Abstract_methods_can_only_appear_within_an_abstract_class: diag(1244, ts.DiagnosticCategory.Error, "Abstract_methods_can_only_appear_within_an_abstract_class_1244", "Abstract methods can only appear within an abstract class."),
        Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: diag(1245, ts.DiagnosticCategory.Error, "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245", "Method '{0}' cannot have an implementation because it is marked abstract."),
        An_interface_property_cannot_have_an_initializer: diag(1246, ts.DiagnosticCategory.Error, "An_interface_property_cannot_have_an_initializer_1246", "An interface property cannot have an initializer."),
        A_type_literal_property_cannot_have_an_initializer: diag(1247, ts.DiagnosticCategory.Error, "A_type_literal_property_cannot_have_an_initializer_1247", "A type literal property cannot have an initializer."),
        A_class_member_cannot_have_the_0_keyword: diag(1248, ts.DiagnosticCategory.Error, "A_class_member_cannot_have_the_0_keyword_1248", "A class member cannot have the '{0}' keyword."),
        A_decorator_can_only_decorate_a_method_implementation_not_an_overload: diag(1249, ts.DiagnosticCategory.Error, "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249", "A decorator can only decorate a method implementation, not an overload."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5: diag(1250, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode: diag(1251, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_d_1251", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Class definitions are automatically in strict mode."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode: diag(1252, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_1252", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode."),
        _0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag: diag(1253, ts.DiagnosticCategory.Error, "_0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag_1253", "'{0}' tag cannot be used independently as a top level JSDoc tag."),
        A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference: diag(1254, ts.DiagnosticCategory.Error, "A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_refere_1254", "A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference."),
        A_definite_assignment_assertion_is_not_permitted_in_this_context: diag(1255, ts.DiagnosticCategory.Error, "A_definite_assignment_assertion_is_not_permitted_in_this_context_1255", "A definite assignment assertion '!' is not permitted in this context."),
        A_rest_element_must_be_last_in_a_tuple_type: diag(1256, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_tuple_type_1256", "A rest element must be last in a tuple type."),
        A_required_element_cannot_follow_an_optional_element: diag(1257, ts.DiagnosticCategory.Error, "A_required_element_cannot_follow_an_optional_element_1257", "A required element cannot follow an optional element."),
        Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation: diag(1258, ts.DiagnosticCategory.Error, "Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation_1258", "Definite assignment assertions can only be used along with a type annotation."),
        Module_0_can_only_be_default_imported_using_the_1_flag: diag(1259, ts.DiagnosticCategory.Error, "Module_0_can_only_be_default_imported_using_the_1_flag_1259", "Module '{0}' can only be default-imported using the '{1}' flag"),
        Keywords_cannot_contain_escape_characters: diag(1260, ts.DiagnosticCategory.Error, "Keywords_cannot_contain_escape_characters_1260", "Keywords cannot contain escape characters."),
        Already_included_file_name_0_differs_from_file_name_1_only_in_casing: diag(1261, ts.DiagnosticCategory.Error, "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", "Already included file name '{0}' differs from file name '{1}' only in casing."),
        with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."),
        await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules: diag(1308, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", "'await' expressions are only allowed within async functions and at the top levels of modules."),
        can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."),
        The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."),
        Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."),
        Global_module_exports_may_only_appear_in_declaration_files: diag(1315, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_declaration_files_1315", "Global module exports may only appear in declaration files."),
        Global_module_exports_may_only_appear_at_top_level: diag(1316, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_at_top_level_1316", "Global module exports may only appear at top level."),
        A_parameter_property_cannot_be_declared_using_a_rest_parameter: diag(1317, ts.DiagnosticCategory.Error, "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317", "A parameter property cannot be declared using a rest parameter."),
        An_abstract_accessor_cannot_have_an_implementation: diag(1318, ts.DiagnosticCategory.Error, "An_abstract_accessor_cannot_have_an_implementation_1318", "An abstract accessor cannot have an implementation."),
        A_default_export_can_only_be_used_in_an_ECMAScript_style_module: diag(1319, ts.DiagnosticCategory.Error, "A_default_export_can_only_be_used_in_an_ECMAScript_style_module_1319", "A default export can only be used in an ECMAScript-style module."),
        Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1320, ts.DiagnosticCategory.Error, "Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member_1320", "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member."),
        Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1321, ts.DiagnosticCategory.Error, "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321", "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member."),
        Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1322, ts.DiagnosticCategory.Error, "Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322", "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member."),
        Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_esnext_commonjs_amd_system_or_umd: diag(1323, ts.DiagnosticCategory.Error, "Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_esnext_commonjs_amd_system__1323", "Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'esnext', 'commonjs', 'amd', 'system', or 'umd'."),
        Dynamic_import_must_have_one_specifier_as_an_argument: diag(1324, ts.DiagnosticCategory.Error, "Dynamic_import_must_have_one_specifier_as_an_argument_1324", "Dynamic import must have one specifier as an argument."),
        Specifier_of_dynamic_import_cannot_be_spread_element: diag(1325, ts.DiagnosticCategory.Error, "Specifier_of_dynamic_import_cannot_be_spread_element_1325", "Specifier of dynamic import cannot be spread element."),
        Dynamic_import_cannot_have_type_arguments: diag(1326, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_have_type_arguments_1326", "Dynamic import cannot have type arguments"),
        String_literal_with_double_quotes_expected: diag(1327, ts.DiagnosticCategory.Error, "String_literal_with_double_quotes_expected_1327", "String literal with double quotes expected."),
        Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal: diag(1328, ts.DiagnosticCategory.Error, "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328", "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal."),
        _0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0: diag(1329, ts.DiagnosticCategory.Error, "_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329", "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?"),
        A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly: diag(1330, ts.DiagnosticCategory.Error, "A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330", "A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'."),
        A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly: diag(1331, ts.DiagnosticCategory.Error, "A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly_1331", "A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'."),
        A_variable_whose_type_is_a_unique_symbol_type_must_be_const: diag(1332, ts.DiagnosticCategory.Error, "A_variable_whose_type_is_a_unique_symbol_type_must_be_const_1332", "A variable whose type is a 'unique symbol' type must be 'const'."),
        unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name: diag(1333, ts.DiagnosticCategory.Error, "unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name_1333", "'unique symbol' types may not be used on a variable declaration with a binding name."),
        unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement: diag(1334, ts.DiagnosticCategory.Error, "unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement_1334", "'unique symbol' types are only allowed on variables in a variable statement."),
        unique_symbol_types_are_not_allowed_here: diag(1335, ts.DiagnosticCategory.Error, "unique_symbol_types_are_not_allowed_here_1335", "'unique symbol' types are not allowed here."),
        An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead: diag(1336, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead_1336", "An index signature parameter type cannot be a type alias. Consider writing '[{0}: {1}]: {2}' instead."),
        An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead: diag(1337, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead_1337", "An index signature parameter type cannot be a union type. Consider using a mapped object type instead."),
        infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type: diag(1338, ts.DiagnosticCategory.Error, "infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type_1338", "'infer' declarations are only permitted in the 'extends' clause of a conditional type."),
        Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here: diag(1339, ts.DiagnosticCategory.Error, "Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here_1339", "Module '{0}' does not refer to a value, but is used as a value here."),
        Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0: diag(1340, ts.DiagnosticCategory.Error, "Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0_1340", "Module '{0}' does not refer to a type, but is used as a type here. Did you mean 'typeof import('{0}')'?"),
        Type_arguments_cannot_be_used_here: diag(1342, ts.DiagnosticCategory.Error, "Type_arguments_cannot_be_used_here_1342", "Type arguments cannot be used here."),
        The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_esnext_or_system: diag(1343, ts.DiagnosticCategory.Error, "The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_esnext_or_system_1343", "The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'."),
        A_label_is_not_allowed_here: diag(1344, ts.DiagnosticCategory.Error, "A_label_is_not_allowed_here_1344", "'A label is not allowed here."),
        An_expression_of_type_void_cannot_be_tested_for_truthiness: diag(1345, ts.DiagnosticCategory.Error, "An_expression_of_type_void_cannot_be_tested_for_truthiness_1345", "An expression of type 'void' cannot be tested for truthiness"),
        This_parameter_is_not_allowed_with_use_strict_directive: diag(1346, ts.DiagnosticCategory.Error, "This_parameter_is_not_allowed_with_use_strict_directive_1346", "This parameter is not allowed with 'use strict' directive."),
        use_strict_directive_cannot_be_used_with_non_simple_parameter_list: diag(1347, ts.DiagnosticCategory.Error, "use_strict_directive_cannot_be_used_with_non_simple_parameter_list_1347", "'use strict' directive cannot be used with non-simple parameter list."),
        Non_simple_parameter_declared_here: diag(1348, ts.DiagnosticCategory.Error, "Non_simple_parameter_declared_here_1348", "Non-simple parameter declared here."),
        use_strict_directive_used_here: diag(1349, ts.DiagnosticCategory.Error, "use_strict_directive_used_here_1349", "'use strict' directive used here."),
        Print_the_final_configuration_instead_of_building: diag(1350, ts.DiagnosticCategory.Message, "Print_the_final_configuration_instead_of_building_1350", "Print the final configuration instead of building."),
        An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal: diag(1351, ts.DiagnosticCategory.Error, "An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal_1351", "An identifier or keyword cannot immediately follow a numeric literal."),
        A_bigint_literal_cannot_use_exponential_notation: diag(1352, ts.DiagnosticCategory.Error, "A_bigint_literal_cannot_use_exponential_notation_1352", "A bigint literal cannot use exponential notation."),
        A_bigint_literal_must_be_an_integer: diag(1353, ts.DiagnosticCategory.Error, "A_bigint_literal_must_be_an_integer_1353", "A bigint literal must be an integer."),
        readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types: diag(1354, ts.DiagnosticCategory.Error, "readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types_1354", "'readonly' type modifier is only permitted on array and tuple literal types."),
        A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals: diag(1355, ts.DiagnosticCategory.Error, "A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array__1355", "A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals."),
        Did_you_mean_to_mark_this_function_as_async: diag(1356, ts.DiagnosticCategory.Error, "Did_you_mean_to_mark_this_function_as_async_1356", "Did you mean to mark this function as 'async'?"),
        An_enum_member_name_must_be_followed_by_a_or: diag(1357, ts.DiagnosticCategory.Error, "An_enum_member_name_must_be_followed_by_a_or_1357", "An enum member name must be followed by a ',', '=', or '}'."),
        Tagged_template_expressions_are_not_permitted_in_an_optional_chain: diag(1358, ts.DiagnosticCategory.Error, "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", "Tagged template expressions are not permitted in an optional chain."),
        Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here: diag(1359, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", "Identifier expected. '{0}' is a reserved word that cannot be used here."),
        Did_you_mean_to_parenthesize_this_function_type: diag(1360, ts.DiagnosticCategory.Error, "Did_you_mean_to_parenthesize_this_function_type_1360", "Did you mean to parenthesize this function type?"),
        _0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type: diag(1361, ts.DiagnosticCategory.Error, "_0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type_1361", "'{0}' cannot be used as a value because it was imported using 'import type'."),
        _0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type: diag(1362, ts.DiagnosticCategory.Error, "_0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type_1362", "'{0}' cannot be used as a value because it was exported using 'export type'."),
        A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both: diag(1363, ts.DiagnosticCategory.Error, "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", "A type-only import can specify a default import or named bindings, but not both."),
        Convert_to_type_only_export: diag(1364, ts.DiagnosticCategory.Message, "Convert_to_type_only_export_1364", "Convert to type-only export"),
        Convert_all_re_exported_types_to_type_only_exports: diag(1365, ts.DiagnosticCategory.Message, "Convert_all_re_exported_types_to_type_only_exports_1365", "Convert all re-exported types to type-only exports"),
        Split_into_two_separate_import_declarations: diag(1366, ts.DiagnosticCategory.Message, "Split_into_two_separate_import_declarations_1366", "Split into two separate import declarations"),
        Split_all_invalid_type_only_imports: diag(1367, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1367", "Split all invalid type-only imports"),
        Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types: diag(1368, ts.DiagnosticCategory.Message, "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_1368", "Specify emit/checking behavior for imports that are only used for types"),
        Did_you_mean_0: diag(1369, ts.DiagnosticCategory.Message, "Did_you_mean_0_1369", "Did you mean '{0}'?"),
        Only_ECMAScript_imports_may_use_import_type: diag(1370, ts.DiagnosticCategory.Error, "Only_ECMAScript_imports_may_use_import_type_1370", "Only ECMAScript imports may use 'import type'."),
        This_import_is_never_used_as_a_value_and_must_use_import_type_because_the_importsNotUsedAsValues_is_set_to_error: diag(1371, ts.DiagnosticCategory.Error, "This_import_is_never_used_as_a_value_and_must_use_import_type_because_the_importsNotUsedAsValues_is__1371", "This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'."),
        Convert_to_type_only_import: diag(1373, ts.DiagnosticCategory.Message, "Convert_to_type_only_import_1373", "Convert to type-only import"),
        Convert_all_imports_not_used_as_a_value_to_type_only_imports: diag(1374, ts.DiagnosticCategory.Message, "Convert_all_imports_not_used_as_a_value_to_type_only_imports_1374", "Convert all imports not used as a value to type-only imports"),
        await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module: diag(1375, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."),
        _0_was_imported_here: diag(1376, ts.DiagnosticCategory.Message, "_0_was_imported_here_1376", "'{0}' was imported here."),
        _0_was_exported_here: diag(1377, ts.DiagnosticCategory.Message, "_0_was_exported_here_1377", "'{0}' was exported here."),
        Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher: diag(1378, ts.DiagnosticCategory.Error, "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_t_1378", "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher."),
        An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type: diag(1379, ts.DiagnosticCategory.Error, "An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type_1379", "An import alias cannot reference a declaration that was exported using 'export type'."),
        An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type: diag(1380, ts.DiagnosticCategory.Error, "An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type_1380", "An import alias cannot reference a declaration that was imported using 'import type'."),
        Unexpected_token_Did_you_mean_or_rbrace: diag(1381, ts.DiagnosticCategory.Error, "Unexpected_token_Did_you_mean_or_rbrace_1381", "Unexpected token. Did you mean `{'}'}` or `&rbrace;`?"),
        Unexpected_token_Did_you_mean_or_gt: diag(1382, ts.DiagnosticCategory.Error, "Unexpected_token_Did_you_mean_or_gt_1382", "Unexpected token. Did you mean `{'>'}` or `&gt;`?"),
        Only_named_exports_may_use_export_type: diag(1383, ts.DiagnosticCategory.Error, "Only_named_exports_may_use_export_type_1383", "Only named exports may use 'export type'."),
        A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list: diag(1384, ts.DiagnosticCategory.Error, "A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list_1384", "A 'new' expression with type arguments must always be followed by a parenthesized argument list."),
        The_types_of_0_are_incompatible_between_these_types: diag(2200, ts.DiagnosticCategory.Error, "The_types_of_0_are_incompatible_between_these_types_2200", "The types of '{0}' are incompatible between these types."),
        The_types_returned_by_0_are_incompatible_between_these_types: diag(2201, ts.DiagnosticCategory.Error, "The_types_returned_by_0_are_incompatible_between_these_types_2201", "The types returned by '{0}' are incompatible between these types."),
        Call_signature_return_types_0_and_1_are_incompatible: diag(2202, ts.DiagnosticCategory.Error, "Call_signature_return_types_0_and_1_are_incompatible_2202", "Call signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true),
        Construct_signature_return_types_0_and_1_are_incompatible: diag(2203, ts.DiagnosticCategory.Error, "Construct_signature_return_types_0_and_1_are_incompatible_2203", "Construct signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true),
        Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1: diag(2204, ts.DiagnosticCategory.Error, "Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1_2204", "Call signatures with no arguments have incompatible return types '{0}' and '{1}'.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true),
        Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1: diag(2205, ts.DiagnosticCategory.Error, "Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1_2205", "Construct signatures with no arguments have incompatible return types '{0}' and '{1}'.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true),
        Duplicate_identifier_0: diag(2300, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_2300", "Duplicate identifier '{0}'."),
        Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: diag(2301, ts.DiagnosticCategory.Error, "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301", "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor."),
        Static_members_cannot_reference_class_type_parameters: diag(2302, ts.DiagnosticCategory.Error, "Static_members_cannot_reference_class_type_parameters_2302", "Static members cannot reference class type parameters."),
        Circular_definition_of_import_alias_0: diag(2303, ts.DiagnosticCategory.Error, "Circular_definition_of_import_alias_0_2303", "Circular definition of import alias '{0}'."),
        Cannot_find_name_0: diag(2304, ts.DiagnosticCategory.Error, "Cannot_find_name_0_2304", "Cannot find name '{0}'."),
        Module_0_has_no_exported_member_1: diag(2305, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_2305", "Module '{0}' has no exported member '{1}'."),
        File_0_is_not_a_module: diag(2306, ts.DiagnosticCategory.Error, "File_0_is_not_a_module_2306", "File '{0}' is not a module."),
        Cannot_find_module_0_or_its_corresponding_type_declarations: diag(2307, ts.DiagnosticCategory.Error, "Cannot_find_module_0_or_its_corresponding_type_declarations_2307", "Cannot find module '{0}' or its corresponding type declarations."),
        Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity: diag(2308, ts.DiagnosticCategory.Error, "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308", "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity."),
        An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: diag(2309, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309", "An export assignment cannot be used in a module with other exported elements."),
        Type_0_recursively_references_itself_as_a_base_type: diag(2310, ts.DiagnosticCategory.Error, "Type_0_recursively_references_itself_as_a_base_type_2310", "Type '{0}' recursively references itself as a base type."),
        A_class_may_only_extend_another_class: diag(2311, ts.DiagnosticCategory.Error, "A_class_may_only_extend_another_class_2311", "A class may only extend another class."),
        An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2312, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_me_2312", "An interface can only extend an object type or intersection of object types with statically known members."),
        Type_parameter_0_has_a_circular_constraint: diag(2313, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_constraint_2313", "Type parameter '{0}' has a circular constraint."),
        Generic_type_0_requires_1_type_argument_s: diag(2314, ts.DiagnosticCategory.Error, "Generic_type_0_requires_1_type_argument_s_2314", "Generic type '{0}' requires {1} type argument(s)."),
        Type_0_is_not_generic: diag(2315, ts.DiagnosticCategory.Error, "Type_0_is_not_generic_2315", "Type '{0}' is not generic."),
        Global_type_0_must_be_a_class_or_interface_type: diag(2316, ts.DiagnosticCategory.Error, "Global_type_0_must_be_a_class_or_interface_type_2316", "Global type '{0}' must be a class or interface type."),
        Global_type_0_must_have_1_type_parameter_s: diag(2317, ts.DiagnosticCategory.Error, "Global_type_0_must_have_1_type_parameter_s_2317", "Global type '{0}' must have {1} type parameter(s)."),
        Cannot_find_global_type_0: diag(2318, ts.DiagnosticCategory.Error, "Cannot_find_global_type_0_2318", "Cannot find global type '{0}'."),
        Named_property_0_of_types_1_and_2_are_not_identical: diag(2319, ts.DiagnosticCategory.Error, "Named_property_0_of_types_1_and_2_are_not_identical_2319", "Named property '{0}' of types '{1}' and '{2}' are not identical."),
        Interface_0_cannot_simultaneously_extend_types_1_and_2: diag(2320, ts.DiagnosticCategory.Error, "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320", "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'."),
        Excessive_stack_depth_comparing_types_0_and_1: diag(2321, ts.DiagnosticCategory.Error, "Excessive_stack_depth_comparing_types_0_and_1_2321", "Excessive stack depth comparing types '{0}' and '{1}'."),
        Type_0_is_not_assignable_to_type_1: diag(2322, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_2322", "Type '{0}' is not assignable to type '{1}'."),
        Cannot_redeclare_exported_variable_0: diag(2323, ts.DiagnosticCategory.Error, "Cannot_redeclare_exported_variable_0_2323", "Cannot redeclare exported variable '{0}'."),
        Property_0_is_missing_in_type_1: diag(2324, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_2324", "Property '{0}' is missing in type '{1}'."),
        Property_0_is_private_in_type_1_but_not_in_type_2: diag(2325, ts.DiagnosticCategory.Error, "Property_0_is_private_in_type_1_but_not_in_type_2_2325", "Property '{0}' is private in type '{1}' but not in type '{2}'."),
        Types_of_property_0_are_incompatible: diag(2326, ts.DiagnosticCategory.Error, "Types_of_property_0_are_incompatible_2326", "Types of property '{0}' are incompatible."),
        Property_0_is_optional_in_type_1_but_required_in_type_2: diag(2327, ts.DiagnosticCategory.Error, "Property_0_is_optional_in_type_1_but_required_in_type_2_2327", "Property '{0}' is optional in type '{1}' but required in type '{2}'."),
        Types_of_parameters_0_and_1_are_incompatible: diag(2328, ts.DiagnosticCategory.Error, "Types_of_parameters_0_and_1_are_incompatible_2328", "Types of parameters '{0}' and '{1}' are incompatible."),
        Index_signature_is_missing_in_type_0: diag(2329, ts.DiagnosticCategory.Error, "Index_signature_is_missing_in_type_0_2329", "Index signature is missing in type '{0}'."),
        Index_signatures_are_incompatible: diag(2330, ts.DiagnosticCategory.Error, "Index_signatures_are_incompatible_2330", "Index signatures are incompatible."),
        this_cannot_be_referenced_in_a_module_or_namespace_body: diag(2331, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_module_or_namespace_body_2331", "'this' cannot be referenced in a module or namespace body."),
        this_cannot_be_referenced_in_current_location: diag(2332, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_current_location_2332", "'this' cannot be referenced in current location."),
        this_cannot_be_referenced_in_constructor_arguments: diag(2333, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_constructor_arguments_2333", "'this' cannot be referenced in constructor arguments."),
        this_cannot_be_referenced_in_a_static_property_initializer: diag(2334, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_static_property_initializer_2334", "'this' cannot be referenced in a static property initializer."),
        super_can_only_be_referenced_in_a_derived_class: diag(2335, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_a_derived_class_2335", "'super' can only be referenced in a derived class."),
        super_cannot_be_referenced_in_constructor_arguments: diag(2336, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_constructor_arguments_2336", "'super' cannot be referenced in constructor arguments."),
        Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: diag(2337, ts.DiagnosticCategory.Error, "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337", "Super calls are not permitted outside constructors or in nested functions inside constructors."),
        super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: diag(2338, ts.DiagnosticCategory.Error, "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338", "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class."),
        Property_0_does_not_exist_on_type_1: diag(2339, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_2339", "Property '{0}' does not exist on type '{1}'."),
        Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: diag(2340, ts.DiagnosticCategory.Error, "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340", "Only public and protected methods of the base class are accessible via the 'super' keyword."),
        Property_0_is_private_and_only_accessible_within_class_1: diag(2341, ts.DiagnosticCategory.Error, "Property_0_is_private_and_only_accessible_within_class_1_2341", "Property '{0}' is private and only accessible within class '{1}'."),
        An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: diag(2342, ts.DiagnosticCategory.Error, "An_index_expression_argument_must_be_of_type_string_number_symbol_or_any_2342", "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'."),
        This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0: diag(2343, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_ve_2343", "This syntax requires an imported helper named '{1}' which does not exist in '{0}'. Consider upgrading your version of '{0}'."),
        Type_0_does_not_satisfy_the_constraint_1: diag(2344, ts.DiagnosticCategory.Error, "Type_0_does_not_satisfy_the_constraint_1_2344", "Type '{0}' does not satisfy the constraint '{1}'."),
        Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: diag(2345, ts.DiagnosticCategory.Error, "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345", "Argument of type '{0}' is not assignable to parameter of type '{1}'."),
        Call_target_does_not_contain_any_signatures: diag(2346, ts.DiagnosticCategory.Error, "Call_target_does_not_contain_any_signatures_2346", "Call target does not contain any signatures."),
        Untyped_function_calls_may_not_accept_type_arguments: diag(2347, ts.DiagnosticCategory.Error, "Untyped_function_calls_may_not_accept_type_arguments_2347", "Untyped function calls may not accept type arguments."),
        Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: diag(2348, ts.DiagnosticCategory.Error, "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348", "Value of type '{0}' is not callable. Did you mean to include 'new'?"),
        This_expression_is_not_callable: diag(2349, ts.DiagnosticCategory.Error, "This_expression_is_not_callable_2349", "This expression is not callable."),
        Only_a_void_function_can_be_called_with_the_new_keyword: diag(2350, ts.DiagnosticCategory.Error, "Only_a_void_function_can_be_called_with_the_new_keyword_2350", "Only a void function can be called with the 'new' keyword."),
        This_expression_is_not_constructable: diag(2351, ts.DiagnosticCategory.Error, "This_expression_is_not_constructable_2351", "This expression is not constructable."),
        Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first: diag(2352, ts.DiagnosticCategory.Error, "Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the__2352", "Conversion of type '{0}' to type '{1}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first."),
        Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1: diag(2353, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353", "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'."),
        This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found: diag(2354, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354", "This syntax requires an imported helper but module '{0}' cannot be found."),
        A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value: diag(2355, ts.DiagnosticCategory.Error, "A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_2355", "A function whose declared type is neither 'void' nor 'any' must return a value."),
        An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2356, ts.DiagnosticCategory.Error, "An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_2356", "An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type."),
        The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access: diag(2357, ts.DiagnosticCategory.Error, "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access_2357", "The operand of an increment or decrement operator must be a variable or a property access."),
        The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2358, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358", "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter."),
        The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: diag(2359, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_F_2359", "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type."),
        The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol: diag(2360, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol_2360", "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'."),
        The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2361, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter_2361", "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter."),
        The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2362, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2362", "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type."),
        The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2363, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2363", "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type."),
        The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access: diag(2364, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access_2364", "The left-hand side of an assignment expression must be a variable or a property access."),
        Operator_0_cannot_be_applied_to_types_1_and_2: diag(2365, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_types_1_and_2_2365", "Operator '{0}' cannot be applied to types '{1}' and '{2}'."),
        Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined: diag(2366, ts.DiagnosticCategory.Error, "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366", "Function lacks ending return statement and return type does not include 'undefined'."),
        This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap: diag(2367, ts.DiagnosticCategory.Error, "This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap_2367", "This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap."),
        Type_parameter_name_cannot_be_0: diag(2368, ts.DiagnosticCategory.Error, "Type_parameter_name_cannot_be_0_2368", "Type parameter name cannot be '{0}'."),
        A_parameter_property_is_only_allowed_in_a_constructor_implementation: diag(2369, ts.DiagnosticCategory.Error, "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369", "A parameter property is only allowed in a constructor implementation."),
        A_rest_parameter_must_be_of_an_array_type: diag(2370, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_of_an_array_type_2370", "A rest parameter must be of an array type."),
        A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: diag(2371, ts.DiagnosticCategory.Error, "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371", "A parameter initializer is only allowed in a function or constructor implementation."),
        Parameter_0_cannot_reference_itself: diag(2372, ts.DiagnosticCategory.Error, "Parameter_0_cannot_reference_itself_2372", "Parameter '{0}' cannot reference itself."),
        Parameter_0_cannot_reference_identifier_1_declared_after_it: diag(2373, ts.DiagnosticCategory.Error, "Parameter_0_cannot_reference_identifier_1_declared_after_it_2373", "Parameter '{0}' cannot reference identifier '{1}' declared after it."),
        Duplicate_string_index_signature: diag(2374, ts.DiagnosticCategory.Error, "Duplicate_string_index_signature_2374", "Duplicate string index signature."),
        Duplicate_number_index_signature: diag(2375, ts.DiagnosticCategory.Error, "Duplicate_number_index_signature_2375", "Duplicate number index signature."),
        A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_parameter_properties_or_private_identifiers: diag(2376, ts.DiagnosticCategory.Error, "A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_proper_2376", "A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers."),
        Constructors_for_derived_classes_must_contain_a_super_call: diag(2377, ts.DiagnosticCategory.Error, "Constructors_for_derived_classes_must_contain_a_super_call_2377", "Constructors for derived classes must contain a 'super' call."),
        A_get_accessor_must_return_a_value: diag(2378, ts.DiagnosticCategory.Error, "A_get_accessor_must_return_a_value_2378", "A 'get' accessor must return a value."),
        Getter_and_setter_accessors_do_not_agree_in_visibility: diag(2379, ts.DiagnosticCategory.Error, "Getter_and_setter_accessors_do_not_agree_in_visibility_2379", "Getter and setter accessors do not agree in visibility."),
        get_and_set_accessor_must_have_the_same_type: diag(2380, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_type_2380", "'get' and 'set' accessor must have the same type."),
        A_signature_with_an_implementation_cannot_use_a_string_literal_type: diag(2381, ts.DiagnosticCategory.Error, "A_signature_with_an_implementation_cannot_use_a_string_literal_type_2381", "A signature with an implementation cannot use a string literal type."),
        Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: diag(2382, ts.DiagnosticCategory.Error, "Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382", "Specialized overload signature is not assignable to any non-specialized signature."),
        Overload_signatures_must_all_be_exported_or_non_exported: diag(2383, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_exported_or_non_exported_2383", "Overload signatures must all be exported or non-exported."),
        Overload_signatures_must_all_be_ambient_or_non_ambient: diag(2384, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_ambient_or_non_ambient_2384", "Overload signatures must all be ambient or non-ambient."),
        Overload_signatures_must_all_be_public_private_or_protected: diag(2385, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_public_private_or_protected_2385", "Overload signatures must all be public, private or protected."),
        Overload_signatures_must_all_be_optional_or_required: diag(2386, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_optional_or_required_2386", "Overload signatures must all be optional or required."),
        Function_overload_must_be_static: diag(2387, ts.DiagnosticCategory.Error, "Function_overload_must_be_static_2387", "Function overload must be static."),
        Function_overload_must_not_be_static: diag(2388, ts.DiagnosticCategory.Error, "Function_overload_must_not_be_static_2388", "Function overload must not be static."),
        Function_implementation_name_must_be_0: diag(2389, ts.DiagnosticCategory.Error, "Function_implementation_name_must_be_0_2389", "Function implementation name must be '{0}'."),
        Constructor_implementation_is_missing: diag(2390, ts.DiagnosticCategory.Error, "Constructor_implementation_is_missing_2390", "Constructor implementation is missing."),
        Function_implementation_is_missing_or_not_immediately_following_the_declaration: diag(2391, ts.DiagnosticCategory.Error, "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391", "Function implementation is missing or not immediately following the declaration."),
        Multiple_constructor_implementations_are_not_allowed: diag(2392, ts.DiagnosticCategory.Error, "Multiple_constructor_implementations_are_not_allowed_2392", "Multiple constructor implementations are not allowed."),
        Duplicate_function_implementation: diag(2393, ts.DiagnosticCategory.Error, "Duplicate_function_implementation_2393", "Duplicate function implementation."),
        This_overload_signature_is_not_compatible_with_its_implementation_signature: diag(2394, ts.DiagnosticCategory.Error, "This_overload_signature_is_not_compatible_with_its_implementation_signature_2394", "This overload signature is not compatible with its implementation signature."),
        Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: diag(2395, ts.DiagnosticCategory.Error, "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395", "Individual declarations in merged declaration '{0}' must be all exported or all local."),
        Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: diag(2396, ts.DiagnosticCategory.Error, "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396", "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters."),
        Declaration_name_conflicts_with_built_in_global_identifier_0: diag(2397, ts.DiagnosticCategory.Error, "Declaration_name_conflicts_with_built_in_global_identifier_0_2397", "Declaration name conflicts with built-in global identifier '{0}'."),
        constructor_cannot_be_used_as_a_parameter_property_name: diag(2398, ts.DiagnosticCategory.Error, "constructor_cannot_be_used_as_a_parameter_property_name_2398", "'constructor' cannot be used as a parameter property name."),
        Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: diag(2399, ts.DiagnosticCategory.Error, "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399", "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference."),
        Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: diag(2400, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400", "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference."),
        Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: diag(2401, ts.DiagnosticCategory.Error, "Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference_2401", "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference."),
        Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: diag(2402, ts.DiagnosticCategory.Error, "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402", "Expression resolves to '_super' that compiler uses to capture base class reference."),
        Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: diag(2403, ts.DiagnosticCategory.Error, "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403", "Subsequent variable declarations must have the same type.  Variable '{0}' must be of type '{1}', but here has type '{2}'."),
        The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation: diag(2404, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404", "The left-hand side of a 'for...in' statement cannot use a type annotation."),
        The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any: diag(2405, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405", "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."),
        The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access: diag(2406, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access_2406", "The left-hand side of a 'for...in' statement must be a variable or a property access."),
        The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0: diag(2407, ts.DiagnosticCategory.Error, "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_2407", "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type '{0}'."),
        Setters_cannot_return_a_value: diag(2408, ts.DiagnosticCategory.Error, "Setters_cannot_return_a_value_2408", "Setters cannot return a value."),
        Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: diag(2409, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409", "Return type of constructor signature must be assignable to the instance type of the class."),
        The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any: diag(2410, ts.DiagnosticCategory.Error, "The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410", "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'."),
        Property_0_of_type_1_is_not_assignable_to_string_index_type_2: diag(2411, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411", "Property '{0}' of type '{1}' is not assignable to string index type '{2}'."),
        Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: diag(2412, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412", "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'."),
        Numeric_index_type_0_is_not_assignable_to_string_index_type_1: diag(2413, ts.DiagnosticCategory.Error, "Numeric_index_type_0_is_not_assignable_to_string_index_type_1_2413", "Numeric index type '{0}' is not assignable to string index type '{1}'."),
        Class_name_cannot_be_0: diag(2414, ts.DiagnosticCategory.Error, "Class_name_cannot_be_0_2414", "Class name cannot be '{0}'."),
        Class_0_incorrectly_extends_base_class_1: diag(2415, ts.DiagnosticCategory.Error, "Class_0_incorrectly_extends_base_class_1_2415", "Class '{0}' incorrectly extends base class '{1}'."),
        Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2: diag(2416, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2_2416", "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'."),
        Class_static_side_0_incorrectly_extends_base_class_static_side_1: diag(2417, ts.DiagnosticCategory.Error, "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417", "Class static side '{0}' incorrectly extends base class static side '{1}'."),
        Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1: diag(2418, ts.DiagnosticCategory.Error, "Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1_2418", "Type of computed property's value is '{0}', which is not assignable to type '{1}'."),
        Class_0_incorrectly_implements_interface_1: diag(2420, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_interface_1_2420", "Class '{0}' incorrectly implements interface '{1}'."),
        A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2422, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_memb_2422", "A class can only implement an object type or intersection of object types with statically known members."),
        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: diag(2423, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor."),
        Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2425, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425", "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function."),
        Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2426, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426", "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function."),
        Interface_name_cannot_be_0: diag(2427, ts.DiagnosticCategory.Error, "Interface_name_cannot_be_0_2427", "Interface name cannot be '{0}'."),
        All_declarations_of_0_must_have_identical_type_parameters: diag(2428, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_type_parameters_2428", "All declarations of '{0}' must have identical type parameters."),
        Interface_0_incorrectly_extends_interface_1: diag(2430, ts.DiagnosticCategory.Error, "Interface_0_incorrectly_extends_interface_1_2430", "Interface '{0}' incorrectly extends interface '{1}'."),
        Enum_name_cannot_be_0: diag(2431, ts.DiagnosticCategory.Error, "Enum_name_cannot_be_0_2431", "Enum name cannot be '{0}'."),
        In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: diag(2432, ts.DiagnosticCategory.Error, "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432", "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element."),
        A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged: diag(2433, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433", "A namespace declaration cannot be in a different file from a class or function with which it is merged."),
        A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged: diag(2434, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434", "A namespace declaration cannot be located prior to a class or function with which it is merged."),
        Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces: diag(2435, ts.DiagnosticCategory.Error, "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435", "Ambient modules cannot be nested in other modules or namespaces."),
        Ambient_module_declaration_cannot_specify_relative_module_name: diag(2436, ts.DiagnosticCategory.Error, "Ambient_module_declaration_cannot_specify_relative_module_name_2436", "Ambient module declaration cannot specify relative module name."),
        Module_0_is_hidden_by_a_local_declaration_with_the_same_name: diag(2437, ts.DiagnosticCategory.Error, "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437", "Module '{0}' is hidden by a local declaration with the same name."),
        Import_name_cannot_be_0: diag(2438, ts.DiagnosticCategory.Error, "Import_name_cannot_be_0_2438", "Import name cannot be '{0}'."),
        Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name: diag(2439, ts.DiagnosticCategory.Error, "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439", "Import or export declaration in an ambient module declaration cannot reference module through relative module name."),
        Import_declaration_conflicts_with_local_declaration_of_0: diag(2440, ts.DiagnosticCategory.Error, "Import_declaration_conflicts_with_local_declaration_of_0_2440", "Import declaration conflicts with local declaration of '{0}'."),
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module: diag(2441, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module."),
        Types_have_separate_declarations_of_a_private_property_0: diag(2442, ts.DiagnosticCategory.Error, "Types_have_separate_declarations_of_a_private_property_0_2442", "Types have separate declarations of a private property '{0}'."),
        Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: diag(2443, ts.DiagnosticCategory.Error, "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443", "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'."),
        Property_0_is_protected_in_type_1_but_public_in_type_2: diag(2444, ts.DiagnosticCategory.Error, "Property_0_is_protected_in_type_1_but_public_in_type_2_2444", "Property '{0}' is protected in type '{1}' but public in type '{2}'."),
        Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: diag(2445, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445", "Property '{0}' is protected and only accessible within class '{1}' and its subclasses."),
        Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: diag(2446, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_2446", "Property '{0}' is protected and only accessible through an instance of class '{1}'."),
        The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: diag(2447, ts.DiagnosticCategory.Error, "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447", "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead."),
        Block_scoped_variable_0_used_before_its_declaration: diag(2448, ts.DiagnosticCategory.Error, "Block_scoped_variable_0_used_before_its_declaration_2448", "Block-scoped variable '{0}' used before its declaration."),
        Class_0_used_before_its_declaration: diag(2449, ts.DiagnosticCategory.Error, "Class_0_used_before_its_declaration_2449", "Class '{0}' used before its declaration."),
        Enum_0_used_before_its_declaration: diag(2450, ts.DiagnosticCategory.Error, "Enum_0_used_before_its_declaration_2450", "Enum '{0}' used before its declaration."),
        Cannot_redeclare_block_scoped_variable_0: diag(2451, ts.DiagnosticCategory.Error, "Cannot_redeclare_block_scoped_variable_0_2451", "Cannot redeclare block-scoped variable '{0}'."),
        An_enum_member_cannot_have_a_numeric_name: diag(2452, ts.DiagnosticCategory.Error, "An_enum_member_cannot_have_a_numeric_name_2452", "An enum member cannot have a numeric name."),
        The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly: diag(2453, ts.DiagnosticCategory.Error, "The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_typ_2453", "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly."),
        Variable_0_is_used_before_being_assigned: diag(2454, ts.DiagnosticCategory.Error, "Variable_0_is_used_before_being_assigned_2454", "Variable '{0}' is used before being assigned."),
        Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: diag(2455, ts.DiagnosticCategory.Error, "Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0_2455", "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'."),
        Type_alias_0_circularly_references_itself: diag(2456, ts.DiagnosticCategory.Error, "Type_alias_0_circularly_references_itself_2456", "Type alias '{0}' circularly references itself."),
        Type_alias_name_cannot_be_0: diag(2457, ts.DiagnosticCategory.Error, "Type_alias_name_cannot_be_0_2457", "Type alias name cannot be '{0}'."),
        An_AMD_module_cannot_have_multiple_name_assignments: diag(2458, ts.DiagnosticCategory.Error, "An_AMD_module_cannot_have_multiple_name_assignments_2458", "An AMD module cannot have multiple name assignments."),
        Module_0_declares_1_locally_but_it_is_not_exported: diag(2459, ts.DiagnosticCategory.Error, "Module_0_declares_1_locally_but_it_is_not_exported_2459", "Module '{0}' declares '{1}' locally, but it is not exported."),
        Module_0_declares_1_locally_but_it_is_exported_as_2: diag(2460, ts.DiagnosticCategory.Error, "Module_0_declares_1_locally_but_it_is_exported_as_2_2460", "Module '{0}' declares '{1}' locally, but it is exported as '{2}'."),
        Type_0_is_not_an_array_type: diag(2461, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_2461", "Type '{0}' is not an array type."),
        A_rest_element_must_be_last_in_a_destructuring_pattern: diag(2462, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_destructuring_pattern_2462", "A rest element must be last in a destructuring pattern."),
        A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: diag(2463, ts.DiagnosticCategory.Error, "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463", "A binding pattern parameter cannot be optional in an implementation signature."),
        A_computed_property_name_must_be_of_type_string_number_symbol_or_any: diag(2464, ts.DiagnosticCategory.Error, "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464", "A computed property name must be of type 'string', 'number', 'symbol', or 'any'."),
        this_cannot_be_referenced_in_a_computed_property_name: diag(2465, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_computed_property_name_2465", "'this' cannot be referenced in a computed property name."),
        super_cannot_be_referenced_in_a_computed_property_name: diag(2466, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_a_computed_property_name_2466", "'super' cannot be referenced in a computed property name."),
        A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: diag(2467, ts.DiagnosticCategory.Error, "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467", "A computed property name cannot reference a type parameter from its containing type."),
        Cannot_find_global_value_0: diag(2468, ts.DiagnosticCategory.Error, "Cannot_find_global_value_0_2468", "Cannot find global value '{0}'."),
        The_0_operator_cannot_be_applied_to_type_symbol: diag(2469, ts.DiagnosticCategory.Error, "The_0_operator_cannot_be_applied_to_type_symbol_2469", "The '{0}' operator cannot be applied to type 'symbol'."),
        Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: diag(2470, ts.DiagnosticCategory.Error, "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470", "'Symbol' reference does not refer to the global Symbol constructor object."),
        A_computed_property_name_of_the_form_0_must_be_of_type_symbol: diag(2471, ts.DiagnosticCategory.Error, "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471", "A computed property name of the form '{0}' must be of type 'symbol'."),
        Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: diag(2472, ts.DiagnosticCategory.Error, "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472", "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher."),
        Enum_declarations_must_all_be_const_or_non_const: diag(2473, ts.DiagnosticCategory.Error, "Enum_declarations_must_all_be_const_or_non_const_2473", "Enum declarations must all be const or non-const."),
        const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values: diag(2474, ts.DiagnosticCategory.Error, "const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values_2474", "const enum member initializers can only contain literal values and other computed enum values."),
        const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query: diag(2475, ts.DiagnosticCategory.Error, "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475", "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query."),
        A_const_enum_member_can_only_be_accessed_using_a_string_literal: diag(2476, ts.DiagnosticCategory.Error, "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", "A const enum member can only be accessed using a string literal."),
        const_enum_member_initializer_was_evaluated_to_a_non_finite_value: diag(2477, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", "'const' enum member initializer was evaluated to a non-finite value."),
        const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: diag(2478, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", "'const' enum member initializer was evaluated to disallowed value 'NaN'."),
        Property_0_does_not_exist_on_const_enum_1: diag(2479, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_const_enum_1_2479", "Property '{0}' does not exist on 'const' enum '{1}'."),
        let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: diag(2480, ts.DiagnosticCategory.Error, "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", "'let' is not allowed to be used as a name in 'let' or 'const' declarations."),
        Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: diag(2481, ts.DiagnosticCategory.Error, "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481", "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'."),
        The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: diag(2483, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", "The left-hand side of a 'for...of' statement cannot use a type annotation."),
        Export_declaration_conflicts_with_exported_declaration_of_0: diag(2484, ts.DiagnosticCategory.Error, "Export_declaration_conflicts_with_exported_declaration_of_0_2484", "Export declaration conflicts with exported declaration of '{0}'."),
        The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access: diag(2487, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access_2487", "The left-hand side of a 'for...of' statement must be a variable or a property access."),
        Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2488, ts.DiagnosticCategory.Error, "Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator."),
        An_iterator_must_have_a_next_method: diag(2489, ts.DiagnosticCategory.Error, "An_iterator_must_have_a_next_method_2489", "An iterator must have a 'next()' method."),
        The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property: diag(2490, ts.DiagnosticCategory.Error, "The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property_2490", "The type returned by the '{0}()' method of an iterator must have a 'value' property."),
        The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern: diag(2491, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491", "The left-hand side of a 'for...in' statement cannot be a destructuring pattern."),
        Cannot_redeclare_identifier_0_in_catch_clause: diag(2492, ts.DiagnosticCategory.Error, "Cannot_redeclare_identifier_0_in_catch_clause_2492", "Cannot redeclare identifier '{0}' in catch clause."),
        Tuple_type_0_of_length_1_has_no_element_at_index_2: diag(2493, ts.DiagnosticCategory.Error, "Tuple_type_0_of_length_1_has_no_element_at_index_2_2493", "Tuple type '{0}' of length '{1}' has no element at index '{2}'."),
        Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher: diag(2494, ts.DiagnosticCategory.Error, "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494", "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher."),
        Type_0_is_not_an_array_type_or_a_string_type: diag(2495, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_2495", "Type '{0}' is not an array type or a string type."),
        The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression: diag(2496, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_stand_2496", "The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. Consider using a standard function expression."),
        This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export: diag(2497, ts.DiagnosticCategory.Error, "This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_2497", "This module can only be referenced with ECMAScript imports/exports by turning on the '{0}' flag and referencing its default export."),
        Module_0_uses_export_and_cannot_be_used_with_export_Asterisk: diag(2498, ts.DiagnosticCategory.Error, "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498", "Module '{0}' uses 'export =' and cannot be used with 'export *'."),
        An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2499, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499", "An interface can only extend an identifier/qualified-name with optional type arguments."),
        A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2500, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500", "A class can only implement an identifier/qualified-name with optional type arguments."),
        A_rest_element_cannot_contain_a_binding_pattern: diag(2501, ts.DiagnosticCategory.Error, "A_rest_element_cannot_contain_a_binding_pattern_2501", "A rest element cannot contain a binding pattern."),
        _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: diag(2502, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502", "'{0}' is referenced directly or indirectly in its own type annotation."),
        Cannot_find_namespace_0: diag(2503, ts.DiagnosticCategory.Error, "Cannot_find_namespace_0_2503", "Cannot find namespace '{0}'."),
        Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator: diag(2504, ts.DiagnosticCategory.Error, "Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_2504", "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator."),
        A_generator_cannot_have_a_void_type_annotation: diag(2505, ts.DiagnosticCategory.Error, "A_generator_cannot_have_a_void_type_annotation_2505", "A generator cannot have a 'void' type annotation."),
        _0_is_referenced_directly_or_indirectly_in_its_own_base_expression: diag(2506, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506", "'{0}' is referenced directly or indirectly in its own base expression."),
        Type_0_is_not_a_constructor_function_type: diag(2507, ts.DiagnosticCategory.Error, "Type_0_is_not_a_constructor_function_type_2507", "Type '{0}' is not a constructor function type."),
        No_base_constructor_has_the_specified_number_of_type_arguments: diag(2508, ts.DiagnosticCategory.Error, "No_base_constructor_has_the_specified_number_of_type_arguments_2508", "No base constructor has the specified number of type arguments."),
        Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2509, ts.DiagnosticCategory.Error, "Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_2509", "Base constructor return type '{0}' is not an object type or intersection of object types with statically known members."),
        Base_constructors_must_all_have_the_same_return_type: diag(2510, ts.DiagnosticCategory.Error, "Base_constructors_must_all_have_the_same_return_type_2510", "Base constructors must all have the same return type."),
        Cannot_create_an_instance_of_an_abstract_class: diag(2511, ts.DiagnosticCategory.Error, "Cannot_create_an_instance_of_an_abstract_class_2511", "Cannot create an instance of an abstract class."),
        Overload_signatures_must_all_be_abstract_or_non_abstract: diag(2512, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_abstract_or_non_abstract_2512", "Overload signatures must all be abstract or non-abstract."),
        Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: diag(2513, ts.DiagnosticCategory.Error, "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513", "Abstract method '{0}' in class '{1}' cannot be accessed via super expression."),
        Classes_containing_abstract_methods_must_be_marked_abstract: diag(2514, ts.DiagnosticCategory.Error, "Classes_containing_abstract_methods_must_be_marked_abstract_2514", "Classes containing abstract methods must be marked abstract."),
        Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: diag(2515, ts.DiagnosticCategory.Error, "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515", "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'."),
        All_declarations_of_an_abstract_method_must_be_consecutive: diag(2516, ts.DiagnosticCategory.Error, "All_declarations_of_an_abstract_method_must_be_consecutive_2516", "All declarations of an abstract method must be consecutive."),
        Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: diag(2517, ts.DiagnosticCategory.Error, "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517", "Cannot assign an abstract constructor type to a non-abstract constructor type."),
        A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard: diag(2518, ts.DiagnosticCategory.Error, "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518", "A 'this'-based type guard is not compatible with a parameter-based type guard."),
        An_async_iterator_must_have_a_next_method: diag(2519, ts.DiagnosticCategory.Error, "An_async_iterator_must_have_a_next_method_2519", "An async iterator must have a 'next()' method."),
        Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: diag(2520, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520", "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions."),
        Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: diag(2521, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521", "Expression resolves to variable declaration '{0}' that compiler uses to support async functions."),
        The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method: diag(2522, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_usi_2522", "The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method."),
        yield_expressions_cannot_be_used_in_a_parameter_initializer: diag(2523, ts.DiagnosticCategory.Error, "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523", "'yield' expressions cannot be used in a parameter initializer."),
        await_expressions_cannot_be_used_in_a_parameter_initializer: diag(2524, ts.DiagnosticCategory.Error, "await_expressions_cannot_be_used_in_a_parameter_initializer_2524", "'await' expressions cannot be used in a parameter initializer."),
        Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value: diag(2525, ts.DiagnosticCategory.Error, "Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value_2525", "Initializer provides no value for this binding element and the binding element has no default value."),
        A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface: diag(2526, ts.DiagnosticCategory.Error, "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526", "A 'this' type is available only in a non-static member of a class or interface."),
        The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary: diag(2527, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527", "The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary."),
        A_module_cannot_have_multiple_default_exports: diag(2528, ts.DiagnosticCategory.Error, "A_module_cannot_have_multiple_default_exports_2528", "A module cannot have multiple default exports."),
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions: diag(2529, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions."),
        Property_0_is_incompatible_with_index_signature: diag(2530, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_index_signature_2530", "Property '{0}' is incompatible with index signature."),
        Object_is_possibly_null: diag(2531, ts.DiagnosticCategory.Error, "Object_is_possibly_null_2531", "Object is possibly 'null'."),
        Object_is_possibly_undefined: diag(2532, ts.DiagnosticCategory.Error, "Object_is_possibly_undefined_2532", "Object is possibly 'undefined'."),
        Object_is_possibly_null_or_undefined: diag(2533, ts.DiagnosticCategory.Error, "Object_is_possibly_null_or_undefined_2533", "Object is possibly 'null' or 'undefined'."),
        A_function_returning_never_cannot_have_a_reachable_end_point: diag(2534, ts.DiagnosticCategory.Error, "A_function_returning_never_cannot_have_a_reachable_end_point_2534", "A function returning 'never' cannot have a reachable end point."),
        Enum_type_0_has_members_with_initializers_that_are_not_literals: diag(2535, ts.DiagnosticCategory.Error, "Enum_type_0_has_members_with_initializers_that_are_not_literals_2535", "Enum type '{0}' has members with initializers that are not literals."),
        Type_0_cannot_be_used_to_index_type_1: diag(2536, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_to_index_type_1_2536", "Type '{0}' cannot be used to index type '{1}'."),
        Type_0_has_no_matching_index_signature_for_type_1: diag(2537, ts.DiagnosticCategory.Error, "Type_0_has_no_matching_index_signature_for_type_1_2537", "Type '{0}' has no matching index signature for type '{1}'."),
        Type_0_cannot_be_used_as_an_index_type: diag(2538, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_as_an_index_type_2538", "Type '{0}' cannot be used as an index type."),
        Cannot_assign_to_0_because_it_is_not_a_variable: diag(2539, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_not_a_variable_2539", "Cannot assign to '{0}' because it is not a variable."),
        Cannot_assign_to_0_because_it_is_a_read_only_property: diag(2540, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_read_only_property_2540", "Cannot assign to '{0}' because it is a read-only property."),
        The_target_of_an_assignment_must_be_a_variable_or_a_property_access: diag(2541, ts.DiagnosticCategory.Error, "The_target_of_an_assignment_must_be_a_variable_or_a_property_access_2541", "The target of an assignment must be a variable or a property access."),
        Index_signature_in_type_0_only_permits_reading: diag(2542, ts.DiagnosticCategory.Error, "Index_signature_in_type_0_only_permits_reading_2542", "Index signature in type '{0}' only permits reading."),
        Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference: diag(2543, ts.DiagnosticCategory.Error, "Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_me_2543", "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference."),
        Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference: diag(2544, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544", "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference."),
        A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any: diag(2545, ts.DiagnosticCategory.Error, "A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any_2545", "A mixin class must have a constructor with a single rest parameter of type 'any[]'."),
        The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property: diag(2547, ts.DiagnosticCategory.Error, "The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_pro_2547", "The type returned by the '{0}()' method of an async iterator must be a promise for a type with a 'value' property."),
        Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2548, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_2548", "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
        Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2549, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549", "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
        Property_0_does_not_exist_on_type_1_Did_you_mean_2: diag(2551, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_Did_you_mean_2_2551", "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?"),
        Cannot_find_name_0_Did_you_mean_1: diag(2552, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_1_2552", "Cannot find name '{0}'. Did you mean '{1}'?"),
        Computed_values_are_not_permitted_in_an_enum_with_string_valued_members: diag(2553, ts.DiagnosticCategory.Error, "Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553", "Computed values are not permitted in an enum with string valued members."),
        Expected_0_arguments_but_got_1: diag(2554, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_2554", "Expected {0} arguments, but got {1}."),
        Expected_at_least_0_arguments_but_got_1: diag(2555, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_2555", "Expected at least {0} arguments, but got {1}."),
        Expected_0_arguments_but_got_1_or_more: diag(2556, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_or_more_2556", "Expected {0} arguments, but got {1} or more."),
        Expected_at_least_0_arguments_but_got_1_or_more: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_or_more_2557", "Expected at least {0} arguments, but got {1} or more."),
        Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."),
        Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."),
        Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"),
        Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2: diag(2561, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_writ_2561", "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?"),
        Base_class_expressions_cannot_reference_class_type_parameters: diag(2562, ts.DiagnosticCategory.Error, "Base_class_expressions_cannot_reference_class_type_parameters_2562", "Base class expressions cannot reference class type parameters."),
        The_containing_function_or_module_body_is_too_large_for_control_flow_analysis: diag(2563, ts.DiagnosticCategory.Error, "The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563", "The containing function or module body is too large for control flow analysis."),
        Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor: diag(2564, ts.DiagnosticCategory.Error, "Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor_2564", "Property '{0}' has no initializer and is not definitely assigned in the constructor."),
        Property_0_is_used_before_being_assigned: diag(2565, ts.DiagnosticCategory.Error, "Property_0_is_used_before_being_assigned_2565", "Property '{0}' is used before being assigned."),
        A_rest_element_cannot_have_a_property_name: diag(2566, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_a_property_name_2566", "A rest element cannot have a property name."),
        Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations: diag(2567, ts.DiagnosticCategory.Error, "Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567", "Enum declarations can only merge with namespace or other enum declarations."),
        Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators: diag(2569, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569", "Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators."),
        Object_is_of_type_unknown: diag(2571, ts.DiagnosticCategory.Error, "Object_is_of_type_unknown_2571", "Object is of type 'unknown'."),
        Rest_signatures_are_incompatible: diag(2572, ts.DiagnosticCategory.Error, "Rest_signatures_are_incompatible_2572", "Rest signatures are incompatible."),
        Property_0_is_incompatible_with_rest_element_type: diag(2573, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_rest_element_type_2573", "Property '{0}' is incompatible with rest element type."),
        A_rest_element_type_must_be_an_array_type: diag(2574, ts.DiagnosticCategory.Error, "A_rest_element_type_must_be_an_array_type_2574", "A rest element type must be an array type."),
        No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments: diag(2575, ts.DiagnosticCategory.Error, "No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments_2575", "No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments."),
        Property_0_is_a_static_member_of_type_1: diag(2576, ts.DiagnosticCategory.Error, "Property_0_is_a_static_member_of_type_1_2576", "Property '{0}' is a static member of type '{1}'"),
        Return_type_annotation_circularly_references_itself: diag(2577, ts.DiagnosticCategory.Error, "Return_type_annotation_circularly_references_itself_2577", "Return type annotation circularly references itself."),
        Unused_ts_expect_error_directive: diag(2578, ts.DiagnosticCategory.Error, "Unused_ts_expect_error_directive_2578", "Unused '@ts-expect-error' directive."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode: diag(2580, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_2580", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node`."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery: diag(2581, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_2581", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery`."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha: diag(2582, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashje_2582", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha`."),
        Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later: diag(2583, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2583", "Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later."),
        Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom: diag(2584, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2584", "Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later: diag(2585, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_2585", "'{0}' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later."),
        Enum_type_0_circularly_references_itself: diag(2586, ts.DiagnosticCategory.Error, "Enum_type_0_circularly_references_itself_2586", "Enum type '{0}' circularly references itself."),
        JSDoc_type_0_circularly_references_itself: diag(2587, ts.DiagnosticCategory.Error, "JSDoc_type_0_circularly_references_itself_2587", "JSDoc type '{0}' circularly references itself."),
        Cannot_assign_to_0_because_it_is_a_constant: diag(2588, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_constant_2588", "Cannot assign to '{0}' because it is a constant."),
        Type_instantiation_is_excessively_deep_and_possibly_infinite: diag(2589, ts.DiagnosticCategory.Error, "Type_instantiation_is_excessively_deep_and_possibly_infinite_2589", "Type instantiation is excessively deep and possibly infinite."),
        Expression_produces_a_union_type_that_is_too_complex_to_represent: diag(2590, ts.DiagnosticCategory.Error, "Expression_produces_a_union_type_that_is_too_complex_to_represent_2590", "Expression produces a union type that is too complex to represent."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_th_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_an_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery` and then add `jquery` to the types field in your tsconfig."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashje_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig."),
        This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."),
        _0_can_only_be_imported_by_using_a_default_import: diag(2595, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_default_import_2595", "'{0}' can only be imported by using a default import."),
        _0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2596, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."),
        _0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import: diag(2597, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", "'{0}' can only be imported by using a 'require' call or by using a default import."),
        _0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2598, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using__2598", "'{0}' can only be imported by using a 'require' call or by turning on the 'esModuleInterop' flag and using a default import."),
        JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."),
        The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."),
        JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."),
        Property_0_in_type_1_is_not_assignable_to_type_2: diag(2603, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_type_2_2603", "Property '{0}' in type '{1}' is not assignable to type '{2}'."),
        JSX_element_type_0_does_not_have_any_construct_or_call_signatures: diag(2604, ts.DiagnosticCategory.Error, "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604", "JSX element type '{0}' does not have any construct or call signatures."),
        JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements: diag(2605, ts.DiagnosticCategory.Error, "JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements_2605", "JSX element type '{0}' is not a constructor function for JSX elements."),
        Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property: diag(2606, ts.DiagnosticCategory.Error, "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606", "Property '{0}' of JSX spread attribute is not assignable to target property."),
        JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: diag(2607, ts.DiagnosticCategory.Error, "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607", "JSX element class does not support attributes because it does not have a '{0}' property."),
        The_global_type_JSX_0_may_not_have_more_than_one_property: diag(2608, ts.DiagnosticCategory.Error, "The_global_type_JSX_0_may_not_have_more_than_one_property_2608", "The global type 'JSX.{0}' may not have more than one property."),
        JSX_spread_child_must_be_an_array_type: diag(2609, ts.DiagnosticCategory.Error, "JSX_spread_child_must_be_an_array_type_2609", "JSX spread child must be an array type."),
        _0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property: diag(2610, ts.DiagnosticCategory.Error, "_0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property_2610", "'{0}' is defined as an accessor in class '{1}', but is overridden here in '{2}' as an instance property."),
        _0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor: diag(2611, ts.DiagnosticCategory.Error, "_0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor_2611", "'{0}' is defined as a property in class '{1}', but is overridden here in '{2}' as an accessor."),
        Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration: diag(2612, ts.DiagnosticCategory.Error, "Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_2612", "Property '{0}' will overwrite the base property in '{1}'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration."),
        Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead: diag(2613, ts.DiagnosticCategory.Error, "Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead_2613", "Module '{0}' has no default export. Did you mean to use 'import { {1} } from {0}' instead?"),
        Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead: diag(2614, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead_2614", "Module '{0}' has no exported member '{1}'. Did you mean to use 'import {1} from {0}' instead?"),
        Type_of_property_0_circularly_references_itself_in_mapped_type_1: diag(2615, ts.DiagnosticCategory.Error, "Type_of_property_0_circularly_references_itself_in_mapped_type_1_2615", "Type of property '{0}' circularly references itself in mapped type '{1}'."),
        _0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import: diag(2616, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import_2616", "'{0}' can only be imported by using 'import {1} = require({2})' or a default import."),
        _0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2617, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_us_2617", "'{0}' can only be imported by using 'import {1} = require({2})' or by turning on the 'esModuleInterop' flag and using a default import."),
        Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity: diag(2649, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity_2649", "Cannot augment module '{0}' with value exports because it resolves to a non-module entity."),
        A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: diag(2651, ts.DiagnosticCategory.Error, "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651", "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums."),
        Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: diag(2652, ts.DiagnosticCategory.Error, "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652", "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead."),
        Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1: diag(2653, ts.DiagnosticCategory.Error, "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653", "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'."),
        Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition: diag(2654, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654", "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition."),
        Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition: diag(2656, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656", "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition."),
        JSX_expressions_must_have_one_parent_element: diag(2657, ts.DiagnosticCategory.Error, "JSX_expressions_must_have_one_parent_element_2657", "JSX expressions must have one parent element."),
        Type_0_provides_no_match_for_the_signature_1: diag(2658, ts.DiagnosticCategory.Error, "Type_0_provides_no_match_for_the_signature_1_2658", "Type '{0}' provides no match for the signature '{1}'."),
        super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher: diag(2659, ts.DiagnosticCategory.Error, "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659", "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher."),
        super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions: diag(2660, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660", "'super' can only be referenced in members of derived classes or object literal expressions."),
        Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module: diag(2661, ts.DiagnosticCategory.Error, "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661", "Cannot export '{0}'. Only local declarations can be exported from a module."),
        Cannot_find_name_0_Did_you_mean_the_static_member_1_0: diag(2662, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662", "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?"),
        Cannot_find_name_0_Did_you_mean_the_instance_member_this_0: diag(2663, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663", "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?"),
        Invalid_module_name_in_augmentation_module_0_cannot_be_found: diag(2664, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664", "Invalid module name in augmentation, module '{0}' cannot be found."),
        Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented: diag(2665, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augm_2665", "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented."),
        Exports_and_export_assignments_are_not_permitted_in_module_augmentations: diag(2666, ts.DiagnosticCategory.Error, "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666", "Exports and export assignments are not permitted in module augmentations."),
        Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module: diag(2667, ts.DiagnosticCategory.Error, "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667", "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module."),
        export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible: diag(2668, ts.DiagnosticCategory.Error, "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668", "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible."),
        Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations: diag(2669, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669", "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."),
        Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context: diag(2670, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670", "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context."),
        Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity: diag(2671, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671", "Cannot augment module '{0}' because it resolves to a non-module entity."),
        Cannot_assign_a_0_constructor_type_to_a_1_constructor_type: diag(2672, ts.DiagnosticCategory.Error, "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672", "Cannot assign a '{0}' constructor type to a '{1}' constructor type."),
        Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration: diag(2673, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673", "Constructor of class '{0}' is private and only accessible within the class declaration."),
        Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration: diag(2674, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674", "Constructor of class '{0}' is protected and only accessible within the class declaration."),
        Cannot_extend_a_class_0_Class_constructor_is_marked_as_private: diag(2675, ts.DiagnosticCategory.Error, "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675", "Cannot extend a class '{0}'. Class constructor is marked as private."),
        Accessors_must_both_be_abstract_or_non_abstract: diag(2676, ts.DiagnosticCategory.Error, "Accessors_must_both_be_abstract_or_non_abstract_2676", "Accessors must both be abstract or non-abstract."),
        A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type: diag(2677, ts.DiagnosticCategory.Error, "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677", "A type predicate's type must be assignable to its parameter's type."),
        Type_0_is_not_comparable_to_type_1: diag(2678, ts.DiagnosticCategory.Error, "Type_0_is_not_comparable_to_type_1_2678", "Type '{0}' is not comparable to type '{1}'."),
        A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void: diag(2679, ts.DiagnosticCategory.Error, "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679", "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'."),
        A_0_parameter_must_be_the_first_parameter: diag(2680, ts.DiagnosticCategory.Error, "A_0_parameter_must_be_the_first_parameter_2680", "A '{0}' parameter must be the first parameter."),
        A_constructor_cannot_have_a_this_parameter: diag(2681, ts.DiagnosticCategory.Error, "A_constructor_cannot_have_a_this_parameter_2681", "A constructor cannot have a 'this' parameter."),
        get_and_set_accessor_must_have_the_same_this_type: diag(2682, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_this_type_2682", "'get' and 'set' accessor must have the same 'this' type."),
        this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: diag(2683, ts.DiagnosticCategory.Error, "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", "'this' implicitly has type 'any' because it does not have a type annotation."),
        The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: diag(2684, ts.DiagnosticCategory.Error, "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'."),
        The_this_types_of_each_signature_are_incompatible: diag(2685, ts.DiagnosticCategory.Error, "The_this_types_of_each_signature_are_incompatible_2685", "The 'this' types of each signature are incompatible."),
        _0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead: diag(2686, ts.DiagnosticCategory.Error, "_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686", "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead."),
        All_declarations_of_0_must_have_identical_modifiers: diag(2687, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_modifiers_2687", "All declarations of '{0}' must have identical modifiers."),
        Cannot_find_type_definition_file_for_0: diag(2688, ts.DiagnosticCategory.Error, "Cannot_find_type_definition_file_for_0_2688", "Cannot find type definition file for '{0}'."),
        Cannot_extend_an_interface_0_Did_you_mean_implements: diag(2689, ts.DiagnosticCategory.Error, "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", "Cannot extend an interface '{0}'. Did you mean 'implements'?"),
        An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: diag(2691, ts.DiagnosticCategory.Error, "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead."),
        _0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible: diag(2692, ts.DiagnosticCategory.Error, "_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible_2692", "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_value_here: diag(2693, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_2693", "'{0}' only refers to a type, but is being used as a value here."),
        Namespace_0_has_no_exported_member_1: diag(2694, ts.DiagnosticCategory.Error, "Namespace_0_has_no_exported_member_1_2694", "Namespace '{0}' has no exported member '{1}'."),
        Left_side_of_comma_operator_is_unused_and_has_no_side_effects: diag(2695, ts.DiagnosticCategory.Error, "Left_side_of_comma_operator_is_unused_and_has_no_side_effects_2695", "Left side of comma operator is unused and has no side effects.", /*reportsUnnecessary*/ true),
        The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead: diag(2696, ts.DiagnosticCategory.Error, "The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead_2696", "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?"),
        An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2697, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_in_2697", "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
        Spread_types_may_only_be_created_from_object_types: diag(2698, ts.DiagnosticCategory.Error, "Spread_types_may_only_be_created_from_object_types_2698", "Spread types may only be created from object types."),
        Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1: diag(2699, ts.DiagnosticCategory.Error, "Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1_2699", "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'."),
        Rest_types_may_only_be_created_from_object_types: diag(2700, ts.DiagnosticCategory.Error, "Rest_types_may_only_be_created_from_object_types_2700", "Rest types may only be created from object types."),
        The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access: diag(2701, ts.DiagnosticCategory.Error, "The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access_2701", "The target of an object rest assignment must be a variable or a property access."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here: diag(2702, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here_2702", "'{0}' only refers to a type, but is being used as a namespace here."),
        The_operand_of_a_delete_operator_must_be_a_property_reference: diag(2703, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_must_be_a_property_reference_2703", "The operand of a 'delete' operator must be a property reference."),
        The_operand_of_a_delete_operator_cannot_be_a_read_only_property: diag(2704, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_read_only_property_2704", "The operand of a 'delete' operator cannot be a read-only property."),
        An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2705, ts.DiagnosticCategory.Error, "An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_de_2705", "An async function or method in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
        Required_type_parameters_may_not_follow_optional_type_parameters: diag(2706, ts.DiagnosticCategory.Error, "Required_type_parameters_may_not_follow_optional_type_parameters_2706", "Required type parameters may not follow optional type parameters."),
        Generic_type_0_requires_between_1_and_2_type_arguments: diag(2707, ts.DiagnosticCategory.Error, "Generic_type_0_requires_between_1_and_2_type_arguments_2707", "Generic type '{0}' requires between {1} and {2} type arguments."),
        Cannot_use_namespace_0_as_a_value: diag(2708, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_value_2708", "Cannot use namespace '{0}' as a value."),
        Cannot_use_namespace_0_as_a_type: diag(2709, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_type_2709", "Cannot use namespace '{0}' as a type."),
        _0_are_specified_twice_The_attribute_named_0_will_be_overwritten: diag(2710, ts.DiagnosticCategory.Error, "_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710", "'{0}' are specified twice. The attribute named '{0}' will be overwritten."),
        A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2711, ts.DiagnosticCategory.Error, "A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES20_2711", "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
        A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2712, ts.DiagnosticCategory.Error, "A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declarat_2712", "A dynamic import call in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
        Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1: diag(2713, ts.DiagnosticCategory.Error, "Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_p_2713", "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?"),
        The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context: diag(2714, ts.DiagnosticCategory.Error, "The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context_2714", "The expression of an export assignment must be an identifier or qualified name in an ambient context."),
        Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor: diag(2715, ts.DiagnosticCategory.Error, "Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715", "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor."),
        Type_parameter_0_has_a_circular_default: diag(2716, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_default_2716", "Type parameter '{0}' has a circular default."),
        Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2: diag(2717, ts.DiagnosticCategory.Error, "Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_t_2717", "Subsequent property declarations must have the same type.  Property '{0}' must be of type '{1}', but here has type '{2}'."),
        Duplicate_property_0: diag(2718, ts.DiagnosticCategory.Error, "Duplicate_property_0_2718", "Duplicate property '{0}'."),
        Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated: diag(2719, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_2719", "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated."),
        Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass: diag(2720, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclas_2720", "Class '{0}' incorrectly implements class '{1}'. Did you mean to extend '{1}' and inherit its members as a subclass?"),
        Cannot_invoke_an_object_which_is_possibly_null: diag(2721, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_null_2721", "Cannot invoke an object which is possibly 'null'."),
        Cannot_invoke_an_object_which_is_possibly_undefined: diag(2722, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_undefined_2722", "Cannot invoke an object which is possibly 'undefined'."),
        Cannot_invoke_an_object_which_is_possibly_null_or_undefined: diag(2723, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_null_or_undefined_2723", "Cannot invoke an object which is possibly 'null' or 'undefined'."),
        Module_0_has_no_exported_member_1_Did_you_mean_2: diag(2724, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_Did_you_mean_2_2724", "Module '{0}' has no exported member '{1}'. Did you mean '{2}'?"),
        Class_name_cannot_be_Object_when_targeting_ES5_with_module_0: diag(2725, ts.DiagnosticCategory.Error, "Class_name_cannot_be_Object_when_targeting_ES5_with_module_0_2725", "Class name cannot be 'Object' when targeting ES5 with module {0}."),
        Cannot_find_lib_definition_for_0: diag(2726, ts.DiagnosticCategory.Error, "Cannot_find_lib_definition_for_0_2726", "Cannot find lib definition for '{0}'."),
        Cannot_find_lib_definition_for_0_Did_you_mean_1: diag(2727, ts.DiagnosticCategory.Error, "Cannot_find_lib_definition_for_0_Did_you_mean_1_2727", "Cannot find lib definition for '{0}'. Did you mean '{1}'?"),
        _0_is_declared_here: diag(2728, ts.DiagnosticCategory.Message, "_0_is_declared_here_2728", "'{0}' is declared here."),
        Property_0_is_used_before_its_initialization: diag(2729, ts.DiagnosticCategory.Error, "Property_0_is_used_before_its_initialization_2729", "Property '{0}' is used before its initialization."),
        An_arrow_function_cannot_have_a_this_parameter: diag(2730, ts.DiagnosticCategory.Error, "An_arrow_function_cannot_have_a_this_parameter_2730", "An arrow function cannot have a 'this' parameter."),
        Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String: diag(2731, ts.DiagnosticCategory.Error, "Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_i_2731", "Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'."),
        Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension: diag(2732, ts.DiagnosticCategory.Error, "Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension_2732", "Cannot find module '{0}'. Consider using '--resolveJsonModule' to import module with '.json' extension"),
        Property_0_was_also_declared_here: diag(2733, ts.DiagnosticCategory.Error, "Property_0_was_also_declared_here_2733", "Property '{0}' was also declared here."),
        Are_you_missing_a_semicolon: diag(2734, ts.DiagnosticCategory.Error, "Are_you_missing_a_semicolon_2734", "Are you missing a semicolon?"),
        Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1: diag(2735, ts.DiagnosticCategory.Error, "Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1_2735", "Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?"),
        Operator_0_cannot_be_applied_to_type_1: diag(2736, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_type_1_2736", "Operator '{0}' cannot be applied to type '{1}'."),
        BigInt_literals_are_not_available_when_targeting_lower_than_ES2020: diag(2737, ts.DiagnosticCategory.Error, "BigInt_literals_are_not_available_when_targeting_lower_than_ES2020_2737", "BigInt literals are not available when targeting lower than ES2020."),
        An_outer_value_of_this_is_shadowed_by_this_container: diag(2738, ts.DiagnosticCategory.Message, "An_outer_value_of_this_is_shadowed_by_this_container_2738", "An outer value of 'this' is shadowed by this container."),
        Type_0_is_missing_the_following_properties_from_type_1_Colon_2: diag(2739, ts.DiagnosticCategory.Error, "Type_0_is_missing_the_following_properties_from_type_1_Colon_2_2739", "Type '{0}' is missing the following properties from type '{1}': {2}"),
        Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more: diag(2740, ts.DiagnosticCategory.Error, "Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more_2740", "Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more."),
        Property_0_is_missing_in_type_1_but_required_in_type_2: diag(2741, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_but_required_in_type_2_2741", "Property '{0}' is missing in type '{1}' but required in type '{2}'."),
        The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary: diag(2742, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_a_2742", "The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary."),
        No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments: diag(2743, ts.DiagnosticCategory.Error, "No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments_2743", "No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments."),
        Type_parameter_defaults_can_only_reference_previously_declared_type_parameters: diag(2744, ts.DiagnosticCategory.Error, "Type_parameter_defaults_can_only_reference_previously_declared_type_parameters_2744", "Type parameter defaults can only reference previously declared type parameters."),
        This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided: diag(2745, ts.DiagnosticCategory.Error, "This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_pr_2745", "This JSX tag's '{0}' prop expects type '{1}' which requires multiple children, but only a single child was provided."),
        This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided: diag(2746, ts.DiagnosticCategory.Error, "This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided_2746", "This JSX tag's '{0}' prop expects a single child of type '{1}', but multiple children were provided."),
        _0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2: diag(2747, ts.DiagnosticCategory.Error, "_0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_t_2747", "'{0}' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of '{1}' is '{2}'."),
        Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided: diag(2748, ts.DiagnosticCategory.Error, "Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided_2748", "Cannot access ambient const enums when the '--isolatedModules' flag is provided."),
        _0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0: diag(2749, ts.DiagnosticCategory.Error, "_0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0_2749", "'{0}' refers to a value, but is being used as a type here. Did you mean 'typeof {0}'?"),
        The_implementation_signature_is_declared_here: diag(2750, ts.DiagnosticCategory.Error, "The_implementation_signature_is_declared_here_2750", "The implementation signature is declared here."),
        Circularity_originates_in_type_at_this_location: diag(2751, ts.DiagnosticCategory.Error, "Circularity_originates_in_type_at_this_location_2751", "Circularity originates in type at this location."),
        The_first_export_default_is_here: diag(2752, ts.DiagnosticCategory.Error, "The_first_export_default_is_here_2752", "The first export default is here."),
        Another_export_default_is_here: diag(2753, ts.DiagnosticCategory.Error, "Another_export_default_is_here_2753", "Another export default is here."),
        super_may_not_use_type_arguments: diag(2754, ts.DiagnosticCategory.Error, "super_may_not_use_type_arguments_2754", "'super' may not use type arguments."),
        No_constituent_of_type_0_is_callable: diag(2755, ts.DiagnosticCategory.Error, "No_constituent_of_type_0_is_callable_2755", "No constituent of type '{0}' is callable."),
        Not_all_constituents_of_type_0_are_callable: diag(2756, ts.DiagnosticCategory.Error, "Not_all_constituents_of_type_0_are_callable_2756", "Not all constituents of type '{0}' are callable."),
        Type_0_has_no_call_signatures: diag(2757, ts.DiagnosticCategory.Error, "Type_0_has_no_call_signatures_2757", "Type '{0}' has no call signatures."),
        Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_other: diag(2758, ts.DiagnosticCategory.Error, "Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_2758", "Each member of the union type '{0}' has signatures, but none of those signatures are compatible with each other."),
        No_constituent_of_type_0_is_constructable: diag(2759, ts.DiagnosticCategory.Error, "No_constituent_of_type_0_is_constructable_2759", "No constituent of type '{0}' is constructable."),
        Not_all_constituents_of_type_0_are_constructable: diag(2760, ts.DiagnosticCategory.Error, "Not_all_constituents_of_type_0_are_constructable_2760", "Not all constituents of type '{0}' are constructable."),
        Type_0_has_no_construct_signatures: diag(2761, ts.DiagnosticCategory.Error, "Type_0_has_no_construct_signatures_2761", "Type '{0}' has no construct signatures."),
        Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_with_each_other: diag(2762, ts.DiagnosticCategory.Error, "Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_2762", "Each member of the union type '{0}' has construct signatures, but none of those signatures are compatible with each other."),
        Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_send_0: diag(2763, ts.DiagnosticCategory.Error, "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_s_2763", "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but for-of will always send '{0}'."),
        Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_always_send_0: diag(2764, ts.DiagnosticCategory.Error, "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_al_2764", "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array spread will always send '{0}'."),
        Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring_will_always_send_0: diag(2765, ts.DiagnosticCategory.Error, "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring__2765", "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array destructuring will always send '{0}'."),
        Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_containing_generator_will_always_send_0: diag(2766, ts.DiagnosticCategory.Error, "Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_co_2766", "Cannot delegate iteration to value because the 'next' method of its iterator expects type '{1}', but the containing generator will always send '{0}'."),
        The_0_property_of_an_iterator_must_be_a_method: diag(2767, ts.DiagnosticCategory.Error, "The_0_property_of_an_iterator_must_be_a_method_2767", "The '{0}' property of an iterator must be a method."),
        The_0_property_of_an_async_iterator_must_be_a_method: diag(2768, ts.DiagnosticCategory.Error, "The_0_property_of_an_async_iterator_must_be_a_method_2768", "The '{0}' property of an async iterator must be a method."),
        No_overload_matches_this_call: diag(2769, ts.DiagnosticCategory.Error, "No_overload_matches_this_call_2769", "No overload matches this call."),
        The_last_overload_gave_the_following_error: diag(2770, ts.DiagnosticCategory.Error, "The_last_overload_gave_the_following_error_2770", "The last overload gave the following error."),
        The_last_overload_is_declared_here: diag(2771, ts.DiagnosticCategory.Error, "The_last_overload_is_declared_here_2771", "The last overload is declared here."),
        Overload_0_of_1_2_gave_the_following_error: diag(2772, ts.DiagnosticCategory.Error, "Overload_0_of_1_2_gave_the_following_error_2772", "Overload {0} of {1}, '{2}', gave the following error."),
        Did_you_forget_to_use_await: diag(2773, ts.DiagnosticCategory.Error, "Did_you_forget_to_use_await_2773", "Did you forget to use 'await'?"),
        This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead: diag(2774, ts.DiagnosticCategory.Error, "This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it__2774", "This condition will always return true since the function is always defined. Did you mean to call it instead?"),
        Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation: diag(2775, ts.DiagnosticCategory.Error, "Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation_2775", "Assertions require every name in the call target to be declared with an explicit type annotation."),
        Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name: diag(2776, ts.DiagnosticCategory.Error, "Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name_2776", "Assertions require the call target to be an identifier or qualified name."),
        The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access: diag(2777, ts.DiagnosticCategory.Error, "The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access_2777", "The operand of an increment or decrement operator may not be an optional property access."),
        The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access: diag(2778, ts.DiagnosticCategory.Error, "The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access_2778", "The target of an object rest assignment may not be an optional property access."),
        The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access: diag(2779, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access_2779", "The left-hand side of an assignment expression may not be an optional property access."),
        The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access: diag(2780, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access_2780", "The left-hand side of a 'for...in' statement may not be an optional property access."),
        The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access: diag(2781, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access_2781", "The left-hand side of a 'for...of' statement may not be an optional property access."),
        _0_needs_an_explicit_type_annotation: diag(2782, ts.DiagnosticCategory.Message, "_0_needs_an_explicit_type_annotation_2782", "'{0}' needs an explicit type annotation."),
        _0_is_specified_more_than_once_so_this_usage_will_be_overwritten: diag(2783, ts.DiagnosticCategory.Error, "_0_is_specified_more_than_once_so_this_usage_will_be_overwritten_2783", "'{0}' is specified more than once, so this usage will be overwritten."),
        get_and_set_accessors_cannot_declare_this_parameters: diag(2784, ts.DiagnosticCategory.Error, "get_and_set_accessors_cannot_declare_this_parameters_2784", "'get' and 'set' accessors cannot declare 'this' parameters."),
        This_spread_always_overwrites_this_property: diag(2785, ts.DiagnosticCategory.Error, "This_spread_always_overwrites_this_property_2785", "This spread always overwrites this property."),
        _0_cannot_be_used_as_a_JSX_component: diag(2786, ts.DiagnosticCategory.Error, "_0_cannot_be_used_as_a_JSX_component_2786", "'{0}' cannot be used as a JSX component."),
        Its_return_type_0_is_not_a_valid_JSX_element: diag(2787, ts.DiagnosticCategory.Error, "Its_return_type_0_is_not_a_valid_JSX_element_2787", "Its return type '{0}' is not a valid JSX element."),
        Its_instance_type_0_is_not_a_valid_JSX_element: diag(2788, ts.DiagnosticCategory.Error, "Its_instance_type_0_is_not_a_valid_JSX_element_2788", "Its instance type '{0}' is not a valid JSX element."),
        Its_element_type_0_is_not_a_valid_JSX_element: diag(2789, ts.DiagnosticCategory.Error, "Its_element_type_0_is_not_a_valid_JSX_element_2789", "Its element type '{0}' is not a valid JSX element."),
        Import_declaration_0_is_using_private_name_1: diag(4000, ts.DiagnosticCategory.Error, "Import_declaration_0_is_using_private_name_1_4000", "Import declaration '{0}' is using private name '{1}'."),
        Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: diag(4002, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", "Type parameter '{0}' of exported class has or is using private name '{1}'."),
        Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: diag(4004, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", "Type parameter '{0}' of exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4006, ts.DiagnosticCategory.Error, "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006", "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4008, ts.DiagnosticCategory.Error, "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008", "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4010, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010", "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
        Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4012, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012", "Type parameter '{0}' of public method from exported class has or is using private name '{1}'."),
        Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4014, ts.DiagnosticCategory.Error, "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014", "Type parameter '{0}' of method from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4016, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016", "Type parameter '{0}' of exported function has or is using private name '{1}'."),
        Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4019, ts.DiagnosticCategory.Error, "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019", "Implements clause of exported class '{0}' has or is using private name '{1}'."),
        extends_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4020, ts.DiagnosticCategory.Error, "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020", "'extends' clause of exported class '{0}' has or is using private name '{1}'."),
        extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: diag(4022, ts.DiagnosticCategory.Error, "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022", "'extends' clause of exported interface '{0}' has or is using private name '{1}'."),
        Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4023, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023", "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named."),
        Exported_variable_0_has_or_is_using_name_1_from_private_module_2: diag(4024, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024", "Exported variable '{0}' has or is using name '{1}' from private module '{2}'."),
        Exported_variable_0_has_or_is_using_private_name_1: diag(4025, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_private_name_1_4025", "Exported variable '{0}' has or is using private name '{1}'."),
        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4026, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026", "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4027, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027", "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_static_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4028, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028", "Public static property '{0}' of exported class has or is using private name '{1}'."),
        Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4029, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029", "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4030, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030", "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4031, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031", "Public property '{0}' of exported class has or is using private name '{1}'."),
        Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4032, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032", "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'."),
        Property_0_of_exported_interface_has_or_is_using_private_name_1: diag(4033, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033", "Property '{0}' of exported interface has or is using private name '{1}'."),
        Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4034, ts.DiagnosticCategory.Error, "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_mod_4034", "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1: diag(4035, ts.DiagnosticCategory.Error, "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1_4035", "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'."),
        Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4036, ts.DiagnosticCategory.Error, "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036", "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1: diag(4037, ts.DiagnosticCategory.Error, "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1_4037", "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4038, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_modul_4038", "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4039, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_4039", "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1: diag(4040, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1_4040", "Return type of public static getter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4041, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_4041", "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4042, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4042", "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1: diag(4043, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1_4043", "Return type of public getter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4044, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044", "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4045, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045", "Return type of constructor signature from exported interface has or is using private name '{0}'."),
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4046, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046", "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4047, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047", "Return type of call signature from exported interface has or is using private name '{0}'."),
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4048, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048", "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4049, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049", "Return type of index signature from exported interface has or is using private name '{0}'."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4050, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050", "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4051, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051", "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0: diag(4052, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052", "Return type of public static method from exported class has or is using private name '{0}'."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4053, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053", "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4054, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054", "Return type of public method from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0: diag(4055, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055", "Return type of public method from exported class has or is using private name '{0}'."),
        Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4056, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056", "Return type of method from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0: diag(4057, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057", "Return type of method from exported interface has or is using private name '{0}'."),
        Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4058, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058", "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1: diag(4059, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059", "Return type of exported function has or is using name '{0}' from private module '{1}'."),
        Return_type_of_exported_function_has_or_is_using_private_name_0: diag(4060, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_private_name_0_4060", "Return type of exported function has or is using private name '{0}'."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4061, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4062, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1: diag(4063, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063", "Parameter '{0}' of constructor from exported class has or is using private name '{1}'."),
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4064, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064", "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4065, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065", "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4066, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066", "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4067, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067", "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4068, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4069, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4070, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070", "Parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4071, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071", "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4072, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072", "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4073, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073", "Parameter '{0}' of public method from exported class has or is using private name '{1}'."),
        Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4074, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074", "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4075, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075", "Parameter '{0}' of method from exported interface has or is using private name '{1}'."),
        Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4076, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076", "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: diag(4077, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077", "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4078, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078", "Parameter '{0}' of exported function has or is using private name '{1}'."),
        Exported_type_alias_0_has_or_is_using_private_name_1: diag(4081, ts.DiagnosticCategory.Error, "Exported_type_alias_0_has_or_is_using_private_name_1_4081", "Exported type alias '{0}' has or is using private name '{1}'."),
        Default_export_of_the_module_has_or_is_using_private_name_0: diag(4082, ts.DiagnosticCategory.Error, "Default_export_of_the_module_has_or_is_using_private_name_0_4082", "Default export of the module has or is using private name '{0}'."),
        Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1: diag(4083, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083", "Type parameter '{0}' of exported type alias has or is using private name '{1}'."),
        Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict: diag(4090, ts.DiagnosticCategory.Error, "Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_librar_4090", "Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict."),
        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4091, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091", "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4092, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092", "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'."),
        Property_0_of_exported_class_expression_may_not_be_private_or_protected: diag(4094, ts.DiagnosticCategory.Error, "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094", "Property '{0}' of exported class expression may not be private or protected."),
        Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4095, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095", "Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4096, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096", "Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_static_method_0_of_exported_class_has_or_is_using_private_name_1: diag(4097, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097", "Public static method '{0}' of exported class has or is using private name '{1}'."),
        Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4098, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098", "Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4099, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099", "Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_method_0_of_exported_class_has_or_is_using_private_name_1: diag(4100, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100", "Public method '{0}' of exported class has or is using private name '{1}'."),
        Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4101, ts.DiagnosticCategory.Error, "Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101", "Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'."),
        Method_0_of_exported_interface_has_or_is_using_private_name_1: diag(4102, ts.DiagnosticCategory.Error, "Method_0_of_exported_interface_has_or_is_using_private_name_1_4102", "Method '{0}' of exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1: diag(4103, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1_4103", "Type parameter '{0}' of exported mapped object type is using private name '{1}'."),
        The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1: diag(4104, ts.DiagnosticCategory.Error, "The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1_4104", "The type '{0}' is 'readonly' and cannot be assigned to the mutable type '{1}'."),
        Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter: diag(4105, ts.DiagnosticCategory.Error, "Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter_4105", "Private or protected member '{0}' cannot be accessed on a type parameter."),
        Parameter_0_of_accessor_has_or_is_using_private_name_1: diag(4106, ts.DiagnosticCategory.Error, "Parameter_0_of_accessor_has_or_is_using_private_name_1_4106", "Parameter '{0}' of accessor has or is using private name '{1}'."),
        Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2: diag(4107, ts.DiagnosticCategory.Error, "Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2_4107", "Parameter '{0}' of accessor has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4108, ts.DiagnosticCategory.Error, "Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4108", "Parameter '{0}' of accessor has or is using name '{1}' from external module '{2}' but cannot be named."),
        Type_arguments_for_0_circularly_reference_themselves: diag(4109, ts.DiagnosticCategory.Error, "Type_arguments_for_0_circularly_reference_themselves_4109", "Type arguments for '{0}' circularly reference themselves."),
        Tuple_type_arguments_circularly_reference_themselves: diag(4110, ts.DiagnosticCategory.Error, "Tuple_type_arguments_circularly_reference_themselves_4110", "Tuple type arguments circularly reference themselves."),
        The_current_host_does_not_support_the_0_option: diag(5001, ts.DiagnosticCategory.Error, "The_current_host_does_not_support_the_0_option_5001", "The current host does not support the '{0}' option."),
        Cannot_find_the_common_subdirectory_path_for_the_input_files: diag(5009, ts.DiagnosticCategory.Error, "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009", "Cannot find the common subdirectory path for the input files."),
        File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5010, ts.DiagnosticCategory.Error, "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010", "File specification cannot end in a recursive directory wildcard ('**'): '{0}'."),
        Cannot_read_file_0_Colon_1: diag(5012, ts.DiagnosticCategory.Error, "Cannot_read_file_0_Colon_1_5012", "Cannot read file '{0}': {1}."),
        Failed_to_parse_file_0_Colon_1: diag(5014, ts.DiagnosticCategory.Error, "Failed_to_parse_file_0_Colon_1_5014", "Failed to parse file '{0}': {1}."),
        Unknown_compiler_option_0: diag(5023, ts.DiagnosticCategory.Error, "Unknown_compiler_option_0_5023", "Unknown compiler option '{0}'."),
        Compiler_option_0_requires_a_value_of_type_1: diag(5024, ts.DiagnosticCategory.Error, "Compiler_option_0_requires_a_value_of_type_1_5024", "Compiler option '{0}' requires a value of type {1}."),
        Unknown_compiler_option_0_Did_you_mean_1: diag(5025, ts.DiagnosticCategory.Error, "Unknown_compiler_option_0_Did_you_mean_1_5025", "Unknown compiler option '{0}'. Did you mean '{1}'?"),
        Could_not_write_file_0_Colon_1: diag(5033, ts.DiagnosticCategory.Error, "Could_not_write_file_0_Colon_1_5033", "Could not write file '{0}': {1}."),
        Option_project_cannot_be_mixed_with_source_files_on_a_command_line: diag(5042, ts.DiagnosticCategory.Error, "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042", "Option 'project' cannot be mixed with source files on a command line."),
        Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher: diag(5047, ts.DiagnosticCategory.Error, "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047", "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher."),
        Option_0_cannot_be_specified_when_option_target_is_ES3: diag(5048, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_when_option_target_is_ES3_5048", "Option '{0}' cannot be specified when option 'target' is 'ES3'."),
        Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: diag(5051, ts.DiagnosticCategory.Error, "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051", "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided."),
        Option_0_cannot_be_specified_without_specifying_option_1: diag(5052, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_5052", "Option '{0}' cannot be specified without specifying option '{1}'."),
        Option_0_cannot_be_specified_with_option_1: diag(5053, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_with_option_1_5053", "Option '{0}' cannot be specified with option '{1}'."),
        A_tsconfig_json_file_is_already_defined_at_Colon_0: diag(5054, ts.DiagnosticCategory.Error, "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054", "A 'tsconfig.json' file is already defined at: '{0}'."),
        Cannot_write_file_0_because_it_would_overwrite_input_file: diag(5055, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_overwrite_input_file_5055", "Cannot write file '{0}' because it would overwrite input file."),
        Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files: diag(5056, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056", "Cannot write file '{0}' because it would be overwritten by multiple input files."),
        Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0: diag(5057, ts.DiagnosticCategory.Error, "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057", "Cannot find a tsconfig.json file at the specified directory: '{0}'."),
        The_specified_path_does_not_exist_Colon_0: diag(5058, ts.DiagnosticCategory.Error, "The_specified_path_does_not_exist_Colon_0_5058", "The specified path does not exist: '{0}'."),
        Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier: diag(5059, ts.DiagnosticCategory.Error, "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059", "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier."),
        Option_paths_cannot_be_used_without_specifying_baseUrl_option: diag(5060, ts.DiagnosticCategory.Error, "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", "Option 'paths' cannot be used without specifying '--baseUrl' option."),
        Pattern_0_can_have_at_most_one_Asterisk_character: diag(5061, ts.DiagnosticCategory.Error, "Pattern_0_can_have_at_most_one_Asterisk_character_5061", "Pattern '{0}' can have at most one '*' character."),
        Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character: diag(5062, ts.DiagnosticCategory.Error, "Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character_5062", "Substitution '{0}' in pattern '{1}' can have at most one '*' character."),
        Substitutions_for_pattern_0_should_be_an_array: diag(5063, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_should_be_an_array_5063", "Substitutions for pattern '{0}' should be an array."),
        Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: diag(5064, ts.DiagnosticCategory.Error, "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'."),
        File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5065, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065", "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'."),
        Substitutions_for_pattern_0_shouldn_t_be_an_empty_array: diag(5066, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_shouldn_t_be_an_empty_array_5066", "Substitutions for pattern '{0}' shouldn't be an empty array."),
        Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name: diag(5067, ts.DiagnosticCategory.Error, "Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name_5067", "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name."),
        Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig: diag(5068, ts.DiagnosticCategory.Error, "Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068", "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig."),
        Option_0_cannot_be_specified_without_specifying_option_1_or_option_2: diag(5069, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_or_option_2_5069", "Option '{0}' cannot be specified without specifying option '{1}' or option '{2}'."),
        Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy: diag(5070, ts.DiagnosticCategory.Error, "Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070", "Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy."),
        Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext: diag(5071, ts.DiagnosticCategory.Error, "Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_5071", "Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'."),
        Unknown_build_option_0: diag(5072, ts.DiagnosticCategory.Error, "Unknown_build_option_0_5072", "Unknown build option '{0}'."),
        Build_option_0_requires_a_value_of_type_1: diag(5073, ts.DiagnosticCategory.Error, "Build_option_0_requires_a_value_of_type_1_5073", "Build option '{0}' requires a value of type {1}."),
        Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified: diag(5074, ts.DiagnosticCategory.Error, "Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBui_5074", "Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified."),
        _0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2: diag(5075, ts.DiagnosticCategory.Error, "_0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_5075", "'{0}' is assignable to the constraint of type '{1}', but '{1}' could be instantiated with a different subtype of constraint '{2}'."),
        _0_and_1_operations_cannot_be_mixed_without_parentheses: diag(5076, ts.DiagnosticCategory.Error, "_0_and_1_operations_cannot_be_mixed_without_parentheses_5076", "'{0}' and '{1}' operations cannot be mixed without parentheses."),
        Unknown_build_option_0_Did_you_mean_1: diag(5077, ts.DiagnosticCategory.Error, "Unknown_build_option_0_Did_you_mean_1_5077", "Unknown build option '{0}'. Did you mean '{1}'?"),
        Unknown_watch_option_0: diag(5078, ts.DiagnosticCategory.Error, "Unknown_watch_option_0_5078", "Unknown watch option '{0}'."),
        Unknown_watch_option_0_Did_you_mean_1: diag(5079, ts.DiagnosticCategory.Error, "Unknown_watch_option_0_Did_you_mean_1_5079", "Unknown watch option '{0}'. Did you mean '{1}'?"),
        Watch_option_0_requires_a_value_of_type_1: diag(5080, ts.DiagnosticCategory.Error, "Watch_option_0_requires_a_value_of_type_1_5080", "Watch option '{0}' requires a value of type {1}."),
        Cannot_find_a_tsconfig_json_file_at_the_current_directory_Colon_0: diag(5081, ts.DiagnosticCategory.Error, "Cannot_find_a_tsconfig_json_file_at_the_current_directory_Colon_0_5081", "Cannot find a tsconfig.json file at the current directory: {0}."),
        _0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1: diag(5082, ts.DiagnosticCategory.Error, "_0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1_5082", "'{0}' could be instantiated with an arbitrary type which could be unrelated to '{1}'."),
        Cannot_read_file_0: diag(5083, ts.DiagnosticCategory.Error, "Cannot_read_file_0_5083", "Cannot read file '{0}'."),
        The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary: diag(5088, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088", "The inferred type of '{0}' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary."),
        Generates_a_sourcemap_for_each_corresponding_d_ts_file: diag(6000, ts.DiagnosticCategory.Message, "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000", "Generates a sourcemap for each corresponding '.d.ts' file."),
        Concatenate_and_emit_output_to_single_file: diag(6001, ts.DiagnosticCategory.Message, "Concatenate_and_emit_output_to_single_file_6001", "Concatenate and emit output to single file."),
        Generates_corresponding_d_ts_file: diag(6002, ts.DiagnosticCategory.Message, "Generates_corresponding_d_ts_file_6002", "Generates corresponding '.d.ts' file."),
        Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: diag(6003, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6003", "Specify the location where debugger should locate map files instead of generated locations."),
        Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: diag(6004, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004", "Specify the location where debugger should locate TypeScript files instead of source locations."),
        Watch_input_files: diag(6005, ts.DiagnosticCategory.Message, "Watch_input_files_6005", "Watch input files."),
        Redirect_output_structure_to_the_directory: diag(6006, ts.DiagnosticCategory.Message, "Redirect_output_structure_to_the_directory_6006", "Redirect output structure to the directory."),
        Do_not_erase_const_enum_declarations_in_generated_code: diag(6007, ts.DiagnosticCategory.Message, "Do_not_erase_const_enum_declarations_in_generated_code_6007", "Do not erase const enum declarations in generated code."),
        Do_not_emit_outputs_if_any_errors_were_reported: diag(6008, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_if_any_errors_were_reported_6008", "Do not emit outputs if any errors were reported."),
        Do_not_emit_comments_to_output: diag(6009, ts.DiagnosticCategory.Message, "Do_not_emit_comments_to_output_6009", "Do not emit comments to output."),
        Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."),
        Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."),
        Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."),
        Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."),
        Only_emit_d_ts_declaration_files: diag(6014, ts.DiagnosticCategory.Message, "Only_emit_d_ts_declaration_files_6014", "Only emit '.d.ts' declaration files."),
        Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_ES2020_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_ES2020_or_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'."),
        Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_es2020_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_es2020_or_ESNext_6016", "Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'."),
        Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."),
        Print_the_compiler_s_version: diag(6019, ts.DiagnosticCategory.Message, "Print_the_compiler_s_version_6019", "Print the compiler's version."),
        Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json: diag(6020, ts.DiagnosticCategory.Message, "Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020", "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."),
        Syntax_Colon_0: diag(6023, ts.DiagnosticCategory.Message, "Syntax_Colon_0_6023", "Syntax: {0}"),
        options: diag(6024, ts.DiagnosticCategory.Message, "options_6024", "options"),
        file: diag(6025, ts.DiagnosticCategory.Message, "file_6025", "file"),
        Examples_Colon_0: diag(6026, ts.DiagnosticCategory.Message, "Examples_Colon_0_6026", "Examples: {0}"),
        Options_Colon: diag(6027, ts.DiagnosticCategory.Message, "Options_Colon_6027", "Options:"),
        Version_0: diag(6029, ts.DiagnosticCategory.Message, "Version_0_6029", "Version {0}"),
        Insert_command_line_options_and_files_from_a_file: diag(6030, ts.DiagnosticCategory.Message, "Insert_command_line_options_and_files_from_a_file_6030", "Insert command line options and files from a file."),
        Starting_compilation_in_watch_mode: diag(6031, ts.DiagnosticCategory.Message, "Starting_compilation_in_watch_mode_6031", "Starting compilation in watch mode..."),
        File_change_detected_Starting_incremental_compilation: diag(6032, ts.DiagnosticCategory.Message, "File_change_detected_Starting_incremental_compilation_6032", "File change detected. Starting incremental compilation..."),
        KIND: diag(6034, ts.DiagnosticCategory.Message, "KIND_6034", "KIND"),
        FILE: diag(6035, ts.DiagnosticCategory.Message, "FILE_6035", "FILE"),
        VERSION: diag(6036, ts.DiagnosticCategory.Message, "VERSION_6036", "VERSION"),
        LOCATION: diag(6037, ts.DiagnosticCategory.Message, "LOCATION_6037", "LOCATION"),
        DIRECTORY: diag(6038, ts.DiagnosticCategory.Message, "DIRECTORY_6038", "DIRECTORY"),
        STRATEGY: diag(6039, ts.DiagnosticCategory.Message, "STRATEGY_6039", "STRATEGY"),
        FILE_OR_DIRECTORY: diag(6040, ts.DiagnosticCategory.Message, "FILE_OR_DIRECTORY_6040", "FILE OR DIRECTORY"),
        Generates_corresponding_map_file: diag(6043, ts.DiagnosticCategory.Message, "Generates_corresponding_map_file_6043", "Generates corresponding '.map' file."),
        Compiler_option_0_expects_an_argument: diag(6044, ts.DiagnosticCategory.Error, "Compiler_option_0_expects_an_argument_6044", "Compiler option '{0}' expects an argument."),
        Unterminated_quoted_string_in_response_file_0: diag(6045, ts.DiagnosticCategory.Error, "Unterminated_quoted_string_in_response_file_0_6045", "Unterminated quoted string in response file '{0}'."),
        Argument_for_0_option_must_be_Colon_1: diag(6046, ts.DiagnosticCategory.Error, "Argument_for_0_option_must_be_Colon_1_6046", "Argument for '{0}' option must be: {1}."),
        Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: diag(6048, ts.DiagnosticCategory.Error, "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048", "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'."),
        Unsupported_locale_0: diag(6049, ts.DiagnosticCategory.Error, "Unsupported_locale_0_6049", "Unsupported locale '{0}'."),
        Unable_to_open_file_0: diag(6050, ts.DiagnosticCategory.Error, "Unable_to_open_file_0_6050", "Unable to open file '{0}'."),
        Corrupted_locale_file_0: diag(6051, ts.DiagnosticCategory.Error, "Corrupted_locale_file_0_6051", "Corrupted locale file {0}."),
        Raise_error_on_expressions_and_declarations_with_an_implied_any_type: diag(6052, ts.DiagnosticCategory.Message, "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052", "Raise error on expressions and declarations with an implied 'any' type."),
        File_0_not_found: diag(6053, ts.DiagnosticCategory.Error, "File_0_not_found_6053", "File '{0}' not found."),
        File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1: diag(6054, ts.DiagnosticCategory.Error, "File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1_6054", "File '{0}' has an unsupported extension. The only supported extensions are {1}."),
        Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: diag(6055, ts.DiagnosticCategory.Message, "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055", "Suppress noImplicitAny errors for indexing objects lacking index signatures."),
        Do_not_emit_declarations_for_code_that_has_an_internal_annotation: diag(6056, ts.DiagnosticCategory.Message, "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056", "Do not emit declarations for code that has an '@internal' annotation."),
        Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir: diag(6058, ts.DiagnosticCategory.Message, "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058", "Specify the root directory of input files. Use to control the output directory structure with --outDir."),
        File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files: diag(6059, ts.DiagnosticCategory.Error, "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059", "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files."),
        Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: diag(6060, ts.DiagnosticCategory.Message, "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060", "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)."),
        NEWLINE: diag(6061, ts.DiagnosticCategory.Message, "NEWLINE_6061", "NEWLINE"),
        Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line: diag(6064, ts.DiagnosticCategory.Error, "Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line_6064", "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'null' on command line."),
        Enables_experimental_support_for_ES7_decorators: diag(6065, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_decorators_6065", "Enables experimental support for ES7 decorators."),
        Enables_experimental_support_for_emitting_type_metadata_for_decorators: diag(6066, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066", "Enables experimental support for emitting type metadata for decorators."),
        Enables_experimental_support_for_ES7_async_functions: diag(6068, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_async_functions_6068", "Enables experimental support for ES7 async functions."),
        Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6: diag(6069, ts.DiagnosticCategory.Message, "Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6_6069", "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)."),
        Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: diag(6070, ts.DiagnosticCategory.Message, "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070", "Initializes a TypeScript project and creates a tsconfig.json file."),
        Successfully_created_a_tsconfig_json_file: diag(6071, ts.DiagnosticCategory.Message, "Successfully_created_a_tsconfig_json_file_6071", "Successfully created a tsconfig.json file."),
        Suppress_excess_property_checks_for_object_literals: diag(6072, ts.DiagnosticCategory.Message, "Suppress_excess_property_checks_for_object_literals_6072", "Suppress excess property checks for object literals."),
        Stylize_errors_and_messages_using_color_and_context_experimental: diag(6073, ts.DiagnosticCategory.Message, "Stylize_errors_and_messages_using_color_and_context_experimental_6073", "Stylize errors and messages using color and context (experimental)."),
        Do_not_report_errors_on_unused_labels: diag(6074, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unused_labels_6074", "Do not report errors on unused labels."),
        Report_error_when_not_all_code_paths_in_function_return_a_value: diag(6075, ts.DiagnosticCategory.Message, "Report_error_when_not_all_code_paths_in_function_return_a_value_6075", "Report error when not all code paths in function return a value."),
        Report_errors_for_fallthrough_cases_in_switch_statement: diag(6076, ts.DiagnosticCategory.Message, "Report_errors_for_fallthrough_cases_in_switch_statement_6076", "Report errors for fallthrough cases in switch statement."),
        Do_not_report_errors_on_unreachable_code: diag(6077, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unreachable_code_6077", "Do not report errors on unreachable code."),
        Disallow_inconsistently_cased_references_to_the_same_file: diag(6078, ts.DiagnosticCategory.Message, "Disallow_inconsistently_cased_references_to_the_same_file_6078", "Disallow inconsistently-cased references to the same file."),
        Specify_library_files_to_be_included_in_the_compilation: diag(6079, ts.DiagnosticCategory.Message, "Specify_library_files_to_be_included_in_the_compilation_6079", "Specify library files to be included in the compilation."),
        Specify_JSX_code_generation_Colon_preserve_react_native_or_react: diag(6080, ts.DiagnosticCategory.Message, "Specify_JSX_code_generation_Colon_preserve_react_native_or_react_6080", "Specify JSX code generation: 'preserve', 'react-native', or 'react'."),
        File_0_has_an_unsupported_extension_so_skipping_it: diag(6081, ts.DiagnosticCategory.Message, "File_0_has_an_unsupported_extension_so_skipping_it_6081", "File '{0}' has an unsupported extension, so skipping it."),
        Only_amd_and_system_modules_are_supported_alongside_0: diag(6082, ts.DiagnosticCategory.Error, "Only_amd_and_system_modules_are_supported_alongside_0_6082", "Only 'amd' and 'system' modules are supported alongside --{0}."),
        Base_directory_to_resolve_non_absolute_module_names: diag(6083, ts.DiagnosticCategory.Message, "Base_directory_to_resolve_non_absolute_module_names_6083", "Base directory to resolve non-absolute module names."),
        Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit: diag(6084, ts.DiagnosticCategory.Message, "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084", "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit"),
        Enable_tracing_of_the_name_resolution_process: diag(6085, ts.DiagnosticCategory.Message, "Enable_tracing_of_the_name_resolution_process_6085", "Enable tracing of the name resolution process."),
        Resolving_module_0_from_1: diag(6086, ts.DiagnosticCategory.Message, "Resolving_module_0_from_1_6086", "======== Resolving module '{0}' from '{1}'. ========"),
        Explicitly_specified_module_resolution_kind_Colon_0: diag(6087, ts.DiagnosticCategory.Message, "Explicitly_specified_module_resolution_kind_Colon_0_6087", "Explicitly specified module resolution kind: '{0}'."),
        Module_resolution_kind_is_not_specified_using_0: diag(6088, ts.DiagnosticCategory.Message, "Module_resolution_kind_is_not_specified_using_0_6088", "Module resolution kind is not specified, using '{0}'."),
        Module_name_0_was_successfully_resolved_to_1: diag(6089, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_6089", "======== Module name '{0}' was successfully resolved to '{1}'. ========"),
        Module_name_0_was_not_resolved: diag(6090, ts.DiagnosticCategory.Message, "Module_name_0_was_not_resolved_6090", "======== Module name '{0}' was not resolved. ========"),
        paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0: diag(6091, ts.DiagnosticCategory.Message, "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091", "'paths' option is specified, looking for a pattern to match module name '{0}'."),
        Module_name_0_matched_pattern_1: diag(6092, ts.DiagnosticCategory.Message, "Module_name_0_matched_pattern_1_6092", "Module name '{0}', matched pattern '{1}'."),
        Trying_substitution_0_candidate_module_location_Colon_1: diag(6093, ts.DiagnosticCategory.Message, "Trying_substitution_0_candidate_module_location_Colon_1_6093", "Trying substitution '{0}', candidate module location: '{1}'."),
        Resolving_module_name_0_relative_to_base_url_1_2: diag(6094, ts.DiagnosticCategory.Message, "Resolving_module_name_0_relative_to_base_url_1_2_6094", "Resolving module name '{0}' relative to base url '{1}' - '{2}'."),
        Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1: diag(6095, ts.DiagnosticCategory.Message, "Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1_6095", "Loading module as file / folder, candidate module location '{0}', target file type '{1}'."),
        File_0_does_not_exist: diag(6096, ts.DiagnosticCategory.Message, "File_0_does_not_exist_6096", "File '{0}' does not exist."),
        File_0_exist_use_it_as_a_name_resolution_result: diag(6097, ts.DiagnosticCategory.Message, "File_0_exist_use_it_as_a_name_resolution_result_6097", "File '{0}' exist - use it as a name resolution result."),
        Loading_module_0_from_node_modules_folder_target_file_type_1: diag(6098, ts.DiagnosticCategory.Message, "Loading_module_0_from_node_modules_folder_target_file_type_1_6098", "Loading module '{0}' from 'node_modules' folder, target file type '{1}'."),
        Found_package_json_at_0: diag(6099, ts.DiagnosticCategory.Message, "Found_package_json_at_0_6099", "Found 'package.json' at '{0}'."),
        package_json_does_not_have_a_0_field: diag(6100, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_0_field_6100", "'package.json' does not have a '{0}' field."),
        package_json_has_0_field_1_that_references_2: diag(6101, ts.DiagnosticCategory.Message, "package_json_has_0_field_1_that_references_2_6101", "'package.json' has '{0}' field '{1}' that references '{2}'."),
        Allow_javascript_files_to_be_compiled: diag(6102, ts.DiagnosticCategory.Message, "Allow_javascript_files_to_be_compiled_6102", "Allow javascript files to be compiled."),
        Option_0_should_have_array_of_strings_as_a_value: diag(6103, ts.DiagnosticCategory.Error, "Option_0_should_have_array_of_strings_as_a_value_6103", "Option '{0}' should have array of strings as a value."),
        Checking_if_0_is_the_longest_matching_prefix_for_1_2: diag(6104, ts.DiagnosticCategory.Message, "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104", "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'."),
        Expected_type_of_0_field_in_package_json_to_be_1_got_2: diag(6105, ts.DiagnosticCategory.Message, "Expected_type_of_0_field_in_package_json_to_be_1_got_2_6105", "Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'."),
        baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1: diag(6106, ts.DiagnosticCategory.Message, "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106", "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'."),
        rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0: diag(6107, ts.DiagnosticCategory.Message, "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107", "'rootDirs' option is set, using it to resolve relative module name '{0}'."),
        Longest_matching_prefix_for_0_is_1: diag(6108, ts.DiagnosticCategory.Message, "Longest_matching_prefix_for_0_is_1_6108", "Longest matching prefix for '{0}' is '{1}'."),
        Loading_0_from_the_root_dir_1_candidate_location_2: diag(6109, ts.DiagnosticCategory.Message, "Loading_0_from_the_root_dir_1_candidate_location_2_6109", "Loading '{0}' from the root dir '{1}', candidate location '{2}'."),
        Trying_other_entries_in_rootDirs: diag(6110, ts.DiagnosticCategory.Message, "Trying_other_entries_in_rootDirs_6110", "Trying other entries in 'rootDirs'."),
        Module_resolution_using_rootDirs_has_failed: diag(6111, ts.DiagnosticCategory.Message, "Module_resolution_using_rootDirs_has_failed_6111", "Module resolution using 'rootDirs' has failed."),
        Do_not_emit_use_strict_directives_in_module_output: diag(6112, ts.DiagnosticCategory.Message, "Do_not_emit_use_strict_directives_in_module_output_6112", "Do not emit 'use strict' directives in module output."),
        Enable_strict_null_checks: diag(6113, ts.DiagnosticCategory.Message, "Enable_strict_null_checks_6113", "Enable strict null checks."),
        Unknown_option_excludes_Did_you_mean_exclude: diag(6114, ts.DiagnosticCategory.Error, "Unknown_option_excludes_Did_you_mean_exclude_6114", "Unknown option 'excludes'. Did you mean 'exclude'?"),
        Raise_error_on_this_expressions_with_an_implied_any_type: diag(6115, ts.DiagnosticCategory.Message, "Raise_error_on_this_expressions_with_an_implied_any_type_6115", "Raise error on 'this' expressions with an implied 'any' type."),
        Resolving_type_reference_directive_0_containing_file_1_root_directory_2: diag(6116, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116", "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========"),
        Resolving_using_primary_search_paths: diag(6117, ts.DiagnosticCategory.Message, "Resolving_using_primary_search_paths_6117", "Resolving using primary search paths..."),
        Resolving_from_node_modules_folder: diag(6118, ts.DiagnosticCategory.Message, "Resolving_from_node_modules_folder_6118", "Resolving from node_modules folder..."),
        Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2: diag(6119, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119", "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========"),
        Type_reference_directive_0_was_not_resolved: diag(6120, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_not_resolved_6120", "======== Type reference directive '{0}' was not resolved. ========"),
        Resolving_with_primary_search_path_0: diag(6121, ts.DiagnosticCategory.Message, "Resolving_with_primary_search_path_0_6121", "Resolving with primary search path '{0}'."),
        Root_directory_cannot_be_determined_skipping_primary_search_paths: diag(6122, ts.DiagnosticCategory.Message, "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122", "Root directory cannot be determined, skipping primary search paths."),
        Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set: diag(6123, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123", "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========"),
        Type_declaration_files_to_be_included_in_compilation: diag(6124, ts.DiagnosticCategory.Message, "Type_declaration_files_to_be_included_in_compilation_6124", "Type declaration files to be included in compilation."),
        Looking_up_in_node_modules_folder_initial_location_0: diag(6125, ts.DiagnosticCategory.Message, "Looking_up_in_node_modules_folder_initial_location_0_6125", "Looking up in 'node_modules' folder, initial location '{0}'."),
        Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder: diag(6126, ts.DiagnosticCategory.Message, "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126", "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder."),
        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1: diag(6127, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127", "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========"),
        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: diag(6128, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========"),
        Resolving_real_path_for_0_result_1: diag(6130, ts.DiagnosticCategory.Message, "Resolving_real_path_for_0_result_1_6130", "Resolving real path for '{0}', result '{1}'."),
        Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: diag(6131, ts.DiagnosticCategory.Error, "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'."),
        File_name_0_has_a_1_extension_stripping_it: diag(6132, ts.DiagnosticCategory.Message, "File_name_0_has_a_1_extension_stripping_it_6132", "File name '{0}' has a '{1}' extension - stripping it."),
        _0_is_declared_but_its_value_is_never_read: diag(6133, ts.DiagnosticCategory.Error, "_0_is_declared_but_its_value_is_never_read_6133", "'{0}' is declared but its value is never read.", /*reportsUnnecessary*/ true),
        Report_errors_on_unused_locals: diag(6134, ts.DiagnosticCategory.Message, "Report_errors_on_unused_locals_6134", "Report errors on unused locals."),
        Report_errors_on_unused_parameters: diag(6135, ts.DiagnosticCategory.Message, "Report_errors_on_unused_parameters_6135", "Report errors on unused parameters."),
        The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: diag(6136, ts.DiagnosticCategory.Message, "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", "The maximum dependency depth to search under node_modules and load JavaScript files."),
        Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1: diag(6137, ts.DiagnosticCategory.Error, "Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1_6137", "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'."),
        Property_0_is_declared_but_its_value_is_never_read: diag(6138, ts.DiagnosticCategory.Error, "Property_0_is_declared_but_its_value_is_never_read_6138", "Property '{0}' is declared but its value is never read.", /*reportsUnnecessary*/ true),
        Import_emit_helpers_from_tslib: diag(6139, ts.DiagnosticCategory.Message, "Import_emit_helpers_from_tslib_6139", "Import emit helpers from 'tslib'."),
        Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2: diag(6140, ts.DiagnosticCategory.Error, "Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using__6140", "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'."),
        Parse_in_strict_mode_and_emit_use_strict_for_each_source_file: diag(6141, ts.DiagnosticCategory.Message, "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141", "Parse in strict mode and emit \"use strict\" for each source file."),
        Module_0_was_resolved_to_1_but_jsx_is_not_set: diag(6142, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_jsx_is_not_set_6142", "Module '{0}' was resolved to '{1}', but '--jsx' is not set."),
        Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1: diag(6144, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1_6144", "Module '{0}' was resolved as locally declared ambient module in file '{1}'."),
        Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified: diag(6145, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified_6145", "Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified."),
        Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h: diag(6146, ts.DiagnosticCategory.Message, "Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h_6146", "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'."),
        Resolution_for_module_0_was_found_in_cache_from_location_1: diag(6147, ts.DiagnosticCategory.Message, "Resolution_for_module_0_was_found_in_cache_from_location_1_6147", "Resolution for module '{0}' was found in cache from location '{1}'."),
        Directory_0_does_not_exist_skipping_all_lookups_in_it: diag(6148, ts.DiagnosticCategory.Message, "Directory_0_does_not_exist_skipping_all_lookups_in_it_6148", "Directory '{0}' does not exist, skipping all lookups in it."),
        Show_diagnostic_information: diag(6149, ts.DiagnosticCategory.Message, "Show_diagnostic_information_6149", "Show diagnostic information."),
        Show_verbose_diagnostic_information: diag(6150, ts.DiagnosticCategory.Message, "Show_verbose_diagnostic_information_6150", "Show verbose diagnostic information."),
        Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file: diag(6151, ts.DiagnosticCategory.Message, "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151", "Emit a single file with source maps instead of having a separate file."),
        Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set: diag(6152, ts.DiagnosticCategory.Message, "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152", "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set."),
        Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule: diag(6153, ts.DiagnosticCategory.Message, "Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153", "Transpile each file as a separate module (similar to 'ts.transpileModule')."),
        Print_names_of_generated_files_part_of_the_compilation: diag(6154, ts.DiagnosticCategory.Message, "Print_names_of_generated_files_part_of_the_compilation_6154", "Print names of generated files part of the compilation."),
        Print_names_of_files_part_of_the_compilation: diag(6155, ts.DiagnosticCategory.Message, "Print_names_of_files_part_of_the_compilation_6155", "Print names of files part of the compilation."),
        The_locale_used_when_displaying_messages_to_the_user_e_g_en_us: diag(6156, ts.DiagnosticCategory.Message, "The_locale_used_when_displaying_messages_to_the_user_e_g_en_us_6156", "The locale used when displaying messages to the user (e.g. 'en-us')"),
        Do_not_generate_custom_helper_functions_like_extends_in_compiled_output: diag(6157, ts.DiagnosticCategory.Message, "Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157", "Do not generate custom helper functions like '__extends' in compiled output."),
        Do_not_include_the_default_library_file_lib_d_ts: diag(6158, ts.DiagnosticCategory.Message, "Do_not_include_the_default_library_file_lib_d_ts_6158", "Do not include the default library file (lib.d.ts)."),
        Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files: diag(6159, ts.DiagnosticCategory.Message, "Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files_6159", "Do not add triple-slash references or imported modules to the list of compiled files."),
        Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files: diag(6160, ts.DiagnosticCategory.Message, "Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160", "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files."),
        List_of_folders_to_include_type_definitions_from: diag(6161, ts.DiagnosticCategory.Message, "List_of_folders_to_include_type_definitions_from_6161", "List of folders to include type definitions from."),
        Disable_size_limitations_on_JavaScript_projects: diag(6162, ts.DiagnosticCategory.Message, "Disable_size_limitations_on_JavaScript_projects_6162", "Disable size limitations on JavaScript projects."),
        The_character_set_of_the_input_files: diag(6163, ts.DiagnosticCategory.Message, "The_character_set_of_the_input_files_6163", "The character set of the input files."),
        Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files: diag(6164, ts.DiagnosticCategory.Message, "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164", "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files."),
        Do_not_truncate_error_messages: diag(6165, ts.DiagnosticCategory.Message, "Do_not_truncate_error_messages_6165", "Do not truncate error messages."),
        Output_directory_for_generated_declaration_files: diag(6166, ts.DiagnosticCategory.Message, "Output_directory_for_generated_declaration_files_6166", "Output directory for generated declaration files."),
        A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl: diag(6167, ts.DiagnosticCategory.Message, "A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167", "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'."),
        List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime: diag(6168, ts.DiagnosticCategory.Message, "List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime_6168", "List of root folders whose combined content represents the structure of the project at runtime."),
        Show_all_compiler_options: diag(6169, ts.DiagnosticCategory.Message, "Show_all_compiler_options_6169", "Show all compiler options."),
        Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file: diag(6170, ts.DiagnosticCategory.Message, "Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170", "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file"),
        Command_line_Options: diag(6171, ts.DiagnosticCategory.Message, "Command_line_Options_6171", "Command-line Options"),
        Basic_Options: diag(6172, ts.DiagnosticCategory.Message, "Basic_Options_6172", "Basic Options"),
        Strict_Type_Checking_Options: diag(6173, ts.DiagnosticCategory.Message, "Strict_Type_Checking_Options_6173", "Strict Type-Checking Options"),
        Module_Resolution_Options: diag(6174, ts.DiagnosticCategory.Message, "Module_Resolution_Options_6174", "Module Resolution Options"),
        Source_Map_Options: diag(6175, ts.DiagnosticCategory.Message, "Source_Map_Options_6175", "Source Map Options"),
        Additional_Checks: diag(6176, ts.DiagnosticCategory.Message, "Additional_Checks_6176", "Additional Checks"),
        Experimental_Options: diag(6177, ts.DiagnosticCategory.Message, "Experimental_Options_6177", "Experimental Options"),
        Advanced_Options: diag(6178, ts.DiagnosticCategory.Message, "Advanced_Options_6178", "Advanced Options"),
        Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3: diag(6179, ts.DiagnosticCategory.Message, "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3_6179", "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'."),
        Enable_all_strict_type_checking_options: diag(6180, ts.DiagnosticCategory.Message, "Enable_all_strict_type_checking_options_6180", "Enable all strict type-checking options."),
        List_of_language_service_plugins: diag(6181, ts.DiagnosticCategory.Message, "List_of_language_service_plugins_6181", "List of language service plugins."),
        Scoped_package_detected_looking_in_0: diag(6182, ts.DiagnosticCategory.Message, "Scoped_package_detected_looking_in_0_6182", "Scoped package detected, looking in '{0}'"),
        Reusing_resolution_of_module_0_to_file_1_from_old_program: diag(6183, ts.DiagnosticCategory.Message, "Reusing_resolution_of_module_0_to_file_1_from_old_program_6183", "Reusing resolution of module '{0}' to file '{1}' from old program."),
        Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program: diag(6184, ts.DiagnosticCategory.Message, "Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program_6184", "Reusing module resolutions originating in '{0}' since resolutions are unchanged from old program."),
        Disable_strict_checking_of_generic_signatures_in_function_types: diag(6185, ts.DiagnosticCategory.Message, "Disable_strict_checking_of_generic_signatures_in_function_types_6185", "Disable strict checking of generic signatures in function types."),
        Enable_strict_checking_of_function_types: diag(6186, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_function_types_6186", "Enable strict checking of function types."),
        Enable_strict_checking_of_property_initialization_in_classes: diag(6187, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_property_initialization_in_classes_6187", "Enable strict checking of property initialization in classes."),
        Numeric_separators_are_not_allowed_here: diag(6188, ts.DiagnosticCategory.Error, "Numeric_separators_are_not_allowed_here_6188", "Numeric separators are not allowed here."),
        Multiple_consecutive_numeric_separators_are_not_permitted: diag(6189, ts.DiagnosticCategory.Error, "Multiple_consecutive_numeric_separators_are_not_permitted_6189", "Multiple consecutive numeric separators are not permitted."),
        Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen: diag(6191, ts.DiagnosticCategory.Message, "Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen_6191", "Whether to keep outdated console output in watch mode instead of clearing the screen."),
        All_imports_in_import_declaration_are_unused: diag(6192, ts.DiagnosticCategory.Error, "All_imports_in_import_declaration_are_unused_6192", "All imports in import declaration are unused.", /*reportsUnnecessary*/ true),
        Found_1_error_Watching_for_file_changes: diag(6193, ts.DiagnosticCategory.Message, "Found_1_error_Watching_for_file_changes_6193", "Found 1 error. Watching for file changes."),
        Found_0_errors_Watching_for_file_changes: diag(6194, ts.DiagnosticCategory.Message, "Found_0_errors_Watching_for_file_changes_6194", "Found {0} errors. Watching for file changes."),
        Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols: diag(6195, ts.DiagnosticCategory.Message, "Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195", "Resolve 'keyof' to string valued property names only (no numbers or symbols)."),
        _0_is_declared_but_never_used: diag(6196, ts.DiagnosticCategory.Error, "_0_is_declared_but_never_used_6196", "'{0}' is declared but never used.", /*reportsUnnecessary*/ true),
        Include_modules_imported_with_json_extension: diag(6197, ts.DiagnosticCategory.Message, "Include_modules_imported_with_json_extension_6197", "Include modules imported with '.json' extension"),
        All_destructured_elements_are_unused: diag(6198, ts.DiagnosticCategory.Error, "All_destructured_elements_are_unused_6198", "All destructured elements are unused.", /*reportsUnnecessary*/ true),
        All_variables_are_unused: diag(6199, ts.DiagnosticCategory.Error, "All_variables_are_unused_6199", "All variables are unused.", /*reportsUnnecessary*/ true),
        Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0: diag(6200, ts.DiagnosticCategory.Error, "Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0_6200", "Definitions of the following identifiers conflict with those in another file: {0}"),
        Conflicts_are_in_this_file: diag(6201, ts.DiagnosticCategory.Message, "Conflicts_are_in_this_file_6201", "Conflicts are in this file."),
        Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0: diag(6202, ts.DiagnosticCategory.Error, "Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0_6202", "Project references may not form a circular graph. Cycle detected: {0}"),
        _0_was_also_declared_here: diag(6203, ts.DiagnosticCategory.Message, "_0_was_also_declared_here_6203", "'{0}' was also declared here."),
        and_here: diag(6204, ts.DiagnosticCategory.Message, "and_here_6204", "and here."),
        All_type_parameters_are_unused: diag(6205, ts.DiagnosticCategory.Error, "All_type_parameters_are_unused_6205", "All type parameters are unused"),
        package_json_has_a_typesVersions_field_with_version_specific_path_mappings: diag(6206, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_field_with_version_specific_path_mappings_6206", "'package.json' has a 'typesVersions' field with version-specific path mappings."),
        package_json_does_not_have_a_typesVersions_entry_that_matches_version_0: diag(6207, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_typesVersions_entry_that_matches_version_0_6207", "'package.json' does not have a 'typesVersions' entry that matches version '{0}'."),
        package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2: diag(6208, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_ma_6208", "'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'."),
        package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range: diag(6209, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range_6209", "'package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range."),
        An_argument_for_0_was_not_provided: diag(6210, ts.DiagnosticCategory.Message, "An_argument_for_0_was_not_provided_6210", "An argument for '{0}' was not provided."),
        An_argument_matching_this_binding_pattern_was_not_provided: diag(6211, ts.DiagnosticCategory.Message, "An_argument_matching_this_binding_pattern_was_not_provided_6211", "An argument matching this binding pattern was not provided."),
        Did_you_mean_to_call_this_expression: diag(6212, ts.DiagnosticCategory.Message, "Did_you_mean_to_call_this_expression_6212", "Did you mean to call this expression?"),
        Did_you_mean_to_use_new_with_this_expression: diag(6213, ts.DiagnosticCategory.Message, "Did_you_mean_to_use_new_with_this_expression_6213", "Did you mean to use 'new' with this expression?"),
        Enable_strict_bind_call_and_apply_methods_on_functions: diag(6214, ts.DiagnosticCategory.Message, "Enable_strict_bind_call_and_apply_methods_on_functions_6214", "Enable strict 'bind', 'call', and 'apply' methods on functions."),
        Using_compiler_options_of_project_reference_redirect_0: diag(6215, ts.DiagnosticCategory.Message, "Using_compiler_options_of_project_reference_redirect_0_6215", "Using compiler options of project reference redirect '{0}'."),
        Found_1_error: diag(6216, ts.DiagnosticCategory.Message, "Found_1_error_6216", "Found 1 error."),
        Found_0_errors: diag(6217, ts.DiagnosticCategory.Message, "Found_0_errors_6217", "Found {0} errors."),
        Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2: diag(6218, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2_6218", "======== Module name '{0}' was successfully resolved to '{1}' with Package ID '{2}'. ========"),
        Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3: diag(6219, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3_6219", "======== Type reference directive '{0}' was successfully resolved to '{1}' with Package ID '{2}', primary: {3}. ========"),
        package_json_had_a_falsy_0_field: diag(6220, ts.DiagnosticCategory.Message, "package_json_had_a_falsy_0_field_6220", "'package.json' had a falsy '{0}' field."),
        Disable_use_of_source_files_instead_of_declaration_files_from_referenced_projects: diag(6221, ts.DiagnosticCategory.Message, "Disable_use_of_source_files_instead_of_declaration_files_from_referenced_projects_6221", "Disable use of source files instead of declaration files from referenced projects."),
        Emit_class_fields_with_Define_instead_of_Set: diag(6222, ts.DiagnosticCategory.Message, "Emit_class_fields_with_Define_instead_of_Set_6222", "Emit class fields with Define instead of Set."),
        Generates_a_CPU_profile: diag(6223, ts.DiagnosticCategory.Message, "Generates_a_CPU_profile_6223", "Generates a CPU profile."),
        Disable_solution_searching_for_this_project: diag(6224, ts.DiagnosticCategory.Message, "Disable_solution_searching_for_this_project_6224", "Disable solution searching for this project."),
        Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_DynamicPriorityPolling_UseFsEvents_UseFsEventsOnParentDirectory: diag(6225, ts.DiagnosticCategory.Message, "Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_Dynami_6225", "Specify strategy for watching file: 'FixedPollingInterval' (default), 'PriorityPollingInterval', 'DynamicPriorityPolling', 'UseFsEvents', 'UseFsEventsOnParentDirectory'."),
        Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively_Colon_UseFsEvents_default_FixedPollingInterval_DynamicPriorityPolling: diag(6226, ts.DiagnosticCategory.Message, "Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively__6226", "Specify strategy for watching directory on platforms that don't support recursive watching natively: 'UseFsEvents' (default), 'FixedPollingInterval', 'DynamicPriorityPolling'."),
        Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_FixedInterval_default_PriorityInterval_DynamicPriority: diag(6227, ts.DiagnosticCategory.Message, "Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_6227", "Specify strategy for creating a polling watch when it fails to create using file system events: 'FixedInterval' (default), 'PriorityInterval', 'DynamicPriority'."),
        Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively: diag(6228, ts.DiagnosticCategory.Message, "Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_supp_6228", "Synchronously call callbacks and update the state of directory watchers on platforms that don't support recursive watching natively."),
        Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3: diag(6229, ts.DiagnosticCategory.Error, "Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3_6229", "Tag '{0}' expects at least '{1}' arguments, but the JSX factory '{2}' provides at most '{3}'."),
        Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line: diag(6230, ts.DiagnosticCategory.Error, "Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line_6230", "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'false' or 'null' on command line."),
        Could_not_resolve_the_path_0_with_the_extensions_Colon_1: diag(6231, ts.DiagnosticCategory.Error, "Could_not_resolve_the_path_0_with_the_extensions_Colon_1_6231", "Could not resolve the path '{0}' with the extensions: {1}."),
        Declaration_augments_declaration_in_another_file_This_cannot_be_serialized: diag(6232, ts.DiagnosticCategory.Error, "Declaration_augments_declaration_in_another_file_This_cannot_be_serialized_6232", "Declaration augments declaration in another file. This cannot be serialized."),
        This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file: diag(6233, ts.DiagnosticCategory.Error, "This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_fil_6233", "This is the declaration being augmented. Consider moving the augmenting declaration into the same file."),
        Projects_to_reference: diag(6300, ts.DiagnosticCategory.Message, "Projects_to_reference_6300", "Projects to reference"),
        Enable_project_compilation: diag(6302, ts.DiagnosticCategory.Message, "Enable_project_compilation_6302", "Enable project compilation"),
        Composite_projects_may_not_disable_declaration_emit: diag(6304, ts.DiagnosticCategory.Error, "Composite_projects_may_not_disable_declaration_emit_6304", "Composite projects may not disable declaration emit."),
        Output_file_0_has_not_been_built_from_source_file_1: diag(6305, ts.DiagnosticCategory.Error, "Output_file_0_has_not_been_built_from_source_file_1_6305", "Output file '{0}' has not been built from source file '{1}'."),
        Referenced_project_0_must_have_setting_composite_Colon_true: diag(6306, ts.DiagnosticCategory.Error, "Referenced_project_0_must_have_setting_composite_Colon_true_6306", "Referenced project '{0}' must have setting \"composite\": true."),
        File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern: diag(6307, ts.DiagnosticCategory.Error, "File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_includ_6307", "File '{0}' is not listed within the file list of project '{1}'. Projects must list all files or use an 'include' pattern."),
        Cannot_prepend_project_0_because_it_does_not_have_outFile_set: diag(6308, ts.DiagnosticCategory.Error, "Cannot_prepend_project_0_because_it_does_not_have_outFile_set_6308", "Cannot prepend project '{0}' because it does not have 'outFile' set"),
        Output_file_0_from_project_1_does_not_exist: diag(6309, ts.DiagnosticCategory.Error, "Output_file_0_from_project_1_does_not_exist_6309", "Output file '{0}' from project '{1}' does not exist"),
        Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2: diag(6350, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2_6350", "Project '{0}' is out of date because oldest output '{1}' is older than newest input '{2}'"),
        Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2: diag(6351, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2_6351", "Project '{0}' is up to date because newest input '{1}' is older than oldest output '{2}'"),
        Project_0_is_out_of_date_because_output_file_1_does_not_exist: diag(6352, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_file_1_does_not_exist_6352", "Project '{0}' is out of date because output file '{1}' does not exist"),
        Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date: diag(6353, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date_6353", "Project '{0}' is out of date because its dependency '{1}' is out of date"),
        Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies: diag(6354, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies_6354", "Project '{0}' is up to date with .d.ts files from its dependencies"),
        Projects_in_this_build_Colon_0: diag(6355, ts.DiagnosticCategory.Message, "Projects_in_this_build_Colon_0_6355", "Projects in this build: {0}"),
        A_non_dry_build_would_delete_the_following_files_Colon_0: diag(6356, ts.DiagnosticCategory.Message, "A_non_dry_build_would_delete_the_following_files_Colon_0_6356", "A non-dry build would delete the following files: {0}"),
        A_non_dry_build_would_build_project_0: diag(6357, ts.DiagnosticCategory.Message, "A_non_dry_build_would_build_project_0_6357", "A non-dry build would build project '{0}'"),
        Building_project_0: diag(6358, ts.DiagnosticCategory.Message, "Building_project_0_6358", "Building project '{0}'..."),
        Updating_output_timestamps_of_project_0: diag(6359, ts.DiagnosticCategory.Message, "Updating_output_timestamps_of_project_0_6359", "Updating output timestamps of project '{0}'..."),
        delete_this_Project_0_is_up_to_date_because_it_was_previously_built: diag(6360, ts.DiagnosticCategory.Message, "delete_this_Project_0_is_up_to_date_because_it_was_previously_built_6360", "delete this - Project '{0}' is up to date because it was previously built"),
        Project_0_is_up_to_date: diag(6361, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_6361", "Project '{0}' is up to date"),
        Skipping_build_of_project_0_because_its_dependency_1_has_errors: diag(6362, ts.DiagnosticCategory.Message, "Skipping_build_of_project_0_because_its_dependency_1_has_errors_6362", "Skipping build of project '{0}' because its dependency '{1}' has errors"),
        Project_0_can_t_be_built_because_its_dependency_1_has_errors: diag(6363, ts.DiagnosticCategory.Message, "Project_0_can_t_be_built_because_its_dependency_1_has_errors_6363", "Project '{0}' can't be built because its dependency '{1}' has errors"),
        Build_one_or_more_projects_and_their_dependencies_if_out_of_date: diag(6364, ts.DiagnosticCategory.Message, "Build_one_or_more_projects_and_their_dependencies_if_out_of_date_6364", "Build one or more projects and their dependencies, if out of date"),
        Delete_the_outputs_of_all_projects: diag(6365, ts.DiagnosticCategory.Message, "Delete_the_outputs_of_all_projects_6365", "Delete the outputs of all projects"),
        Enable_verbose_logging: diag(6366, ts.DiagnosticCategory.Message, "Enable_verbose_logging_6366", "Enable verbose logging"),
        Show_what_would_be_built_or_deleted_if_specified_with_clean: diag(6367, ts.DiagnosticCategory.Message, "Show_what_would_be_built_or_deleted_if_specified_with_clean_6367", "Show what would be built (or deleted, if specified with '--clean')"),
        Build_all_projects_including_those_that_appear_to_be_up_to_date: diag(6368, ts.DiagnosticCategory.Message, "Build_all_projects_including_those_that_appear_to_be_up_to_date_6368", "Build all projects, including those that appear to be up to date"),
        Option_build_must_be_the_first_command_line_argument: diag(6369, ts.DiagnosticCategory.Error, "Option_build_must_be_the_first_command_line_argument_6369", "Option '--build' must be the first command line argument."),
        Options_0_and_1_cannot_be_combined: diag(6370, ts.DiagnosticCategory.Error, "Options_0_and_1_cannot_be_combined_6370", "Options '{0}' and '{1}' cannot be combined."),
        Updating_unchanged_output_timestamps_of_project_0: diag(6371, ts.DiagnosticCategory.Message, "Updating_unchanged_output_timestamps_of_project_0_6371", "Updating unchanged output timestamps of project '{0}'..."),
        Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed: diag(6372, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed_6372", "Project '{0}' is out of date because output of its dependency '{1}' has changed"),
        Updating_output_of_project_0: diag(6373, ts.DiagnosticCategory.Message, "Updating_output_of_project_0_6373", "Updating output of project '{0}'..."),
        A_non_dry_build_would_update_timestamps_for_output_of_project_0: diag(6374, ts.DiagnosticCategory.Message, "A_non_dry_build_would_update_timestamps_for_output_of_project_0_6374", "A non-dry build would update timestamps for output of project '{0}'"),
        A_non_dry_build_would_update_output_of_project_0: diag(6375, ts.DiagnosticCategory.Message, "A_non_dry_build_would_update_output_of_project_0_6375", "A non-dry build would update output of project '{0}'"),
        Cannot_update_output_of_project_0_because_there_was_error_reading_file_1: diag(6376, ts.DiagnosticCategory.Message, "Cannot_update_output_of_project_0_because_there_was_error_reading_file_1_6376", "Cannot update output of project '{0}' because there was error reading file '{1}'"),
        Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1: diag(6377, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1_6377", "Cannot write file '{0}' because it will overwrite '.tsbuildinfo' file generated by referenced project '{1}'"),
        Enable_incremental_compilation: diag(6378, ts.DiagnosticCategory.Message, "Enable_incremental_compilation_6378", "Enable incremental compilation"),
        Composite_projects_may_not_disable_incremental_compilation: diag(6379, ts.DiagnosticCategory.Error, "Composite_projects_may_not_disable_incremental_compilation_6379", "Composite projects may not disable incremental compilation."),
        Specify_file_to_store_incremental_compilation_information: diag(6380, ts.DiagnosticCategory.Message, "Specify_file_to_store_incremental_compilation_information_6380", "Specify file to store incremental compilation information"),
        Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2: diag(6381, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_curren_6381", "Project '{0}' is out of date because output for it was generated with version '{1}' that differs with current version '{2}'"),
        Skipping_build_of_project_0_because_its_dependency_1_was_not_built: diag(6382, ts.DiagnosticCategory.Message, "Skipping_build_of_project_0_because_its_dependency_1_was_not_built_6382", "Skipping build of project '{0}' because its dependency '{1}' was not built"),
        Project_0_can_t_be_built_because_its_dependency_1_was_not_built: diag(6383, ts.DiagnosticCategory.Message, "Project_0_can_t_be_built_because_its_dependency_1_was_not_built_6383", "Project '{0}' can't be built because its dependency '{1}' was not built"),
        Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it: diag(6384, ts.DiagnosticCategory.Message, "Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_di_6384", "Have recompiles in '--incremental' and '--watch' assume that changes within a file will only affect files directly depending on it."),
        The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1: diag(6500, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1_6500", "The expected type comes from property '{0}' which is declared here on type '{1}'"),
        The_expected_type_comes_from_this_index_signature: diag(6501, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_this_index_signature_6501", "The expected type comes from this index signature."),
        The_expected_type_comes_from_the_return_type_of_this_signature: diag(6502, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_the_return_type_of_this_signature_6502", "The expected type comes from the return type of this signature."),
        Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing: diag(6503, ts.DiagnosticCategory.Message, "Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing_6503", "Print names of files that are part of the compilation and then stop processing."),
        File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option: diag(6504, ts.DiagnosticCategory.Error, "File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option_6504", "File '{0}' is a JavaScript file. Did you mean to enable the 'allowJs' option?"),
        Variable_0_implicitly_has_an_1_type: diag(7005, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_an_1_type_7005", "Variable '{0}' implicitly has an '{1}' type."),
        Parameter_0_implicitly_has_an_1_type: diag(7006, ts.DiagnosticCategory.Error, "Parameter_0_implicitly_has_an_1_type_7006", "Parameter '{0}' implicitly has an '{1}' type."),
        Member_0_implicitly_has_an_1_type: diag(7008, ts.DiagnosticCategory.Error, "Member_0_implicitly_has_an_1_type_7008", "Member '{0}' implicitly has an '{1}' type."),
        new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: diag(7009, ts.DiagnosticCategory.Error, "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009", "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type."),
        _0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: diag(7010, ts.DiagnosticCategory.Error, "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010", "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type."),
        Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7011, ts.DiagnosticCategory.Error, "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011", "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type."),
        Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7013, ts.DiagnosticCategory.Error, "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013", "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type."),
        Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7014, ts.DiagnosticCategory.Error, "Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7014", "Function type, which lacks return-type annotation, implicitly has an '{0}' return type."),
        Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number: diag(7015, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015", "Element implicitly has an 'any' type because index expression is not of type 'number'."),
        Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type: diag(7016, ts.DiagnosticCategory.Error, "Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type_7016", "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type."),
        Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature: diag(7017, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017", "Element implicitly has an 'any' type because type '{0}' has no index signature."),
        Object_literal_s_property_0_implicitly_has_an_1_type: diag(7018, ts.DiagnosticCategory.Error, "Object_literal_s_property_0_implicitly_has_an_1_type_7018", "Object literal's property '{0}' implicitly has an '{1}' type."),
        Rest_parameter_0_implicitly_has_an_any_type: diag(7019, ts.DiagnosticCategory.Error, "Rest_parameter_0_implicitly_has_an_any_type_7019", "Rest parameter '{0}' implicitly has an 'any[]' type."),
        Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7020, ts.DiagnosticCategory.Error, "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020", "Call signature, which lacks return-type annotation, implicitly has an 'any' return type."),
        _0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: diag(7022, ts.DiagnosticCategory.Error, "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022", "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer."),
        _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7023, ts.DiagnosticCategory.Error, "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023", "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
        Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7024, ts.DiagnosticCategory.Error, "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024", "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
        Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type_annotation: diag(7025, ts.DiagnosticCategory.Error, "Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_retu_7025", "Generator implicitly has yield type '{0}' because it does not yield any values. Consider supplying a return type annotation."),
        JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: diag(7026, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026", "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists."),
        Unreachable_code_detected: diag(7027, ts.DiagnosticCategory.Error, "Unreachable_code_detected_7027", "Unreachable code detected.", /*reportsUnnecessary*/ true),
        Unused_label: diag(7028, ts.DiagnosticCategory.Error, "Unused_label_7028", "Unused label.", /*reportsUnnecessary*/ true),
        Fallthrough_case_in_switch: diag(7029, ts.DiagnosticCategory.Error, "Fallthrough_case_in_switch_7029", "Fallthrough case in switch."),
        Not_all_code_paths_return_a_value: diag(7030, ts.DiagnosticCategory.Error, "Not_all_code_paths_return_a_value_7030", "Not all code paths return a value."),
        Binding_element_0_implicitly_has_an_1_type: diag(7031, ts.DiagnosticCategory.Error, "Binding_element_0_implicitly_has_an_1_type_7031", "Binding element '{0}' implicitly has an '{1}' type."),
        Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation: diag(7032, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation_7032", "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation."),
        Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation: diag(7033, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation_7033", "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation."),
        Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined: diag(7034, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034", "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined."),
        Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0: diag(7035, ts.DiagnosticCategory.Error, "Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035", "Try `npm install @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`"),
        Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0: diag(7036, ts.DiagnosticCategory.Error, "Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036", "Dynamic import's specifier must be of type 'string', but here has type '{0}'."),
        Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports: diag(7037, ts.DiagnosticCategory.Message, "Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for__7037", "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'."),
        Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead: diag(7038, ts.DiagnosticCategory.Message, "Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cau_7038", "Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead."),
        Mapped_object_type_implicitly_has_an_any_template_type: diag(7039, ts.DiagnosticCategory.Error, "Mapped_object_type_implicitly_has_an_any_template_type_7039", "Mapped object type implicitly has an 'any' template type."),
        If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1: diag(7040, ts.DiagnosticCategory.Error, "If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_S_7040", "If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}`"),
        The_containing_arrow_function_captures_the_global_value_of_this: diag(7041, ts.DiagnosticCategory.Error, "The_containing_arrow_function_captures_the_global_value_of_this_7041", "The containing arrow function captures the global value of 'this'."),
        Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used: diag(7042, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used_7042", "Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used."),
        Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7043, ts.DiagnosticCategory.Suggestion, "Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7043", "Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7044, ts.DiagnosticCategory.Suggestion, "Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7044", "Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7045, ts.DiagnosticCategory.Suggestion, "Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7045", "Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage: diag(7046, ts.DiagnosticCategory.Suggestion, "Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage_7046", "Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage."),
        Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage: diag(7047, ts.DiagnosticCategory.Suggestion, "Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage_7047", "Rest parameter '{0}' implicitly has an 'any[]' type, but a better type may be inferred from usage."),
        Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage: diag(7048, ts.DiagnosticCategory.Suggestion, "Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage_7048", "Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage."),
        Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage: diag(7049, ts.DiagnosticCategory.Suggestion, "Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage_7049", "Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage."),
        _0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage: diag(7050, ts.DiagnosticCategory.Suggestion, "_0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage_7050", "'{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage."),
        Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1: diag(7051, ts.DiagnosticCategory.Error, "Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1_7051", "Parameter has a name but no type. Did you mean '{0}: {1}'?"),
        Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1: diag(7052, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1_7052", "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}'?"),
        Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1: diag(7053, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1_7053", "Element implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'."),
        No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1: diag(7054, ts.DiagnosticCategory.Error, "No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1_7054", "No index signature with a parameter of type '{0}' was found on type '{1}'."),
        _0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type: diag(7055, ts.DiagnosticCategory.Error, "_0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type_7055", "'{0}', which lacks return-type annotation, implicitly has an '{1}' yield type."),
        You_cannot_rename_this_element: diag(8000, ts.DiagnosticCategory.Error, "You_cannot_rename_this_element_8000", "You cannot rename this element."),
        You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: diag(8001, ts.DiagnosticCategory.Error, "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001", "You cannot rename elements that are defined in the standard TypeScript library."),
        import_can_only_be_used_in_TypeScript_files: diag(8002, ts.DiagnosticCategory.Error, "import_can_only_be_used_in_TypeScript_files_8002", "'import ... =' can only be used in TypeScript files."),
        export_can_only_be_used_in_TypeScript_files: diag(8003, ts.DiagnosticCategory.Error, "export_can_only_be_used_in_TypeScript_files_8003", "'export =' can only be used in TypeScript files."),
        Type_parameter_declarations_can_only_be_used_in_TypeScript_files: diag(8004, ts.DiagnosticCategory.Error, "Type_parameter_declarations_can_only_be_used_in_TypeScript_files_8004", "Type parameter declarations can only be used in TypeScript files."),
        implements_clauses_can_only_be_used_in_TypeScript_files: diag(8005, ts.DiagnosticCategory.Error, "implements_clauses_can_only_be_used_in_TypeScript_files_8005", "'implements' clauses can only be used in TypeScript files."),
        _0_declarations_can_only_be_used_in_TypeScript_files: diag(8006, ts.DiagnosticCategory.Error, "_0_declarations_can_only_be_used_in_TypeScript_files_8006", "'{0}' declarations can only be used in TypeScript files."),
        Type_aliases_can_only_be_used_in_TypeScript_files: diag(8008, ts.DiagnosticCategory.Error, "Type_aliases_can_only_be_used_in_TypeScript_files_8008", "Type aliases can only be used in TypeScript files."),
        The_0_modifier_can_only_be_used_in_TypeScript_files: diag(8009, ts.DiagnosticCategory.Error, "The_0_modifier_can_only_be_used_in_TypeScript_files_8009", "The '{0}' modifier can only be used in TypeScript files."),
        Type_annotations_can_only_be_used_in_TypeScript_files: diag(8010, ts.DiagnosticCategory.Error, "Type_annotations_can_only_be_used_in_TypeScript_files_8010", "Type annotations can only be used in TypeScript files."),
        Type_arguments_can_only_be_used_in_TypeScript_files: diag(8011, ts.DiagnosticCategory.Error, "Type_arguments_can_only_be_used_in_TypeScript_files_8011", "Type arguments can only be used in TypeScript files."),
        Parameter_modifiers_can_only_be_used_in_TypeScript_files: diag(8012, ts.DiagnosticCategory.Error, "Parameter_modifiers_can_only_be_used_in_TypeScript_files_8012", "Parameter modifiers can only be used in TypeScript files."),
        Non_null_assertions_can_only_be_used_in_TypeScript_files: diag(8013, ts.DiagnosticCategory.Error, "Non_null_assertions_can_only_be_used_in_TypeScript_files_8013", "Non-null assertions can only be used in TypeScript files."),
        Type_assertion_expressions_can_only_be_used_in_TypeScript_files: diag(8016, ts.DiagnosticCategory.Error, "Type_assertion_expressions_can_only_be_used_in_TypeScript_files_8016", "Type assertion expressions can only be used in TypeScript files."),
        Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0: diag(8017, ts.DiagnosticCategory.Error, "Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0_8017", "Octal literal types must use ES2015 syntax. Use the syntax '{0}'."),
        Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0: diag(8018, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0_8018", "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'."),
        Report_errors_in_js_files: diag(8019, ts.DiagnosticCategory.Message, "Report_errors_in_js_files_8019", "Report errors in .js files."),
        JSDoc_types_can_only_be_used_inside_documentation_comments: diag(8020, ts.DiagnosticCategory.Error, "JSDoc_types_can_only_be_used_inside_documentation_comments_8020", "JSDoc types can only be used inside documentation comments."),
        JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags: diag(8021, ts.DiagnosticCategory.Error, "JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021", "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags."),
        JSDoc_0_is_not_attached_to_a_class: diag(8022, ts.DiagnosticCategory.Error, "JSDoc_0_is_not_attached_to_a_class_8022", "JSDoc '@{0}' is not attached to a class."),
        JSDoc_0_1_does_not_match_the_extends_2_clause: diag(8023, ts.DiagnosticCategory.Error, "JSDoc_0_1_does_not_match_the_extends_2_clause_8023", "JSDoc '@{0} {1}' does not match the 'extends {2}' clause."),
        JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name: diag(8024, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name."),
        Class_declarations_cannot_have_more_than_one_augments_or_extends_tag: diag(8025, ts.DiagnosticCategory.Error, "Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025", "Class declarations cannot have more than one `@augments` or `@extends` tag."),
        Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."),
        Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."),
        JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."),
        JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."),
        The_type_of_a_function_declaration_must_match_the_function_s_signature: diag(8030, ts.DiagnosticCategory.Error, "The_type_of_a_function_declaration_must_match_the_function_s_signature_8030", "The type of a function declaration must match the function's signature."),
        You_cannot_rename_a_module_via_a_global_import: diag(8031, ts.DiagnosticCategory.Error, "You_cannot_rename_a_module_via_a_global_import_8031", "You cannot rename a module via a global import."),
        Qualified_name_0_is_not_allowed_without_a_leading_param_object_1: diag(8032, ts.DiagnosticCategory.Error, "Qualified_name_0_is_not_allowed_without_a_leading_param_object_1_8032", "Qualified name '{0}' is not allowed without a leading '@param {object} {1}'."),
        Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."),
        class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."),
        Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."),
        Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit: diag(9005, ts.DiagnosticCategory.Error, "Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_9005", "Declaration emit for this file requires using private name '{0}'. An explicit type annotation may unblock declaration emit."),
        Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit: diag(9006, ts.DiagnosticCategory.Error, "Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotati_9006", "Declaration emit for this file requires using private name '{0}' from module '{1}'. An explicit type annotation may unblock declaration emit."),
        JSX_attributes_must_only_be_assigned_a_non_empty_expression: diag(17000, ts.DiagnosticCategory.Error, "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000", "JSX attributes must only be assigned a non-empty 'expression'."),
        JSX_elements_cannot_have_multiple_attributes_with_the_same_name: diag(17001, ts.DiagnosticCategory.Error, "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001", "JSX elements cannot have multiple attributes with the same name."),
        Expected_corresponding_JSX_closing_tag_for_0: diag(17002, ts.DiagnosticCategory.Error, "Expected_corresponding_JSX_closing_tag_for_0_17002", "Expected corresponding JSX closing tag for '{0}'."),
        JSX_attribute_expected: diag(17003, ts.DiagnosticCategory.Error, "JSX_attribute_expected_17003", "JSX attribute expected."),
        Cannot_use_JSX_unless_the_jsx_flag_is_provided: diag(17004, ts.DiagnosticCategory.Error, "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004", "Cannot use JSX unless the '--jsx' flag is provided."),
        A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: diag(17005, ts.DiagnosticCategory.Error, "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005", "A constructor cannot contain a 'super' call when its class extends 'null'."),
        An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17006, ts.DiagnosticCategory.Error, "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006", "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
        A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17007, ts.DiagnosticCategory.Error, "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007", "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
        JSX_element_0_has_no_corresponding_closing_tag: diag(17008, ts.DiagnosticCategory.Error, "JSX_element_0_has_no_corresponding_closing_tag_17008", "JSX element '{0}' has no corresponding closing tag."),
        super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class: diag(17009, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009", "'super' must be called before accessing 'this' in the constructor of a derived class."),
        Unknown_type_acquisition_option_0: diag(17010, ts.DiagnosticCategory.Error, "Unknown_type_acquisition_option_0_17010", "Unknown type acquisition option '{0}'."),
        super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class: diag(17011, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class_17011", "'super' must be called before accessing a property of 'super' in the constructor of a derived class."),
        _0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2: diag(17012, ts.DiagnosticCategory.Error, "_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012", "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?"),
        Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor: diag(17013, ts.DiagnosticCategory.Error, "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013", "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor."),
        JSX_fragment_has_no_corresponding_closing_tag: diag(17014, ts.DiagnosticCategory.Error, "JSX_fragment_has_no_corresponding_closing_tag_17014", "JSX fragment has no corresponding closing tag."),
        Expected_corresponding_closing_tag_for_JSX_fragment: diag(17015, ts.DiagnosticCategory.Error, "Expected_corresponding_closing_tag_for_JSX_fragment_17015", "Expected corresponding closing tag for JSX fragment."),
        JSX_fragment_is_not_supported_when_using_jsxFactory: diag(17016, ts.DiagnosticCategory.Error, "JSX_fragment_is_not_supported_when_using_jsxFactory_17016", "JSX fragment is not supported when using --jsxFactory"),
        JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma: diag(17017, ts.DiagnosticCategory.Error, "JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma_17017", "JSX fragment is not supported when using an inline JSX factory pragma"),
        Unknown_type_acquisition_option_0_Did_you_mean_1: diag(17018, ts.DiagnosticCategory.Error, "Unknown_type_acquisition_option_0_Did_you_mean_1_17018", "Unknown type acquisition option '{0}'. Did you mean '{1}'?"),
        Circularity_detected_while_resolving_configuration_Colon_0: diag(18000, ts.DiagnosticCategory.Error, "Circularity_detected_while_resolving_configuration_Colon_0_18000", "Circularity detected while resolving configuration: {0}"),
        A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not: diag(18001, ts.DiagnosticCategory.Error, "A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not_18001", "A path in an 'extends' option must be relative or rooted, but '{0}' is not."),
        The_files_list_in_config_file_0_is_empty: diag(18002, ts.DiagnosticCategory.Error, "The_files_list_in_config_file_0_is_empty_18002", "The 'files' list in config file '{0}' is empty."),
        No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2: diag(18003, ts.DiagnosticCategory.Error, "No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2_18003", "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'."),
        File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module: diag(80001, ts.DiagnosticCategory.Suggestion, "File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module_80001", "File is a CommonJS module; it may be converted to an ES6 module."),
        This_constructor_function_may_be_converted_to_a_class_declaration: diag(80002, ts.DiagnosticCategory.Suggestion, "This_constructor_function_may_be_converted_to_a_class_declaration_80002", "This constructor function may be converted to a class declaration."),
        Import_may_be_converted_to_a_default_import: diag(80003, ts.DiagnosticCategory.Suggestion, "Import_may_be_converted_to_a_default_import_80003", "Import may be converted to a default import."),
        JSDoc_types_may_be_moved_to_TypeScript_types: diag(80004, ts.DiagnosticCategory.Suggestion, "JSDoc_types_may_be_moved_to_TypeScript_types_80004", "JSDoc types may be moved to TypeScript types."),
        require_call_may_be_converted_to_an_import: diag(80005, ts.DiagnosticCategory.Suggestion, "require_call_may_be_converted_to_an_import_80005", "'require' call may be converted to an import."),
        This_may_be_converted_to_an_async_function: diag(80006, ts.DiagnosticCategory.Suggestion, "This_may_be_converted_to_an_async_function_80006", "This may be converted to an async function."),
        await_has_no_effect_on_the_type_of_this_expression: diag(80007, ts.DiagnosticCategory.Suggestion, "await_has_no_effect_on_the_type_of_this_expression_80007", "'await' has no effect on the type of this expression."),
        Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers: diag(80008, ts.DiagnosticCategory.Suggestion, "Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accur_80008", "Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as integers."),
        Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"),
        Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"),
        Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"),
        Remove_unused_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_unused_declaration_for_Colon_0_90004", "Remove unused declaration for: '{0}'"),
        Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"),
        Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"),
        Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"),
        Add_0_to_unresolved_variable: diag(90008, ts.DiagnosticCategory.Message, "Add_0_to_unresolved_variable_90008", "Add '{0}.' to unresolved variable"),
        Remove_destructuring: diag(90009, ts.DiagnosticCategory.Message, "Remove_destructuring_90009", "Remove destructuring"),
        Remove_variable_statement: diag(90010, ts.DiagnosticCategory.Message, "Remove_variable_statement_90010", "Remove variable statement"),
        Remove_template_tag: diag(90011, ts.DiagnosticCategory.Message, "Remove_template_tag_90011", "Remove template tag"),
        Remove_type_parameters: diag(90012, ts.DiagnosticCategory.Message, "Remove_type_parameters_90012", "Remove type parameters"),
        Import_0_from_module_1: diag(90013, ts.DiagnosticCategory.Message, "Import_0_from_module_1_90013", "Import '{0}' from module \"{1}\""),
        Change_0_to_1: diag(90014, ts.DiagnosticCategory.Message, "Change_0_to_1_90014", "Change '{0}' to '{1}'"),
        Add_0_to_existing_import_declaration_from_1: diag(90015, ts.DiagnosticCategory.Message, "Add_0_to_existing_import_declaration_from_1_90015", "Add '{0}' to existing import declaration from \"{1}\""),
        Declare_property_0: diag(90016, ts.DiagnosticCategory.Message, "Declare_property_0_90016", "Declare property '{0}'"),
        Add_index_signature_for_property_0: diag(90017, ts.DiagnosticCategory.Message, "Add_index_signature_for_property_0_90017", "Add index signature for property '{0}'"),
        Disable_checking_for_this_file: diag(90018, ts.DiagnosticCategory.Message, "Disable_checking_for_this_file_90018", "Disable checking for this file"),
        Ignore_this_error_message: diag(90019, ts.DiagnosticCategory.Message, "Ignore_this_error_message_90019", "Ignore this error message"),
        Initialize_property_0_in_the_constructor: diag(90020, ts.DiagnosticCategory.Message, "Initialize_property_0_in_the_constructor_90020", "Initialize property '{0}' in the constructor"),
        Initialize_static_property_0: diag(90021, ts.DiagnosticCategory.Message, "Initialize_static_property_0_90021", "Initialize static property '{0}'"),
        Change_spelling_to_0: diag(90022, ts.DiagnosticCategory.Message, "Change_spelling_to_0_90022", "Change spelling to '{0}'"),
        Declare_method_0: diag(90023, ts.DiagnosticCategory.Message, "Declare_method_0_90023", "Declare method '{0}'"),
        Declare_static_method_0: diag(90024, ts.DiagnosticCategory.Message, "Declare_static_method_0_90024", "Declare static method '{0}'"),
        Prefix_0_with_an_underscore: diag(90025, ts.DiagnosticCategory.Message, "Prefix_0_with_an_underscore_90025", "Prefix '{0}' with an underscore"),
        Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'"),
        Declare_static_property_0: diag(90027, ts.DiagnosticCategory.Message, "Declare_static_property_0_90027", "Declare static property '{0}'"),
        Call_decorator_expression: diag(90028, ts.DiagnosticCategory.Message, "Call_decorator_expression_90028", "Call decorator expression"),
        Add_async_modifier_to_containing_function: diag(90029, ts.DiagnosticCategory.Message, "Add_async_modifier_to_containing_function_90029", "Add async modifier to containing function"),
        Replace_infer_0_with_unknown: diag(90030, ts.DiagnosticCategory.Message, "Replace_infer_0_with_unknown_90030", "Replace 'infer {0}' with 'unknown'"),
        Replace_all_unused_infer_with_unknown: diag(90031, ts.DiagnosticCategory.Message, "Replace_all_unused_infer_with_unknown_90031", "Replace all unused 'infer' with 'unknown'"),
        Import_default_0_from_module_1: diag(90032, ts.DiagnosticCategory.Message, "Import_default_0_from_module_1_90032", "Import default '{0}' from module \"{1}\""),
        Add_default_import_0_to_existing_import_declaration_from_1: diag(90033, ts.DiagnosticCategory.Message, "Add_default_import_0_to_existing_import_declaration_from_1_90033", "Add default import '{0}' to existing import declaration from \"{1}\""),
        Add_parameter_name: diag(90034, ts.DiagnosticCategory.Message, "Add_parameter_name_90034", "Add parameter name"),
        Declare_private_property_0: diag(90035, ts.DiagnosticCategory.Message, "Declare_private_property_0_90035", "Declare private property '{0}'"),
        Declare_a_private_field_named_0: diag(90053, ts.DiagnosticCategory.Message, "Declare_a_private_field_named_0_90053", "Declare a private field named '{0}'."),
        Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"),
        Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"),
        Extract_to_0_in_1: diag(95004, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_95004", "Extract to {0} in {1}"),
        Extract_function: diag(95005, ts.DiagnosticCategory.Message, "Extract_function_95005", "Extract function"),
        Extract_constant: diag(95006, ts.DiagnosticCategory.Message, "Extract_constant_95006", "Extract constant"),
        Extract_to_0_in_enclosing_scope: diag(95007, ts.DiagnosticCategory.Message, "Extract_to_0_in_enclosing_scope_95007", "Extract to {0} in enclosing scope"),
        Extract_to_0_in_1_scope: diag(95008, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_scope_95008", "Extract to {0} in {1} scope"),
        Annotate_with_type_from_JSDoc: diag(95009, ts.DiagnosticCategory.Message, "Annotate_with_type_from_JSDoc_95009", "Annotate with type from JSDoc"),
        Annotate_with_types_from_JSDoc: diag(95010, ts.DiagnosticCategory.Message, "Annotate_with_types_from_JSDoc_95010", "Annotate with types from JSDoc"),
        Infer_type_of_0_from_usage: diag(95011, ts.DiagnosticCategory.Message, "Infer_type_of_0_from_usage_95011", "Infer type of '{0}' from usage"),
        Infer_parameter_types_from_usage: diag(95012, ts.DiagnosticCategory.Message, "Infer_parameter_types_from_usage_95012", "Infer parameter types from usage"),
        Convert_to_default_import: diag(95013, ts.DiagnosticCategory.Message, "Convert_to_default_import_95013", "Convert to default import"),
        Install_0: diag(95014, ts.DiagnosticCategory.Message, "Install_0_95014", "Install '{0}'"),
        Replace_import_with_0: diag(95015, ts.DiagnosticCategory.Message, "Replace_import_with_0_95015", "Replace import with '{0}'."),
        Use_synthetic_default_member: diag(95016, ts.DiagnosticCategory.Message, "Use_synthetic_default_member_95016", "Use synthetic 'default' member."),
        Convert_to_ES6_module: diag(95017, ts.DiagnosticCategory.Message, "Convert_to_ES6_module_95017", "Convert to ES6 module"),
        Add_undefined_type_to_property_0: diag(95018, ts.DiagnosticCategory.Message, "Add_undefined_type_to_property_0_95018", "Add 'undefined' type to property '{0}'"),
        Add_initializer_to_property_0: diag(95019, ts.DiagnosticCategory.Message, "Add_initializer_to_property_0_95019", "Add initializer to property '{0}'"),
        Add_definite_assignment_assertion_to_property_0: diag(95020, ts.DiagnosticCategory.Message, "Add_definite_assignment_assertion_to_property_0_95020", "Add definite assignment assertion to property '{0}'"),
        Add_all_missing_members: diag(95022, ts.DiagnosticCategory.Message, "Add_all_missing_members_95022", "Add all missing members"),
        Infer_all_types_from_usage: diag(95023, ts.DiagnosticCategory.Message, "Infer_all_types_from_usage_95023", "Infer all types from usage"),
        Delete_all_unused_declarations: diag(95024, ts.DiagnosticCategory.Message, "Delete_all_unused_declarations_95024", "Delete all unused declarations"),
        Prefix_all_unused_declarations_with_where_possible: diag(95025, ts.DiagnosticCategory.Message, "Prefix_all_unused_declarations_with_where_possible_95025", "Prefix all unused declarations with '_' where possible"),
        Fix_all_detected_spelling_errors: diag(95026, ts.DiagnosticCategory.Message, "Fix_all_detected_spelling_errors_95026", "Fix all detected spelling errors"),
        Add_initializers_to_all_uninitialized_properties: diag(95027, ts.DiagnosticCategory.Message, "Add_initializers_to_all_uninitialized_properties_95027", "Add initializers to all uninitialized properties"),
        Add_definite_assignment_assertions_to_all_uninitialized_properties: diag(95028, ts.DiagnosticCategory.Message, "Add_definite_assignment_assertions_to_all_uninitialized_properties_95028", "Add definite assignment assertions to all uninitialized properties"),
        Add_undefined_type_to_all_uninitialized_properties: diag(95029, ts.DiagnosticCategory.Message, "Add_undefined_type_to_all_uninitialized_properties_95029", "Add undefined type to all uninitialized properties"),
        Change_all_jsdoc_style_types_to_TypeScript: diag(95030, ts.DiagnosticCategory.Message, "Change_all_jsdoc_style_types_to_TypeScript_95030", "Change all jsdoc-style types to TypeScript"),
        Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types: diag(95031, ts.DiagnosticCategory.Message, "Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types_95031", "Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)"),
        Implement_all_unimplemented_interfaces: diag(95032, ts.DiagnosticCategory.Message, "Implement_all_unimplemented_interfaces_95032", "Implement all unimplemented interfaces"),
        Install_all_missing_types_packages: diag(95033, ts.DiagnosticCategory.Message, "Install_all_missing_types_packages_95033", "Install all missing types packages"),
        Rewrite_all_as_indexed_access_types: diag(95034, ts.DiagnosticCategory.Message, "Rewrite_all_as_indexed_access_types_95034", "Rewrite all as indexed access types"),
        Convert_all_to_default_imports: diag(95035, ts.DiagnosticCategory.Message, "Convert_all_to_default_imports_95035", "Convert all to default imports"),
        Make_all_super_calls_the_first_statement_in_their_constructor: diag(95036, ts.DiagnosticCategory.Message, "Make_all_super_calls_the_first_statement_in_their_constructor_95036", "Make all 'super()' calls the first statement in their constructor"),
        Add_qualifier_to_all_unresolved_variables_matching_a_member_name: diag(95037, ts.DiagnosticCategory.Message, "Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037", "Add qualifier to all unresolved variables matching a member name"),
        Change_all_extended_interfaces_to_implements: diag(95038, ts.DiagnosticCategory.Message, "Change_all_extended_interfaces_to_implements_95038", "Change all extended interfaces to 'implements'"),
        Add_all_missing_super_calls: diag(95039, ts.DiagnosticCategory.Message, "Add_all_missing_super_calls_95039", "Add all missing super calls"),
        Implement_all_inherited_abstract_classes: diag(95040, ts.DiagnosticCategory.Message, "Implement_all_inherited_abstract_classes_95040", "Implement all inherited abstract classes"),
        Add_all_missing_async_modifiers: diag(95041, ts.DiagnosticCategory.Message, "Add_all_missing_async_modifiers_95041", "Add all missing 'async' modifiers"),
        Add_ts_ignore_to_all_error_messages: diag(95042, ts.DiagnosticCategory.Message, "Add_ts_ignore_to_all_error_messages_95042", "Add '@ts-ignore' to all error messages"),
        Annotate_everything_with_types_from_JSDoc: diag(95043, ts.DiagnosticCategory.Message, "Annotate_everything_with_types_from_JSDoc_95043", "Annotate everything with types from JSDoc"),
        Add_to_all_uncalled_decorators: diag(95044, ts.DiagnosticCategory.Message, "Add_to_all_uncalled_decorators_95044", "Add '()' to all uncalled decorators"),
        Convert_all_constructor_functions_to_classes: diag(95045, ts.DiagnosticCategory.Message, "Convert_all_constructor_functions_to_classes_95045", "Convert all constructor functions to classes"),
        Generate_get_and_set_accessors: diag(95046, ts.DiagnosticCategory.Message, "Generate_get_and_set_accessors_95046", "Generate 'get' and 'set' accessors"),
        Convert_require_to_import: diag(95047, ts.DiagnosticCategory.Message, "Convert_require_to_import_95047", "Convert 'require' to 'import'"),
        Convert_all_require_to_import: diag(95048, ts.DiagnosticCategory.Message, "Convert_all_require_to_import_95048", "Convert all 'require' to 'import'"),
        Move_to_a_new_file: diag(95049, ts.DiagnosticCategory.Message, "Move_to_a_new_file_95049", "Move to a new file"),
        Remove_unreachable_code: diag(95050, ts.DiagnosticCategory.Message, "Remove_unreachable_code_95050", "Remove unreachable code"),
        Remove_all_unreachable_code: diag(95051, ts.DiagnosticCategory.Message, "Remove_all_unreachable_code_95051", "Remove all unreachable code"),
        Add_missing_typeof: diag(95052, ts.DiagnosticCategory.Message, "Add_missing_typeof_95052", "Add missing 'typeof'"),
        Remove_unused_label: diag(95053, ts.DiagnosticCategory.Message, "Remove_unused_label_95053", "Remove unused label"),
        Remove_all_unused_labels: diag(95054, ts.DiagnosticCategory.Message, "Remove_all_unused_labels_95054", "Remove all unused labels"),
        Convert_0_to_mapped_object_type: diag(95055, ts.DiagnosticCategory.Message, "Convert_0_to_mapped_object_type_95055", "Convert '{0}' to mapped object type"),
        Convert_namespace_import_to_named_imports: diag(95056, ts.DiagnosticCategory.Message, "Convert_namespace_import_to_named_imports_95056", "Convert namespace import to named imports"),
        Convert_named_imports_to_namespace_import: diag(95057, ts.DiagnosticCategory.Message, "Convert_named_imports_to_namespace_import_95057", "Convert named imports to namespace import"),
        Add_or_remove_braces_in_an_arrow_function: diag(95058, ts.DiagnosticCategory.Message, "Add_or_remove_braces_in_an_arrow_function_95058", "Add or remove braces in an arrow function"),
        Add_braces_to_arrow_function: diag(95059, ts.DiagnosticCategory.Message, "Add_braces_to_arrow_function_95059", "Add braces to arrow function"),
        Remove_braces_from_arrow_function: diag(95060, ts.DiagnosticCategory.Message, "Remove_braces_from_arrow_function_95060", "Remove braces from arrow function"),
        Convert_default_export_to_named_export: diag(95061, ts.DiagnosticCategory.Message, "Convert_default_export_to_named_export_95061", "Convert default export to named export"),
        Convert_named_export_to_default_export: diag(95062, ts.DiagnosticCategory.Message, "Convert_named_export_to_default_export_95062", "Convert named export to default export"),
        Add_missing_enum_member_0: diag(95063, ts.DiagnosticCategory.Message, "Add_missing_enum_member_0_95063", "Add missing enum member '{0}'"),
        Add_all_missing_imports: diag(95064, ts.DiagnosticCategory.Message, "Add_all_missing_imports_95064", "Add all missing imports"),
        Convert_to_async_function: diag(95065, ts.DiagnosticCategory.Message, "Convert_to_async_function_95065", "Convert to async function"),
        Convert_all_to_async_functions: diag(95066, ts.DiagnosticCategory.Message, "Convert_all_to_async_functions_95066", "Convert all to async functions"),
        Add_missing_call_parentheses: diag(95067, ts.DiagnosticCategory.Message, "Add_missing_call_parentheses_95067", "Add missing call parentheses"),
        Add_all_missing_call_parentheses: diag(95068, ts.DiagnosticCategory.Message, "Add_all_missing_call_parentheses_95068", "Add all missing call parentheses"),
        Add_unknown_conversion_for_non_overlapping_types: diag(95069, ts.DiagnosticCategory.Message, "Add_unknown_conversion_for_non_overlapping_types_95069", "Add 'unknown' conversion for non-overlapping types"),
        Add_unknown_to_all_conversions_of_non_overlapping_types: diag(95070, ts.DiagnosticCategory.Message, "Add_unknown_to_all_conversions_of_non_overlapping_types_95070", "Add 'unknown' to all conversions of non-overlapping types"),
        Add_missing_new_operator_to_call: diag(95071, ts.DiagnosticCategory.Message, "Add_missing_new_operator_to_call_95071", "Add missing 'new' operator to call"),
        Add_missing_new_operator_to_all_calls: diag(95072, ts.DiagnosticCategory.Message, "Add_missing_new_operator_to_all_calls_95072", "Add missing 'new' operator to all calls"),
        Add_names_to_all_parameters_without_names: diag(95073, ts.DiagnosticCategory.Message, "Add_names_to_all_parameters_without_names_95073", "Add names to all parameters without names"),
        Enable_the_experimentalDecorators_option_in_your_configuration_file: diag(95074, ts.DiagnosticCategory.Message, "Enable_the_experimentalDecorators_option_in_your_configuration_file_95074", "Enable the 'experimentalDecorators' option in your configuration file"),
        Convert_parameters_to_destructured_object: diag(95075, ts.DiagnosticCategory.Message, "Convert_parameters_to_destructured_object_95075", "Convert parameters to destructured object"),
        Allow_accessing_UMD_globals_from_modules: diag(95076, ts.DiagnosticCategory.Message, "Allow_accessing_UMD_globals_from_modules_95076", "Allow accessing UMD globals from modules."),
        Extract_type: diag(95077, ts.DiagnosticCategory.Message, "Extract_type_95077", "Extract type"),
        Extract_to_type_alias: diag(95078, ts.DiagnosticCategory.Message, "Extract_to_type_alias_95078", "Extract to type alias"),
        Extract_to_typedef: diag(95079, ts.DiagnosticCategory.Message, "Extract_to_typedef_95079", "Extract to typedef"),
        Infer_this_type_of_0_from_usage: diag(95080, ts.DiagnosticCategory.Message, "Infer_this_type_of_0_from_usage_95080", "Infer 'this' type of '{0}' from usage"),
        Add_const_to_unresolved_variable: diag(95081, ts.DiagnosticCategory.Message, "Add_const_to_unresolved_variable_95081", "Add 'const' to unresolved variable"),
        Add_const_to_all_unresolved_variables: diag(95082, ts.DiagnosticCategory.Message, "Add_const_to_all_unresolved_variables_95082", "Add 'const' to all unresolved variables"),
        Add_await: diag(95083, ts.DiagnosticCategory.Message, "Add_await_95083", "Add 'await'"),
        Add_await_to_initializer_for_0: diag(95084, ts.DiagnosticCategory.Message, "Add_await_to_initializer_for_0_95084", "Add 'await' to initializer for '{0}'"),
        Fix_all_expressions_possibly_missing_await: diag(95085, ts.DiagnosticCategory.Message, "Fix_all_expressions_possibly_missing_await_95085", "Fix all expressions possibly missing 'await'"),
        Remove_unnecessary_await: diag(95086, ts.DiagnosticCategory.Message, "Remove_unnecessary_await_95086", "Remove unnecessary 'await'"),
        Remove_all_unnecessary_uses_of_await: diag(95087, ts.DiagnosticCategory.Message, "Remove_all_unnecessary_uses_of_await_95087", "Remove all unnecessary uses of 'await'"),
        Enable_the_jsx_flag_in_your_configuration_file: diag(95088, ts.DiagnosticCategory.Message, "Enable_the_jsx_flag_in_your_configuration_file_95088", "Enable the '--jsx' flag in your configuration file"),
        Add_await_to_initializers: diag(95089, ts.DiagnosticCategory.Message, "Add_await_to_initializers_95089", "Add 'await' to initializers"),
        Extract_to_interface: diag(95090, ts.DiagnosticCategory.Message, "Extract_to_interface_95090", "Extract to interface"),
        Convert_to_a_bigint_numeric_literal: diag(95091, ts.DiagnosticCategory.Message, "Convert_to_a_bigint_numeric_literal_95091", "Convert to a bigint numeric literal"),
        Convert_all_to_bigint_numeric_literals: diag(95092, ts.DiagnosticCategory.Message, "Convert_all_to_bigint_numeric_literals_95092", "Convert all to bigint numeric literals"),
        Convert_const_to_let: diag(95093, ts.DiagnosticCategory.Message, "Convert_const_to_let_95093", "Convert 'const' to 'let'"),
        Prefix_with_declare: diag(95094, ts.DiagnosticCategory.Message, "Prefix_with_declare_95094", "Prefix with 'declare'"),
        Prefix_all_incorrect_property_declarations_with_declare: diag(95095, ts.DiagnosticCategory.Message, "Prefix_all_incorrect_property_declarations_with_declare_95095", "Prefix all incorrect property declarations with 'declare'"),
        Convert_to_template_string: diag(95096, ts.DiagnosticCategory.Message, "Convert_to_template_string_95096", "Convert to template string"),
        Add_export_to_make_this_file_into_a_module: diag(95097, ts.DiagnosticCategory.Message, "Add_export_to_make_this_file_into_a_module_95097", "Add 'export {}' to make this file into a module"),
        Set_the_target_option_in_your_configuration_file_to_0: diag(95098, ts.DiagnosticCategory.Message, "Set_the_target_option_in_your_configuration_file_to_0_95098", "Set the 'target' option in your configuration file to '{0}'"),
        Set_the_module_option_in_your_configuration_file_to_0: diag(95099, ts.DiagnosticCategory.Message, "Set_the_module_option_in_your_configuration_file_to_0_95099", "Set the 'module' option in your configuration file to '{0}'"),
        Convert_invalid_character_to_its_html_entity_code: diag(95100, ts.DiagnosticCategory.Message, "Convert_invalid_character_to_its_html_entity_code_95100", "Convert invalid character to its html entity code"),
        Convert_all_invalid_characters_to_HTML_entity_code: diag(95101, ts.DiagnosticCategory.Message, "Convert_all_invalid_characters_to_HTML_entity_code_95101", "Convert all invalid characters to HTML entity code"),
        Add_class_tag: diag(95102, ts.DiagnosticCategory.Message, "Add_class_tag_95102", "Add '@class' tag"),
        Add_this_tag: diag(95103, ts.DiagnosticCategory.Message, "Add_this_tag_95103", "Add '@this' tag"),
        Add_this_parameter: diag(95104, ts.DiagnosticCategory.Message, "Add_this_parameter_95104", "Add 'this' parameter."),
        Convert_function_expression_0_to_arrow_function: diag(95105, ts.DiagnosticCategory.Message, "Convert_function_expression_0_to_arrow_function_95105", "Convert function expression '{0}' to arrow function"),
        Convert_function_declaration_0_to_arrow_function: diag(95106, ts.DiagnosticCategory.Message, "Convert_function_declaration_0_to_arrow_function_95106", "Convert function declaration '{0}' to arrow function"),
        Fix_all_implicit_this_errors: diag(95107, ts.DiagnosticCategory.Message, "Fix_all_implicit_this_errors_95107", "Fix all implicit-'this' errors"),
        Wrap_invalid_character_in_an_expression_container: diag(95108, ts.DiagnosticCategory.Message, "Wrap_invalid_character_in_an_expression_container_95108", "Wrap invalid character in an expression container"),
        Wrap_all_invalid_characters_in_an_expression_container: diag(95109, ts.DiagnosticCategory.Message, "Wrap_all_invalid_characters_in_an_expression_container_95109", "Wrap all invalid characters in an expression container"),
        Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_json_to_read_more_about_this_file: diag(95110, ts.DiagnosticCategory.Message, "Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_json_to_read_more_about_this_file_95110", "Visit https://aka.ms/tsconfig.json to read more about this file"),
        Add_a_return_statement: diag(95111, ts.DiagnosticCategory.Message, "Add_a_return_statement_95111", "Add a return statement"),
        Remove_block_body_braces: diag(95112, ts.DiagnosticCategory.Message, "Remove_block_body_braces_95112", "Remove block body braces"),
        Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal: diag(95113, ts.DiagnosticCategory.Message, "Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal_95113", "Wrap the following body with parentheses which should be an object literal"),
        Add_all_missing_return_statement: diag(95114, ts.DiagnosticCategory.Message, "Add_all_missing_return_statement_95114", "Add all missing return statement"),
        Remove_all_incorrect_body_block_braces: diag(95115, ts.DiagnosticCategory.Message, "Remove_all_incorrect_body_block_braces_95115", "Remove all incorrect body block braces"),
        Wrap_all_object_literal_with_parentheses: diag(95116, ts.DiagnosticCategory.Message, "Wrap_all_object_literal_with_parentheses_95116", "Wrap all object literal with parentheses"),
        No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."),
        Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."),
        JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array: diag(18007, ts.DiagnosticCategory.Error, "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", "JSX expressions may not use the comma operator. Did you mean to write an array?"),
        Private_identifiers_cannot_be_used_as_parameters: diag(18009, ts.DiagnosticCategory.Error, "Private_identifiers_cannot_be_used_as_parameters_18009", "Private identifiers cannot be used as parameters"),
        An_accessibility_modifier_cannot_be_used_with_a_private_identifier: diag(18010, ts.DiagnosticCategory.Error, "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", "An accessibility modifier cannot be used with a private identifier."),
        The_operand_of_a_delete_operator_cannot_be_a_private_identifier: diag(18011, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", "The operand of a 'delete' operator cannot be a private identifier."),
        constructor_is_a_reserved_word: diag(18012, ts.DiagnosticCategory.Error, "constructor_is_a_reserved_word_18012", "'#constructor' is a reserved word."),
        Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier: diag(18013, ts.DiagnosticCategory.Error, "Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier_18013", "Property '{0}' is not accessible outside class '{1}' because it has a private identifier."),
        The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_private_identifier_with_the_same_spelling: diag(18014, ts.DiagnosticCategory.Error, "The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_priv_18014", "The property '{0}' cannot be accessed on type '{1}' within this class because it is shadowed by another private identifier with the same spelling."),
        Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2: diag(18015, ts.DiagnosticCategory.Error, "Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2_18015", "Property '{0}' in type '{1}' refers to a different member that cannot be accessed from within type '{2}'."),
        Private_identifiers_are_not_allowed_outside_class_bodies: diag(18016, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_outside_class_bodies_18016", "Private identifiers are not allowed outside class bodies."),
        The_shadowing_declaration_of_0_is_defined_here: diag(18017, ts.DiagnosticCategory.Error, "The_shadowing_declaration_of_0_is_defined_here_18017", "The shadowing declaration of '{0}' is defined here"),
        The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here: diag(18018, ts.DiagnosticCategory.Error, "The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here_18018", "The declaration of '{0}' that you probably intended to use is defined here"),
        _0_modifier_cannot_be_used_with_a_private_identifier: diag(18019, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_a_private_identifier_18019", "'{0}' modifier cannot be used with a private identifier"),
        A_method_cannot_be_named_with_a_private_identifier: diag(18022, ts.DiagnosticCategory.Error, "A_method_cannot_be_named_with_a_private_identifier_18022", "A method cannot be named with a private identifier."),
        An_accessor_cannot_be_named_with_a_private_identifier: diag(18023, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_named_with_a_private_identifier_18023", "An accessor cannot be named with a private identifier."),
        An_enum_member_cannot_be_named_with_a_private_identifier: diag(18024, ts.DiagnosticCategory.Error, "An_enum_member_cannot_be_named_with_a_private_identifier_18024", "An enum member cannot be named with a private identifier."),
        can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."),
        Compiler_reserves_name_0_when_emitting_private_identifier_downlevel: diag(18027, ts.DiagnosticCategory.Error, "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", "Compiler reserves name '{0}' when emitting private identifier downlevel."),
        Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher: diag(18028, ts.DiagnosticCategory.Error, "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", "Private identifiers are only available when targeting ECMAScript 2015 and higher."),
        Private_identifiers_are_not_allowed_in_variable_declarations: diag(18029, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_in_variable_declarations_18029", "Private identifiers are not allowed in variable declarations."),
        An_optional_chain_cannot_contain_private_identifiers: diag(18030, ts.DiagnosticCategory.Error, "An_optional_chain_cannot_contain_private_identifiers_18030", "An optional chain cannot contain private identifiers."),
        The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents: diag(18031, ts.DiagnosticCategory.Error, "The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituent_18031", "The intersection '{0}' was reduced to 'never' because property '{1}' has conflicting types in some constituents."),
        The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some: diag(18032, ts.DiagnosticCategory.Error, "The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_pr_18032", "The intersection '{0}' was reduced to 'never' because property '{1}' exists in multiple constituents and is private in some."),
        Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhaustiveness_checks_consider_using_an_object_literal_instead: diag(18033, ts.DiagnosticCategory.Error, "Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhau_18033", "Only numeric enums can have computed members, but this expression has type '{0}'. If you do not need exhaustiveness checks, consider using an object literal instead."),
    };
})(ts || (ts = {}));
var ts;
(function (ts) {
    var _a;
    /* @internal */
    function tokenIsIdentifierOrKeyword(token) {
        return token >= 75 /* Identifier */;
    }
    ts.tokenIsIdentifierOrKeyword = tokenIsIdentifierOrKeyword;
    /* @internal */
    function tokenIsIdentifierOrKeywordOrGreaterThan(token) {
        return token === 31 /* GreaterThanToken */ || tokenIsIdentifierOrKeyword(token);
    }
    ts.tokenIsIdentifierOrKeywordOrGreaterThan = tokenIsIdentifierOrKeywordOrGreaterThan;
    var textToKeywordObj = (_a = {
            abstract: 122 /* AbstractKeyword */,
            any: 125 /* AnyKeyword */,
            as: 123 /* AsKeyword */,
            asserts: 124 /* AssertsKeyword */,
            bigint: 151 /* BigIntKeyword */,
            boolean: 128 /* BooleanKeyword */,
            break: 77 /* BreakKeyword */,
            case: 78 /* CaseKeyword */,
            catch: 79 /* CatchKeyword */,
            class: 80 /* ClassKeyword */,
            continue: 82 /* ContinueKeyword */,
            const: 81 /* ConstKeyword */
        },
        _a["" + "constructor"] = 129 /* ConstructorKeyword */,
        _a.debugger = 83 /* DebuggerKeyword */,
        _a.declare = 130 /* DeclareKeyword */,
        _a.default = 84 /* DefaultKeyword */,
        _a.delete = 85 /* DeleteKeyword */,
        _a.do = 86 /* DoKeyword */,
        _a.else = 87 /* ElseKeyword */,
        _a.enum = 88 /* EnumKeyword */,
        _a.export = 89 /* ExportKeyword */,
        _a.extends = 90 /* ExtendsKeyword */,
        _a.false = 91 /* FalseKeyword */,
        _a.finally = 92 /* FinallyKeyword */,
        _a.for = 93 /* ForKeyword */,
        _a.from = 149 /* FromKeyword */,
        _a.function = 94 /* FunctionKeyword */,
        _a.get = 131 /* GetKeyword */,
        _a.if = 95 /* IfKeyword */,
        _a.implements = 113 /* ImplementsKeyword */,
        _a.import = 96 /* ImportKeyword */,
        _a.in = 97 /* InKeyword */,
        _a.infer = 132 /* InferKeyword */,
        _a.instanceof = 98 /* InstanceOfKeyword */,
        _a.interface = 114 /* InterfaceKeyword */,
        _a.is = 133 /* IsKeyword */,
        _a.keyof = 134 /* KeyOfKeyword */,
        _a.let = 115 /* LetKeyword */,
        _a.module = 135 /* ModuleKeyword */,
        _a.namespace = 136 /* NamespaceKeyword */,
        _a.never = 137 /* NeverKeyword */,
        _a.new = 99 /* NewKeyword */,
        _a.null = 100 /* NullKeyword */,
        _a.number = 140 /* NumberKeyword */,
        _a.object = 141 /* ObjectKeyword */,
        _a.package = 116 /* PackageKeyword */,
        _a.private = 117 /* PrivateKeyword */,
        _a.protected = 118 /* ProtectedKeyword */,
        _a.public = 119 /* PublicKeyword */,
        _a.readonly = 138 /* ReadonlyKeyword */,
        _a.require = 139 /* RequireKeyword */,
        _a.global = 150 /* GlobalKeyword */,
        _a.return = 101 /* ReturnKeyword */,
        _a.set = 142 /* SetKeyword */,
        _a.static = 120 /* StaticKeyword */,
        _a.string = 143 /* StringKeyword */,
        _a.super = 102 /* SuperKeyword */,
        _a.switch = 103 /* SwitchKeyword */,
        _a.symbol = 144 /* SymbolKeyword */,
        _a.this = 104 /* ThisKeyword */,
        _a.throw = 105 /* ThrowKeyword */,
        _a.true = 106 /* TrueKeyword */,
        _a.try = 107 /* TryKeyword */,
        _a.type = 145 /* TypeKeyword */,
        _a.typeof = 108 /* TypeOfKeyword */,
        _a.undefined = 146 /* UndefinedKeyword */,
        _a.unique = 147 /* UniqueKeyword */,
        _a.unknown = 148 /* UnknownKeyword */,
        _a.var = 109 /* VarKeyword */,
        _a.void = 110 /* VoidKeyword */,
        _a.while = 111 /* WhileKeyword */,
        _a.with = 112 /* WithKeyword */,
        _a.yield = 121 /* YieldKeyword */,
        _a.async = 126 /* AsyncKeyword */,
        _a.await = 127 /* AwaitKeyword */,
        _a.of = 152 /* OfKeyword */,
        _a);
    var textToKeyword = ts.createMapFromTemplate(textToKeywordObj);
    var textToToken = ts.createMapFromTemplate(__assign(__assign({}, textToKeywordObj), { "{": 18 /* OpenBraceToken */, "}": 19 /* CloseBraceToken */, "(": 20 /* OpenParenToken */, ")": 21 /* CloseParenToken */, "[": 22 /* OpenBracketToken */, "]": 23 /* CloseBracketToken */, ".": 24 /* DotToken */, "...": 25 /* DotDotDotToken */, ";": 26 /* SemicolonToken */, ",": 27 /* CommaToken */, "<": 29 /* LessThanToken */, ">": 31 /* GreaterThanToken */, "<=": 32 /* LessThanEqualsToken */, ">=": 33 /* GreaterThanEqualsToken */, "==": 34 /* EqualsEqualsToken */, "!=": 35 /* ExclamationEqualsToken */, "===": 36 /* EqualsEqualsEqualsToken */, "!==": 37 /* ExclamationEqualsEqualsToken */, "=>": 38 /* EqualsGreaterThanToken */, "+": 39 /* PlusToken */, "-": 40 /* MinusToken */, "**": 42 /* AsteriskAsteriskToken */, "*": 41 /* AsteriskToken */, "/": 43 /* SlashToken */, "%": 44 /* PercentToken */, "++": 45 /* PlusPlusToken */, "--": 46 /* MinusMinusToken */, "<<": 47 /* LessThanLessThanToken */, "</": 30 /* LessThanSlashToken */, ">>": 48 /* GreaterThanGreaterThanToken */, ">>>": 49 /* GreaterThanGreaterThanGreaterThanToken */, "&": 50 /* AmpersandToken */, "|": 51 /* BarToken */, "^": 52 /* CaretToken */, "!": 53 /* ExclamationToken */, "~": 54 /* TildeToken */, "&&": 55 /* AmpersandAmpersandToken */, "||": 56 /* BarBarToken */, "?": 57 /* QuestionToken */, "??": 60 /* QuestionQuestionToken */, "?.": 28 /* QuestionDotToken */, ":": 58 /* ColonToken */, "=": 62 /* EqualsToken */, "+=": 63 /* PlusEqualsToken */, "-=": 64 /* MinusEqualsToken */, "*=": 65 /* AsteriskEqualsToken */, "**=": 66 /* AsteriskAsteriskEqualsToken */, "/=": 67 /* SlashEqualsToken */, "%=": 68 /* PercentEqualsToken */, "<<=": 69 /* LessThanLessThanEqualsToken */, ">>=": 70 /* GreaterThanGreaterThanEqualsToken */, ">>>=": 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */, "&=": 72 /* AmpersandEqualsToken */, "|=": 73 /* BarEqualsToken */, "^=": 74 /* CaretEqualsToken */, "@": 59 /* AtToken */, "`": 61 /* BacktickToken */ }));
    /*
        As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers
        IdentifierStart ::
            Can contain Unicode 3.0.0 categories:
            Uppercase letter (Lu),
            Lowercase letter (Ll),
            Titlecase letter (Lt),
            Modifier letter (Lm),
            Other letter (Lo), or
            Letter number (Nl).
        IdentifierPart :: =
            Can contain IdentifierStart + Unicode 3.0.0 categories:
            Non-spacing mark (Mn),
            Combining spacing mark (Mc),
            Decimal number (Nd), or
            Connector punctuation (Pc).

        Codepoint ranges for ES3 Identifiers are extracted from the Unicode 3.0.0 specification at:
        http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt
    */
    var unicodeES3IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    var unicodeES3IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    /*
        As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers
        IdentifierStart ::
            Can contain Unicode 6.2 categories:
            Uppercase letter (Lu),
            Lowercase letter (Ll),
            Titlecase letter (Lt),
            Modifier letter (Lm),
            Other letter (Lo), or
            Letter number (Nl).
        IdentifierPart ::
            Can contain IdentifierStart + Unicode 6.2 categories:
            Non-spacing mark (Mn),
            Combining spacing mark (Mc),
            Decimal number (Nd),
            Connector punctuation (Pc),
            <ZWNJ>, or
            <ZWJ>.

        Codepoint ranges for ES5 Identifiers are extracted from the Unicode 6.2 specification at:
        http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt
    */
    var unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2208, 2208, 2210, 2220, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7413, 7414, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    var unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    /**
     * Generated by scripts/regenerate-unicode-identifier-parts.js on node v12.4.0 with unicode 12.1
     * based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords
     * unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and
     * unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start
     */
    var unicodeESNextIdentifierStart = [65, 90, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 895, 895, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1488, 1514, 1519, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2144, 2154, 2208, 2228, 2230, 2237, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2432, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2556, 2556, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2809, 2809, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3133, 3160, 3162, 3168, 3169, 3200, 3200, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3412, 3414, 3423, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6264, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6430, 6480, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7401, 7404, 7406, 7411, 7413, 7414, 7418, 7418, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40943, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42653, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42943, 42946, 42950, 42999, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43261, 43262, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43488, 43492, 43494, 43503, 43514, 43518, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43646, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43879, 43888, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66335, 66349, 66378, 66384, 66421, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 67072, 67382, 67392, 67413, 67424, 67431, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68096, 68112, 68115, 68117, 68119, 68121, 68149, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68324, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68899, 69376, 69404, 69415, 69415, 69424, 69445, 69600, 69622, 69635, 69687, 69763, 69807, 69840, 69864, 69891, 69926, 69956, 69956, 69968, 70002, 70006, 70006, 70019, 70066, 70081, 70084, 70106, 70106, 70108, 70108, 70144, 70161, 70163, 70187, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70366, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70461, 70461, 70480, 70480, 70493, 70497, 70656, 70708, 70727, 70730, 70751, 70751, 70784, 70831, 70852, 70853, 70855, 70855, 71040, 71086, 71128, 71131, 71168, 71215, 71236, 71236, 71296, 71338, 71352, 71352, 71424, 71450, 71680, 71723, 71840, 71903, 71935, 71935, 72096, 72103, 72106, 72144, 72161, 72161, 72163, 72163, 72192, 72192, 72203, 72242, 72250, 72250, 72272, 72272, 72284, 72329, 72349, 72349, 72384, 72440, 72704, 72712, 72714, 72750, 72768, 72768, 72818, 72847, 72960, 72966, 72968, 72969, 72971, 73008, 73030, 73030, 73056, 73061, 73063, 73064, 73066, 73097, 73112, 73112, 73440, 73458, 73728, 74649, 74752, 74862, 74880, 75075, 77824, 78894, 82944, 83526, 92160, 92728, 92736, 92766, 92880, 92909, 92928, 92975, 92992, 92995, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94032, 94032, 94099, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101106, 110592, 110878, 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 123136, 123180, 123191, 123197, 123214, 123214, 123584, 123627, 124928, 125124, 125184, 125251, 125259, 125259, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173782, 173824, 177972, 177984, 178205, 178208, 183969, 183984, 191456, 194560, 195101];
    var unicodeESNextIdentifierPart = [48, 57, 65, 90, 95, 95, 97, 122, 170, 170, 181, 181, 183, 183, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 895, 895, 902, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1519, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2045, 2045, 2048, 2093, 2112, 2139, 2144, 2154, 2208, 2228, 2230, 2237, 2259, 2273, 2275, 2403, 2406, 2415, 2417, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2556, 2556, 2558, 2558, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2809, 2815, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3072, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3162, 3168, 3171, 3174, 3183, 3200, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3328, 3331, 3333, 3340, 3342, 3344, 3346, 3396, 3398, 3400, 3402, 3406, 3412, 3415, 3423, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3558, 3567, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4969, 4977, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6264, 6272, 6314, 6320, 6389, 6400, 6430, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6618, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6832, 6845, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7376, 7378, 7380, 7418, 7424, 7673, 7675, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40943, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42737, 42775, 42783, 42786, 42888, 42891, 42943, 42946, 42950, 42999, 43047, 43072, 43123, 43136, 43205, 43216, 43225, 43232, 43255, 43259, 43259, 43261, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43488, 43518, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43879, 43888, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65071, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66045, 66045, 66176, 66204, 66208, 66256, 66272, 66272, 66304, 66335, 66349, 66378, 66384, 66426, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66720, 66729, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 67072, 67382, 67392, 67413, 67424, 67431, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68099, 68101, 68102, 68108, 68115, 68117, 68119, 68121, 68149, 68152, 68154, 68159, 68159, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68326, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68903, 68912, 68921, 69376, 69404, 69415, 69415, 69424, 69456, 69600, 69622, 69632, 69702, 69734, 69743, 69759, 69818, 69840, 69864, 69872, 69881, 69888, 69940, 69942, 69951, 69956, 69958, 69968, 70003, 70006, 70006, 70016, 70084, 70089, 70092, 70096, 70106, 70108, 70108, 70144, 70161, 70163, 70199, 70206, 70206, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70378, 70384, 70393, 70400, 70403, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70459, 70468, 70471, 70472, 70475, 70477, 70480, 70480, 70487, 70487, 70493, 70499, 70502, 70508, 70512, 70516, 70656, 70730, 70736, 70745, 70750, 70751, 70784, 70853, 70855, 70855, 70864, 70873, 71040, 71093, 71096, 71104, 71128, 71133, 71168, 71232, 71236, 71236, 71248, 71257, 71296, 71352, 71360, 71369, 71424, 71450, 71453, 71467, 71472, 71481, 71680, 71738, 71840, 71913, 71935, 71935, 72096, 72103, 72106, 72151, 72154, 72161, 72163, 72164, 72192, 72254, 72263, 72263, 72272, 72345, 72349, 72349, 72384, 72440, 72704, 72712, 72714, 72758, 72760, 72768, 72784, 72793, 72818, 72847, 72850, 72871, 72873, 72886, 72960, 72966, 72968, 72969, 72971, 73014, 73018, 73018, 73020, 73021, 73023, 73031, 73040, 73049, 73056, 73061, 73063, 73064, 73066, 73102, 73104, 73105, 73107, 73112, 73120, 73129, 73440, 73462, 73728, 74649, 74752, 74862, 74880, 75075, 77824, 78894, 82944, 83526, 92160, 92728, 92736, 92766, 92768, 92777, 92880, 92909, 92912, 92916, 92928, 92982, 92992, 92995, 93008, 93017, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94031, 94087, 94095, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101106, 110592, 110878, 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 113821, 113822, 119141, 119145, 119149, 119154, 119163, 119170, 119173, 119179, 119210, 119213, 119362, 119364, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 120782, 120831, 121344, 121398, 121403, 121452, 121461, 121461, 121476, 121476, 121499, 121503, 121505, 121519, 122880, 122886, 122888, 122904, 122907, 122913, 122915, 122916, 122918, 122922, 123136, 123180, 123184, 123197, 123200, 123209, 123214, 123214, 123584, 123641, 124928, 125124, 125136, 125142, 125184, 125259, 125264, 125273, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173782, 173824, 177972, 177984, 178205, 178208, 183969, 183984, 191456, 194560, 195101, 917760, 917999];
    /**
     * Test for whether a single line comment's text contains a directive.
     */
    var commentDirectiveRegExSingleLine = /^\s*\/\/\/?\s*@(ts-expect-error|ts-ignore)/;
    /**
     * Test for whether a multi-line comment's last line contains a directive.
     */
    var commentDirectiveRegExMultiLine = /^\s*(?:\/|\*)*\s*@(ts-expect-error|ts-ignore)/;
    function lookupInUnicodeMap(code, map) {
        // Bail out quickly if it couldn't possibly be in the map.
        if (code < map[0]) {
            return false;
        }
        // Perform binary search in one of the Unicode range maps
        var lo = 0;
        var hi = map.length;
        var mid;
        while (lo + 1 < hi) {
            mid = lo + (hi - lo) / 2;
            // mid has to be even to catch a range's beginning
            mid -= mid % 2;
            if (map[mid] <= code && code <= map[mid + 1]) {
                return true;
            }
            if (code < map[mid]) {
                hi = mid;
            }
            else {
                lo = mid + 2;
            }
        }
        return false;
    }
    /* @internal */ function isUnicodeIdentifierStart(code, languageVersion) {
        return languageVersion >= 2 /* ES2015 */ ?
            lookupInUnicodeMap(code, unicodeESNextIdentifierStart) :
            languageVersion === 1 /* ES5 */ ? lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
                lookupInUnicodeMap(code, unicodeES3IdentifierStart);
    }
    ts.isUnicodeIdentifierStart = isUnicodeIdentifierStart;
    function isUnicodeIdentifierPart(code, languageVersion) {
        return languageVersion >= 2 /* ES2015 */ ?
            lookupInUnicodeMap(code, unicodeESNextIdentifierPart) :
            languageVersion === 1 /* ES5 */ ? lookupInUnicodeMap(code, unicodeES5IdentifierPart) :
                lookupInUnicodeMap(code, unicodeES3IdentifierPart);
    }
    function makeReverseMap(source) {
        var result = [];
        source.forEach(function (value, name) {
            result[value] = name;
        });
        return result;
    }
    var tokenStrings = makeReverseMap(textToToken);
    function tokenToString(t) {
        return tokenStrings[t];
    }
    ts.tokenToString = tokenToString;
    /* @internal */
    function stringToToken(s) {
        return textToToken.get(s);
    }
    ts.stringToToken = stringToToken;
    /* @internal */
    function computeLineStarts(text) {
        var result = new Array();
        var pos = 0;
        var lineStart = 0;
        while (pos < text.length) {
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    result.push(lineStart);
                    lineStart = pos;
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && isLineBreak(ch)) {
                        result.push(lineStart);
                        lineStart = pos;
                    }
                    break;
            }
        }
        result.push(lineStart);
        return result;
    }
    ts.computeLineStarts = computeLineStarts;
    function getPositionOfLineAndCharacter(sourceFile, line, character, allowEdits) {
        return sourceFile.getPositionOfLineAndCharacter ?
            sourceFile.getPositionOfLineAndCharacter(line, character, allowEdits) :
            computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text, allowEdits);
    }
    ts.getPositionOfLineAndCharacter = getPositionOfLineAndCharacter;
    /* @internal */
    function computePositionOfLineAndCharacter(lineStarts, line, character, debugText, allowEdits) {
        if (line < 0 || line >= lineStarts.length) {
            if (allowEdits) {
                // Clamp line to nearest allowable value
                line = line < 0 ? 0 : line >= lineStarts.length ? lineStarts.length - 1 : line;
            }
            else {
                ts.Debug.fail("Bad line number. Line: " + line + ", lineStarts.length: " + lineStarts.length + " , line map is correct? " + (debugText !== undefined ? ts.arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"));
            }
        }
        var res = lineStarts[line] + character;
        if (allowEdits) {
            // Clamp to nearest allowable values to allow the underlying to be edited without crashing (accuracy is lost, instead)
            // TODO: Somehow track edits between file as it was during the creation of sourcemap we have and the current file and
            // apply them to the computed position to improve accuracy
            return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res;
        }
        if (line < lineStarts.length - 1) {
            ts.Debug.assert(res < lineStarts[line + 1]);
        }
        else if (debugText !== undefined) {
            ts.Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline
        }
        return res;
    }
    ts.computePositionOfLineAndCharacter = computePositionOfLineAndCharacter;
    /* @internal */
    function getLineStarts(sourceFile) {
        return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
    }
    ts.getLineStarts = getLineStarts;
    /* @internal */
    function computeLineAndCharacterOfPosition(lineStarts, position) {
        var lineNumber = computeLineOfPosition(lineStarts, position);
        return {
            line: lineNumber,
            character: position - lineStarts[lineNumber]
        };
    }
    ts.computeLineAndCharacterOfPosition = computeLineAndCharacterOfPosition;
    /**
     * @internal
     * We assume the first line starts at position 0 and 'position' is non-negative.
     */
    function computeLineOfPosition(lineStarts, position, lowerBound) {
        var lineNumber = ts.binarySearch(lineStarts, position, ts.identity, ts.compareValues, lowerBound);
        if (lineNumber < 0) {
            // If the actual position was not found,
            // the binary search returns the 2's-complement of the next line start
            // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
            // then the search will return -2.
            //
            // We want the index of the previous line start, so we subtract 1.
            // Review 2's-complement if this is confusing.
            lineNumber = ~lineNumber - 1;
            ts.Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file");
        }
        return lineNumber;
    }
    ts.computeLineOfPosition = computeLineOfPosition;
    /** @internal */
    function getLinesBetweenPositions(sourceFile, pos1, pos2) {
        if (pos1 === pos2)
            return 0;
        var lineStarts = getLineStarts(sourceFile);
        var lower = Math.min(pos1, pos2);
        var isNegative = lower === pos2;
        var upper = isNegative ? pos1 : pos2;
        var lowerLine = computeLineOfPosition(lineStarts, lower);
        var upperLine = computeLineOfPosition(lineStarts, upper, lowerLine);
        return isNegative ? lowerLine - upperLine : upperLine - lowerLine;
    }
    ts.getLinesBetweenPositions = getLinesBetweenPositions;
    function getLineAndCharacterOfPosition(sourceFile, position) {
        return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position);
    }
    ts.getLineAndCharacterOfPosition = getLineAndCharacterOfPosition;
    function isWhiteSpaceLike(ch) {
        return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
    }
    ts.isWhiteSpaceLike = isWhiteSpaceLike;
    /** Does not include line breaks. For that, see isWhiteSpaceLike. */
    function isWhiteSpaceSingleLine(ch) {
        // Note: nextLine is in the Zs space, and should be considered to be a whitespace.
        // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript.
        return ch === 32 /* space */ ||
            ch === 9 /* tab */ ||
            ch === 11 /* verticalTab */ ||
            ch === 12 /* formFeed */ ||
            ch === 160 /* nonBreakingSpace */ ||
            ch === 133 /* nextLine */ ||
            ch === 5760 /* ogham */ ||
            ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ ||
            ch === 8239 /* narrowNoBreakSpace */ ||
            ch === 8287 /* mathematicalSpace */ ||
            ch === 12288 /* ideographicSpace */ ||
            ch === 65279 /* byteOrderMark */;
    }
    ts.isWhiteSpaceSingleLine = isWhiteSpaceSingleLine;
    function isLineBreak(ch) {
        // ES5 7.3:
        // The ECMAScript line terminator characters are listed in Table 3.
        //     Table 3: Line Terminator Characters
        //     Code Unit Value     Name                    Formal Name
        //     \u000A              Line Feed               <LF>
        //     \u000D              Carriage Return         <CR>
        //     \u2028              Line separator          <LS>
        //     \u2029              Paragraph separator     <PS>
        // Only the characters in Table 3 are treated as line terminators. Other new line or line
        // breaking characters are treated as white space but not as line terminators.
        return ch === 10 /* lineFeed */ ||
            ch === 13 /* carriageReturn */ ||
            ch === 8232 /* lineSeparator */ ||
            ch === 8233 /* paragraphSeparator */;
    }
    ts.isLineBreak = isLineBreak;
    function isDigit(ch) {
        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
    }
    function isHexDigit(ch) {
        return isDigit(ch) || ch >= 65 /* A */ && ch <= 70 /* F */ || ch >= 97 /* a */ && ch <= 102 /* f */;
    }
    function isCodePoint(code) {
        return code <= 0x10FFFF;
    }
    /* @internal */
    function isOctalDigit(ch) {
        return ch >= 48 /* _0 */ && ch <= 55 /* _7 */;
    }
    ts.isOctalDigit = isOctalDigit;
    function couldStartTrivia(text, pos) {
        // Keep in sync with skipTrivia
        var ch = text.charCodeAt(pos);
        switch (ch) {
            case 13 /* carriageReturn */:
            case 10 /* lineFeed */:
            case 9 /* tab */:
            case 11 /* verticalTab */:
            case 12 /* formFeed */:
            case 32 /* space */:
            case 47 /* slash */:
            // starts of normal trivia
            // falls through
            case 60 /* lessThan */:
            case 124 /* bar */:
            case 61 /* equals */:
            case 62 /* greaterThan */:
                // Starts of conflict marker trivia
                return true;
            case 35 /* hash */:
                // Only if its the beginning can we have #! trivia
                return pos === 0;
            default:
                return ch > 127 /* maxAsciiCharacter */;
        }
    }
    ts.couldStartTrivia = couldStartTrivia;
    /* @internal */
    function skipTrivia(text, pos, stopAfterLineBreak, stopAtComments) {
        if (stopAtComments === void 0) { stopAtComments = false; }
        if (ts.positionIsSynthesized(pos)) {
            return pos;
        }
        // Keep in sync with couldStartTrivia
        while (true) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    pos++;
                    if (stopAfterLineBreak) {
                        return pos;
                    }
                    continue;
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    pos++;
                    continue;
                case 47 /* slash */:
                    if (stopAtComments) {
                        break;
                    }
                    if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                        pos += 2;
                        while (pos < text.length) {
                            if (isLineBreak(text.charCodeAt(pos))) {
                                break;
                            }
                            pos++;
                        }
                        continue;
                    }
                    if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                        pos += 2;
                        while (pos < text.length) {
                            if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                pos += 2;
                                break;
                            }
                            pos++;
                        }
                        continue;
                    }
                    break;
                case 60 /* lessThan */:
                case 124 /* bar */:
                case 61 /* equals */:
                case 62 /* greaterThan */:
                    if (isConflictMarkerTrivia(text, pos)) {
                        pos = scanConflictMarkerTrivia(text, pos);
                        continue;
                    }
                    break;
                case 35 /* hash */:
                    if (pos === 0 && isShebangTrivia(text, pos)) {
                        pos = scanShebangTrivia(text, pos);
                        continue;
                    }
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
                        pos++;
                        continue;
                    }
                    break;
            }
            return pos;
        }
    }
    ts.skipTrivia = skipTrivia;
    // All conflict markers consist of the same character repeated seven times.  If it is
    // a <<<<<<< or >>>>>>> marker then it is also followed by a space.
    var mergeConflictMarkerLength = "<<<<<<<".length;
    function isConflictMarkerTrivia(text, pos) {
        ts.Debug.assert(pos >= 0);
        // Conflict markers must be at the start of a line.
        if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) {
            var ch = text.charCodeAt(pos);
            if ((pos + mergeConflictMarkerLength) < text.length) {
                for (var i = 0; i < mergeConflictMarkerLength; i++) {
                    if (text.charCodeAt(pos + i) !== ch) {
                        return false;
                    }
                }
                return ch === 61 /* equals */ ||
                    text.charCodeAt(pos + mergeConflictMarkerLength) === 32 /* space */;
            }
        }
        return false;
    }
    function scanConflictMarkerTrivia(text, pos, error) {
        if (error) {
            error(ts.Diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength);
        }
        var ch = text.charCodeAt(pos);
        var len = text.length;
        if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
            while (pos < len && !isLineBreak(text.charCodeAt(pos))) {
                pos++;
            }
        }
        else {
            ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
            // Consume everything from the start of a ||||||| or ======= marker to the start
            // of the next ======= or >>>>>>> marker.
            while (pos < len) {
                var currentChar = text.charCodeAt(pos);
                if ((currentChar === 61 /* equals */ || currentChar === 62 /* greaterThan */) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) {
                    break;
                }
                pos++;
            }
        }
        return pos;
    }
    var shebangTriviaRegex = /^#!.*/;
    /*@internal*/
    function isShebangTrivia(text, pos) {
        // Shebangs check must only be done at the start of the file
        ts.Debug.assert(pos === 0);
        return shebangTriviaRegex.test(text);
    }
    ts.isShebangTrivia = isShebangTrivia;
    /*@internal*/
    function scanShebangTrivia(text, pos) {
        var shebang = shebangTriviaRegex.exec(text)[0];
        pos = pos + shebang.length;
        return pos;
    }
    ts.scanShebangTrivia = scanShebangTrivia;
    /**
     * Invokes a callback for each comment range following the provided position.
     *
     * Single-line comment ranges include the leading double-slash characters but not the ending
     * line break. Multi-line comment ranges include the leading slash-asterisk and trailing
     * asterisk-slash characters.
     *
     * @param reduce If true, accumulates the result of calling the callback in a fashion similar
     *      to reduceLeft. If false, iteration stops when the callback returns a truthy value.
     * @param text The source text to scan.
     * @param pos The position at which to start scanning.
     * @param trailing If false, whitespace is skipped until the first line break and comments
     *      between that location and the next token are returned. If true, comments occurring
     *      between the given position and the next line break are returned.
     * @param cb The callback to execute as each comment range is encountered.
     * @param state A state value to pass to each iteration of the callback.
     * @param initial An initial value to pass when accumulating results (when "reduce" is true).
     * @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
     *      return value of the callback.
     */
    function iterateCommentRanges(reduce, text, pos, trailing, cb, state, initial) {
        var pendingPos;
        var pendingEnd;
        var pendingKind;
        var pendingHasTrailingNewLine;
        var hasPendingCommentRange = false;
        var collecting = trailing;
        var accumulator = initial;
        if (pos === 0) {
            collecting = true;
            var shebang = getShebang(text);
            if (shebang) {
                pos = shebang.length;
            }
        }
        scan: while (pos >= 0 && pos < text.length) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    pos++;
                    if (trailing) {
                        break scan;
                    }
                    collecting = true;
                    if (hasPendingCommentRange) {
                        pendingHasTrailingNewLine = true;
                    }
                    continue;
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    pos++;
                    continue;
                case 47 /* slash */:
                    var nextChar = text.charCodeAt(pos + 1);
                    var hasTrailingNewLine = false;
                    if (nextChar === 47 /* slash */ || nextChar === 42 /* asterisk */) {
                        var kind = nextChar === 47 /* slash */ ? 2 /* SingleLineCommentTrivia */ : 3 /* MultiLineCommentTrivia */;
                        var startPos = pos;
                        pos += 2;
                        if (nextChar === 47 /* slash */) {
                            while (pos < text.length) {
                                if (isLineBreak(text.charCodeAt(pos))) {
                                    hasTrailingNewLine = true;
                                    break;
                                }
                                pos++;
                            }
                        }
                        else {
                            while (pos < text.length) {
                                if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    break;
                                }
                                pos++;
                            }
                        }
                        if (collecting) {
                            if (hasPendingCommentRange) {
                                accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
                                if (!reduce && accumulator) {
                                    // If we are not reducing and we have a truthy result, return it.
                                    return accumulator;
                                }
                            }
                            pendingPos = startPos;
                            pendingEnd = pos;
                            pendingKind = kind;
                            pendingHasTrailingNewLine = hasTrailingNewLine;
                            hasPendingCommentRange = true;
                        }
                        continue;
                    }
                    break scan;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
                        if (hasPendingCommentRange && isLineBreak(ch)) {
                            pendingHasTrailingNewLine = true;
                        }
                        pos++;
                        continue;
                    }
                    break scan;
            }
        }
        if (hasPendingCommentRange) {
            accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
        }
        return accumulator;
    }
    function forEachLeadingCommentRange(text, pos, cb, state) {
        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
    }
    ts.forEachLeadingCommentRange = forEachLeadingCommentRange;
    function forEachTrailingCommentRange(text, pos, cb, state) {
        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
    }
    ts.forEachTrailingCommentRange = forEachTrailingCommentRange;
    function reduceEachLeadingCommentRange(text, pos, cb, state, initial) {
        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
    }
    ts.reduceEachLeadingCommentRange = reduceEachLeadingCommentRange;
    function reduceEachTrailingCommentRange(text, pos, cb, state, initial) {
        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
    }
    ts.reduceEachTrailingCommentRange = reduceEachTrailingCommentRange;
    function appendCommentRange(pos, end, kind, hasTrailingNewLine, _state, comments) {
        if (!comments) {
            comments = [];
        }
        comments.push({ kind: kind, pos: pos, end: end, hasTrailingNewLine: hasTrailingNewLine });
        return comments;
    }
    function getLeadingCommentRanges(text, pos) {
        return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
    }
    ts.getLeadingCommentRanges = getLeadingCommentRanges;
    function getTrailingCommentRanges(text, pos) {
        return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
    }
    ts.getTrailingCommentRanges = getTrailingCommentRanges;
    /** Optionally, get the shebang */
    function getShebang(text) {
        var match = shebangTriviaRegex.exec(text);
        if (match) {
            return match[0];
        }
    }
    ts.getShebang = getShebang;
    function isIdentifierStart(ch, languageVersion) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
            ch === 36 /* $ */ || ch === 95 /* _ */ ||
            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierStart(ch, languageVersion);
    }
    ts.isIdentifierStart = isIdentifierStart;
    function isIdentifierPart(ch, languageVersion, identifierVariant) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
            ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch === 36 /* $ */ || ch === 95 /* _ */ ||
            // "-" and ":" are valid in JSX Identifiers
            (identifierVariant === 1 /* JSX */ ? (ch === 45 /* minus */ || ch === 58 /* colon */) : false) ||
            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion);
    }
    ts.isIdentifierPart = isIdentifierPart;
    /* @internal */
    function isIdentifierText(name, languageVersion, identifierVariant) {
        var ch = codePointAt(name, 0);
        if (!isIdentifierStart(ch, languageVersion)) {
            return false;
        }
        for (var i = charSize(ch); i < name.length; i += charSize(ch)) {
            if (!isIdentifierPart(ch = codePointAt(name, i), languageVersion, identifierVariant)) {
                return false;
            }
        }
        return true;
    }
    ts.isIdentifierText = isIdentifierText;
    // Creates a scanner over a (possibly unspecified) range of a piece of text.
    function createScanner(languageVersion, skipTrivia, languageVariant, textInitial, onError, start, length) {
        if (languageVariant === void 0) { languageVariant = 0 /* Standard */; }
        var text = textInitial;
        // Current position (end position of text of current token)
        var pos;
        // end of text
        var end;
        // Start position of whitespace before current token
        var startPos;
        // Start position of text of current token
        var tokenPos;
        var token;
        var tokenValue;
        var tokenFlags;
        var commentDirectives;
        var inJSDocType = 0;
        setText(text, start, length);
        var scanner = {
            getStartPos: function () { return startPos; },
            getTextPos: function () { return pos; },
            getToken: function () { return token; },
            getTokenPos: function () { return tokenPos; },
            getTokenText: function () { return text.substring(tokenPos, pos); },
            getTokenValue: function () { return tokenValue; },
            hasUnicodeEscape: function () { return (tokenFlags & 1024 /* UnicodeEscape */) !== 0; },
            hasExtendedUnicodeEscape: function () { return (tokenFlags & 8 /* ExtendedUnicodeEscape */) !== 0; },
            hasPrecedingLineBreak: function () { return (tokenFlags & 1 /* PrecedingLineBreak */) !== 0; },
            isIdentifier: function () { return token === 75 /* Identifier */ || token > 112 /* LastReservedWord */; },
            isReservedWord: function () { return token >= 77 /* FirstReservedWord */ && token <= 112 /* LastReservedWord */; },
            isUnterminated: function () { return (tokenFlags & 4 /* Unterminated */) !== 0; },
            getCommentDirectives: function () { return commentDirectives; },
            getTokenFlags: function () { return tokenFlags; },
            reScanGreaterToken: reScanGreaterToken,
            reScanSlashToken: reScanSlashToken,
            reScanTemplateToken: reScanTemplateToken,
            reScanTemplateHeadOrNoSubstitutionTemplate: reScanTemplateHeadOrNoSubstitutionTemplate,
            scanJsxIdentifier: scanJsxIdentifier,
            scanJsxAttributeValue: scanJsxAttributeValue,
            reScanJsxAttributeValue: reScanJsxAttributeValue,
            reScanJsxToken: reScanJsxToken,
            reScanLessThanToken: reScanLessThanToken,
            reScanQuestionToken: reScanQuestionToken,
            scanJsxToken: scanJsxToken,
            scanJsDocToken: scanJsDocToken,
            scan: scan,
            getText: getText,
            clearCommentDirectives: clearCommentDirectives,
            setText: setText,
            setScriptTarget: setScriptTarget,
            setLanguageVariant: setLanguageVariant,
            setOnError: setOnError,
            setTextPos: setTextPos,
            setInJSDocType: setInJSDocType,
            tryScan: tryScan,
            lookAhead: lookAhead,
            scanRange: scanRange,
        };
        if (ts.Debug.isDebugging) {
            Object.defineProperty(scanner, "__debugShowCurrentPositionInText", {
                get: function () {
                    var text = scanner.getText();
                    return text.slice(0, scanner.getStartPos()) + "║" + text.slice(scanner.getStartPos());
                },
            });
        }
        return scanner;
        function error(message, errPos, length) {
            if (errPos === void 0) { errPos = pos; }
            if (onError) {
                var oldPos = pos;
                pos = errPos;
                onError(message, length || 0);
                pos = oldPos;
            }
        }
        function scanNumberFragment() {
            var start = pos;
            var allowSeparator = false;
            var isPreviousTokenSeparator = false;
            var result = "";
            while (true) {
                var ch = text.charCodeAt(pos);
                if (ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (allowSeparator) {
                        allowSeparator = false;
                        isPreviousTokenSeparator = true;
                        result += text.substring(start, pos);
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    start = pos;
                    continue;
                }
                if (isDigit(ch)) {
                    allowSeparator = true;
                    isPreviousTokenSeparator = false;
                    pos++;
                    continue;
                }
                break;
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return result + text.substring(start, pos);
        }
        function scanNumber() {
            var start = pos;
            var mainFragment = scanNumberFragment();
            var decimalFragment;
            var scientificFragment;
            if (text.charCodeAt(pos) === 46 /* dot */) {
                pos++;
                decimalFragment = scanNumberFragment();
            }
            var end = pos;
            if (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */) {
                pos++;
                tokenFlags |= 16 /* Scientific */;
                if (text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */)
                    pos++;
                var preNumericPart = pos;
                var finalFragment = scanNumberFragment();
                if (!finalFragment) {
                    error(ts.Diagnostics.Digit_expected);
                }
                else {
                    scientificFragment = text.substring(end, preNumericPart) + finalFragment;
                    end = pos;
                }
            }
            var result;
            if (tokenFlags & 512 /* ContainsSeparator */) {
                result = mainFragment;
                if (decimalFragment) {
                    result += "." + decimalFragment;
                }
                if (scientificFragment) {
                    result += scientificFragment;
                }
            }
            else {
                result = text.substring(start, end); // No need to use all the fragments; no _ removal needed
            }
            if (decimalFragment !== undefined || tokenFlags & 16 /* Scientific */) {
                checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & 16 /* Scientific */));
                return {
                    type: 8 /* NumericLiteral */,
                    value: "" + +result // if value is not an integer, it can be safely coerced to a number
                };
            }
            else {
                tokenValue = result;
                var type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
                checkForIdentifierStartAfterNumericLiteral(start);
                return { type: type, value: tokenValue };
            }
        }
        function checkForIdentifierStartAfterNumericLiteral(numericStart, isScientific) {
            if (!isIdentifierStart(codePointAt(text, pos), languageVersion)) {
                return;
            }
            var identifierStart = pos;
            var length = scanIdentifierParts().length;
            if (length === 1 && text[identifierStart] === "n") {
                if (isScientific) {
                    error(ts.Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1);
                }
                else {
                    error(ts.Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1);
                }
            }
            else {
                error(ts.Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
                pos = identifierStart;
            }
        }
        function scanOctalDigits() {
            var start = pos;
            while (isOctalDigit(text.charCodeAt(pos))) {
                pos++;
            }
            return +(text.substring(start, pos));
        }
        /**
         * Scans the given number of hexadecimal digits in the text,
         * returning -1 if the given number is unavailable.
         */
        function scanExactNumberOfHexDigits(count, canHaveSeparators) {
            var valueString = scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators);
            return valueString ? parseInt(valueString, 16) : -1;
        }
        /**
         * Scans as many hexadecimal digits as are available in the text,
         * returning "" if the given number of digits was unavailable.
         */
        function scanMinimumNumberOfHexDigits(count, canHaveSeparators) {
            return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true, canHaveSeparators);
        }
        function scanHexDigits(minCount, scanAsManyAsPossible, canHaveSeparators) {
            var valueChars = [];
            var allowSeparator = false;
            var isPreviousTokenSeparator = false;
            while (valueChars.length < minCount || scanAsManyAsPossible) {
                var ch = text.charCodeAt(pos);
                if (canHaveSeparators && ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (allowSeparator) {
                        allowSeparator = false;
                        isPreviousTokenSeparator = true;
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    continue;
                }
                allowSeparator = canHaveSeparators;
                if (ch >= 65 /* A */ && ch <= 70 /* F */) {
                    ch += 97 /* a */ - 65 /* A */; // standardize hex literals to lowercase
                }
                else if (!((ch >= 48 /* _0 */ && ch <= 57 /* _9 */) ||
                    (ch >= 97 /* a */ && ch <= 102 /* f */))) {
                    break;
                }
                valueChars.push(ch);
                pos++;
                isPreviousTokenSeparator = false;
            }
            if (valueChars.length < minCount) {
                valueChars = [];
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return String.fromCharCode.apply(String, valueChars);
        }
        function scanString(jsxAttributeString) {
            if (jsxAttributeString === void 0) { jsxAttributeString = false; }
            var quote = text.charCodeAt(pos);
            pos++;
            var result = "";
            var start = pos;
            while (true) {
                if (pos >= end) {
                    result += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_string_literal);
                    break;
                }
                var ch = text.charCodeAt(pos);
                if (ch === quote) {
                    result += text.substring(start, pos);
                    pos++;
                    break;
                }
                if (ch === 92 /* backslash */ && !jsxAttributeString) {
                    result += text.substring(start, pos);
                    result += scanEscapeSequence();
                    start = pos;
                    continue;
                }
                if (isLineBreak(ch) && !jsxAttributeString) {
                    result += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_string_literal);
                    break;
                }
                pos++;
            }
            return result;
        }
        /**
         * Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or
         * a literal component of a TemplateExpression.
         */
        function scanTemplateAndSetTokenValue(isTaggedTemplate) {
            var startedWithBacktick = text.charCodeAt(pos) === 96 /* backtick */;
            pos++;
            var start = pos;
            var contents = "";
            var resultingToken;
            while (true) {
                if (pos >= end) {
                    contents += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_template_literal);
                    resultingToken = startedWithBacktick ? 14 /* NoSubstitutionTemplateLiteral */ : 17 /* TemplateTail */;
                    break;
                }
                var currChar = text.charCodeAt(pos);
                // '`'
                if (currChar === 96 /* backtick */) {
                    contents += text.substring(start, pos);
                    pos++;
                    resultingToken = startedWithBacktick ? 14 /* NoSubstitutionTemplateLiteral */ : 17 /* TemplateTail */;
                    break;
                }
                // '${'
                if (currChar === 36 /* $ */ && pos + 1 < end && text.charCodeAt(pos + 1) === 123 /* openBrace */) {
                    contents += text.substring(start, pos);
                    pos += 2;
                    resultingToken = startedWithBacktick ? 15 /* TemplateHead */ : 16 /* TemplateMiddle */;
                    break;
                }
                // Escape character
                if (currChar === 92 /* backslash */) {
                    contents += text.substring(start, pos);
                    contents += scanEscapeSequence(isTaggedTemplate);
                    start = pos;
                    continue;
                }
                // Speculated ECMAScript 6 Spec 11.8.6.1:
                // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values
                if (currChar === 13 /* carriageReturn */) {
                    contents += text.substring(start, pos);
                    pos++;
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                    contents += "\n";
                    start = pos;
                    continue;
                }
                pos++;
            }
            ts.Debug.assert(resultingToken !== undefined);
            tokenValue = contents;
            return resultingToken;
        }
        function scanEscapeSequence(isTaggedTemplate) {
            var start = pos;
            pos++;
            if (pos >= end) {
                error(ts.Diagnostics.Unexpected_end_of_text);
                return "";
            }
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 48 /* _0 */:
                    // '\01'
                    if (isTaggedTemplate && pos < end && isDigit(text.charCodeAt(pos))) {
                        pos++;
                        tokenFlags |= 2048 /* ContainsInvalidEscape */;
                        return text.substring(start, pos);
                    }
                    return "\0";
                case 98 /* b */:
                    return "\b";
                case 116 /* t */:
                    return "\t";
                case 110 /* n */:
                    return "\n";
                case 118 /* v */:
                    return "\v";
                case 102 /* f */:
                    return "\f";
                case 114 /* r */:
                    return "\r";
                case 39 /* singleQuote */:
                    return "\'";
                case 34 /* doubleQuote */:
                    return "\"";
                case 117 /* u */:
                    if (isTaggedTemplate) {
                        // '\u' or '\u0' or '\u00' or '\u000'
                        for (var escapePos = pos; escapePos < pos + 4; escapePos++) {
                            if (escapePos < end && !isHexDigit(text.charCodeAt(escapePos)) && text.charCodeAt(escapePos) !== 123 /* openBrace */) {
                                pos = escapePos;
                                tokenFlags |= 2048 /* ContainsInvalidEscape */;
                                return text.substring(start, pos);
                            }
                        }
                    }
                    // '\u{DDDDDDDD}'
                    if (pos < end && text.charCodeAt(pos) === 123 /* openBrace */) {
                        pos++;
                        // '\u{'
                        if (isTaggedTemplate && !isHexDigit(text.charCodeAt(pos))) {
                            tokenFlags |= 2048 /* ContainsInvalidEscape */;
                            return text.substring(start, pos);
                        }
                        if (isTaggedTemplate) {
                            var savePos = pos;
                            var escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
                            var escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
                            // '\u{Not Code Point' or '\u{CodePoint'
                            if (!isCodePoint(escapedValue) || text.charCodeAt(pos) !== 125 /* closeBrace */) {
                                tokenFlags |= 2048 /* ContainsInvalidEscape */;
                                return text.substring(start, pos);
                            }
                            else {
                                pos = savePos;
                            }
                        }
                        tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                        return scanExtendedUnicodeEscape();
                    }
                    tokenFlags |= 1024 /* UnicodeEscape */;
                    // '\uDDDD'
                    return scanHexadecimalEscape(/*numDigits*/ 4);
                case 120 /* x */:
                    if (isTaggedTemplate) {
                        if (!isHexDigit(text.charCodeAt(pos))) {
                            tokenFlags |= 2048 /* ContainsInvalidEscape */;
                            return text.substring(start, pos);
                        }
                        else if (!isHexDigit(text.charCodeAt(pos + 1))) {
                            pos++;
                            tokenFlags |= 2048 /* ContainsInvalidEscape */;
                            return text.substring(start, pos);
                        }
                    }
                    // '\xDD'
                    return scanHexadecimalEscape(/*numDigits*/ 2);
                // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence),
                // the line terminator is interpreted to be "the empty code unit sequence".
                case 13 /* carriageReturn */:
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                case 8232 /* lineSeparator */:
                case 8233 /* paragraphSeparator */:
                    return "";
                default:
                    return String.fromCharCode(ch);
            }
        }
        function scanHexadecimalEscape(numDigits) {
            var escapedValue = scanExactNumberOfHexDigits(numDigits, /*canHaveSeparators*/ false);
            if (escapedValue >= 0) {
                return String.fromCharCode(escapedValue);
            }
            else {
                error(ts.Diagnostics.Hexadecimal_digit_expected);
                return "";
            }
        }
        function scanExtendedUnicodeEscape() {
            var escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
            var escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
            var isInvalidExtendedEscape = false;
            // Validate the value of the digit
            if (escapedValue < 0) {
                error(ts.Diagnostics.Hexadecimal_digit_expected);
                isInvalidExtendedEscape = true;
            }
            else if (escapedValue > 0x10FFFF) {
                error(ts.Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive);
                isInvalidExtendedEscape = true;
            }
            if (pos >= end) {
                error(ts.Diagnostics.Unexpected_end_of_text);
                isInvalidExtendedEscape = true;
            }
            else if (text.charCodeAt(pos) === 125 /* closeBrace */) {
                // Only swallow the following character up if it's a '}'.
                pos++;
            }
            else {
                error(ts.Diagnostics.Unterminated_Unicode_escape_sequence);
                isInvalidExtendedEscape = true;
            }
            if (isInvalidExtendedEscape) {
                return "";
            }
            return utf16EncodeAsString(escapedValue);
        }
        // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX'
        // and return code point value if valid Unicode escape is found. Otherwise return -1.
        function peekUnicodeEscape() {
            if (pos + 5 < end && text.charCodeAt(pos + 1) === 117 /* u */) {
                var start_1 = pos;
                pos += 2;
                var value = scanExactNumberOfHexDigits(4, /*canHaveSeparators*/ false);
                pos = start_1;
                return value;
            }
            return -1;
        }
        function peekExtendedUnicodeEscape() {
            if (languageVersion >= 2 /* ES2015 */ && codePointAt(text, pos + 1) === 117 /* u */ && codePointAt(text, pos + 2) === 123 /* openBrace */) {
                var start_2 = pos;
                pos += 3;
                var escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
                var escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
                pos = start_2;
                return escapedValue;
            }
            return -1;
        }
        function scanIdentifierParts() {
            var result = "";
            var start = pos;
            while (pos < end) {
                var ch = codePointAt(text, pos);
                if (isIdentifierPart(ch, languageVersion)) {
                    pos += charSize(ch);
                }
                else if (ch === 92 /* backslash */) {
                    ch = peekExtendedUnicodeEscape();
                    if (ch >= 0 && isIdentifierPart(ch, languageVersion)) {
                        pos += 3;
                        tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                        result += scanExtendedUnicodeEscape();
                        start = pos;
                        continue;
                    }
                    ch = peekUnicodeEscape();
                    if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) {
                        break;
                    }
                    tokenFlags |= 1024 /* UnicodeEscape */;
                    result += text.substring(start, pos);
                    result += utf16EncodeAsString(ch);
                    // Valid Unicode escape is always six characters
                    pos += 6;
                    start = pos;
                }
                else {
                    break;
                }
            }
            result += text.substring(start, pos);
            return result;
        }
        function getIdentifierToken() {
            // Reserved words are between 2 and 11 characters long and start with a lowercase letter
            var len = tokenValue.length;
            if (len >= 2 && len <= 11) {
                var ch = tokenValue.charCodeAt(0);
                if (ch >= 97 /* a */ && ch <= 122 /* z */) {
                    var keyword = textToKeyword.get(tokenValue);
                    if (keyword !== undefined) {
                        return token = keyword;
                    }
                }
            }
            return token = 75 /* Identifier */;
        }
        function scanBinaryOrOctalDigits(base) {
            var value = "";
            // For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
            // Similarly valid octalIntegerLiteral must have at least one octal digit following o or O.
            var separatorAllowed = false;
            var isPreviousTokenSeparator = false;
            while (true) {
                var ch = text.charCodeAt(pos);
                // Numeric separators are allowed anywhere within a numeric literal, except not at the beginning, or following another separator
                if (ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (separatorAllowed) {
                        separatorAllowed = false;
                        isPreviousTokenSeparator = true;
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    continue;
                }
                separatorAllowed = true;
                if (!isDigit(ch) || ch - 48 /* _0 */ >= base) {
                    break;
                }
                value += text[pos];
                pos++;
                isPreviousTokenSeparator = false;
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                // Literal ends with underscore - not allowed
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return value;
        }
        function checkBigIntSuffix() {
            if (text.charCodeAt(pos) === 110 /* n */) {
                tokenValue += "n";
                // Use base 10 instead of base 2 or base 8 for shorter literals
                if (tokenFlags & 384 /* BinaryOrOctalSpecifier */) {
                    tokenValue = ts.parsePseudoBigInt(tokenValue) + "n";
                }
                pos++;
                return 9 /* BigIntLiteral */;
            }
            else { // not a bigint, so can convert to number in simplified form
                // Number() may not support 0b or 0o, so use parseInt() instead
                var numericValue = tokenFlags & 128 /* BinarySpecifier */
                    ? parseInt(tokenValue.slice(2), 2) // skip "0b"
                    : tokenFlags & 256 /* OctalSpecifier */
                        ? parseInt(tokenValue.slice(2), 8) // skip "0o"
                        : +tokenValue;
                tokenValue = "" + numericValue;
                return 8 /* NumericLiteral */;
            }
        }
        function scan() {
            var _a;
            startPos = pos;
            tokenFlags = 0 /* None */;
            var asteriskSeen = false;
            while (true) {
                tokenPos = pos;
                if (pos >= end) {
                    return token = 1 /* EndOfFileToken */;
                }
                var ch = codePointAt(text, pos);
                // Special handling for shebang
                if (ch === 35 /* hash */ && pos === 0 && isShebangTrivia(text, pos)) {
                    pos = scanShebangTrivia(text, pos);
                    if (skipTrivia) {
                        continue;
                    }
                    else {
                        return token = 6 /* ShebangTrivia */;
                    }
                }
                switch (ch) {
                    case 10 /* lineFeed */:
                    case 13 /* carriageReturn */:
                        tokenFlags |= 1 /* PrecedingLineBreak */;
                        if (skipTrivia) {
                            pos++;
                            continue;
                        }
                        else {
                            if (ch === 13 /* carriageReturn */ && pos + 1 < end && text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                                // consume both CR and LF
                                pos += 2;
                            }
                            else {
                                pos++;
                            }
                            return token = 4 /* NewLineTrivia */;
                        }
                    case 9 /* tab */:
                    case 11 /* verticalTab */:
                    case 12 /* formFeed */:
                    case 32 /* space */:
                    case 160 /* nonBreakingSpace */:
                    case 5760 /* ogham */:
                    case 8192 /* enQuad */:
                    case 8193 /* emQuad */:
                    case 8194 /* enSpace */:
                    case 8195 /* emSpace */:
                    case 8196 /* threePerEmSpace */:
                    case 8197 /* fourPerEmSpace */:
                    case 8198 /* sixPerEmSpace */:
                    case 8199 /* figureSpace */:
                    case 8200 /* punctuationSpace */:
                    case 8201 /* thinSpace */:
                    case 8202 /* hairSpace */:
                    case 8203 /* zeroWidthSpace */:
                    case 8239 /* narrowNoBreakSpace */:
                    case 8287 /* mathematicalSpace */:
                    case 12288 /* ideographicSpace */:
                    case 65279 /* byteOrderMark */:
                        if (skipTrivia) {
                            pos++;
                            continue;
                        }
                        else {
                            while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
                                pos++;
                            }
                            return token = 5 /* WhitespaceTrivia */;
                        }
                    case 33 /* exclamation */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 37 /* ExclamationEqualsEqualsToken */;
                            }
                            return pos += 2, token = 35 /* ExclamationEqualsToken */;
                        }
                        pos++;
                        return token = 53 /* ExclamationToken */;
                    case 34 /* doubleQuote */:
                    case 39 /* singleQuote */:
                        tokenValue = scanString();
                        return token = 10 /* StringLiteral */;
                    case 96 /* backtick */:
                        return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ false);
                    case 37 /* percent */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 68 /* PercentEqualsToken */;
                        }
                        pos++;
                        return token = 44 /* PercentToken */;
                    case 38 /* ampersand */:
                        if (text.charCodeAt(pos + 1) === 38 /* ampersand */) {
                            return pos += 2, token = 55 /* AmpersandAmpersandToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 72 /* AmpersandEqualsToken */;
                        }
                        pos++;
                        return token = 50 /* AmpersandToken */;
                    case 40 /* openParen */:
                        pos++;
                        return token = 20 /* OpenParenToken */;
                    case 41 /* closeParen */:
                        pos++;
                        return token = 21 /* CloseParenToken */;
                    case 42 /* asterisk */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 65 /* AsteriskEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 66 /* AsteriskAsteriskEqualsToken */;
                            }
                            return pos += 2, token = 42 /* AsteriskAsteriskToken */;
                        }
                        pos++;
                        if (inJSDocType && !asteriskSeen && (tokenFlags & 1 /* PrecedingLineBreak */)) {
                            // decoration at the start of a JSDoc comment line
                            asteriskSeen = true;
                            continue;
                        }
                        return token = 41 /* AsteriskToken */;
                    case 43 /* plus */:
                        if (text.charCodeAt(pos + 1) === 43 /* plus */) {
                            return pos += 2, token = 45 /* PlusPlusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 63 /* PlusEqualsToken */;
                        }
                        pos++;
                        return token = 39 /* PlusToken */;
                    case 44 /* comma */:
                        pos++;
                        return token = 27 /* CommaToken */;
                    case 45 /* minus */:
                        if (text.charCodeAt(pos + 1) === 45 /* minus */) {
                            return pos += 2, token = 46 /* MinusMinusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 64 /* MinusEqualsToken */;
                        }
                        pos++;
                        return token = 40 /* MinusToken */;
                    case 46 /* dot */:
                        if (isDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = scanNumber().value;
                            return token = 8 /* NumericLiteral */;
                        }
                        if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) {
                            return pos += 3, token = 25 /* DotDotDotToken */;
                        }
                        pos++;
                        return token = 24 /* DotToken */;
                    case 47 /* slash */:
                        // Single-line comment
                        if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                            pos += 2;
                            while (pos < end) {
                                if (isLineBreak(text.charCodeAt(pos))) {
                                    break;
                                }
                                pos++;
                            }
                            commentDirectives = appendIfCommentDirective(commentDirectives, text.slice(tokenPos, pos), commentDirectiveRegExSingleLine, tokenPos);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 2 /* SingleLineCommentTrivia */;
                            }
                        }
                        // Multi-line comment
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            pos += 2;
                            if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) !== 47 /* slash */) {
                                tokenFlags |= 2 /* PrecedingJSDocComment */;
                            }
                            var commentClosed = false;
                            var lastLineStart = tokenPos;
                            while (pos < end) {
                                var ch_1 = text.charCodeAt(pos);
                                if (ch_1 === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    commentClosed = true;
                                    break;
                                }
                                pos++;
                                if (isLineBreak(ch_1)) {
                                    lastLineStart = pos;
                                    tokenFlags |= 1 /* PrecedingLineBreak */;
                                }
                            }
                            commentDirectives = appendIfCommentDirective(commentDirectives, text.slice(lastLineStart, pos), commentDirectiveRegExMultiLine, lastLineStart);
                            if (!commentClosed) {
                                error(ts.Diagnostics.Asterisk_Slash_expected);
                            }
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                if (!commentClosed) {
                                    tokenFlags |= 4 /* Unterminated */;
                                }
                                return token = 3 /* MultiLineCommentTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 67 /* SlashEqualsToken */;
                        }
                        pos++;
                        return token = 43 /* SlashToken */;
                    case 48 /* _0 */:
                        if (pos + 2 < end && (text.charCodeAt(pos + 1) === 88 /* X */ || text.charCodeAt(pos + 1) === 120 /* x */)) {
                            pos += 2;
                            tokenValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Hexadecimal_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0x" + tokenValue;
                            tokenFlags |= 64 /* HexSpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 66 /* B */ || text.charCodeAt(pos + 1) === 98 /* b */)) {
                            pos += 2;
                            tokenValue = scanBinaryOrOctalDigits(/* base */ 2);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Binary_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0b" + tokenValue;
                            tokenFlags |= 128 /* BinarySpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 79 /* O */ || text.charCodeAt(pos + 1) === 111 /* o */)) {
                            pos += 2;
                            tokenValue = scanBinaryOrOctalDigits(/* base */ 8);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Octal_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0o" + tokenValue;
                            tokenFlags |= 256 /* OctalSpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        // Try to parse as an octal
                        if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = "" + scanOctalDigits();
                            tokenFlags |= 32 /* Octal */;
                            return token = 8 /* NumericLiteral */;
                        }
                    // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
                    // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being
                    // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do).
                    // falls through
                    case 49 /* _1 */:
                    case 50 /* _2 */:
                    case 51 /* _3 */:
                    case 52 /* _4 */:
                    case 53 /* _5 */:
                    case 54 /* _6 */:
                    case 55 /* _7 */:
                    case 56 /* _8 */:
                    case 57 /* _9 */:
                        (_a = scanNumber(), token = _a.type, tokenValue = _a.value);
                        return token;
                    case 58 /* colon */:
                        pos++;
                        return token = 58 /* ColonToken */;
                    case 59 /* semicolon */:
                        pos++;
                        return token = 26 /* SemicolonToken */;
                    case 60 /* lessThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 60 /* lessThan */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 69 /* LessThanLessThanEqualsToken */;
                            }
                            return pos += 2, token = 47 /* LessThanLessThanToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 32 /* LessThanEqualsToken */;
                        }
                        if (languageVariant === 1 /* JSX */ &&
                            text.charCodeAt(pos + 1) === 47 /* slash */ &&
                            text.charCodeAt(pos + 2) !== 42 /* asterisk */) {
                            return pos += 2, token = 30 /* LessThanSlashToken */;
                        }
                        pos++;
                        return token = 29 /* LessThanToken */;
                    case 61 /* equals */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 36 /* EqualsEqualsEqualsToken */;
                            }
                            return pos += 2, token = 34 /* EqualsEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                            return pos += 2, token = 38 /* EqualsGreaterThanToken */;
                        }
                        pos++;
                        return token = 62 /* EqualsToken */;
                    case 62 /* greaterThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        pos++;
                        return token = 31 /* GreaterThanToken */;
                    case 63 /* question */:
                        pos++;
                        if (text.charCodeAt(pos) === 46 /* dot */ && !isDigit(text.charCodeAt(pos + 1))) {
                            pos++;
                            return token = 28 /* QuestionDotToken */;
                        }
                        if (text.charCodeAt(pos) === 63 /* question */) {
                            pos++;
                            return token = 60 /* QuestionQuestionToken */;
                        }
                        return token = 57 /* QuestionToken */;
                    case 91 /* openBracket */:
                        pos++;
                        return token = 22 /* OpenBracketToken */;
                    case 93 /* closeBracket */:
                        pos++;
                        return token = 23 /* CloseBracketToken */;
                    case 94 /* caret */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 74 /* CaretEqualsToken */;
                        }
                        pos++;
                        return token = 52 /* CaretToken */;
                    case 123 /* openBrace */:
                        pos++;
                        return token = 18 /* OpenBraceToken */;
                    case 124 /* bar */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 124 /* bar */) {
                            return pos += 2, token = 56 /* BarBarToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 73 /* BarEqualsToken */;
                        }
                        pos++;
                        return token = 51 /* BarToken */;
                    case 125 /* closeBrace */:
                        pos++;
                        return token = 19 /* CloseBraceToken */;
                    case 126 /* tilde */:
                        pos++;
                        return token = 54 /* TildeToken */;
                    case 64 /* at */:
                        pos++;
                        return token = 59 /* AtToken */;
                    case 92 /* backslash */:
                        var extendedCookedChar = peekExtendedUnicodeEscape();
                        if (extendedCookedChar >= 0 && isIdentifierStart(extendedCookedChar, languageVersion)) {
                            pos += 3;
                            tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                            tokenValue = scanExtendedUnicodeEscape() + scanIdentifierParts();
                            return token = getIdentifierToken();
                        }
                        var cookedChar = peekUnicodeEscape();
                        if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) {
                            pos += 6;
                            tokenFlags |= 1024 /* UnicodeEscape */;
                            tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts();
                            return token = getIdentifierToken();
                        }
                        error(ts.Diagnostics.Invalid_character);
                        pos++;
                        return token = 0 /* Unknown */;
                    case 35 /* hash */:
                        if (pos !== 0 && text[pos + 1] === "!") {
                            error(ts.Diagnostics.can_only_be_used_at_the_start_of_a_file);
                            pos++;
                            return token = 0 /* Unknown */;
                        }
                        pos++;
                        if (isIdentifierStart(ch = text.charCodeAt(pos), languageVersion)) {
                            pos++;
                            while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion))
                                pos++;
                            tokenValue = text.substring(tokenPos, pos);
                            if (ch === 92 /* backslash */) {
                                tokenValue += scanIdentifierParts();
                            }
                        }
                        else {
                            tokenValue = "#";
                            error(ts.Diagnostics.Invalid_character);
                        }
                        return token = 76 /* PrivateIdentifier */;
                    default:
                        if (isIdentifierStart(ch, languageVersion)) {
                            pos += charSize(ch);
                            while (pos < end && isIdentifierPart(ch = codePointAt(text, pos), languageVersion))
                                pos += charSize(ch);
                            tokenValue = text.substring(tokenPos, pos);
                            if (ch === 92 /* backslash */) {
                                tokenValue += scanIdentifierParts();
                            }
                            return token = getIdentifierToken();
                        }
                        else if (isWhiteSpaceSingleLine(ch)) {
                            pos += charSize(ch);
                            continue;
                        }
                        else if (isLineBreak(ch)) {
                            tokenFlags |= 1 /* PrecedingLineBreak */;
                            pos += charSize(ch);
                            continue;
                        }
                        error(ts.Diagnostics.Invalid_character);
                        pos += charSize(ch);
                        return token = 0 /* Unknown */;
                }
            }
        }
        function reScanGreaterToken() {
            if (token === 31 /* GreaterThanToken */) {
                if (text.charCodeAt(pos) === 62 /* greaterThan */) {
                    if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                        if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                            return pos += 3, token = 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */;
                        }
                        return pos += 2, token = 49 /* GreaterThanGreaterThanGreaterThanToken */;
                    }
                    if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                        return pos += 2, token = 70 /* GreaterThanGreaterThanEqualsToken */;
                    }
                    pos++;
                    return token = 48 /* GreaterThanGreaterThanToken */;
                }
                if (text.charCodeAt(pos) === 61 /* equals */) {
                    pos++;
                    return token = 33 /* GreaterThanEqualsToken */;
                }
            }
            return token;
        }
        function reScanSlashToken() {
            if (token === 43 /* SlashToken */ || token === 67 /* SlashEqualsToken */) {
                var p = tokenPos + 1;
                var inEscape = false;
                var inCharacterClass = false;
                while (true) {
                    // If we reach the end of a file, or hit a newline, then this is an unterminated
                    // regex.  Report error and return what we have so far.
                    if (p >= end) {
                        tokenFlags |= 4 /* Unterminated */;
                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
                        break;
                    }
                    var ch = text.charCodeAt(p);
                    if (isLineBreak(ch)) {
                        tokenFlags |= 4 /* Unterminated */;
                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
                        break;
                    }
                    if (inEscape) {
                        // Parsing an escape character;
                        // reset the flag and just advance to the next char.
                        inEscape = false;
                    }
                    else if (ch === 47 /* slash */ && !inCharacterClass) {
                        // A slash within a character class is permissible,
                        // but in general it signals the end of the regexp literal.
                        p++;
                        break;
                    }
                    else if (ch === 91 /* openBracket */) {
                        inCharacterClass = true;
                    }
                    else if (ch === 92 /* backslash */) {
                        inEscape = true;
                    }
                    else if (ch === 93 /* closeBracket */) {
                        inCharacterClass = false;
                    }
                    p++;
                }
                while (p < end && isIdentifierPart(text.charCodeAt(p), languageVersion)) {
                    p++;
                }
                pos = p;
                tokenValue = text.substring(tokenPos, pos);
                token = 13 /* RegularExpressionLiteral */;
            }
            return token;
        }
        function appendIfCommentDirective(commentDirectives, text, commentDirectiveRegEx, lineStart) {
            var type = getDirectiveFromComment(text, commentDirectiveRegEx);
            if (type === undefined) {
                return commentDirectives;
            }
            return ts.append(commentDirectives, {
                range: { pos: lineStart, end: pos },
                type: type,
            });
        }
        function getDirectiveFromComment(text, commentDirectiveRegEx) {
            var match = commentDirectiveRegEx.exec(text);
            if (!match) {
                return undefined;
            }
            switch (match[1]) {
                case "ts-expect-error":
                    return 0 /* ExpectError */;
                case "ts-ignore":
                    return 1 /* Ignore */;
            }
            return undefined;
        }
        /**
         * Unconditionally back up and scan a template expression portion.
         */
        function reScanTemplateToken(isTaggedTemplate) {
            ts.Debug.assert(token === 19 /* CloseBraceToken */, "'reScanTemplateToken' should only be called on a '}'");
            pos = tokenPos;
            return token = scanTemplateAndSetTokenValue(isTaggedTemplate);
        }
        function reScanTemplateHeadOrNoSubstitutionTemplate() {
            pos = tokenPos;
            return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ true);
        }
        function reScanJsxToken() {
            pos = tokenPos = startPos;
            return token = scanJsxToken();
        }
        function reScanLessThanToken() {
            if (token === 47 /* LessThanLessThanToken */) {
                pos = tokenPos + 1;
                return token = 29 /* LessThanToken */;
            }
            return token;
        }
        function reScanQuestionToken() {
            ts.Debug.assert(token === 60 /* QuestionQuestionToken */, "'reScanQuestionToken' should only be called on a '??'");
            pos = tokenPos + 1;
            return token = 57 /* QuestionToken */;
        }
        function scanJsxToken() {
            startPos = tokenPos = pos;
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            var char = text.charCodeAt(pos);
            if (char === 60 /* lessThan */) {
                if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                    pos += 2;
                    return token = 30 /* LessThanSlashToken */;
                }
                pos++;
                return token = 29 /* LessThanToken */;
            }
            if (char === 123 /* openBrace */) {
                pos++;
                return token = 18 /* OpenBraceToken */;
            }
            // First non-whitespace character on this line.
            var firstNonWhitespace = 0;
            var lastNonWhitespace = -1;
            // These initial values are special because the first line is:
            // firstNonWhitespace = 0 to indicate that we want leading whitespace,
            while (pos < end) {
                // We want to keep track of the last non-whitespace (but including
                // newlines character for hitting the end of the JSX Text region)
                if (!isWhiteSpaceSingleLine(char)) {
                    lastNonWhitespace = pos;
                }
                char = text.charCodeAt(pos);
                if (char === 123 /* openBrace */) {
                    break;
                }
                if (char === 60 /* lessThan */) {
                    if (isConflictMarkerTrivia(text, pos)) {
                        pos = scanConflictMarkerTrivia(text, pos, error);
                        return token = 7 /* ConflictMarkerTrivia */;
                    }
                    break;
                }
                if (char === 62 /* greaterThan */) {
                    error(ts.Diagnostics.Unexpected_token_Did_you_mean_or_gt, pos, 1);
                }
                if (char === 125 /* closeBrace */) {
                    error(ts.Diagnostics.Unexpected_token_Did_you_mean_or_rbrace, pos, 1);
                }
                if (lastNonWhitespace > 0)
                    lastNonWhitespace++;
                // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces.
                // i.e (- : whitespace)
                //      <div>----
                //      </div> becomes <div></div>
                //
                //      <div>----</div> becomes <div>----</div>
                if (isLineBreak(char) && firstNonWhitespace === 0) {
                    firstNonWhitespace = -1;
                }
                else if (!isWhiteSpaceLike(char)) {
                    firstNonWhitespace = pos;
                }
                pos++;
            }
            var endPosition = lastNonWhitespace === -1 ? pos : lastNonWhitespace;
            tokenValue = text.substring(startPos, endPosition);
            return firstNonWhitespace === -1 ? 12 /* JsxTextAllWhiteSpaces */ : 11 /* JsxText */;
        }
        // Scans a JSX identifier; these differ from normal identifiers in that
        // they allow dashes
        function scanJsxIdentifier() {
            if (tokenIsIdentifierOrKeyword(token)) {
                // An identifier or keyword has already been parsed - check for a `-` and then append it and everything after it to the token
                // Do note that this means that `scanJsxIdentifier` effectively _mutates_ the visible token without advancing to a new token
                // Any caller should be expecting this behavior and should only read the pos or token value after calling it.
                while (pos < end) {
                    var ch = text.charCodeAt(pos);
                    if (ch === 45 /* minus */) {
                        tokenValue += "-";
                        pos++;
                        continue;
                    }
                    var oldPos = pos;
                    tokenValue += scanIdentifierParts(); // reuse `scanIdentifierParts` so unicode escapes are handled
                    if (pos === oldPos) {
                        break;
                    }
                }
            }
            return token;
        }
        function scanJsxAttributeValue() {
            startPos = pos;
            switch (text.charCodeAt(pos)) {
                case 34 /* doubleQuote */:
                case 39 /* singleQuote */:
                    tokenValue = scanString(/*jsxAttributeString*/ true);
                    return token = 10 /* StringLiteral */;
                default:
                    // If this scans anything other than `{`, it's a parse error.
                    return scan();
            }
        }
        function reScanJsxAttributeValue() {
            pos = tokenPos = startPos;
            return scanJsxAttributeValue();
        }
        function scanJsDocToken() {
            startPos = tokenPos = pos;
            tokenFlags = 0 /* None */;
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            var ch = codePointAt(text, pos);
            pos += charSize(ch);
            switch (ch) {
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
                        pos++;
                    }
                    return token = 5 /* WhitespaceTrivia */;
                case 64 /* at */:
                    return token = 59 /* AtToken */;
                case 10 /* lineFeed */:
                case 13 /* carriageReturn */:
                    tokenFlags |= 1 /* PrecedingLineBreak */;
                    return token = 4 /* NewLineTrivia */;
                case 42 /* asterisk */:
                    return token = 41 /* AsteriskToken */;
                case 123 /* openBrace */:
                    return token = 18 /* OpenBraceToken */;
                case 125 /* closeBrace */:
                    return token = 19 /* CloseBraceToken */;
                case 91 /* openBracket */:
                    return token = 22 /* OpenBracketToken */;
                case 93 /* closeBracket */:
                    return token = 23 /* CloseBracketToken */;
                case 60 /* lessThan */:
                    return token = 29 /* LessThanToken */;
                case 62 /* greaterThan */:
                    return token = 31 /* GreaterThanToken */;
                case 61 /* equals */:
                    return token = 62 /* EqualsToken */;
                case 44 /* comma */:
                    return token = 27 /* CommaToken */;
                case 46 /* dot */:
                    return token = 24 /* DotToken */;
                case 96 /* backtick */:
                    return token = 61 /* BacktickToken */;
                case 92 /* backslash */:
                    pos--;
                    var extendedCookedChar = peekExtendedUnicodeEscape();
                    if (extendedCookedChar >= 0 && isIdentifierStart(extendedCookedChar, languageVersion)) {
                        pos += 3;
                        tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                        tokenValue = scanExtendedUnicodeEscape() + scanIdentifierParts();
                        return token = getIdentifierToken();
                    }
                    var cookedChar = peekUnicodeEscape();
                    if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) {
                        pos += 6;
                        tokenFlags |= 1024 /* UnicodeEscape */;
                        tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts();
                        return token = getIdentifierToken();
                    }
                    pos++;
                    return token = 0 /* Unknown */;
            }
            if (isIdentifierStart(ch, languageVersion)) {
                var char = ch;
                while (pos < end && isIdentifierPart(char = codePointAt(text, pos), languageVersion) || text.charCodeAt(pos) === 45 /* minus */)
                    pos += charSize(char);
                tokenValue = text.substring(tokenPos, pos);
                if (char === 92 /* backslash */) {
                    tokenValue += scanIdentifierParts();
                }
                return token = getIdentifierToken();
            }
            else {
                return token = 0 /* Unknown */;
            }
        }
        function speculationHelper(callback, isLookahead) {
            var savePos = pos;
            var saveStartPos = startPos;
            var saveTokenPos = tokenPos;
            var saveToken = token;
            var saveTokenValue = tokenValue;
            var saveTokenFlags = tokenFlags;
            var result = callback();
            // If our callback returned something 'falsy' or we're just looking ahead,
            // then unconditionally restore us to where we were.
            if (!result || isLookahead) {
                pos = savePos;
                startPos = saveStartPos;
                tokenPos = saveTokenPos;
                token = saveToken;
                tokenValue = saveTokenValue;
                tokenFlags = saveTokenFlags;
            }
            return result;
        }
        function scanRange(start, length, callback) {
            var saveEnd = end;
            var savePos = pos;
            var saveStartPos = startPos;
            var saveTokenPos = tokenPos;
            var saveToken = token;
            var saveTokenValue = tokenValue;
            var saveTokenFlags = tokenFlags;
            var saveErrorExpectations = commentDirectives;
            setText(text, start, length);
            var result = callback();
            end = saveEnd;
            pos = savePos;
            startPos = saveStartPos;
            tokenPos = saveTokenPos;
            token = saveToken;
            tokenValue = saveTokenValue;
            tokenFlags = saveTokenFlags;
            commentDirectives = saveErrorExpectations;
            return result;
        }
        function lookAhead(callback) {
            return speculationHelper(callback, /*isLookahead*/ true);
        }
        function tryScan(callback) {
            return speculationHelper(callback, /*isLookahead*/ false);
        }
        function getText() {
            return text;
        }
        function clearCommentDirectives() {
            commentDirectives = undefined;
        }
        function setText(newText, start, length) {
            text = newText || "";
            end = length === undefined ? text.length : start + length;
            setTextPos(start || 0);
        }
        function setOnError(errorCallback) {
            onError = errorCallback;
        }
        function setScriptTarget(scriptTarget) {
            languageVersion = scriptTarget;
        }
        function setLanguageVariant(variant) {
            languageVariant = variant;
        }
        function setTextPos(textPos) {
            ts.Debug.assert(textPos >= 0);
            pos = textPos;
            startPos = textPos;
            tokenPos = textPos;
            token = 0 /* Unknown */;
            tokenValue = undefined;
            tokenFlags = 0 /* None */;
        }
        function setInJSDocType(inType) {
            inJSDocType += inType ? 1 : -1;
        }
    }
    ts.createScanner = createScanner;
    /* @internal */
    var codePointAt = String.prototype.codePointAt ? function (s, i) { return s.codePointAt(i); } : function codePointAt(str, i) {
        // from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt
        var size = str.length;
        // Account for out-of-bounds indices:
        if (i < 0 || i >= size) {
            return undefined; // String.codePointAt returns `undefined` for OOB indexes
        }
        // Get the first code unit
        var first = str.charCodeAt(i);
        // check if it’s the start of a surrogate pair
        if (first >= 0xD800 && first <= 0xDBFF && size > i + 1) { // high surrogate and there is a next code unit
            var second = str.charCodeAt(i + 1);
            if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
                // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
                return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
            }
        }
        return first;
    };
    /* @internal */
    function charSize(ch) {
        if (ch >= 0x10000) {
            return 2;
        }
        return 1;
    }
    // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec.
    function utf16EncodeAsStringFallback(codePoint) {
        ts.Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF);
        if (codePoint <= 65535) {
            return String.fromCharCode(codePoint);
        }
        var codeUnit1 = Math.floor((codePoint - 65536) / 1024) + 0xD800;
        var codeUnit2 = ((codePoint - 65536) % 1024) + 0xDC00;
        return String.fromCharCode(codeUnit1, codeUnit2);
    }
    var utf16EncodeAsStringWorker = String.fromCodePoint ? function (codePoint) { return String.fromCodePoint(codePoint); } : utf16EncodeAsStringFallback;
    /* @internal */
    function utf16EncodeAsString(codePoint) {
        return utf16EncodeAsStringWorker(codePoint);
    }
    ts.utf16EncodeAsString = utf16EncodeAsString;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function isExternalModuleNameRelative(moduleName) {
        // TypeScript 1.0 spec (April 2014): 11.2.1
        // An external module name is "relative" if the first term is "." or "..".
        // Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
        return ts.pathIsRelative(moduleName) || ts.isRootedDiskPath(moduleName);
    }
    ts.isExternalModuleNameRelative = isExternalModuleNameRelative;
    function sortAndDeduplicateDiagnostics(diagnostics) {
        return ts.sortAndDeduplicate(diagnostics, ts.compareDiagnostics);
    }
    ts.sortAndDeduplicateDiagnostics = sortAndDeduplicateDiagnostics;
    function getDefaultLibFileName(options) {
        switch (options.target) {
            case 99 /* ESNext */:
                return "lib.esnext.full.d.ts";
            case 7 /* ES2020 */:
                return "lib.es2020.full.d.ts";
            case 6 /* ES2019 */:
                return "lib.es2019.full.d.ts";
            case 5 /* ES2018 */:
                return "lib.es2018.full.d.ts";
            case 4 /* ES2017 */:
                return "lib.es2017.full.d.ts";
            case 3 /* ES2016 */:
                return "lib.es2016.full.d.ts";
            case 2 /* ES2015 */:
                return "lib.es6.d.ts"; // We don't use lib.es2015.full.d.ts due to breaking change.
            default:
                return "lib.d.ts";
        }
    }
    ts.getDefaultLibFileName = getDefaultLibFileName;
    function textSpanEnd(span) {
        return span.start + span.length;
    }
    ts.textSpanEnd = textSpanEnd;
    function textSpanIsEmpty(span) {
        return span.length === 0;
    }
    ts.textSpanIsEmpty = textSpanIsEmpty;
    function textSpanContainsPosition(span, position) {
        return position >= span.start && position < textSpanEnd(span);
    }
    ts.textSpanContainsPosition = textSpanContainsPosition;
    /* @internal */
    function textRangeContainsPositionInclusive(span, position) {
        return position >= span.pos && position <= span.end;
    }
    ts.textRangeContainsPositionInclusive = textRangeContainsPositionInclusive;
    // Returns true if 'span' contains 'other'.
    function textSpanContainsTextSpan(span, other) {
        return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span);
    }
    ts.textSpanContainsTextSpan = textSpanContainsTextSpan;
    function textSpanOverlapsWith(span, other) {
        return textSpanOverlap(span, other) !== undefined;
    }
    ts.textSpanOverlapsWith = textSpanOverlapsWith;
    function textSpanOverlap(span1, span2) {
        var overlap = textSpanIntersection(span1, span2);
        return overlap && overlap.length === 0 ? undefined : overlap;
    }
    ts.textSpanOverlap = textSpanOverlap;
    function textSpanIntersectsWithTextSpan(span, other) {
        return decodedTextSpanIntersectsWith(span.start, span.length, other.start, other.length);
    }
    ts.textSpanIntersectsWithTextSpan = textSpanIntersectsWithTextSpan;
    function textSpanIntersectsWith(span, start, length) {
        return decodedTextSpanIntersectsWith(span.start, span.length, start, length);
    }
    ts.textSpanIntersectsWith = textSpanIntersectsWith;
    function decodedTextSpanIntersectsWith(start1, length1, start2, length2) {
        var end1 = start1 + length1;
        var end2 = start2 + length2;
        return start2 <= end1 && end2 >= start1;
    }
    ts.decodedTextSpanIntersectsWith = decodedTextSpanIntersectsWith;
    function textSpanIntersectsWithPosition(span, position) {
        return position <= textSpanEnd(span) && position >= span.start;
    }
    ts.textSpanIntersectsWithPosition = textSpanIntersectsWithPosition;
    function textSpanIntersection(span1, span2) {
        var start = Math.max(span1.start, span2.start);
        var end = Math.min(textSpanEnd(span1), textSpanEnd(span2));
        return start <= end ? createTextSpanFromBounds(start, end) : undefined;
    }
    ts.textSpanIntersection = textSpanIntersection;
    function createTextSpan(start, length) {
        if (start < 0) {
            throw new Error("start < 0");
        }
        if (length < 0) {
            throw new Error("length < 0");
        }
        return { start: start, length: length };
    }
    ts.createTextSpan = createTextSpan;
    function createTextSpanFromBounds(start, end) {
        return createTextSpan(start, end - start);
    }
    ts.createTextSpanFromBounds = createTextSpanFromBounds;
    function textChangeRangeNewSpan(range) {
        return createTextSpan(range.span.start, range.newLength);
    }
    ts.textChangeRangeNewSpan = textChangeRangeNewSpan;
    function textChangeRangeIsUnchanged(range) {
        return textSpanIsEmpty(range.span) && range.newLength === 0;
    }
    ts.textChangeRangeIsUnchanged = textChangeRangeIsUnchanged;
    function createTextChangeRange(span, newLength) {
        if (newLength < 0) {
            throw new Error("newLength < 0");
        }
        return { span: span, newLength: newLength };
    }
    ts.createTextChangeRange = createTextChangeRange;
    ts.unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0); // eslint-disable-line prefer-const
    /**
     * Called to merge all the changes that occurred across several versions of a script snapshot
     * into a single change.  i.e. if a user keeps making successive edits to a script we will
     * have a text change from V1 to V2, V2 to V3, ..., Vn.
     *
     * This function will then merge those changes into a single change range valid between V1 and
     * Vn.
     */
    function collapseTextChangeRangesAcrossMultipleVersions(changes) {
        if (changes.length === 0) {
            return ts.unchangedTextChangeRange;
        }
        if (changes.length === 1) {
            return changes[0];
        }
        // We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd }
        // as it makes things much easier to reason about.
        var change0 = changes[0];
        var oldStartN = change0.span.start;
        var oldEndN = textSpanEnd(change0.span);
        var newEndN = oldStartN + change0.newLength;
        for (var i = 1; i < changes.length; i++) {
            var nextChange = changes[i];
            // Consider the following case:
            // i.e. two edits.  The first represents the text change range { { 10, 50 }, 30 }.  i.e. The span starting
            // at 10, with length 50 is reduced to length 30.  The second represents the text change range { { 30, 30 }, 40 }.
            // i.e. the span starting at 30 with length 30 is increased to length 40.
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      -------------------------------------------------------------------------------------------------------
            //                |                                                 /
            //                |                                            /----
            //  T1            |                                       /----
            //                |                                  /----
            //                |                             /----
            //      -------------------------------------------------------------------------------------------------------
            //                                     |                            \
            //                                     |                               \
            //   T2                                |                                 \
            //                                     |                                   \
            //                                     |                                      \
            //      -------------------------------------------------------------------------------------------------------
            //
            // Merging these turns out to not be too difficult.  First, determining the new start of the change is trivial
            // it's just the min of the old and new starts.  i.e.:
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      ------------------------------------------------------------*------------------------------------------
            //                |                                                 /
            //                |                                            /----
            //  T1            |                                       /----
            //                |                                  /----
            //                |                             /----
            //      ----------------------------------------$-------------------$------------------------------------------
            //                .                    |                            \
            //                .                    |                               \
            //   T2           .                    |                                 \
            //                .                    |                                   \
            //                .                    |                                      \
            //      ----------------------------------------------------------------------*--------------------------------
            //
            // (Note the dots represent the newly inferred start.
            // Determining the new and old end is also pretty simple.  Basically it boils down to paying attention to the
            // absolute positions at the asterisks, and the relative change between the dollar signs. Basically, we see
            // which if the two $'s precedes the other, and we move that one forward until they line up.  in this case that
            // means:
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      --------------------------------------------------------------------------------*----------------------
            //                |                                                                     /
            //                |                                                                /----
            //  T1            |                                                           /----
            //                |                                                      /----
            //                |                                                 /----
            //      ------------------------------------------------------------$------------------------------------------
            //                .                    |                            \
            //                .                    |                               \
            //   T2           .                    |                                 \
            //                .                    |                                   \
            //                .                    |                                      \
            //      ----------------------------------------------------------------------*--------------------------------
            //
            // In other words (in this case), we're recognizing that the second edit happened after where the first edit
            // ended with a delta of 20 characters (60 - 40).  Thus, if we go back in time to where the first edit started
            // that's the same as if we started at char 80 instead of 60.
            //
            // As it so happens, the same logic applies if the second edit precedes the first edit.  In that case rather
            // than pushing the first edit forward to match the second, we'll push the second edit forward to match the
            // first.
            //
            // In this case that means we have { oldStart: 10, oldEnd: 80, newEnd: 70 } or, in TextChangeRange
            // semantics: { { start: 10, length: 70 }, newLength: 60 }
            //
            // The math then works out as follows.
            // If we have { oldStart1, oldEnd1, newEnd1 } and { oldStart2, oldEnd2, newEnd2 } then we can compute the
            // final result like so:
            //
            // {
            //      oldStart3: Min(oldStart1, oldStart2),
            //      oldEnd3: Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)),
            //      newEnd3: Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
            // }
            var oldStart1 = oldStartN;
            var oldEnd1 = oldEndN;
            var newEnd1 = newEndN;
            var oldStart2 = nextChange.span.start;
            var oldEnd2 = textSpanEnd(nextChange.span);
            var newEnd2 = oldStart2 + nextChange.newLength;
            oldStartN = Math.min(oldStart1, oldStart2);
            oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
            newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
        }
        return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength*/ newEndN - oldStartN);
    }
    ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions;
    function getTypeParameterOwner(d) {
        if (d && d.kind === 155 /* TypeParameter */) {
            for (var current = d; current; current = current.parent) {
                if (isFunctionLike(current) || isClassLike(current) || current.kind === 246 /* InterfaceDeclaration */) {
                    return current;
                }
            }
        }
    }
    ts.getTypeParameterOwner = getTypeParameterOwner;
    function isParameterPropertyDeclaration(node, parent) {
        return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) && parent.kind === 162 /* Constructor */;
    }
    ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration;
    function isEmptyBindingPattern(node) {
        if (isBindingPattern(node)) {
            return ts.every(node.elements, isEmptyBindingElement);
        }
        return false;
    }
    ts.isEmptyBindingPattern = isEmptyBindingPattern;
    function isEmptyBindingElement(node) {
        if (isOmittedExpression(node)) {
            return true;
        }
        return isEmptyBindingPattern(node.name);
    }
    ts.isEmptyBindingElement = isEmptyBindingElement;
    function walkUpBindingElementsAndPatterns(binding) {
        var node = binding.parent;
        while (isBindingElement(node.parent)) {
            node = node.parent.parent;
        }
        return node.parent;
    }
    ts.walkUpBindingElementsAndPatterns = walkUpBindingElementsAndPatterns;
    function getCombinedFlags(node, getFlags) {
        if (isBindingElement(node)) {
            node = walkUpBindingElementsAndPatterns(node);
        }
        var flags = getFlags(node);
        if (node.kind === 242 /* VariableDeclaration */) {
            node = node.parent;
        }
        if (node && node.kind === 243 /* VariableDeclarationList */) {
            flags |= getFlags(node);
            node = node.parent;
        }
        if (node && node.kind === 225 /* VariableStatement */) {
            flags |= getFlags(node);
        }
        return flags;
    }
    function getCombinedModifierFlags(node) {
        return getCombinedFlags(node, ts.getModifierFlags);
    }
    ts.getCombinedModifierFlags = getCombinedModifierFlags;
    // Returns the node flags for this node and all relevant parent nodes.  This is done so that
    // nodes like variable declarations and binding elements can returned a view of their flags
    // that includes the modifiers from their container.  i.e. flags like export/declare aren't
    // stored on the variable declaration directly, but on the containing variable statement
    // (if it has one).  Similarly, flags for let/const are store on the variable declaration
    // list.  By calling this function, all those flags are combined so that the client can treat
    // the node as if it actually had those flags.
    function getCombinedNodeFlags(node) {
        return getCombinedFlags(node, function (n) { return n.flags; });
    }
    ts.getCombinedNodeFlags = getCombinedNodeFlags;
    /**
     * Checks to see if the locale is in the appropriate format,
     * and if it is, attempts to set the appropriate language.
     */
    function validateLocaleAndSetLanguage(locale, sys, errors) {
        var matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
        if (!matchResult) {
            if (errors) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
            }
            return;
        }
        var language = matchResult[1];
        var territory = matchResult[3];
        // First try the entire locale, then fall back to just language if that's all we have.
        // Either ways do not fail, and fallback to the English diagnostic strings.
        if (!trySetLanguageAndTerritory(language, territory, errors)) {
            trySetLanguageAndTerritory(language, /*territory*/ undefined, errors);
        }
        // Set the UI locale for string collation
        ts.setUILocale(locale);
        function trySetLanguageAndTerritory(language, territory, errors) {
            var compilerFilePath = ts.normalizePath(sys.getExecutingFilePath());
            var containingDirectoryPath = ts.getDirectoryPath(compilerFilePath);
            var filePath = ts.combinePaths(containingDirectoryPath, language);
            if (territory) {
                filePath = filePath + "-" + territory;
            }
            filePath = sys.resolvePath(ts.combinePaths(filePath, "diagnosticMessages.generated.json"));
            if (!sys.fileExists(filePath)) {
                return false;
            }
            // TODO: Add codePage support for readFile?
            var fileContents = "";
            try {
                fileContents = sys.readFile(filePath);
            }
            catch (e) {
                if (errors) {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unable_to_open_file_0, filePath));
                }
                return false;
            }
            try {
                // this is a global mutation (or live binding update)!
                ts.setLocalizedDiagnosticMessages(JSON.parse(fileContents));
            }
            catch (_a) {
                if (errors) {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Corrupted_locale_file_0, filePath));
                }
                return false;
            }
            return true;
        }
    }
    ts.validateLocaleAndSetLanguage = validateLocaleAndSetLanguage;
    function getOriginalNode(node, nodeTest) {
        if (node) {
            while (node.original !== undefined) {
                node = node.original;
            }
        }
        return !nodeTest || nodeTest(node) ? node : undefined;
    }
    ts.getOriginalNode = getOriginalNode;
    /**
     * Gets a value indicating whether a node originated in the parse tree.
     *
     * @param node The node to test.
     */
    function isParseTreeNode(node) {
        return (node.flags & 8 /* Synthesized */) === 0;
    }
    ts.isParseTreeNode = isParseTreeNode;
    function getParseTreeNode(node, nodeTest) {
        if (node === undefined || isParseTreeNode(node)) {
            return node;
        }
        node = getOriginalNode(node);
        if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
            return node;
        }
        return undefined;
    }
    ts.getParseTreeNode = getParseTreeNode;
    /** Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' */
    function escapeLeadingUnderscores(identifier) {
        return (identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier);
    }
    ts.escapeLeadingUnderscores = escapeLeadingUnderscores;
    /**
     * Remove extra underscore from escaped identifier text content.
     *
     * @param identifier The escaped identifier text.
     * @returns The unescaped identifier text.
     */
    function unescapeLeadingUnderscores(identifier) {
        var id = identifier;
        return id.length >= 3 && id.charCodeAt(0) === 95 /* _ */ && id.charCodeAt(1) === 95 /* _ */ && id.charCodeAt(2) === 95 /* _ */ ? id.substr(1) : id;
    }
    ts.unescapeLeadingUnderscores = unescapeLeadingUnderscores;
    function idText(identifierOrPrivateName) {
        return unescapeLeadingUnderscores(identifierOrPrivateName.escapedText);
    }
    ts.idText = idText;
    function symbolName(symbol) {
        if (symbol.valueDeclaration && isPrivateIdentifierPropertyDeclaration(symbol.valueDeclaration)) {
            return idText(symbol.valueDeclaration.name);
        }
        return unescapeLeadingUnderscores(symbol.escapedName);
    }
    ts.symbolName = symbolName;
    /**
     * A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should
     * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol
     * will be merged with)
     */
    function nameForNamelessJSDocTypedef(declaration) {
        var hostNode = declaration.parent.parent;
        if (!hostNode) {
            return undefined;
        }
        // Covers classes, functions - any named declaration host node
        if (isDeclaration(hostNode)) {
            return getDeclarationIdentifier(hostNode);
        }
        // Covers remaining cases (returning undefined if none match).
        switch (hostNode.kind) {
            case 225 /* VariableStatement */:
                if (hostNode.declarationList && hostNode.declarationList.declarations[0]) {
                    return getDeclarationIdentifier(hostNode.declarationList.declarations[0]);
                }
                break;
            case 226 /* ExpressionStatement */:
                var expr = hostNode.expression;
                if (expr.kind === 209 /* BinaryExpression */ && expr.operatorToken.kind === 62 /* EqualsToken */) {
                    expr = expr.left;
                }
                switch (expr.kind) {
                    case 194 /* PropertyAccessExpression */:
                        return expr.name;
                    case 195 /* ElementAccessExpression */:
                        var arg = expr.argumentExpression;
                        if (isIdentifier(arg)) {
                            return arg;
                        }
                }
                break;
            case 200 /* ParenthesizedExpression */: {
                return getDeclarationIdentifier(hostNode.expression);
            }
            case 238 /* LabeledStatement */: {
                if (isDeclaration(hostNode.statement) || isExpression(hostNode.statement)) {
                    return getDeclarationIdentifier(hostNode.statement);
                }
                break;
            }
        }
    }
    function getDeclarationIdentifier(node) {
        var name = getNameOfDeclaration(node);
        return name && isIdentifier(name) ? name : undefined;
    }
    /** @internal */
    function nodeHasName(statement, name) {
        if (isNamedDeclaration(statement) && isIdentifier(statement.name) && idText(statement.name) === idText(name)) {
            return true;
        }
        if (isVariableStatement(statement) && ts.some(statement.declarationList.declarations, function (d) { return nodeHasName(d, name); })) {
            return true;
        }
        return false;
    }
    ts.nodeHasName = nodeHasName;
    function getNameOfJSDocTypedef(declaration) {
        return declaration.name || nameForNamelessJSDocTypedef(declaration);
    }
    ts.getNameOfJSDocTypedef = getNameOfJSDocTypedef;
    /** @internal */
    function isNamedDeclaration(node) {
        return !!node.name; // A 'name' property should always be a DeclarationName.
    }
    ts.isNamedDeclaration = isNamedDeclaration;
    /** @internal */
    function getNonAssignedNameOfDeclaration(declaration) {
        switch (declaration.kind) {
            case 75 /* Identifier */:
                return declaration;
            case 323 /* JSDocPropertyTag */:
            case 317 /* JSDocParameterTag */: {
                var name = declaration.name;
                if (name.kind === 153 /* QualifiedName */) {
                    return name.right;
                }
                break;
            }
            case 196 /* CallExpression */:
            case 209 /* BinaryExpression */: {
                var expr_1 = declaration;
                switch (ts.getAssignmentDeclarationKind(expr_1)) {
                    case 1 /* ExportsProperty */:
                    case 4 /* ThisProperty */:
                    case 5 /* Property */:
                    case 3 /* PrototypeProperty */:
                        return ts.getElementOrPropertyAccessArgumentExpressionOrName(expr_1.left);
                    case 7 /* ObjectDefinePropertyValue */:
                    case 8 /* ObjectDefinePropertyExports */:
                    case 9 /* ObjectDefinePrototypeProperty */:
                        return expr_1.arguments[1];
                    default:
                        return undefined;
                }
            }
            case 322 /* JSDocTypedefTag */:
                return getNameOfJSDocTypedef(declaration);
            case 316 /* JSDocEnumTag */:
                return nameForNamelessJSDocTypedef(declaration);
            case 259 /* ExportAssignment */: {
                var expression = declaration.expression;
                return isIdentifier(expression) ? expression : undefined;
            }
            case 195 /* ElementAccessExpression */:
                var expr = declaration;
                if (ts.isBindableStaticElementAccessExpression(expr)) {
                    return expr.argumentExpression;
                }
        }
        return declaration.name;
    }
    ts.getNonAssignedNameOfDeclaration = getNonAssignedNameOfDeclaration;
    function getNameOfDeclaration(declaration) {
        if (declaration === undefined)
            return undefined;
        return getNonAssignedNameOfDeclaration(declaration) ||
            (isFunctionExpression(declaration) || isClassExpression(declaration) ? getAssignedName(declaration) : undefined);
    }
    ts.getNameOfDeclaration = getNameOfDeclaration;
    function getAssignedName(node) {
        if (!node.parent) {
            return undefined;
        }
        else if (isPropertyAssignment(node.parent) || isBindingElement(node.parent)) {
            return node.parent.name;
        }
        else if (isBinaryExpression(node.parent) && node === node.parent.right) {
            if (isIdentifier(node.parent.left)) {
                return node.parent.left;
            }
            else if (ts.isAccessExpression(node.parent.left)) {
                return ts.getElementOrPropertyAccessArgumentExpressionOrName(node.parent.left);
            }
        }
        else if (isVariableDeclaration(node.parent) && isIdentifier(node.parent.name)) {
            return node.parent.name;
        }
    }
    /**
     * Gets the JSDoc parameter tags for the node if present.
     *
     * @remarks Returns any JSDoc param tag whose name matches the provided
     * parameter, whether a param tag on a containing function
     * expression, or a param tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are returned first, so in the previous example, the param
     * tag on the containing function expression would be first.
     *
     * For binding patterns, parameter tags are matched by position.
     */
    function getJSDocParameterTags(param) {
        if (param.name) {
            if (isIdentifier(param.name)) {
                var name_1 = param.name.escapedText;
                return getJSDocTags(param.parent).filter(function (tag) { return isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name_1; });
            }
            else {
                var i = param.parent.parameters.indexOf(param);
                ts.Debug.assert(i > -1, "Parameters should always be in their parents' parameter list");
                var paramTags = getJSDocTags(param.parent).filter(isJSDocParameterTag);
                if (i < paramTags.length) {
                    return [paramTags[i]];
                }
            }
        }
        // return empty array for: out-of-order binding patterns and JSDoc function syntax, which has un-named parameters
        return ts.emptyArray;
    }
    ts.getJSDocParameterTags = getJSDocParameterTags;
    /**
     * Gets the JSDoc type parameter tags for the node if present.
     *
     * @remarks Returns any JSDoc template tag whose names match the provided
     * parameter, whether a template tag on a containing function
     * expression, or a template tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are returned first, so in the previous example, the template
     * tag on the containing function expression would be first.
     */
    function getJSDocTypeParameterTags(param) {
        var name = param.name.escapedText;
        return getJSDocTags(param.parent).filter(function (tag) {
            return isJSDocTemplateTag(tag) && tag.typeParameters.some(function (tp) { return tp.name.escapedText === name; });
        });
    }
    ts.getJSDocTypeParameterTags = getJSDocTypeParameterTags;
    /**
     * Return true if the node has JSDoc parameter tags.
     *
     * @remarks Includes parameter tags that are not directly on the node,
     * for example on a variable declaration whose initializer is a function expression.
     */
    function hasJSDocParameterTags(node) {
        return !!getFirstJSDocTag(node, isJSDocParameterTag);
    }
    ts.hasJSDocParameterTags = hasJSDocParameterTags;
    /** Gets the JSDoc augments tag for the node if present */
    function getJSDocAugmentsTag(node) {
        return getFirstJSDocTag(node, isJSDocAugmentsTag);
    }
    ts.getJSDocAugmentsTag = getJSDocAugmentsTag;
    /** Gets the JSDoc implements tags for the node if present */
    function getJSDocImplementsTags(node) {
        return getAllJSDocTags(node, isJSDocImplementsTag);
    }
    ts.getJSDocImplementsTags = getJSDocImplementsTags;
    /** Gets the JSDoc class tag for the node if present */
    function getJSDocClassTag(node) {
        return getFirstJSDocTag(node, isJSDocClassTag);
    }
    ts.getJSDocClassTag = getJSDocClassTag;
    /** Gets the JSDoc public tag for the node if present */
    function getJSDocPublicTag(node) {
        return getFirstJSDocTag(node, isJSDocPublicTag);
    }
    ts.getJSDocPublicTag = getJSDocPublicTag;
    /** Gets the JSDoc private tag for the node if present */
    function getJSDocPrivateTag(node) {
        return getFirstJSDocTag(node, isJSDocPrivateTag);
    }
    ts.getJSDocPrivateTag = getJSDocPrivateTag;
    /** Gets the JSDoc protected tag for the node if present */
    function getJSDocProtectedTag(node) {
        return getFirstJSDocTag(node, isJSDocProtectedTag);
    }
    ts.getJSDocProtectedTag = getJSDocProtectedTag;
    /** Gets the JSDoc protected tag for the node if present */
    function getJSDocReadonlyTag(node) {
        return getFirstJSDocTag(node, isJSDocReadonlyTag);
    }
    ts.getJSDocReadonlyTag = getJSDocReadonlyTag;
    /** Gets the JSDoc enum tag for the node if present */
    function getJSDocEnumTag(node) {
        return getFirstJSDocTag(node, isJSDocEnumTag);
    }
    ts.getJSDocEnumTag = getJSDocEnumTag;
    /** Gets the JSDoc this tag for the node if present */
    function getJSDocThisTag(node) {
        return getFirstJSDocTag(node, isJSDocThisTag);
    }
    ts.getJSDocThisTag = getJSDocThisTag;
    /** Gets the JSDoc return tag for the node if present */
    function getJSDocReturnTag(node) {
        return getFirstJSDocTag(node, isJSDocReturnTag);
    }
    ts.getJSDocReturnTag = getJSDocReturnTag;
    /** Gets the JSDoc template tag for the node if present */
    function getJSDocTemplateTag(node) {
        return getFirstJSDocTag(node, isJSDocTemplateTag);
    }
    ts.getJSDocTemplateTag = getJSDocTemplateTag;
    /** Gets the JSDoc type tag for the node if present and valid */
    function getJSDocTypeTag(node) {
        // We should have already issued an error if there were multiple type jsdocs, so just use the first one.
        var tag = getFirstJSDocTag(node, isJSDocTypeTag);
        if (tag && tag.typeExpression && tag.typeExpression.type) {
            return tag;
        }
        return undefined;
    }
    ts.getJSDocTypeTag = getJSDocTypeTag;
    /**
     * Gets the type node for the node if provided via JSDoc.
     *
     * @remarks The search includes any JSDoc param tag that relates
     * to the provided parameter, for example a type tag on the
     * parameter itself, or a param tag on a containing function
     * expression, or a param tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are examined first, so in the previous example, the type
     * tag directly on the node would be returned.
     */
    function getJSDocType(node) {
        var tag = getFirstJSDocTag(node, isJSDocTypeTag);
        if (!tag && isParameter(node)) {
            tag = ts.find(getJSDocParameterTags(node), function (tag) { return !!tag.typeExpression; });
        }
        return tag && tag.typeExpression && tag.typeExpression.type;
    }
    ts.getJSDocType = getJSDocType;
    /**
     * Gets the return type node for the node if provided via JSDoc return tag or type tag.
     *
     * @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
     * gets the type from inside the braces, after the fat arrow, etc.
     */
    function getJSDocReturnType(node) {
        var returnTag = getJSDocReturnTag(node);
        if (returnTag && returnTag.typeExpression) {
            return returnTag.typeExpression.type;
        }
        var typeTag = getJSDocTypeTag(node);
        if (typeTag && typeTag.typeExpression) {
            var type = typeTag.typeExpression.type;
            if (isTypeLiteralNode(type)) {
                var sig = ts.find(type.members, isCallSignatureDeclaration);
                return sig && sig.type;
            }
            if (isFunctionTypeNode(type) || isJSDocFunctionType(type)) {
                return type.type;
            }
        }
    }
    ts.getJSDocReturnType = getJSDocReturnType;
    /** Get all JSDoc tags related to a node, including those on parent nodes. */
    function getJSDocTags(node) {
        var tags = node.jsDocCache;
        // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
        if (tags === undefined) {
            var comments = ts.getJSDocCommentsAndTags(node);
            ts.Debug.assert(comments.length < 2 || comments[0] !== comments[1]);
            node.jsDocCache = tags = ts.flatMap(comments, function (j) { return isJSDoc(j) ? j.tags : j; });
        }
        return tags;
    }
    ts.getJSDocTags = getJSDocTags;
    /** Get the first JSDoc tag of a specified kind, or undefined if not present. */
    function getFirstJSDocTag(node, predicate) {
        return ts.find(getJSDocTags(node), predicate);
    }
    /** Gets all JSDoc tags that match a specified predicate */
    function getAllJSDocTags(node, predicate) {
        return getJSDocTags(node).filter(predicate);
    }
    ts.getAllJSDocTags = getAllJSDocTags;
    /** Gets all JSDoc tags of a specified kind */
    function getAllJSDocTagsOfKind(node, kind) {
        return getJSDocTags(node).filter(function (doc) { return doc.kind === kind; });
    }
    ts.getAllJSDocTagsOfKind = getAllJSDocTagsOfKind;
    /**
     * Gets the effective type parameters. If the node was parsed in a
     * JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
     */
    function getEffectiveTypeParameterDeclarations(node) {
        if (isJSDocSignature(node)) {
            return ts.emptyArray;
        }
        if (ts.isJSDocTypeAlias(node)) {
            ts.Debug.assert(node.parent.kind === 303 /* JSDocComment */);
            return ts.flatMap(node.parent.tags, function (tag) { return isJSDocTemplateTag(tag) ? tag.typeParameters : undefined; });
        }
        if (node.typeParameters) {
            return node.typeParameters;
        }
        if (ts.isInJSFile(node)) {
            var decls = ts.getJSDocTypeParameterDeclarations(node);
            if (decls.length) {
                return decls;
            }
            var typeTag = getJSDocType(node);
            if (typeTag && isFunctionTypeNode(typeTag) && typeTag.typeParameters) {
                return typeTag.typeParameters;
            }
        }
        return ts.emptyArray;
    }
    ts.getEffectiveTypeParameterDeclarations = getEffectiveTypeParameterDeclarations;
    function getEffectiveConstraintOfTypeParameter(node) {
        return node.constraint ? node.constraint :
            isJSDocTemplateTag(node.parent) && node === node.parent.typeParameters[0] ? node.parent.constraint :
                undefined;
    }
    ts.getEffectiveConstraintOfTypeParameter = getEffectiveConstraintOfTypeParameter;
    // #region
    // Simple node tests of the form `node.kind === SyntaxKind.Foo`.
    // Literals
    function isNumericLiteral(node) {
        return node.kind === 8 /* NumericLiteral */;
    }
    ts.isNumericLiteral = isNumericLiteral;
    function isBigIntLiteral(node) {
        return node.kind === 9 /* BigIntLiteral */;
    }
    ts.isBigIntLiteral = isBigIntLiteral;
    function isStringLiteral(node) {
        return node.kind === 10 /* StringLiteral */;
    }
    ts.isStringLiteral = isStringLiteral;
    function isJsxText(node) {
        return node.kind === 11 /* JsxText */;
    }
    ts.isJsxText = isJsxText;
    function isRegularExpressionLiteral(node) {
        return node.kind === 13 /* RegularExpressionLiteral */;
    }
    ts.isRegularExpressionLiteral = isRegularExpressionLiteral;
    function isNoSubstitutionTemplateLiteral(node) {
        return node.kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isNoSubstitutionTemplateLiteral = isNoSubstitutionTemplateLiteral;
    // Pseudo-literals
    function isTemplateHead(node) {
        return node.kind === 15 /* TemplateHead */;
    }
    ts.isTemplateHead = isTemplateHead;
    function isTemplateMiddle(node) {
        return node.kind === 16 /* TemplateMiddle */;
    }
    ts.isTemplateMiddle = isTemplateMiddle;
    function isTemplateTail(node) {
        return node.kind === 17 /* TemplateTail */;
    }
    ts.isTemplateTail = isTemplateTail;
    function isIdentifier(node) {
        return node.kind === 75 /* Identifier */;
    }
    ts.isIdentifier = isIdentifier;
    // Names
    function isQualifiedName(node) {
        return node.kind === 153 /* QualifiedName */;
    }
    ts.isQualifiedName = isQualifiedName;
    function isComputedPropertyName(node) {
        return node.kind === 154 /* ComputedPropertyName */;
    }
    ts.isComputedPropertyName = isComputedPropertyName;
    function isPrivateIdentifier(node) {
        return node.kind === 76 /* PrivateIdentifier */;
    }
    ts.isPrivateIdentifier = isPrivateIdentifier;
    function isIdentifierOrPrivateIdentifier(node) {
        return node.kind === 75 /* Identifier */ || node.kind === 76 /* PrivateIdentifier */;
    }
    ts.isIdentifierOrPrivateIdentifier = isIdentifierOrPrivateIdentifier;
    // Signature elements
    function isTypeParameterDeclaration(node) {
        return node.kind === 155 /* TypeParameter */;
    }
    ts.isTypeParameterDeclaration = isTypeParameterDeclaration;
    function isParameter(node) {
        return node.kind === 156 /* Parameter */;
    }
    ts.isParameter = isParameter;
    function isDecorator(node) {
        return node.kind === 157 /* Decorator */;
    }
    ts.isDecorator = isDecorator;
    // TypeMember
    function isPropertySignature(node) {
        return node.kind === 158 /* PropertySignature */;
    }
    ts.isPropertySignature = isPropertySignature;
    function isPropertyDeclaration(node) {
        return node.kind === 159 /* PropertyDeclaration */;
    }
    ts.isPropertyDeclaration = isPropertyDeclaration;
    function isMethodSignature(node) {
        return node.kind === 160 /* MethodSignature */;
    }
    ts.isMethodSignature = isMethodSignature;
    function isMethodDeclaration(node) {
        return node.kind === 161 /* MethodDeclaration */;
    }
    ts.isMethodDeclaration = isMethodDeclaration;
    function isConstructorDeclaration(node) {
        return node.kind === 162 /* Constructor */;
    }
    ts.isConstructorDeclaration = isConstructorDeclaration;
    function isGetAccessorDeclaration(node) {
        return node.kind === 163 /* GetAccessor */;
    }
    ts.isGetAccessorDeclaration = isGetAccessorDeclaration;
    function isSetAccessorDeclaration(node) {
        return node.kind === 164 /* SetAccessor */;
    }
    ts.isSetAccessorDeclaration = isSetAccessorDeclaration;
    function isCallSignatureDeclaration(node) {
        return node.kind === 165 /* CallSignature */;
    }
    ts.isCallSignatureDeclaration = isCallSignatureDeclaration;
    function isConstructSignatureDeclaration(node) {
        return node.kind === 166 /* ConstructSignature */;
    }
    ts.isConstructSignatureDeclaration = isConstructSignatureDeclaration;
    function isIndexSignatureDeclaration(node) {
        return node.kind === 167 /* IndexSignature */;
    }
    ts.isIndexSignatureDeclaration = isIndexSignatureDeclaration;
    /* @internal */
    function isGetOrSetAccessorDeclaration(node) {
        return node.kind === 164 /* SetAccessor */ || node.kind === 163 /* GetAccessor */;
    }
    ts.isGetOrSetAccessorDeclaration = isGetOrSetAccessorDeclaration;
    // Type
    function isTypePredicateNode(node) {
        return node.kind === 168 /* TypePredicate */;
    }
    ts.isTypePredicateNode = isTypePredicateNode;
    function isTypeReferenceNode(node) {
        return node.kind === 169 /* TypeReference */;
    }
    ts.isTypeReferenceNode = isTypeReferenceNode;
    function isFunctionTypeNode(node) {
        return node.kind === 170 /* FunctionType */;
    }
    ts.isFunctionTypeNode = isFunctionTypeNode;
    function isConstructorTypeNode(node) {
        return node.kind === 171 /* ConstructorType */;
    }
    ts.isConstructorTypeNode = isConstructorTypeNode;
    function isTypeQueryNode(node) {
        return node.kind === 172 /* TypeQuery */;
    }
    ts.isTypeQueryNode = isTypeQueryNode;
    function isTypeLiteralNode(node) {
        return node.kind === 173 /* TypeLiteral */;
    }
    ts.isTypeLiteralNode = isTypeLiteralNode;
    function isArrayTypeNode(node) {
        return node.kind === 174 /* ArrayType */;
    }
    ts.isArrayTypeNode = isArrayTypeNode;
    function isTupleTypeNode(node) {
        return node.kind === 175 /* TupleType */;
    }
    ts.isTupleTypeNode = isTupleTypeNode;
    function isUnionTypeNode(node) {
        return node.kind === 178 /* UnionType */;
    }
    ts.isUnionTypeNode = isUnionTypeNode;
    function isIntersectionTypeNode(node) {
        return node.kind === 179 /* IntersectionType */;
    }
    ts.isIntersectionTypeNode = isIntersectionTypeNode;
    function isConditionalTypeNode(node) {
        return node.kind === 180 /* ConditionalType */;
    }
    ts.isConditionalTypeNode = isConditionalTypeNode;
    function isInferTypeNode(node) {
        return node.kind === 181 /* InferType */;
    }
    ts.isInferTypeNode = isInferTypeNode;
    function isParenthesizedTypeNode(node) {
        return node.kind === 182 /* ParenthesizedType */;
    }
    ts.isParenthesizedTypeNode = isParenthesizedTypeNode;
    function isThisTypeNode(node) {
        return node.kind === 183 /* ThisType */;
    }
    ts.isThisTypeNode = isThisTypeNode;
    function isTypeOperatorNode(node) {
        return node.kind === 184 /* TypeOperator */;
    }
    ts.isTypeOperatorNode = isTypeOperatorNode;
    function isIndexedAccessTypeNode(node) {
        return node.kind === 185 /* IndexedAccessType */;
    }
    ts.isIndexedAccessTypeNode = isIndexedAccessTypeNode;
    function isMappedTypeNode(node) {
        return node.kind === 186 /* MappedType */;
    }
    ts.isMappedTypeNode = isMappedTypeNode;
    function isLiteralTypeNode(node) {
        return node.kind === 187 /* LiteralType */;
    }
    ts.isLiteralTypeNode = isLiteralTypeNode;
    function isImportTypeNode(node) {
        return node.kind === 188 /* ImportType */;
    }
    ts.isImportTypeNode = isImportTypeNode;
    // Binding patterns
    function isObjectBindingPattern(node) {
        return node.kind === 189 /* ObjectBindingPattern */;
    }
    ts.isObjectBindingPattern = isObjectBindingPattern;
    function isArrayBindingPattern(node) {
        return node.kind === 190 /* ArrayBindingPattern */;
    }
    ts.isArrayBindingPattern = isArrayBindingPattern;
    function isBindingElement(node) {
        return node.kind === 191 /* BindingElement */;
    }
    ts.isBindingElement = isBindingElement;
    // Expression
    function isArrayLiteralExpression(node) {
        return node.kind === 192 /* ArrayLiteralExpression */;
    }
    ts.isArrayLiteralExpression = isArrayLiteralExpression;
    function isObjectLiteralExpression(node) {
        return node.kind === 193 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralExpression = isObjectLiteralExpression;
    function isPropertyAccessExpression(node) {
        return node.kind === 194 /* PropertyAccessExpression */;
    }
    ts.isPropertyAccessExpression = isPropertyAccessExpression;
    function isPropertyAccessChain(node) {
        return isPropertyAccessExpression(node) && !!(node.flags & 32 /* OptionalChain */);
    }
    ts.isPropertyAccessChain = isPropertyAccessChain;
    function isElementAccessExpression(node) {
        return node.kind === 195 /* ElementAccessExpression */;
    }
    ts.isElementAccessExpression = isElementAccessExpression;
    function isElementAccessChain(node) {
        return isElementAccessExpression(node) && !!(node.flags & 32 /* OptionalChain */);
    }
    ts.isElementAccessChain = isElementAccessChain;
    function isCallExpression(node) {
        return node.kind === 196 /* CallExpression */;
    }
    ts.isCallExpression = isCallExpression;
    function isCallChain(node) {
        return isCallExpression(node) && !!(node.flags & 32 /* OptionalChain */);
    }
    ts.isCallChain = isCallChain;
    function isOptionalChain(node) {
        var kind = node.kind;
        return !!(node.flags & 32 /* OptionalChain */) &&
            (kind === 194 /* PropertyAccessExpression */
                || kind === 195 /* ElementAccessExpression */
                || kind === 196 /* CallExpression */
                || kind === 218 /* NonNullExpression */);
    }
    ts.isOptionalChain = isOptionalChain;
    /* @internal */
    function isOptionalChainRoot(node) {
        return isOptionalChain(node) && !isNonNullExpression(node) && !!node.questionDotToken;
    }
    ts.isOptionalChainRoot = isOptionalChainRoot;
    /**
     * Determines whether a node is the expression preceding an optional chain (i.e. `a` in `a?.b`).
     */
    /* @internal */
    function isExpressionOfOptionalChainRoot(node) {
        return isOptionalChainRoot(node.parent) && node.parent.expression === node;
    }
    ts.isExpressionOfOptionalChainRoot = isExpressionOfOptionalChainRoot;
    /**
     * Determines whether a node is the outermost `OptionalChain` in an ECMAScript `OptionalExpression`:
     *
     * 1. For `a?.b.c`, the outermost chain is `a?.b.c` (`c` is the end of the chain starting at `a?.`)
     * 2. For `a?.b!`, the outermost chain is `a?.b` (`b` is the end of the chain starting at `a?.`)
     * 3. For `(a?.b.c).d`, the outermost chain is `a?.b.c` (`c` is the end of the chain starting at `a?.` since parens end the chain)
     * 4. For `a?.b.c?.d`, both `a?.b.c` and `a?.b.c?.d` are outermost (`c` is the end of the chain starting at `a?.`, and `d` is
     *   the end of the chain starting at `c?.`)
     * 5. For `a?.(b?.c).d`, both `b?.c` and `a?.(b?.c)d` are outermost (`c` is the end of the chain starting at `b`, and `d` is
     *   the end of the chain starting at `a?.`)
     */
    /* @internal */
    function isOutermostOptionalChain(node) {
        return !isOptionalChain(node.parent) // cases 1, 2, and 3
            || isOptionalChainRoot(node.parent) // case 4
            || node !== node.parent.expression; // case 5
    }
    ts.isOutermostOptionalChain = isOutermostOptionalChain;
    function isNullishCoalesce(node) {
        return node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 60 /* QuestionQuestionToken */;
    }
    ts.isNullishCoalesce = isNullishCoalesce;
    function isNewExpression(node) {
        return node.kind === 197 /* NewExpression */;
    }
    ts.isNewExpression = isNewExpression;
    function isTaggedTemplateExpression(node) {
        return node.kind === 198 /* TaggedTemplateExpression */;
    }
    ts.isTaggedTemplateExpression = isTaggedTemplateExpression;
    function isTypeAssertion(node) {
        return node.kind === 199 /* TypeAssertionExpression */;
    }
    ts.isTypeAssertion = isTypeAssertion;
    function isConstTypeReference(node) {
        return isTypeReferenceNode(node) && isIdentifier(node.typeName) &&
            node.typeName.escapedText === "const" && !node.typeArguments;
    }
    ts.isConstTypeReference = isConstTypeReference;
    function isParenthesizedExpression(node) {
        return node.kind === 200 /* ParenthesizedExpression */;
    }
    ts.isParenthesizedExpression = isParenthesizedExpression;
    function skipPartiallyEmittedExpressions(node) {
        return ts.skipOuterExpressions(node, 8 /* PartiallyEmittedExpressions */);
    }
    ts.skipPartiallyEmittedExpressions = skipPartiallyEmittedExpressions;
    function isFunctionExpression(node) {
        return node.kind === 201 /* FunctionExpression */;
    }
    ts.isFunctionExpression = isFunctionExpression;
    function isArrowFunction(node) {
        return node.kind === 202 /* ArrowFunction */;
    }
    ts.isArrowFunction = isArrowFunction;
    function isDeleteExpression(node) {
        return node.kind === 203 /* DeleteExpression */;
    }
    ts.isDeleteExpression = isDeleteExpression;
    function isTypeOfExpression(node) {
        return node.kind === 204 /* TypeOfExpression */;
    }
    ts.isTypeOfExpression = isTypeOfExpression;
    function isVoidExpression(node) {
        return node.kind === 205 /* VoidExpression */;
    }
    ts.isVoidExpression = isVoidExpression;
    function isAwaitExpression(node) {
        return node.kind === 206 /* AwaitExpression */;
    }
    ts.isAwaitExpression = isAwaitExpression;
    function isPrefixUnaryExpression(node) {
        return node.kind === 207 /* PrefixUnaryExpression */;
    }
    ts.isPrefixUnaryExpression = isPrefixUnaryExpression;
    function isPostfixUnaryExpression(node) {
        return node.kind === 208 /* PostfixUnaryExpression */;
    }
    ts.isPostfixUnaryExpression = isPostfixUnaryExpression;
    function isBinaryExpression(node) {
        return node.kind === 209 /* BinaryExpression */;
    }
    ts.isBinaryExpression = isBinaryExpression;
    function isConditionalExpression(node) {
        return node.kind === 210 /* ConditionalExpression */;
    }
    ts.isConditionalExpression = isConditionalExpression;
    function isTemplateExpression(node) {
        return node.kind === 211 /* TemplateExpression */;
    }
    ts.isTemplateExpression = isTemplateExpression;
    function isYieldExpression(node) {
        return node.kind === 212 /* YieldExpression */;
    }
    ts.isYieldExpression = isYieldExpression;
    function isSpreadElement(node) {
        return node.kind === 213 /* SpreadElement */;
    }
    ts.isSpreadElement = isSpreadElement;
    function isClassExpression(node) {
        return node.kind === 214 /* ClassExpression */;
    }
    ts.isClassExpression = isClassExpression;
    function isOmittedExpression(node) {
        return node.kind === 215 /* OmittedExpression */;
    }
    ts.isOmittedExpression = isOmittedExpression;
    function isExpressionWithTypeArguments(node) {
        return node.kind === 216 /* ExpressionWithTypeArguments */;
    }
    ts.isExpressionWithTypeArguments = isExpressionWithTypeArguments;
    function isAsExpression(node) {
        return node.kind === 217 /* AsExpression */;
    }
    ts.isAsExpression = isAsExpression;
    function isNonNullExpression(node) {
        return node.kind === 218 /* NonNullExpression */;
    }
    ts.isNonNullExpression = isNonNullExpression;
    function isNonNullChain(node) {
        return isNonNullExpression(node) && !!(node.flags & 32 /* OptionalChain */);
    }
    ts.isNonNullChain = isNonNullChain;
    function isMetaProperty(node) {
        return node.kind === 219 /* MetaProperty */;
    }
    ts.isMetaProperty = isMetaProperty;
    // Misc
    function isTemplateSpan(node) {
        return node.kind === 221 /* TemplateSpan */;
    }
    ts.isTemplateSpan = isTemplateSpan;
    function isSemicolonClassElement(node) {
        return node.kind === 222 /* SemicolonClassElement */;
    }
    ts.isSemicolonClassElement = isSemicolonClassElement;
    // Block
    function isBlock(node) {
        return node.kind === 223 /* Block */;
    }
    ts.isBlock = isBlock;
    function isVariableStatement(node) {
        return node.kind === 225 /* VariableStatement */;
    }
    ts.isVariableStatement = isVariableStatement;
    function isEmptyStatement(node) {
        return node.kind === 224 /* EmptyStatement */;
    }
    ts.isEmptyStatement = isEmptyStatement;
    function isExpressionStatement(node) {
        return node.kind === 226 /* ExpressionStatement */;
    }
    ts.isExpressionStatement = isExpressionStatement;
    function isIfStatement(node) {
        return node.kind === 227 /* IfStatement */;
    }
    ts.isIfStatement = isIfStatement;
    function isDoStatement(node) {
        return node.kind === 228 /* DoStatement */;
    }
    ts.isDoStatement = isDoStatement;
    function isWhileStatement(node) {
        return node.kind === 229 /* WhileStatement */;
    }
    ts.isWhileStatement = isWhileStatement;
    function isForStatement(node) {
        return node.kind === 230 /* ForStatement */;
    }
    ts.isForStatement = isForStatement;
    function isForInStatement(node) {
        return node.kind === 231 /* ForInStatement */;
    }
    ts.isForInStatement = isForInStatement;
    function isForOfStatement(node) {
        return node.kind === 232 /* ForOfStatement */;
    }
    ts.isForOfStatement = isForOfStatement;
    function isContinueStatement(node) {
        return node.kind === 233 /* ContinueStatement */;
    }
    ts.isContinueStatement = isContinueStatement;
    function isBreakStatement(node) {
        return node.kind === 234 /* BreakStatement */;
    }
    ts.isBreakStatement = isBreakStatement;
    function isBreakOrContinueStatement(node) {
        return node.kind === 234 /* BreakStatement */ || node.kind === 233 /* ContinueStatement */;
    }
    ts.isBreakOrContinueStatement = isBreakOrContinueStatement;
    function isReturnStatement(node) {
        return node.kind === 235 /* ReturnStatement */;
    }
    ts.isReturnStatement = isReturnStatement;
    function isWithStatement(node) {
        return node.kind === 236 /* WithStatement */;
    }
    ts.isWithStatement = isWithStatement;
    function isSwitchStatement(node) {
        return node.kind === 237 /* SwitchStatement */;
    }
    ts.isSwitchStatement = isSwitchStatement;
    function isLabeledStatement(node) {
        return node.kind === 238 /* LabeledStatement */;
    }
    ts.isLabeledStatement = isLabeledStatement;
    function isThrowStatement(node) {
        return node.kind === 239 /* ThrowStatement */;
    }
    ts.isThrowStatement = isThrowStatement;
    function isTryStatement(node) {
        return node.kind === 240 /* TryStatement */;
    }
    ts.isTryStatement = isTryStatement;
    function isDebuggerStatement(node) {
        return node.kind === 241 /* DebuggerStatement */;
    }
    ts.isDebuggerStatement = isDebuggerStatement;
    function isVariableDeclaration(node) {
        return node.kind === 242 /* VariableDeclaration */;
    }
    ts.isVariableDeclaration = isVariableDeclaration;
    function isVariableDeclarationList(node) {
        return node.kind === 243 /* VariableDeclarationList */;
    }
    ts.isVariableDeclarationList = isVariableDeclarationList;
    function isFunctionDeclaration(node) {
        return node.kind === 244 /* FunctionDeclaration */;
    }
    ts.isFunctionDeclaration = isFunctionDeclaration;
    function isClassDeclaration(node) {
        return node.kind === 245 /* ClassDeclaration */;
    }
    ts.isClassDeclaration = isClassDeclaration;
    function isInterfaceDeclaration(node) {
        return node.kind === 246 /* InterfaceDeclaration */;
    }
    ts.isInterfaceDeclaration = isInterfaceDeclaration;
    function isTypeAliasDeclaration(node) {
        return node.kind === 247 /* TypeAliasDeclaration */;
    }
    ts.isTypeAliasDeclaration = isTypeAliasDeclaration;
    function isEnumDeclaration(node) {
        return node.kind === 248 /* EnumDeclaration */;
    }
    ts.isEnumDeclaration = isEnumDeclaration;
    function isModuleDeclaration(node) {
        return node.kind === 249 /* ModuleDeclaration */;
    }
    ts.isModuleDeclaration = isModuleDeclaration;
    function isModuleBlock(node) {
        return node.kind === 250 /* ModuleBlock */;
    }
    ts.isModuleBlock = isModuleBlock;
    function isCaseBlock(node) {
        return node.kind === 251 /* CaseBlock */;
    }
    ts.isCaseBlock = isCaseBlock;
    function isNamespaceExportDeclaration(node) {
        return node.kind === 252 /* NamespaceExportDeclaration */;
    }
    ts.isNamespaceExportDeclaration = isNamespaceExportDeclaration;
    function isImportEqualsDeclaration(node) {
        return node.kind === 253 /* ImportEqualsDeclaration */;
    }
    ts.isImportEqualsDeclaration = isImportEqualsDeclaration;
    function isImportDeclaration(node) {
        return node.kind === 254 /* ImportDeclaration */;
    }
    ts.isImportDeclaration = isImportDeclaration;
    function isImportClause(node) {
        return node.kind === 255 /* ImportClause */;
    }
    ts.isImportClause = isImportClause;
    function isNamespaceImport(node) {
        return node.kind === 256 /* NamespaceImport */;
    }
    ts.isNamespaceImport = isNamespaceImport;
    function isNamespaceExport(node) {
        return node.kind === 262 /* NamespaceExport */;
    }
    ts.isNamespaceExport = isNamespaceExport;
    function isNamedExportBindings(node) {
        return node.kind === 262 /* NamespaceExport */ || node.kind === 261 /* NamedExports */;
    }
    ts.isNamedExportBindings = isNamedExportBindings;
    function isNamedImports(node) {
        return node.kind === 257 /* NamedImports */;
    }
    ts.isNamedImports = isNamedImports;
    function isImportSpecifier(node) {
        return node.kind === 258 /* ImportSpecifier */;
    }
    ts.isImportSpecifier = isImportSpecifier;
    function isExportAssignment(node) {
        return node.kind === 259 /* ExportAssignment */;
    }
    ts.isExportAssignment = isExportAssignment;
    function isExportDeclaration(node) {
        return node.kind === 260 /* ExportDeclaration */;
    }
    ts.isExportDeclaration = isExportDeclaration;
    function isNamedExports(node) {
        return node.kind === 261 /* NamedExports */;
    }
    ts.isNamedExports = isNamedExports;
    function isExportSpecifier(node) {
        return node.kind === 263 /* ExportSpecifier */;
    }
    ts.isExportSpecifier = isExportSpecifier;
    function isMissingDeclaration(node) {
        return node.kind === 264 /* MissingDeclaration */;
    }
    ts.isMissingDeclaration = isMissingDeclaration;
    // Module References
    function isExternalModuleReference(node) {
        return node.kind === 265 /* ExternalModuleReference */;
    }
    ts.isExternalModuleReference = isExternalModuleReference;
    // JSX
    function isJsxElement(node) {
        return node.kind === 266 /* JsxElement */;
    }
    ts.isJsxElement = isJsxElement;
    function isJsxSelfClosingElement(node) {
        return node.kind === 267 /* JsxSelfClosingElement */;
    }
    ts.isJsxSelfClosingElement = isJsxSelfClosingElement;
    function isJsxOpeningElement(node) {
        return node.kind === 268 /* JsxOpeningElement */;
    }
    ts.isJsxOpeningElement = isJsxOpeningElement;
    function isJsxClosingElement(node) {
        return node.kind === 269 /* JsxClosingElement */;
    }
    ts.isJsxClosingElement = isJsxClosingElement;
    function isJsxFragment(node) {
        return node.kind === 270 /* JsxFragment */;
    }
    ts.isJsxFragment = isJsxFragment;
    function isJsxOpeningFragment(node) {
        return node.kind === 271 /* JsxOpeningFragment */;
    }
    ts.isJsxOpeningFragment = isJsxOpeningFragment;
    function isJsxClosingFragment(node) {
        return node.kind === 272 /* JsxClosingFragment */;
    }
    ts.isJsxClosingFragment = isJsxClosingFragment;
    function isJsxAttribute(node) {
        return node.kind === 273 /* JsxAttribute */;
    }
    ts.isJsxAttribute = isJsxAttribute;
    function isJsxAttributes(node) {
        return node.kind === 274 /* JsxAttributes */;
    }
    ts.isJsxAttributes = isJsxAttributes;
    function isJsxSpreadAttribute(node) {
        return node.kind === 275 /* JsxSpreadAttribute */;
    }
    ts.isJsxSpreadAttribute = isJsxSpreadAttribute;
    function isJsxExpression(node) {
        return node.kind === 276 /* JsxExpression */;
    }
    ts.isJsxExpression = isJsxExpression;
    // Clauses
    function isCaseClause(node) {
        return node.kind === 277 /* CaseClause */;
    }
    ts.isCaseClause = isCaseClause;
    function isDefaultClause(node) {
        return node.kind === 278 /* DefaultClause */;
    }
    ts.isDefaultClause = isDefaultClause;
    function isHeritageClause(node) {
        return node.kind === 279 /* HeritageClause */;
    }
    ts.isHeritageClause = isHeritageClause;
    function isCatchClause(node) {
        return node.kind === 280 /* CatchClause */;
    }
    ts.isCatchClause = isCatchClause;
    // Property assignments
    function isPropertyAssignment(node) {
        return node.kind === 281 /* PropertyAssignment */;
    }
    ts.isPropertyAssignment = isPropertyAssignment;
    function isShorthandPropertyAssignment(node) {
        return node.kind === 282 /* ShorthandPropertyAssignment */;
    }
    ts.isShorthandPropertyAssignment = isShorthandPropertyAssignment;
    function isSpreadAssignment(node) {
        return node.kind === 283 /* SpreadAssignment */;
    }
    ts.isSpreadAssignment = isSpreadAssignment;
    // Enum
    function isEnumMember(node) {
        return node.kind === 284 /* EnumMember */;
    }
    ts.isEnumMember = isEnumMember;
    // Top-level nodes
    function isSourceFile(node) {
        return node.kind === 290 /* SourceFile */;
    }
    ts.isSourceFile = isSourceFile;
    function isBundle(node) {
        return node.kind === 291 /* Bundle */;
    }
    ts.isBundle = isBundle;
    function isUnparsedSource(node) {
        return node.kind === 292 /* UnparsedSource */;
    }
    ts.isUnparsedSource = isUnparsedSource;
    function isUnparsedPrepend(node) {
        return node.kind === 286 /* UnparsedPrepend */;
    }
    ts.isUnparsedPrepend = isUnparsedPrepend;
    function isUnparsedTextLike(node) {
        switch (node.kind) {
            case 287 /* UnparsedText */:
            case 288 /* UnparsedInternalText */:
                return true;
            default:
                return false;
        }
    }
    ts.isUnparsedTextLike = isUnparsedTextLike;
    function isUnparsedNode(node) {
        return isUnparsedTextLike(node) ||
            node.kind === 285 /* UnparsedPrologue */ ||
            node.kind === 289 /* UnparsedSyntheticReference */;
    }
    ts.isUnparsedNode = isUnparsedNode;
    // JSDoc
    function isJSDocTypeExpression(node) {
        return node.kind === 294 /* JSDocTypeExpression */;
    }
    ts.isJSDocTypeExpression = isJSDocTypeExpression;
    function isJSDocAllType(node) {
        return node.kind === 295 /* JSDocAllType */;
    }
    ts.isJSDocAllType = isJSDocAllType;
    function isJSDocUnknownType(node) {
        return node.kind === 296 /* JSDocUnknownType */;
    }
    ts.isJSDocUnknownType = isJSDocUnknownType;
    function isJSDocNullableType(node) {
        return node.kind === 297 /* JSDocNullableType */;
    }
    ts.isJSDocNullableType = isJSDocNullableType;
    function isJSDocNonNullableType(node) {
        return node.kind === 298 /* JSDocNonNullableType */;
    }
    ts.isJSDocNonNullableType = isJSDocNonNullableType;
    function isJSDocOptionalType(node) {
        return node.kind === 299 /* JSDocOptionalType */;
    }
    ts.isJSDocOptionalType = isJSDocOptionalType;
    function isJSDocFunctionType(node) {
        return node.kind === 300 /* JSDocFunctionType */;
    }
    ts.isJSDocFunctionType = isJSDocFunctionType;
    function isJSDocVariadicType(node) {
        return node.kind === 301 /* JSDocVariadicType */;
    }
    ts.isJSDocVariadicType = isJSDocVariadicType;
    function isJSDoc(node) {
        return node.kind === 303 /* JSDocComment */;
    }
    ts.isJSDoc = isJSDoc;
    function isJSDocAuthorTag(node) {
        return node.kind === 309 /* JSDocAuthorTag */;
    }
    ts.isJSDocAuthorTag = isJSDocAuthorTag;
    function isJSDocAugmentsTag(node) {
        return node.kind === 307 /* JSDocAugmentsTag */;
    }
    ts.isJSDocAugmentsTag = isJSDocAugmentsTag;
    function isJSDocImplementsTag(node) {
        return node.kind === 308 /* JSDocImplementsTag */;
    }
    ts.isJSDocImplementsTag = isJSDocImplementsTag;
    function isJSDocClassTag(node) {
        return node.kind === 310 /* JSDocClassTag */;
    }
    ts.isJSDocClassTag = isJSDocClassTag;
    function isJSDocPublicTag(node) {
        return node.kind === 311 /* JSDocPublicTag */;
    }
    ts.isJSDocPublicTag = isJSDocPublicTag;
    function isJSDocPrivateTag(node) {
        return node.kind === 312 /* JSDocPrivateTag */;
    }
    ts.isJSDocPrivateTag = isJSDocPrivateTag;
    function isJSDocProtectedTag(node) {
        return node.kind === 313 /* JSDocProtectedTag */;
    }
    ts.isJSDocProtectedTag = isJSDocProtectedTag;
    function isJSDocReadonlyTag(node) {
        return node.kind === 314 /* JSDocReadonlyTag */;
    }
    ts.isJSDocReadonlyTag = isJSDocReadonlyTag;
    function isJSDocEnumTag(node) {
        return node.kind === 316 /* JSDocEnumTag */;
    }
    ts.isJSDocEnumTag = isJSDocEnumTag;
    function isJSDocThisTag(node) {
        return node.kind === 319 /* JSDocThisTag */;
    }
    ts.isJSDocThisTag = isJSDocThisTag;
    function isJSDocParameterTag(node) {
        return node.kind === 317 /* JSDocParameterTag */;
    }
    ts.isJSDocParameterTag = isJSDocParameterTag;
    function isJSDocReturnTag(node) {
        return node.kind === 318 /* JSDocReturnTag */;
    }
    ts.isJSDocReturnTag = isJSDocReturnTag;
    function isJSDocTypeTag(node) {
        return node.kind === 320 /* JSDocTypeTag */;
    }
    ts.isJSDocTypeTag = isJSDocTypeTag;
    function isJSDocTemplateTag(node) {
        return node.kind === 321 /* JSDocTemplateTag */;
    }
    ts.isJSDocTemplateTag = isJSDocTemplateTag;
    function isJSDocTypedefTag(node) {
        return node.kind === 322 /* JSDocTypedefTag */;
    }
    ts.isJSDocTypedefTag = isJSDocTypedefTag;
    function isJSDocPropertyTag(node) {
        return node.kind === 323 /* JSDocPropertyTag */;
    }
    ts.isJSDocPropertyTag = isJSDocPropertyTag;
    function isJSDocPropertyLikeTag(node) {
        return node.kind === 323 /* JSDocPropertyTag */ || node.kind === 317 /* JSDocParameterTag */;
    }
    ts.isJSDocPropertyLikeTag = isJSDocPropertyLikeTag;
    function isJSDocTypeLiteral(node) {
        return node.kind === 304 /* JSDocTypeLiteral */;
    }
    ts.isJSDocTypeLiteral = isJSDocTypeLiteral;
    function isJSDocCallbackTag(node) {
        return node.kind === 315 /* JSDocCallbackTag */;
    }
    ts.isJSDocCallbackTag = isJSDocCallbackTag;
    function isJSDocSignature(node) {
        return node.kind === 305 /* JSDocSignature */;
    }
    ts.isJSDocSignature = isJSDocSignature;
    // #endregion
    // #region
    // Node tests
    //
    // All node tests in the following list should *not* reference parent pointers so that
    // they may be used with transformations.
    /* @internal */
    function isSyntaxList(n) {
        return n.kind === 324 /* SyntaxList */;
    }
    ts.isSyntaxList = isSyntaxList;
    /* @internal */
    function isNode(node) {
        return isNodeKind(node.kind);
    }
    ts.isNode = isNode;
    /* @internal */
    function isNodeKind(kind) {
        return kind >= 153 /* FirstNode */;
    }
    ts.isNodeKind = isNodeKind;
    /**
     * True if node is of some token syntax kind.
     * For example, this is true for an IfKeyword but not for an IfStatement.
     * Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail.
     */
    function isToken(n) {
        return n.kind >= 0 /* FirstToken */ && n.kind <= 152 /* LastToken */;
    }
    ts.isToken = isToken;
    // Node Arrays
    /* @internal */
    function isNodeArray(array) {
        return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
    }
    ts.isNodeArray = isNodeArray;
    // Literals
    /* @internal */
    function isLiteralKind(kind) {
        return 8 /* FirstLiteralToken */ <= kind && kind <= 14 /* LastLiteralToken */;
    }
    ts.isLiteralKind = isLiteralKind;
    function isLiteralExpression(node) {
        return isLiteralKind(node.kind);
    }
    ts.isLiteralExpression = isLiteralExpression;
    // Pseudo-literals
    /* @internal */
    function isTemplateLiteralKind(kind) {
        return 14 /* FirstTemplateToken */ <= kind && kind <= 17 /* LastTemplateToken */;
    }
    ts.isTemplateLiteralKind = isTemplateLiteralKind;
    function isTemplateLiteralToken(node) {
        return isTemplateLiteralKind(node.kind);
    }
    ts.isTemplateLiteralToken = isTemplateLiteralToken;
    function isTemplateMiddleOrTemplateTail(node) {
        var kind = node.kind;
        return kind === 16 /* TemplateMiddle */
            || kind === 17 /* TemplateTail */;
    }
    ts.isTemplateMiddleOrTemplateTail = isTemplateMiddleOrTemplateTail;
    function isImportOrExportSpecifier(node) {
        return isImportSpecifier(node) || isExportSpecifier(node);
    }
    ts.isImportOrExportSpecifier = isImportOrExportSpecifier;
    function isTypeOnlyImportOrExportDeclaration(node) {
        switch (node.kind) {
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
                return node.parent.parent.isTypeOnly;
            case 256 /* NamespaceImport */:
                return node.parent.isTypeOnly;
            case 255 /* ImportClause */:
                return node.isTypeOnly;
            default:
                return false;
        }
    }
    ts.isTypeOnlyImportOrExportDeclaration = isTypeOnlyImportOrExportDeclaration;
    function isStringTextContainingNode(node) {
        return node.kind === 10 /* StringLiteral */ || isTemplateLiteralKind(node.kind);
    }
    ts.isStringTextContainingNode = isStringTextContainingNode;
    // Identifiers
    /* @internal */
    function isGeneratedIdentifier(node) {
        return isIdentifier(node) && (node.autoGenerateFlags & 7 /* KindMask */) > 0 /* None */;
    }
    ts.isGeneratedIdentifier = isGeneratedIdentifier;
    // Private Identifiers
    /*@internal*/
    function isPrivateIdentifierPropertyDeclaration(node) {
        return isPropertyDeclaration(node) && isPrivateIdentifier(node.name);
    }
    ts.isPrivateIdentifierPropertyDeclaration = isPrivateIdentifierPropertyDeclaration;
    /*@internal*/
    function isPrivateIdentifierPropertyAccessExpression(node) {
        return isPropertyAccessExpression(node) && isPrivateIdentifier(node.name);
    }
    ts.isPrivateIdentifierPropertyAccessExpression = isPrivateIdentifierPropertyAccessExpression;
    // Keywords
    /* @internal */
    function isModifierKind(token) {
        switch (token) {
            case 122 /* AbstractKeyword */:
            case 126 /* AsyncKeyword */:
            case 81 /* ConstKeyword */:
            case 130 /* DeclareKeyword */:
            case 84 /* DefaultKeyword */:
            case 89 /* ExportKeyword */:
            case 119 /* PublicKeyword */:
            case 117 /* PrivateKeyword */:
            case 118 /* ProtectedKeyword */:
            case 138 /* ReadonlyKeyword */:
            case 120 /* StaticKeyword */:
                return true;
        }
        return false;
    }
    ts.isModifierKind = isModifierKind;
    /* @internal */
    function isParameterPropertyModifier(kind) {
        return !!(ts.modifierToFlag(kind) & 92 /* ParameterPropertyModifier */);
    }
    ts.isParameterPropertyModifier = isParameterPropertyModifier;
    /* @internal */
    function isClassMemberModifier(idToken) {
        return isParameterPropertyModifier(idToken) || idToken === 120 /* StaticKeyword */;
    }
    ts.isClassMemberModifier = isClassMemberModifier;
    function isModifier(node) {
        return isModifierKind(node.kind);
    }
    ts.isModifier = isModifier;
    function isEntityName(node) {
        var kind = node.kind;
        return kind === 153 /* QualifiedName */
            || kind === 75 /* Identifier */;
    }
    ts.isEntityName = isEntityName;
    function isPropertyName(node) {
        var kind = node.kind;
        return kind === 75 /* Identifier */
            || kind === 76 /* PrivateIdentifier */
            || kind === 10 /* StringLiteral */
            || kind === 8 /* NumericLiteral */
            || kind === 154 /* ComputedPropertyName */;
    }
    ts.isPropertyName = isPropertyName;
    function isBindingName(node) {
        var kind = node.kind;
        return kind === 75 /* Identifier */
            || kind === 189 /* ObjectBindingPattern */
            || kind === 190 /* ArrayBindingPattern */;
    }
    ts.isBindingName = isBindingName;
    // Functions
    function isFunctionLike(node) {
        return node && isFunctionLikeKind(node.kind);
    }
    ts.isFunctionLike = isFunctionLike;
    /* @internal */
    function isFunctionLikeDeclaration(node) {
        return node && isFunctionLikeDeclarationKind(node.kind);
    }
    ts.isFunctionLikeDeclaration = isFunctionLikeDeclaration;
    function isFunctionLikeDeclarationKind(kind) {
        switch (kind) {
            case 244 /* FunctionDeclaration */:
            case 161 /* MethodDeclaration */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
                return true;
            default:
                return false;
        }
    }
    /* @internal */
    function isFunctionLikeKind(kind) {
        switch (kind) {
            case 160 /* MethodSignature */:
            case 165 /* CallSignature */:
            case 305 /* JSDocSignature */:
            case 166 /* ConstructSignature */:
            case 167 /* IndexSignature */:
            case 170 /* FunctionType */:
            case 300 /* JSDocFunctionType */:
            case 171 /* ConstructorType */:
                return true;
            default:
                return isFunctionLikeDeclarationKind(kind);
        }
    }
    ts.isFunctionLikeKind = isFunctionLikeKind;
    /* @internal */
    function isFunctionOrModuleBlock(node) {
        return isSourceFile(node) || isModuleBlock(node) || isBlock(node) && isFunctionLike(node.parent);
    }
    ts.isFunctionOrModuleBlock = isFunctionOrModuleBlock;
    // Classes
    function isClassElement(node) {
        var kind = node.kind;
        return kind === 162 /* Constructor */
            || kind === 159 /* PropertyDeclaration */
            || kind === 161 /* MethodDeclaration */
            || kind === 163 /* GetAccessor */
            || kind === 164 /* SetAccessor */
            || kind === 167 /* IndexSignature */
            || kind === 222 /* SemicolonClassElement */;
    }
    ts.isClassElement = isClassElement;
    function isClassLike(node) {
        return node && (node.kind === 245 /* ClassDeclaration */ || node.kind === 214 /* ClassExpression */);
    }
    ts.isClassLike = isClassLike;
    function isAccessor(node) {
        return node && (node.kind === 163 /* GetAccessor */ || node.kind === 164 /* SetAccessor */);
    }
    ts.isAccessor = isAccessor;
    /* @internal */
    function isMethodOrAccessor(node) {
        switch (node.kind) {
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
                return true;
            default:
                return false;
        }
    }
    ts.isMethodOrAccessor = isMethodOrAccessor;
    // Type members
    function isTypeElement(node) {
        var kind = node.kind;
        return kind === 166 /* ConstructSignature */
            || kind === 165 /* CallSignature */
            || kind === 158 /* PropertySignature */
            || kind === 160 /* MethodSignature */
            || kind === 167 /* IndexSignature */;
    }
    ts.isTypeElement = isTypeElement;
    function isClassOrTypeElement(node) {
        return isTypeElement(node) || isClassElement(node);
    }
    ts.isClassOrTypeElement = isClassOrTypeElement;
    function isObjectLiteralElementLike(node) {
        var kind = node.kind;
        return kind === 281 /* PropertyAssignment */
            || kind === 282 /* ShorthandPropertyAssignment */
            || kind === 283 /* SpreadAssignment */
            || kind === 161 /* MethodDeclaration */
            || kind === 163 /* GetAccessor */
            || kind === 164 /* SetAccessor */;
    }
    ts.isObjectLiteralElementLike = isObjectLiteralElementLike;
    // Type
    /**
     * Node test that determines whether a node is a valid type node.
     * This differs from the `isPartOfTypeNode` function which determines whether a node is *part*
     * of a TypeNode.
     */
    function isTypeNode(node) {
        return ts.isTypeNodeKind(node.kind);
    }
    ts.isTypeNode = isTypeNode;
    function isFunctionOrConstructorTypeNode(node) {
        switch (node.kind) {
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
                return true;
        }
        return false;
    }
    ts.isFunctionOrConstructorTypeNode = isFunctionOrConstructorTypeNode;
    // Binding patterns
    /* @internal */
    function isBindingPattern(node) {
        if (node) {
            var kind = node.kind;
            return kind === 190 /* ArrayBindingPattern */
                || kind === 189 /* ObjectBindingPattern */;
        }
        return false;
    }
    ts.isBindingPattern = isBindingPattern;
    /* @internal */
    function isAssignmentPattern(node) {
        var kind = node.kind;
        return kind === 192 /* ArrayLiteralExpression */
            || kind === 193 /* ObjectLiteralExpression */;
    }
    ts.isAssignmentPattern = isAssignmentPattern;
    /* @internal */
    function isArrayBindingElement(node) {
        var kind = node.kind;
        return kind === 191 /* BindingElement */
            || kind === 215 /* OmittedExpression */;
    }
    ts.isArrayBindingElement = isArrayBindingElement;
    /**
     * Determines whether the BindingOrAssignmentElement is a BindingElement-like declaration
     */
    /* @internal */
    function isDeclarationBindingElement(bindingElement) {
        switch (bindingElement.kind) {
            case 242 /* VariableDeclaration */:
            case 156 /* Parameter */:
            case 191 /* BindingElement */:
                return true;
        }
        return false;
    }
    ts.isDeclarationBindingElement = isDeclarationBindingElement;
    /**
     * Determines whether a node is a BindingOrAssignmentPattern
     */
    /* @internal */
    function isBindingOrAssignmentPattern(node) {
        return isObjectBindingOrAssignmentPattern(node)
            || isArrayBindingOrAssignmentPattern(node);
    }
    ts.isBindingOrAssignmentPattern = isBindingOrAssignmentPattern;
    /**
     * Determines whether a node is an ObjectBindingOrAssignmentPattern
     */
    /* @internal */
    function isObjectBindingOrAssignmentPattern(node) {
        switch (node.kind) {
            case 189 /* ObjectBindingPattern */:
            case 193 /* ObjectLiteralExpression */:
                return true;
        }
        return false;
    }
    ts.isObjectBindingOrAssignmentPattern = isObjectBindingOrAssignmentPattern;
    /**
     * Determines whether a node is an ArrayBindingOrAssignmentPattern
     */
    /* @internal */
    function isArrayBindingOrAssignmentPattern(node) {
        switch (node.kind) {
            case 190 /* ArrayBindingPattern */:
            case 192 /* ArrayLiteralExpression */:
                return true;
        }
        return false;
    }
    ts.isArrayBindingOrAssignmentPattern = isArrayBindingOrAssignmentPattern;
    /* @internal */
    function isPropertyAccessOrQualifiedNameOrImportTypeNode(node) {
        var kind = node.kind;
        return kind === 194 /* PropertyAccessExpression */
            || kind === 153 /* QualifiedName */
            || kind === 188 /* ImportType */;
    }
    ts.isPropertyAccessOrQualifiedNameOrImportTypeNode = isPropertyAccessOrQualifiedNameOrImportTypeNode;
    // Expression
    function isPropertyAccessOrQualifiedName(node) {
        var kind = node.kind;
        return kind === 194 /* PropertyAccessExpression */
            || kind === 153 /* QualifiedName */;
    }
    ts.isPropertyAccessOrQualifiedName = isPropertyAccessOrQualifiedName;
    function isCallLikeExpression(node) {
        switch (node.kind) {
            case 268 /* JsxOpeningElement */:
            case 267 /* JsxSelfClosingElement */:
            case 196 /* CallExpression */:
            case 197 /* NewExpression */:
            case 198 /* TaggedTemplateExpression */:
            case 157 /* Decorator */:
                return true;
            default:
                return false;
        }
    }
    ts.isCallLikeExpression = isCallLikeExpression;
    function isCallOrNewExpression(node) {
        return node.kind === 196 /* CallExpression */ || node.kind === 197 /* NewExpression */;
    }
    ts.isCallOrNewExpression = isCallOrNewExpression;
    function isTemplateLiteral(node) {
        var kind = node.kind;
        return kind === 211 /* TemplateExpression */
            || kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isTemplateLiteral = isTemplateLiteral;
    /* @internal */
    function isLeftHandSideExpression(node) {
        return isLeftHandSideExpressionKind(skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isLeftHandSideExpression = isLeftHandSideExpression;
    function isLeftHandSideExpressionKind(kind) {
        switch (kind) {
            case 194 /* PropertyAccessExpression */:
            case 195 /* ElementAccessExpression */:
            case 197 /* NewExpression */:
            case 196 /* CallExpression */:
            case 266 /* JsxElement */:
            case 267 /* JsxSelfClosingElement */:
            case 270 /* JsxFragment */:
            case 198 /* TaggedTemplateExpression */:
            case 192 /* ArrayLiteralExpression */:
            case 200 /* ParenthesizedExpression */:
            case 193 /* ObjectLiteralExpression */:
            case 214 /* ClassExpression */:
            case 201 /* FunctionExpression */:
            case 75 /* Identifier */:
            case 13 /* RegularExpressionLiteral */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 211 /* TemplateExpression */:
            case 91 /* FalseKeyword */:
            case 100 /* NullKeyword */:
            case 104 /* ThisKeyword */:
            case 106 /* TrueKeyword */:
            case 102 /* SuperKeyword */:
            case 218 /* NonNullExpression */:
            case 219 /* MetaProperty */:
            case 96 /* ImportKeyword */: // technically this is only an Expression if it's in a CallExpression
                return true;
            default:
                return false;
        }
    }
    /* @internal */
    function isUnaryExpression(node) {
        return isUnaryExpressionKind(skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isUnaryExpression = isUnaryExpression;
    function isUnaryExpressionKind(kind) {
        switch (kind) {
            case 207 /* PrefixUnaryExpression */:
            case 208 /* PostfixUnaryExpression */:
            case 203 /* DeleteExpression */:
            case 204 /* TypeOfExpression */:
            case 205 /* VoidExpression */:
            case 206 /* AwaitExpression */:
            case 199 /* TypeAssertionExpression */:
                return true;
            default:
                return isLeftHandSideExpressionKind(kind);
        }
    }
    /* @internal */
    function isUnaryExpressionWithWrite(expr) {
        switch (expr.kind) {
            case 208 /* PostfixUnaryExpression */:
                return true;
            case 207 /* PrefixUnaryExpression */:
                return expr.operator === 45 /* PlusPlusToken */ ||
                    expr.operator === 46 /* MinusMinusToken */;
            default:
                return false;
        }
    }
    ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite;
    /* @internal */
    /**
     * Determines whether a node is an expression based only on its kind.
     * Use `isExpressionNode` if not in transforms.
     */
    function isExpression(node) {
        return isExpressionKind(skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isExpression = isExpression;
    function isExpressionKind(kind) {
        switch (kind) {
            case 210 /* ConditionalExpression */:
            case 212 /* YieldExpression */:
            case 202 /* ArrowFunction */:
            case 209 /* BinaryExpression */:
            case 213 /* SpreadElement */:
            case 217 /* AsExpression */:
            case 215 /* OmittedExpression */:
            case 327 /* CommaListExpression */:
            case 326 /* PartiallyEmittedExpression */:
                return true;
            default:
                return isUnaryExpressionKind(kind);
        }
    }
    function isAssertionExpression(node) {
        var kind = node.kind;
        return kind === 199 /* TypeAssertionExpression */
            || kind === 217 /* AsExpression */;
    }
    ts.isAssertionExpression = isAssertionExpression;
    /* @internal */
    function isPartiallyEmittedExpression(node) {
        return node.kind === 326 /* PartiallyEmittedExpression */;
    }
    ts.isPartiallyEmittedExpression = isPartiallyEmittedExpression;
    /* @internal */
    function isNotEmittedStatement(node) {
        return node.kind === 325 /* NotEmittedStatement */;
    }
    ts.isNotEmittedStatement = isNotEmittedStatement;
    /* @internal */
    function isSyntheticReference(node) {
        return node.kind === 330 /* SyntheticReferenceExpression */;
    }
    ts.isSyntheticReference = isSyntheticReference;
    /* @internal */
    function isNotEmittedOrPartiallyEmittedNode(node) {
        return isNotEmittedStatement(node)
            || isPartiallyEmittedExpression(node);
    }
    ts.isNotEmittedOrPartiallyEmittedNode = isNotEmittedOrPartiallyEmittedNode;
    function isIterationStatement(node, lookInLabeledStatements) {
        switch (node.kind) {
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
            case 228 /* DoStatement */:
            case 229 /* WhileStatement */:
                return true;
            case 238 /* LabeledStatement */:
                return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
        }
        return false;
    }
    ts.isIterationStatement = isIterationStatement;
    /* @internal */
    function isScopeMarker(node) {
        return isExportAssignment(node) || isExportDeclaration(node);
    }
    ts.isScopeMarker = isScopeMarker;
    /* @internal */
    function hasScopeMarker(statements) {
        return ts.some(statements, isScopeMarker);
    }
    ts.hasScopeMarker = hasScopeMarker;
    /* @internal */
    function needsScopeMarker(result) {
        return !ts.isAnyImportOrReExport(result) && !isExportAssignment(result) && !ts.hasModifier(result, 1 /* Export */) && !ts.isAmbientModule(result);
    }
    ts.needsScopeMarker = needsScopeMarker;
    /* @internal */
    function isExternalModuleIndicator(result) {
        // Exported top-level member indicates moduleness
        return ts.isAnyImportOrReExport(result) || isExportAssignment(result) || ts.hasModifier(result, 1 /* Export */);
    }
    ts.isExternalModuleIndicator = isExternalModuleIndicator;
    /* @internal */
    function isForInOrOfStatement(node) {
        return node.kind === 231 /* ForInStatement */ || node.kind === 232 /* ForOfStatement */;
    }
    ts.isForInOrOfStatement = isForInOrOfStatement;
    // Element
    /* @internal */
    function isConciseBody(node) {
        return isBlock(node)
            || isExpression(node);
    }
    ts.isConciseBody = isConciseBody;
    /* @internal */
    function isFunctionBody(node) {
        return isBlock(node);
    }
    ts.isFunctionBody = isFunctionBody;
    /* @internal */
    function isForInitializer(node) {
        return isVariableDeclarationList(node)
            || isExpression(node);
    }
    ts.isForInitializer = isForInitializer;
    /* @internal */
    function isModuleBody(node) {
        var kind = node.kind;
        return kind === 250 /* ModuleBlock */
            || kind === 249 /* ModuleDeclaration */
            || kind === 75 /* Identifier */;
    }
    ts.isModuleBody = isModuleBody;
    /* @internal */
    function isNamespaceBody(node) {
        var kind = node.kind;
        return kind === 250 /* ModuleBlock */
            || kind === 249 /* ModuleDeclaration */;
    }
    ts.isNamespaceBody = isNamespaceBody;
    /* @internal */
    function isJSDocNamespaceBody(node) {
        var kind = node.kind;
        return kind === 75 /* Identifier */
            || kind === 249 /* ModuleDeclaration */;
    }
    ts.isJSDocNamespaceBody = isJSDocNamespaceBody;
    /* @internal */
    function isNamedImportBindings(node) {
        var kind = node.kind;
        return kind === 257 /* NamedImports */
            || kind === 256 /* NamespaceImport */;
    }
    ts.isNamedImportBindings = isNamedImportBindings;
    /* @internal */
    function isModuleOrEnumDeclaration(node) {
        return node.kind === 249 /* ModuleDeclaration */ || node.kind === 248 /* EnumDeclaration */;
    }
    ts.isModuleOrEnumDeclaration = isModuleOrEnumDeclaration;
    function isDeclarationKind(kind) {
        return kind === 202 /* ArrowFunction */
            || kind === 191 /* BindingElement */
            || kind === 245 /* ClassDeclaration */
            || kind === 214 /* ClassExpression */
            || kind === 162 /* Constructor */
            || kind === 248 /* EnumDeclaration */
            || kind === 284 /* EnumMember */
            || kind === 263 /* ExportSpecifier */
            || kind === 244 /* FunctionDeclaration */
            || kind === 201 /* FunctionExpression */
            || kind === 163 /* GetAccessor */
            || kind === 255 /* ImportClause */
            || kind === 253 /* ImportEqualsDeclaration */
            || kind === 258 /* ImportSpecifier */
            || kind === 246 /* InterfaceDeclaration */
            || kind === 273 /* JsxAttribute */
            || kind === 161 /* MethodDeclaration */
            || kind === 160 /* MethodSignature */
            || kind === 249 /* ModuleDeclaration */
            || kind === 252 /* NamespaceExportDeclaration */
            || kind === 256 /* NamespaceImport */
            || kind === 262 /* NamespaceExport */
            || kind === 156 /* Parameter */
            || kind === 281 /* PropertyAssignment */
            || kind === 159 /* PropertyDeclaration */
            || kind === 158 /* PropertySignature */
            || kind === 164 /* SetAccessor */
            || kind === 282 /* ShorthandPropertyAssignment */
            || kind === 247 /* TypeAliasDeclaration */
            || kind === 155 /* TypeParameter */
            || kind === 242 /* VariableDeclaration */
            || kind === 322 /* JSDocTypedefTag */
            || kind === 315 /* JSDocCallbackTag */
            || kind === 323 /* JSDocPropertyTag */;
    }
    function isDeclarationStatementKind(kind) {
        return kind === 244 /* FunctionDeclaration */
            || kind === 264 /* MissingDeclaration */
            || kind === 245 /* ClassDeclaration */
            || kind === 246 /* InterfaceDeclaration */
            || kind === 247 /* TypeAliasDeclaration */
            || kind === 248 /* EnumDeclaration */
            || kind === 249 /* ModuleDeclaration */
            || kind === 254 /* ImportDeclaration */
            || kind === 253 /* ImportEqualsDeclaration */
            || kind === 260 /* ExportDeclaration */
            || kind === 259 /* ExportAssignment */
            || kind === 252 /* NamespaceExportDeclaration */;
    }
    function isStatementKindButNotDeclarationKind(kind) {
        return kind === 234 /* BreakStatement */
            || kind === 233 /* ContinueStatement */
            || kind === 241 /* DebuggerStatement */
            || kind === 228 /* DoStatement */
            || kind === 226 /* ExpressionStatement */
            || kind === 224 /* EmptyStatement */
            || kind === 231 /* ForInStatement */
            || kind === 232 /* ForOfStatement */
            || kind === 230 /* ForStatement */
            || kind === 227 /* IfStatement */
            || kind === 238 /* LabeledStatement */
            || kind === 235 /* ReturnStatement */
            || kind === 237 /* SwitchStatement */
            || kind === 239 /* ThrowStatement */
            || kind === 240 /* TryStatement */
            || kind === 225 /* VariableStatement */
            || kind === 229 /* WhileStatement */
            || kind === 236 /* WithStatement */
            || kind === 325 /* NotEmittedStatement */
            || kind === 329 /* EndOfDeclarationMarker */
            || kind === 328 /* MergeDeclarationMarker */;
    }
    /* @internal */
    function isDeclaration(node) {
        if (node.kind === 155 /* TypeParameter */) {
            return (node.parent && node.parent.kind !== 321 /* JSDocTemplateTag */) || ts.isInJSFile(node);
        }
        return isDeclarationKind(node.kind);
    }
    ts.isDeclaration = isDeclaration;
    /* @internal */
    function isDeclarationStatement(node) {
        return isDeclarationStatementKind(node.kind);
    }
    ts.isDeclarationStatement = isDeclarationStatement;
    /**
     * Determines whether the node is a statement that is not also a declaration
     */
    /* @internal */
    function isStatementButNotDeclaration(node) {
        return isStatementKindButNotDeclarationKind(node.kind);
    }
    ts.isStatementButNotDeclaration = isStatementButNotDeclaration;
    /* @internal */
    function isStatement(node) {
        var kind = node.kind;
        return isStatementKindButNotDeclarationKind(kind)
            || isDeclarationStatementKind(kind)
            || isBlockStatement(node);
    }
    ts.isStatement = isStatement;
    function isBlockStatement(node) {
        if (node.kind !== 223 /* Block */)
            return false;
        if (node.parent !== undefined) {
            if (node.parent.kind === 240 /* TryStatement */ || node.parent.kind === 280 /* CatchClause */) {
                return false;
            }
        }
        return !ts.isFunctionBlock(node);
    }
    // Module references
    /* @internal */
    function isModuleReference(node) {
        var kind = node.kind;
        return kind === 265 /* ExternalModuleReference */
            || kind === 153 /* QualifiedName */
            || kind === 75 /* Identifier */;
    }
    ts.isModuleReference = isModuleReference;
    // JSX
    /* @internal */
    function isJsxTagNameExpression(node) {
        var kind = node.kind;
        return kind === 104 /* ThisKeyword */
            || kind === 75 /* Identifier */
            || kind === 194 /* PropertyAccessExpression */;
    }
    ts.isJsxTagNameExpression = isJsxTagNameExpression;
    /* @internal */
    function isJsxChild(node) {
        var kind = node.kind;
        return kind === 266 /* JsxElement */
            || kind === 276 /* JsxExpression */
            || kind === 267 /* JsxSelfClosingElement */
            || kind === 11 /* JsxText */
            || kind === 270 /* JsxFragment */;
    }
    ts.isJsxChild = isJsxChild;
    /* @internal */
    function isJsxAttributeLike(node) {
        var kind = node.kind;
        return kind === 273 /* JsxAttribute */
            || kind === 275 /* JsxSpreadAttribute */;
    }
    ts.isJsxAttributeLike = isJsxAttributeLike;
    /* @internal */
    function isStringLiteralOrJsxExpression(node) {
        var kind = node.kind;
        return kind === 10 /* StringLiteral */
            || kind === 276 /* JsxExpression */;
    }
    ts.isStringLiteralOrJsxExpression = isStringLiteralOrJsxExpression;
    function isJsxOpeningLikeElement(node) {
        var kind = node.kind;
        return kind === 268 /* JsxOpeningElement */
            || kind === 267 /* JsxSelfClosingElement */;
    }
    ts.isJsxOpeningLikeElement = isJsxOpeningLikeElement;
    // Clauses
    function isCaseOrDefaultClause(node) {
        var kind = node.kind;
        return kind === 277 /* CaseClause */
            || kind === 278 /* DefaultClause */;
    }
    ts.isCaseOrDefaultClause = isCaseOrDefaultClause;
    // JSDoc
    /** True if node is of some JSDoc syntax kind. */
    /* @internal */
    function isJSDocNode(node) {
        return node.kind >= 294 /* FirstJSDocNode */ && node.kind <= 323 /* LastJSDocNode */;
    }
    ts.isJSDocNode = isJSDocNode;
    /** True if node is of a kind that may contain comment text. */
    function isJSDocCommentContainingNode(node) {
        return node.kind === 303 /* JSDocComment */ || node.kind === 302 /* JSDocNamepathType */ || isJSDocTag(node) || isJSDocTypeLiteral(node) || isJSDocSignature(node);
    }
    ts.isJSDocCommentContainingNode = isJSDocCommentContainingNode;
    // TODO: determine what this does before making it public.
    /* @internal */
    function isJSDocTag(node) {
        return node.kind >= 306 /* FirstJSDocTagNode */ && node.kind <= 323 /* LastJSDocTagNode */;
    }
    ts.isJSDocTag = isJSDocTag;
    function isSetAccessor(node) {
        return node.kind === 164 /* SetAccessor */;
    }
    ts.isSetAccessor = isSetAccessor;
    function isGetAccessor(node) {
        return node.kind === 163 /* GetAccessor */;
    }
    ts.isGetAccessor = isGetAccessor;
    /** True if has jsdoc nodes attached to it. */
    /* @internal */
    // TODO: GH#19856 Would like to return `node is Node & { jsDoc: JSDoc[] }` but it causes long compile times
    function hasJSDocNodes(node) {
        var jsDoc = node.jsDoc;
        return !!jsDoc && jsDoc.length > 0;
    }
    ts.hasJSDocNodes = hasJSDocNodes;
    /** True if has type node attached to it. */
    /* @internal */
    function hasType(node) {
        return !!node.type;
    }
    ts.hasType = hasType;
    /** True if has initializer node attached to it. */
    /* @internal */
    function hasInitializer(node) {
        return !!node.initializer;
    }
    ts.hasInitializer = hasInitializer;
    /** True if has initializer node attached to it. */
    function hasOnlyExpressionInitializer(node) {
        switch (node.kind) {
            case 242 /* VariableDeclaration */:
            case 156 /* Parameter */:
            case 191 /* BindingElement */:
            case 158 /* PropertySignature */:
            case 159 /* PropertyDeclaration */:
            case 281 /* PropertyAssignment */:
            case 284 /* EnumMember */:
                return true;
            default:
                return false;
        }
    }
    ts.hasOnlyExpressionInitializer = hasOnlyExpressionInitializer;
    function isObjectLiteralElement(node) {
        return node.kind === 273 /* JsxAttribute */ || node.kind === 275 /* JsxSpreadAttribute */ || isObjectLiteralElementLike(node);
    }
    ts.isObjectLiteralElement = isObjectLiteralElement;
    /* @internal */
    function isTypeReferenceType(node) {
        return node.kind === 169 /* TypeReference */ || node.kind === 216 /* ExpressionWithTypeArguments */;
    }
    ts.isTypeReferenceType = isTypeReferenceType;
    var MAX_SMI_X86 = 1073741823;
    /* @internal */
    function guessIndentation(lines) {
        var indentation = MAX_SMI_X86;
        for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
            var line = lines_1[_i];
            if (!line.length) {
                continue;
            }
            var i = 0;
            for (; i < line.length && i < indentation; i++) {
                if (!ts.isWhiteSpaceLike(line.charCodeAt(i))) {
                    break;
                }
            }
            if (i < indentation) {
                indentation = i;
            }
            if (indentation === 0) {
                return 0;
            }
        }
        return indentation === MAX_SMI_X86 ? undefined : indentation;
    }
    ts.guessIndentation = guessIndentation;
    function isStringLiteralLike(node) {
        return node.kind === 10 /* StringLiteral */ || node.kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isStringLiteralLike = isStringLiteralLike;
    // #endregion
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    ts.resolvingEmptyArray = [];
    ts.emptyMap = ts.createMap();
    ts.emptyUnderscoreEscapedMap = ts.emptyMap;
    ts.externalHelpersModuleNameText = "tslib";
    ts.defaultMaximumTruncationLength = 160;
    ts.noTruncationMaximumTruncationLength = 1000000;
    function getDeclarationOfKind(symbol, kind) {
        var declarations = symbol.declarations;
        if (declarations) {
            for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
                var declaration = declarations_1[_i];
                if (declaration.kind === kind) {
                    return declaration;
                }
            }
        }
        return undefined;
    }
    ts.getDeclarationOfKind = getDeclarationOfKind;
    /** Create a new escaped identifier map. */
    function createUnderscoreEscapedMap() {
        return new ts.Map();
    }
    ts.createUnderscoreEscapedMap = createUnderscoreEscapedMap;
    function hasEntries(map) {
        return !!map && !!map.size;
    }
    ts.hasEntries = hasEntries;
    function createSymbolTable(symbols) {
        var result = ts.createMap();
        if (symbols) {
            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
                var symbol = symbols_1[_i];
                result.set(symbol.escapedName, symbol);
            }
        }
        return result;
    }
    ts.createSymbolTable = createSymbolTable;
    function isTransientSymbol(symbol) {
        return (symbol.flags & 33554432 /* Transient */) !== 0;
    }
    ts.isTransientSymbol = isTransientSymbol;
    var stringWriter = createSingleLineStringWriter();
    function createSingleLineStringWriter() {
        var str = "";
        var writeText = function (text) { return str += text; };
        return {
            getText: function () { return str; },
            write: writeText,
            rawWrite: writeText,
            writeKeyword: writeText,
            writeOperator: writeText,
            writePunctuation: writeText,
            writeSpace: writeText,
            writeStringLiteral: writeText,
            writeLiteral: writeText,
            writeParameter: writeText,
            writeProperty: writeText,
            writeSymbol: function (s, _) { return writeText(s); },
            writeTrailingSemicolon: writeText,
            writeComment: writeText,
            getTextPos: function () { return str.length; },
            getLine: function () { return 0; },
            getColumn: function () { return 0; },
            getIndent: function () { return 0; },
            isAtStartOfLine: function () { return false; },
            hasTrailingComment: function () { return false; },
            hasTrailingWhitespace: function () { return !!str.length && ts.isWhiteSpaceLike(str.charCodeAt(str.length - 1)); },
            // Completely ignore indentation for string writers.  And map newlines to
            // a single space.
            writeLine: function () { return str += " "; },
            increaseIndent: ts.noop,
            decreaseIndent: ts.noop,
            clear: function () { return str = ""; },
            trackSymbol: ts.noop,
            reportInaccessibleThisError: ts.noop,
            reportInaccessibleUniqueSymbolError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
        };
    }
    function changesAffectModuleResolution(oldOptions, newOptions) {
        return oldOptions.configFilePath !== newOptions.configFilePath ||
            optionsHaveModuleResolutionChanges(oldOptions, newOptions);
    }
    ts.changesAffectModuleResolution = changesAffectModuleResolution;
    function optionsHaveModuleResolutionChanges(oldOptions, newOptions) {
        return ts.moduleResolutionOptionDeclarations.some(function (o) {
            return !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(newOptions, o));
        });
    }
    ts.optionsHaveModuleResolutionChanges = optionsHaveModuleResolutionChanges;
    function findAncestor(node, callback) {
        while (node) {
            var result = callback(node);
            if (result === "quit") {
                return undefined;
            }
            else if (result) {
                return node;
            }
            node = node.parent;
        }
        return undefined;
    }
    ts.findAncestor = findAncestor;
    function forEachAncestor(node, callback) {
        while (true) {
            var res = callback(node);
            if (res === "quit")
                return undefined;
            if (res !== undefined)
                return res;
            if (ts.isSourceFile(node))
                return undefined;
            node = node.parent;
        }
    }
    ts.forEachAncestor = forEachAncestor;
    function forEachEntry(map, callback) {
        var iterator = map.entries();
        for (var iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
            var _a = iterResult.value, key = _a[0], value = _a[1];
            var result = callback(value, key);
            if (result) {
                return result;
            }
        }
        return undefined;
    }
    ts.forEachEntry = forEachEntry;
    function forEachKey(map, callback) {
        var iterator = map.keys();
        for (var iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
            var result = callback(iterResult.value);
            if (result) {
                return result;
            }
        }
        return undefined;
    }
    ts.forEachKey = forEachKey;
    function copyEntries(source, target) {
        source.forEach(function (value, key) {
            target.set(key, value);
        });
    }
    ts.copyEntries = copyEntries;
    function arrayToSet(array, makeKey) {
        return ts.arrayToMap(array, makeKey || (function (s) { return s; }), ts.returnTrue);
    }
    ts.arrayToSet = arrayToSet;
    function cloneMap(map) {
        var clone = ts.createMap();
        copyEntries(map, clone);
        return clone;
    }
    ts.cloneMap = cloneMap;
    function usingSingleLineStringWriter(action) {
        var oldString = stringWriter.getText();
        try {
            action(stringWriter);
            return stringWriter.getText();
        }
        finally {
            stringWriter.clear();
            stringWriter.writeKeyword(oldString);
        }
    }
    ts.usingSingleLineStringWriter = usingSingleLineStringWriter;
    function getFullWidth(node) {
        return node.end - node.pos;
    }
    ts.getFullWidth = getFullWidth;
    function getResolvedModule(sourceFile, moduleNameText) {
        return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText);
    }
    ts.getResolvedModule = getResolvedModule;
    function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
        if (!sourceFile.resolvedModules) {
            sourceFile.resolvedModules = ts.createMap();
        }
        sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
    }
    ts.setResolvedModule = setResolvedModule;
    function setResolvedTypeReferenceDirective(sourceFile, typeReferenceDirectiveName, resolvedTypeReferenceDirective) {
        if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
            sourceFile.resolvedTypeReferenceDirectiveNames = ts.createMap();
        }
        sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective);
    }
    ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective;
    function projectReferenceIsEqualTo(oldRef, newRef) {
        return oldRef.path === newRef.path &&
            !oldRef.prepend === !newRef.prepend &&
            !oldRef.circular === !newRef.circular;
    }
    ts.projectReferenceIsEqualTo = projectReferenceIsEqualTo;
    function moduleResolutionIsEqualTo(oldResolution, newResolution) {
        return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
            oldResolution.extension === newResolution.extension &&
            oldResolution.resolvedFileName === newResolution.resolvedFileName &&
            oldResolution.originalPath === newResolution.originalPath &&
            packageIdIsEqual(oldResolution.packageId, newResolution.packageId);
    }
    ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo;
    function packageIdIsEqual(a, b) {
        return a === b || !!a && !!b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
    }
    function packageIdToString(_a) {
        var name = _a.name, subModuleName = _a.subModuleName, version = _a.version;
        var fullName = subModuleName ? name + "/" + subModuleName : name;
        return fullName + "@" + version;
    }
    ts.packageIdToString = packageIdToString;
    function typeDirectiveIsEqualTo(oldResolution, newResolution) {
        return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary;
    }
    ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo;
    function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) {
        ts.Debug.assert(names.length === newResolutions.length);
        for (var i = 0; i < names.length; i++) {
            var newResolution = newResolutions[i];
            var oldResolution = oldResolutions && oldResolutions.get(names[i]);
            var changed = oldResolution
                ? !newResolution || !comparer(oldResolution, newResolution)
                : newResolution;
            if (changed) {
                return true;
            }
        }
        return false;
    }
    ts.hasChangesInResolutions = hasChangesInResolutions;
    // Returns true if this node contains a parse error anywhere underneath it.
    function containsParseError(node) {
        aggregateChildData(node);
        return (node.flags & 262144 /* ThisNodeOrAnySubNodesHasError */) !== 0;
    }
    ts.containsParseError = containsParseError;
    function aggregateChildData(node) {
        if (!(node.flags & 524288 /* HasAggregatedChildData */)) {
            // A node is considered to contain a parse error if:
            //  a) the parser explicitly marked that it had an error
            //  b) any of it's children reported that it had an error.
            var thisNodeOrAnySubNodesHasError = ((node.flags & 65536 /* ThisNodeHasError */) !== 0) ||
                ts.forEachChild(node, containsParseError);
            // If so, mark ourselves accordingly.
            if (thisNodeOrAnySubNodesHasError) {
                node.flags |= 262144 /* ThisNodeOrAnySubNodesHasError */;
            }
            // Also mark that we've propagated the child information to this node.  This way we can
            // always consult the bit directly on this node without needing to check its children
            // again.
            node.flags |= 524288 /* HasAggregatedChildData */;
        }
    }
    function getSourceFileOfNode(node) {
        while (node && node.kind !== 290 /* SourceFile */) {
            node = node.parent;
        }
        return node;
    }
    ts.getSourceFileOfNode = getSourceFileOfNode;
    function isStatementWithLocals(node) {
        switch (node.kind) {
            case 223 /* Block */:
            case 251 /* CaseBlock */:
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
                return true;
        }
        return false;
    }
    ts.isStatementWithLocals = isStatementWithLocals;
    function getStartPositionOfLine(line, sourceFile) {
        ts.Debug.assert(line >= 0);
        return ts.getLineStarts(sourceFile)[line];
    }
    ts.getStartPositionOfLine = getStartPositionOfLine;
    // This is a useful function for debugging purposes.
    function nodePosToString(node) {
        var file = getSourceFileOfNode(node);
        var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
        return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
    }
    ts.nodePosToString = nodePosToString;
    function getEndLinePosition(line, sourceFile) {
        ts.Debug.assert(line >= 0);
        var lineStarts = ts.getLineStarts(sourceFile);
        var lineIndex = line;
        var sourceText = sourceFile.text;
        if (lineIndex + 1 === lineStarts.length) {
            // last line - return EOF
            return sourceText.length - 1;
        }
        else {
            // current line start
            var start = lineStarts[lineIndex];
            // take the start position of the next line - 1 = it should be some line break
            var pos = lineStarts[lineIndex + 1] - 1;
            ts.Debug.assert(ts.isLineBreak(sourceText.charCodeAt(pos)));
            // walk backwards skipping line breaks, stop the the beginning of current line.
            // i.e:
            // <some text>
            // $ <- end of line for this position should match the start position
            while (start <= pos && ts.isLineBreak(sourceText.charCodeAt(pos))) {
                pos--;
            }
            return pos;
        }
    }
    ts.getEndLinePosition = getEndLinePosition;
    /**
     * Returns a value indicating whether a name is unique globally or within the current file.
     * Note: This does not consider whether a name appears as a free identifier or not, so at the expression `x.y` this includes both `x` and `y`.
     */
    function isFileLevelUniqueName(sourceFile, name, hasGlobalName) {
        return !(hasGlobalName && hasGlobalName(name)) && !sourceFile.identifiers.has(name);
    }
    ts.isFileLevelUniqueName = isFileLevelUniqueName;
    // Returns true if this node is missing from the actual source code. A 'missing' node is different
    // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
    // in the tree), it is definitely missing. However, a node may be defined, but still be
    // missing.  This happens whenever the parser knows it needs to parse something, but can't
    // get anything in the source code that it expects at that location. For example:
    //
    //          let a: ;
    //
    // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
    // code). So the parser will attempt to parse out a type, and will create an actual node.
    // However, this node will be 'missing' in the sense that no actual source-code/tokens are
    // contained within it.
    function nodeIsMissing(node) {
        if (node === undefined) {
            return true;
        }
        return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
    }
    ts.nodeIsMissing = nodeIsMissing;
    function nodeIsPresent(node) {
        return !nodeIsMissing(node);
    }
    ts.nodeIsPresent = nodeIsPresent;
    function insertStatementsAfterPrologue(to, from, isPrologueDirective) {
        if (from === undefined || from.length === 0)
            return to;
        var statementIndex = 0;
        // skip all prologue directives to insert at the correct position
        for (; statementIndex < to.length; ++statementIndex) {
            if (!isPrologueDirective(to[statementIndex])) {
                break;
            }
        }
        to.splice.apply(to, __spreadArrays([statementIndex, 0], from));
        return to;
    }
    function insertStatementAfterPrologue(to, statement, isPrologueDirective) {
        if (statement === undefined)
            return to;
        var statementIndex = 0;
        // skip all prologue directives to insert at the correct position
        for (; statementIndex < to.length; ++statementIndex) {
            if (!isPrologueDirective(to[statementIndex])) {
                break;
            }
        }
        to.splice(statementIndex, 0, statement);
        return to;
    }
    function isAnyPrologueDirective(node) {
        return isPrologueDirective(node) || !!(getEmitFlags(node) & 1048576 /* CustomPrologue */);
    }
    /**
     * Prepends statements to an array while taking care of prologue directives.
     */
    function insertStatementsAfterStandardPrologue(to, from) {
        return insertStatementsAfterPrologue(to, from, isPrologueDirective);
    }
    ts.insertStatementsAfterStandardPrologue = insertStatementsAfterStandardPrologue;
    function insertStatementsAfterCustomPrologue(to, from) {
        return insertStatementsAfterPrologue(to, from, isAnyPrologueDirective);
    }
    ts.insertStatementsAfterCustomPrologue = insertStatementsAfterCustomPrologue;
    /**
     * Prepends statements to an array while taking care of prologue directives.
     */
    function insertStatementAfterStandardPrologue(to, statement) {
        return insertStatementAfterPrologue(to, statement, isPrologueDirective);
    }
    ts.insertStatementAfterStandardPrologue = insertStatementAfterStandardPrologue;
    function insertStatementAfterCustomPrologue(to, statement) {
        return insertStatementAfterPrologue(to, statement, isAnyPrologueDirective);
    }
    ts.insertStatementAfterCustomPrologue = insertStatementAfterCustomPrologue;
    /**
     * Determine if the given comment is a triple-slash
     *
     * @return true if the comment is a triple-slash comment else false
     */
    function isRecognizedTripleSlashComment(text, commentPos, commentEnd) {
        // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
        // so that we don't end up computing comment string and doing match for all // comments
        if (text.charCodeAt(commentPos + 1) === 47 /* slash */ &&
            commentPos + 2 < commentEnd &&
            text.charCodeAt(commentPos + 2) === 47 /* slash */) {
            var textSubStr = text.substring(commentPos, commentEnd);
            return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
                textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ||
                textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) ||
                textSubStr.match(defaultLibReferenceRegEx) ?
                true : false;
        }
        return false;
    }
    ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment;
    function isPinnedComment(text, start) {
        return text.charCodeAt(start + 1) === 42 /* asterisk */ &&
            text.charCodeAt(start + 2) === 33 /* exclamation */;
    }
    ts.isPinnedComment = isPinnedComment;
    function createCommentDirectivesMap(sourceFile, commentDirectives) {
        var directivesByLine = ts.createMapFromEntries(commentDirectives.map(function (commentDirective) { return ([
            "" + ts.getLineAndCharacterOfPosition(sourceFile, commentDirective.range.end).line,
            commentDirective,
        ]); }));
        var usedLines = ts.createMap();
        return { getUnusedExpectations: getUnusedExpectations, markUsed: markUsed };
        function getUnusedExpectations() {
            return ts.arrayFrom(directivesByLine.entries())
                .filter(function (_a) {
                var line = _a[0], directive = _a[1];
                return directive.type === 0 /* ExpectError */ && !usedLines.get(line);
            })
                .map(function (_a) {
                var _ = _a[0], directive = _a[1];
                return directive;
            });
        }
        function markUsed(line) {
            if (!directivesByLine.has("" + line)) {
                return false;
            }
            usedLines.set("" + line, true);
            return true;
        }
    }
    ts.createCommentDirectivesMap = createCommentDirectivesMap;
    function getTokenPosOfNode(node, sourceFile, includeJsDoc) {
        // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
        // want to skip trivia because this will launch us forward to the next token.
        if (nodeIsMissing(node)) {
            return node.pos;
        }
        if (ts.isJSDocNode(node)) {
            return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        if (includeJsDoc && ts.hasJSDocNodes(node)) {
            return getTokenPosOfNode(node.jsDoc[0], sourceFile);
        }
        // For a syntax list, it is possible that one of its children has JSDocComment nodes, while
        // the syntax list itself considers them as normal trivia. Therefore if we simply skip
        // trivia for the list, we may have skipped the JSDocComment as well. So we should process its
        // first child to determine the actual position of its first token.
        if (node.kind === 324 /* SyntaxList */ && node._children.length > 0) {
            return getTokenPosOfNode(node._children[0], sourceFile, includeJsDoc);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
    }
    ts.getTokenPosOfNode = getTokenPosOfNode;
    function getNonDecoratorTokenPosOfNode(node, sourceFile) {
        if (nodeIsMissing(node) || !node.decorators) {
            return getTokenPosOfNode(node, sourceFile);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
    }
    ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
    function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        return getTextOfNodeFromSourceText(sourceFile.text, node, includeTrivia);
    }
    ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
    function isJSDocTypeExpressionOrChild(node) {
        return !!findAncestor(node, ts.isJSDocTypeExpression);
    }
    function getTextOfNodeFromSourceText(sourceText, node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        if (nodeIsMissing(node)) {
            return "";
        }
        var text = sourceText.substring(includeTrivia ? node.pos : ts.skipTrivia(sourceText, node.pos), node.end);
        if (isJSDocTypeExpressionOrChild(node)) {
            // strip space + asterisk at line start
            text = text.replace(/(^|\r?\n|\r)\s*\*\s*/g, "$1");
        }
        return text;
    }
    ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
    function getTextOfNode(node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
    }
    ts.getTextOfNode = getTextOfNode;
    function getPos(range) {
        return range.pos;
    }
    /**
     * Note: it is expected that the `nodeArray` and the `node` are within the same file.
     * For example, searching for a `SourceFile` in a `SourceFile[]` wouldn't work.
     */
    function indexOfNode(nodeArray, node) {
        return ts.binarySearch(nodeArray, node, getPos, ts.compareValues);
    }
    ts.indexOfNode = indexOfNode;
    /**
     * Gets flags that control emit behavior of a node.
     */
    function getEmitFlags(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.flags || 0;
    }
    ts.getEmitFlags = getEmitFlags;
    function getLiteralText(node, sourceFile, neverAsciiEscape, jsxAttributeEscape) {
        // If we don't need to downlevel and we can reach the original source text using
        // the node's parent reference, then simply get the text as it was originally written.
        if (!nodeIsSynthesized(node) && node.parent && !((ts.isNumericLiteral(node) && node.numericLiteralFlags & 512 /* ContainsSeparator */) ||
            ts.isBigIntLiteral(node))) {
            return getSourceTextOfNodeFromSourceFile(sourceFile, node);
        }
        // If we can't reach the original source text, use the canonical form if it's a number,
        // or a (possibly escaped) quoted form of the original text if it's string-like.
        switch (node.kind) {
            case 10 /* StringLiteral */: {
                var escapeText = jsxAttributeEscape ? escapeJsxAttributeString :
                    neverAsciiEscape || (getEmitFlags(node) & 16777216 /* NoAsciiEscaping */) ? escapeString :
                        escapeNonAsciiString;
                if (node.singleQuote) {
                    return "'" + escapeText(node.text, 39 /* singleQuote */) + "'";
                }
                else {
                    return '"' + escapeText(node.text, 34 /* doubleQuote */) + '"';
                }
            }
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 15 /* TemplateHead */:
            case 16 /* TemplateMiddle */:
            case 17 /* TemplateTail */: {
                // If a NoSubstitutionTemplateLiteral appears to have a substitution in it, the original text
                // had to include a backslash: `not \${a} substitution`.
                var escapeText = neverAsciiEscape || (getEmitFlags(node) & 16777216 /* NoAsciiEscaping */) ? escapeString :
                    escapeNonAsciiString;
                var rawText = node.rawText || escapeTemplateSubstitution(escapeText(node.text, 96 /* backtick */));
                switch (node.kind) {
                    case 14 /* NoSubstitutionTemplateLiteral */:
                        return "`" + rawText + "`";
                    case 15 /* TemplateHead */:
                        return "`" + rawText + "${";
                    case 16 /* TemplateMiddle */:
                        return "}" + rawText + "${";
                    case 17 /* TemplateTail */:
                        return "}" + rawText + "`";
                }
                break;
            }
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 13 /* RegularExpressionLiteral */:
                return node.text;
        }
        return ts.Debug.fail("Literal kind '" + node.kind + "' not accounted for.");
    }
    ts.getLiteralText = getLiteralText;
    function getTextOfConstantValue(value) {
        return ts.isString(value) ? '"' + escapeNonAsciiString(value) + '"' : "" + value;
    }
    ts.getTextOfConstantValue = getTextOfConstantValue;
    // Make an identifier from an external module name by extracting the string after the last "/" and replacing
    // all non-alphanumeric characters with underscores
    function makeIdentifierFromModuleName(moduleName) {
        return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
    }
    ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
    function isBlockOrCatchScoped(declaration) {
        return (ts.getCombinedNodeFlags(declaration) & 3 /* BlockScoped */) !== 0 ||
            isCatchClauseVariableDeclarationOrBindingElement(declaration);
    }
    ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
    function isCatchClauseVariableDeclarationOrBindingElement(declaration) {
        var node = getRootDeclaration(declaration);
        return node.kind === 242 /* VariableDeclaration */ && node.parent.kind === 280 /* CatchClause */;
    }
    ts.isCatchClauseVariableDeclarationOrBindingElement = isCatchClauseVariableDeclarationOrBindingElement;
    function isAmbientModule(node) {
        return ts.isModuleDeclaration(node) && (node.name.kind === 10 /* StringLiteral */ || isGlobalScopeAugmentation(node));
    }
    ts.isAmbientModule = isAmbientModule;
    function isModuleWithStringLiteralName(node) {
        return ts.isModuleDeclaration(node) && node.name.kind === 10 /* StringLiteral */;
    }
    ts.isModuleWithStringLiteralName = isModuleWithStringLiteralName;
    function isNonGlobalAmbientModule(node) {
        return ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name);
    }
    ts.isNonGlobalAmbientModule = isNonGlobalAmbientModule;
    /**
     * An effective module (namespace) declaration is either
     * 1. An actual declaration: namespace X { ... }
     * 2. A Javascript declaration, which is:
     *    An identifier in a nested property access expression: Y in `X.Y.Z = { ... }`
     */
    function isEffectiveModuleDeclaration(node) {
        return ts.isModuleDeclaration(node) || ts.isIdentifier(node);
    }
    ts.isEffectiveModuleDeclaration = isEffectiveModuleDeclaration;
    /** Given a symbol for a module, checks that it is a shorthand ambient module. */
    function isShorthandAmbientModuleSymbol(moduleSymbol) {
        return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
    }
    ts.isShorthandAmbientModuleSymbol = isShorthandAmbientModuleSymbol;
    function isShorthandAmbientModule(node) {
        // The only kind of module that can be missing a body is a shorthand ambient module.
        return node && node.kind === 249 /* ModuleDeclaration */ && (!node.body);
    }
    function isBlockScopedContainerTopLevel(node) {
        return node.kind === 290 /* SourceFile */ ||
            node.kind === 249 /* ModuleDeclaration */ ||
            ts.isFunctionLike(node);
    }
    ts.isBlockScopedContainerTopLevel = isBlockScopedContainerTopLevel;
    function isGlobalScopeAugmentation(module) {
        return !!(module.flags & 1024 /* GlobalAugmentation */);
    }
    ts.isGlobalScopeAugmentation = isGlobalScopeAugmentation;
    function isExternalModuleAugmentation(node) {
        return isAmbientModule(node) && isModuleAugmentationExternal(node);
    }
    ts.isExternalModuleAugmentation = isExternalModuleAugmentation;
    function isModuleAugmentationExternal(node) {
        // external module augmentation is a ambient module declaration that is either:
        // - defined in the top level scope and source file is an external module
        // - defined inside ambient module declaration located in the top level scope and source file not an external module
        switch (node.parent.kind) {
            case 290 /* SourceFile */:
                return ts.isExternalModule(node.parent);
            case 250 /* ModuleBlock */:
                return isAmbientModule(node.parent.parent) && ts.isSourceFile(node.parent.parent.parent) && !ts.isExternalModule(node.parent.parent.parent);
        }
        return false;
    }
    ts.isModuleAugmentationExternal = isModuleAugmentationExternal;
    function getNonAugmentationDeclaration(symbol) {
        return ts.find(symbol.declarations, function (d) { return !isExternalModuleAugmentation(d) && !(ts.isModuleDeclaration(d) && isGlobalScopeAugmentation(d)); });
    }
    ts.getNonAugmentationDeclaration = getNonAugmentationDeclaration;
    function isEffectiveExternalModule(node, compilerOptions) {
        return ts.isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS) && !!node.commonJsModuleIndicator);
    }
    ts.isEffectiveExternalModule = isEffectiveExternalModule;
    /**
     * Returns whether the source file will be treated as if it were in strict mode at runtime.
     */
    function isEffectiveStrictModeSourceFile(node, compilerOptions) {
        // We can only verify strict mode for JS/TS files
        switch (node.scriptKind) {
            case 1 /* JS */:
            case 3 /* TS */:
            case 2 /* JSX */:
            case 4 /* TSX */:
                break;
            default:
                return false;
        }
        // Strict mode does not matter for declaration files.
        if (node.isDeclarationFile) {
            return false;
        }
        // If `alwaysStrict` is set, then treat the file as strict.
        if (getStrictOptionValue(compilerOptions, "alwaysStrict")) {
            return true;
        }
        // Starting with a "use strict" directive indicates the file is strict.
        if (ts.startsWithUseStrict(node.statements)) {
            return true;
        }
        if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
            // ECMAScript Modules are always strict.
            if (getEmitModuleKind(compilerOptions) >= ts.ModuleKind.ES2015) {
                return true;
            }
            // Other modules are strict unless otherwise specified.
            return !compilerOptions.noImplicitUseStrict;
        }
        return false;
    }
    ts.isEffectiveStrictModeSourceFile = isEffectiveStrictModeSourceFile;
    function isBlockScope(node, parentNode) {
        switch (node.kind) {
            case 290 /* SourceFile */:
            case 251 /* CaseBlock */:
            case 280 /* CatchClause */:
            case 249 /* ModuleDeclaration */:
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
            case 162 /* Constructor */:
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
                return true;
            case 223 /* Block */:
                // function block is not considered block-scope container
                // see comment in binder.ts: bind(...), case for SyntaxKind.Block
                return !ts.isFunctionLike(parentNode);
        }
        return false;
    }
    ts.isBlockScope = isBlockScope;
    function isDeclarationWithTypeParameters(node) {
        switch (node.kind) {
            case 315 /* JSDocCallbackTag */:
            case 322 /* JSDocTypedefTag */:
            case 305 /* JSDocSignature */:
                return true;
            default:
                ts.assertType(node);
                return isDeclarationWithTypeParameterChildren(node);
        }
    }
    ts.isDeclarationWithTypeParameters = isDeclarationWithTypeParameters;
    function isDeclarationWithTypeParameterChildren(node) {
        switch (node.kind) {
            case 165 /* CallSignature */:
            case 166 /* ConstructSignature */:
            case 160 /* MethodSignature */:
            case 167 /* IndexSignature */:
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
            case 300 /* JSDocFunctionType */:
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 321 /* JSDocTemplateTag */:
            case 244 /* FunctionDeclaration */:
            case 161 /* MethodDeclaration */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
                return true;
            default:
                ts.assertType(node);
                return false;
        }
    }
    ts.isDeclarationWithTypeParameterChildren = isDeclarationWithTypeParameterChildren;
    function isAnyImportSyntax(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
            case 253 /* ImportEqualsDeclaration */:
                return true;
            default:
                return false;
        }
    }
    ts.isAnyImportSyntax = isAnyImportSyntax;
    function isLateVisibilityPaintedStatement(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
            case 253 /* ImportEqualsDeclaration */:
            case 225 /* VariableStatement */:
            case 245 /* ClassDeclaration */:
            case 244 /* FunctionDeclaration */:
            case 249 /* ModuleDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 246 /* InterfaceDeclaration */:
            case 248 /* EnumDeclaration */:
                return true;
            default:
                return false;
        }
    }
    ts.isLateVisibilityPaintedStatement = isLateVisibilityPaintedStatement;
    function isAnyImportOrReExport(node) {
        return isAnyImportSyntax(node) || ts.isExportDeclaration(node);
    }
    ts.isAnyImportOrReExport = isAnyImportOrReExport;
    // Gets the nearest enclosing block scope container that has the provided node
    // as a descendant, that is not the provided node.
    function getEnclosingBlockScopeContainer(node) {
        return findAncestor(node.parent, function (current) { return isBlockScope(current, current.parent); });
    }
    ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
    // Return display name of an identifier
    // Computed property names will just be emitted as "[<expr>]", where <expr> is the source
    // text of the expression in the computed property.
    function declarationNameToString(name) {
        return !name || getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
    }
    ts.declarationNameToString = declarationNameToString;
    function getNameFromIndexInfo(info) {
        return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
    }
    ts.getNameFromIndexInfo = getNameFromIndexInfo;
    function isComputedNonLiteralName(name) {
        return name.kind === 154 /* ComputedPropertyName */ && !isStringOrNumericLiteralLike(name.expression);
    }
    ts.isComputedNonLiteralName = isComputedNonLiteralName;
    function getTextOfPropertyName(name) {
        switch (name.kind) {
            case 75 /* Identifier */:
            case 76 /* PrivateIdentifier */:
                return name.escapedText;
            case 10 /* StringLiteral */:
            case 8 /* NumericLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
                return ts.escapeLeadingUnderscores(name.text);
            case 154 /* ComputedPropertyName */:
                if (isStringOrNumericLiteralLike(name.expression))
                    return ts.escapeLeadingUnderscores(name.expression.text);
                return ts.Debug.fail("Text of property name cannot be read from non-literal-valued ComputedPropertyNames");
            default:
                return ts.Debug.assertNever(name);
        }
    }
    ts.getTextOfPropertyName = getTextOfPropertyName;
    function entityNameToString(name) {
        switch (name.kind) {
            case 104 /* ThisKeyword */:
                return "this";
            case 76 /* PrivateIdentifier */:
            case 75 /* Identifier */:
                return getFullWidth(name) === 0 ? ts.idText(name) : getTextOfNode(name);
            case 153 /* QualifiedName */:
                return entityNameToString(name.left) + "." + entityNameToString(name.right);
            case 194 /* PropertyAccessExpression */:
                if (ts.isIdentifier(name.name) || ts.isPrivateIdentifier(name.name)) {
                    return entityNameToString(name.expression) + "." + entityNameToString(name.name);
                }
                else {
                    return ts.Debug.assertNever(name.name);
                }
            default:
                return ts.Debug.assertNever(name);
        }
    }
    ts.entityNameToString = entityNameToString;
    function createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3) {
        var sourceFile = getSourceFileOfNode(node);
        return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNode = createDiagnosticForNode;
    function createDiagnosticForNodeArray(sourceFile, nodes, message, arg0, arg1, arg2, arg3) {
        var start = ts.skipTrivia(sourceFile.text, nodes.pos);
        return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNodeArray = createDiagnosticForNodeArray;
    function createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3) {
        var span = getErrorSpanForNode(sourceFile, node);
        return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNodeInSourceFile = createDiagnosticForNodeInSourceFile;
    function createDiagnosticForNodeFromMessageChain(node, messageChain, relatedInformation) {
        var sourceFile = getSourceFileOfNode(node);
        var span = getErrorSpanForNode(sourceFile, node);
        return {
            file: sourceFile,
            start: span.start,
            length: span.length,
            code: messageChain.code,
            category: messageChain.category,
            messageText: messageChain.next ? messageChain : messageChain.messageText,
            relatedInformation: relatedInformation
        };
    }
    ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain;
    function createDiagnosticForRange(sourceFile, range, message) {
        return {
            file: sourceFile,
            start: range.pos,
            length: range.end - range.pos,
            code: message.code,
            category: message.category,
            messageText: message.message,
        };
    }
    ts.createDiagnosticForRange = createDiagnosticForRange;
    function getSpanOfTokenAtPosition(sourceFile, pos) {
        var scanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
        scanner.scan();
        var start = scanner.getTokenPos();
        return ts.createTextSpanFromBounds(start, scanner.getTextPos());
    }
    ts.getSpanOfTokenAtPosition = getSpanOfTokenAtPosition;
    function getErrorSpanForArrowFunction(sourceFile, node) {
        var pos = ts.skipTrivia(sourceFile.text, node.pos);
        if (node.body && node.body.kind === 223 /* Block */) {
            var startLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.pos).line;
            var endLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.end).line;
            if (startLine < endLine) {
                // The arrow function spans multiple lines,
                // make the error span be the first line, inclusive.
                return ts.createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1);
            }
        }
        return ts.createTextSpanFromBounds(pos, node.end);
    }
    function getErrorSpanForNode(sourceFile, node) {
        var errorNode = node;
        switch (node.kind) {
            case 290 /* SourceFile */:
                var pos_1 = ts.skipTrivia(sourceFile.text, 0, /*stopAfterLineBreak*/ false);
                if (pos_1 === sourceFile.text.length) {
                    // file is empty - return span for the beginning of the file
                    return ts.createTextSpan(0, 0);
                }
                return getSpanOfTokenAtPosition(sourceFile, pos_1);
            // This list is a work in progress. Add missing node kinds to improve their error
            // spans.
            case 242 /* VariableDeclaration */:
            case 191 /* BindingElement */:
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
            case 246 /* InterfaceDeclaration */:
            case 249 /* ModuleDeclaration */:
            case 248 /* EnumDeclaration */:
            case 284 /* EnumMember */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 247 /* TypeAliasDeclaration */:
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
                errorNode = node.name;
                break;
            case 202 /* ArrowFunction */:
                return getErrorSpanForArrowFunction(sourceFile, node);
            case 277 /* CaseClause */:
            case 278 /* DefaultClause */:
                var start = ts.skipTrivia(sourceFile.text, node.pos);
                var end = node.statements.length > 0 ? node.statements[0].pos : node.end;
                return ts.createTextSpanFromBounds(start, end);
        }
        if (errorNode === undefined) {
            // If we don't have a better node, then just set the error on the first token of
            // construct.
            return getSpanOfTokenAtPosition(sourceFile, node.pos);
        }
        ts.Debug.assert(!ts.isJSDoc(errorNode));
        var isMissing = nodeIsMissing(errorNode);
        var pos = isMissing || ts.isJsxText(node)
            ? errorNode.pos
            : ts.skipTrivia(sourceFile.text, errorNode.pos);
        // These asserts should all be satisfied for a properly constructed `errorNode`.
        if (isMissing) {
            ts.Debug.assert(pos === errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
            ts.Debug.assert(pos === errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
        }
        else {
            ts.Debug.assert(pos >= errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
            ts.Debug.assert(pos <= errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
        }
        return ts.createTextSpanFromBounds(pos, errorNode.end);
    }
    ts.getErrorSpanForNode = getErrorSpanForNode;
    function isExternalOrCommonJsModule(file) {
        return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
    }
    ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
    function isJsonSourceFile(file) {
        return file.scriptKind === 6 /* JSON */;
    }
    ts.isJsonSourceFile = isJsonSourceFile;
    function isEnumConst(node) {
        return !!(ts.getCombinedModifierFlags(node) & 2048 /* Const */);
    }
    ts.isEnumConst = isEnumConst;
    function isDeclarationReadonly(declaration) {
        return !!(ts.getCombinedModifierFlags(declaration) & 64 /* Readonly */ && !ts.isParameterPropertyDeclaration(declaration, declaration.parent));
    }
    ts.isDeclarationReadonly = isDeclarationReadonly;
    function isVarConst(node) {
        return !!(ts.getCombinedNodeFlags(node) & 2 /* Const */);
    }
    ts.isVarConst = isVarConst;
    function isLet(node) {
        return !!(ts.getCombinedNodeFlags(node) & 1 /* Let */);
    }
    ts.isLet = isLet;
    function isSuperCall(n) {
        return n.kind === 196 /* CallExpression */ && n.expression.kind === 102 /* SuperKeyword */;
    }
    ts.isSuperCall = isSuperCall;
    function isImportCall(n) {
        return n.kind === 196 /* CallExpression */ && n.expression.kind === 96 /* ImportKeyword */;
    }
    ts.isImportCall = isImportCall;
    function isImportMeta(n) {
        return ts.isMetaProperty(n)
            && n.keywordToken === 96 /* ImportKeyword */
            && n.name.escapedText === "meta";
    }
    ts.isImportMeta = isImportMeta;
    function isLiteralImportTypeNode(n) {
        return ts.isImportTypeNode(n) && ts.isLiteralTypeNode(n.argument) && ts.isStringLiteral(n.argument.literal);
    }
    ts.isLiteralImportTypeNode = isLiteralImportTypeNode;
    function isPrologueDirective(node) {
        return node.kind === 226 /* ExpressionStatement */
            && node.expression.kind === 10 /* StringLiteral */;
    }
    ts.isPrologueDirective = isPrologueDirective;
    function isCustomPrologue(node) {
        return !!(getEmitFlags(node) & 1048576 /* CustomPrologue */);
    }
    ts.isCustomPrologue = isCustomPrologue;
    function isHoistedFunction(node) {
        return isCustomPrologue(node)
            && ts.isFunctionDeclaration(node);
    }
    ts.isHoistedFunction = isHoistedFunction;
    function isHoistedVariable(node) {
        return ts.isIdentifier(node.name)
            && !node.initializer;
    }
    function isHoistedVariableStatement(node) {
        return isCustomPrologue(node)
            && ts.isVariableStatement(node)
            && ts.every(node.declarationList.declarations, isHoistedVariable);
    }
    ts.isHoistedVariableStatement = isHoistedVariableStatement;
    function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
        return node.kind !== 11 /* JsxText */ ? ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined;
    }
    ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
    function getJSDocCommentRanges(node, text) {
        var commentRanges = (node.kind === 156 /* Parameter */ ||
            node.kind === 155 /* TypeParameter */ ||
            node.kind === 201 /* FunctionExpression */ ||
            node.kind === 202 /* ArrowFunction */ ||
            node.kind === 200 /* ParenthesizedExpression */) ?
            ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
            ts.getLeadingCommentRanges(text, node.pos);
        // True if the comment starts with '/**' but not if it is '/**/'
        return ts.filter(commentRanges, function (comment) {
            return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
        });
    }
    ts.getJSDocCommentRanges = getJSDocCommentRanges;
    ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*<reference\s+types\s*=\s*)('|")(.+?)\2.*?\/>/;
    ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*<amd-dependency\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    var defaultLibReferenceRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/;
    function isPartOfTypeNode(node) {
        if (168 /* FirstTypeNode */ <= node.kind && node.kind <= 188 /* LastTypeNode */) {
            return true;
        }
        switch (node.kind) {
            case 125 /* AnyKeyword */:
            case 148 /* UnknownKeyword */:
            case 140 /* NumberKeyword */:
            case 151 /* BigIntKeyword */:
            case 143 /* StringKeyword */:
            case 128 /* BooleanKeyword */:
            case 144 /* SymbolKeyword */:
            case 141 /* ObjectKeyword */:
            case 146 /* UndefinedKeyword */:
            case 137 /* NeverKeyword */:
                return true;
            case 110 /* VoidKeyword */:
                return node.parent.kind !== 205 /* VoidExpression */;
            case 216 /* ExpressionWithTypeArguments */:
                return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
            case 155 /* TypeParameter */:
                return node.parent.kind === 186 /* MappedType */ || node.parent.kind === 181 /* InferType */;
            // Identifiers and qualified names may be type nodes, depending on their context. Climb
            // above them to find the lowest container
            case 75 /* Identifier */:
                // If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
                if (node.parent.kind === 153 /* QualifiedName */ && node.parent.right === node) {
                    node = node.parent;
                }
                else if (node.parent.kind === 194 /* PropertyAccessExpression */ && node.parent.name === node) {
                    node = node.parent;
                }
                // At this point, node is either a qualified name or an identifier
                ts.Debug.assert(node.kind === 75 /* Identifier */ || node.kind === 153 /* QualifiedName */ || node.kind === 194 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'.");
            // falls through
            case 153 /* QualifiedName */:
            case 194 /* PropertyAccessExpression */:
            case 104 /* ThisKeyword */: {
                var parent = node.parent;
                if (parent.kind === 172 /* TypeQuery */) {
                    return false;
                }
                if (parent.kind === 188 /* ImportType */) {
                    return !parent.isTypeOf;
                }
                // Do not recursively call isPartOfTypeNode on the parent. In the example:
                //
                //     let a: A.B.C;
                //
                // Calling isPartOfTypeNode would consider the qualified name A.B a type node.
                // Only C and A.B.C are type nodes.
                if (168 /* FirstTypeNode */ <= parent.kind && parent.kind <= 188 /* LastTypeNode */) {
                    return true;
                }
                switch (parent.kind) {
                    case 216 /* ExpressionWithTypeArguments */:
                        return !isExpressionWithTypeArgumentsInClassExtendsClause(parent);
                    case 155 /* TypeParameter */:
                        return node === parent.constraint;
                    case 321 /* JSDocTemplateTag */:
                        return node === parent.constraint;
                    case 159 /* PropertyDeclaration */:
                    case 158 /* PropertySignature */:
                    case 156 /* Parameter */:
                    case 242 /* VariableDeclaration */:
                        return node === parent.type;
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                    case 162 /* Constructor */:
                    case 161 /* MethodDeclaration */:
                    case 160 /* MethodSignature */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        return node === parent.type;
                    case 165 /* CallSignature */:
                    case 166 /* ConstructSignature */:
                    case 167 /* IndexSignature */:
                        return node === parent.type;
                    case 199 /* TypeAssertionExpression */:
                        return node === parent.type;
                    case 196 /* CallExpression */:
                    case 197 /* NewExpression */:
                        return ts.contains(parent.typeArguments, node);
                    case 198 /* TaggedTemplateExpression */:
                        // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
                        return false;
                }
            }
        }
        return false;
    }
    ts.isPartOfTypeNode = isPartOfTypeNode;
    function isChildOfNodeWithKind(node, kind) {
        while (node) {
            if (node.kind === kind) {
                return true;
            }
            node = node.parent;
        }
        return false;
    }
    ts.isChildOfNodeWithKind = isChildOfNodeWithKind;
    // Warning: This has the same semantics as the forEach family of functions,
    //          in that traversal terminates in the event that 'visitor' supplies a truthy value.
    function forEachReturnStatement(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 235 /* ReturnStatement */:
                    return visitor(node);
                case 251 /* CaseBlock */:
                case 223 /* Block */:
                case 227 /* IfStatement */:
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                case 236 /* WithStatement */:
                case 237 /* SwitchStatement */:
                case 277 /* CaseClause */:
                case 278 /* DefaultClause */:
                case 238 /* LabeledStatement */:
                case 240 /* TryStatement */:
                case 280 /* CatchClause */:
                    return ts.forEachChild(node, traverse);
            }
        }
    }
    ts.forEachReturnStatement = forEachReturnStatement;
    function forEachYieldExpression(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 212 /* YieldExpression */:
                    visitor(node);
                    var operand = node.expression;
                    if (operand) {
                        traverse(operand);
                    }
                    return;
                case 248 /* EnumDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                    // These are not allowed inside a generator now, but eventually they may be allowed
                    // as local types. Regardless, skip them to avoid the work.
                    return;
                default:
                    if (ts.isFunctionLike(node)) {
                        if (node.name && node.name.kind === 154 /* ComputedPropertyName */) {
                            // Note that we will not include methods/accessors of a class because they would require
                            // first descending into the class. This is by design.
                            traverse(node.name.expression);
                            return;
                        }
                    }
                    else if (!isPartOfTypeNode(node)) {
                        // This is the general case, which should include mostly expressions and statements.
                        // Also includes NodeArrays.
                        ts.forEachChild(node, traverse);
                    }
            }
        }
    }
    ts.forEachYieldExpression = forEachYieldExpression;
    /**
     * Gets the most likely element type for a TypeNode. This is not an exhaustive test
     * as it assumes a rest argument can only be an array type (either T[], or Array<T>).
     *
     * @param node The type node.
     */
    function getRestParameterElementType(node) {
        if (node && node.kind === 174 /* ArrayType */) {
            return node.elementType;
        }
        else if (node && node.kind === 169 /* TypeReference */) {
            return ts.singleOrUndefined(node.typeArguments);
        }
        else {
            return undefined;
        }
    }
    ts.getRestParameterElementType = getRestParameterElementType;
    function getMembersOfDeclaration(node) {
        switch (node.kind) {
            case 246 /* InterfaceDeclaration */:
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
            case 173 /* TypeLiteral */:
                return node.members;
            case 193 /* ObjectLiteralExpression */:
                return node.properties;
        }
    }
    ts.getMembersOfDeclaration = getMembersOfDeclaration;
    function isVariableLike(node) {
        if (node) {
            switch (node.kind) {
                case 191 /* BindingElement */:
                case 284 /* EnumMember */:
                case 156 /* Parameter */:
                case 281 /* PropertyAssignment */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 282 /* ShorthandPropertyAssignment */:
                case 242 /* VariableDeclaration */:
                    return true;
            }
        }
        return false;
    }
    ts.isVariableLike = isVariableLike;
    function isVariableLikeOrAccessor(node) {
        return isVariableLike(node) || ts.isAccessor(node);
    }
    ts.isVariableLikeOrAccessor = isVariableLikeOrAccessor;
    function isVariableDeclarationInVariableStatement(node) {
        return node.parent.kind === 243 /* VariableDeclarationList */
            && node.parent.parent.kind === 225 /* VariableStatement */;
    }
    ts.isVariableDeclarationInVariableStatement = isVariableDeclarationInVariableStatement;
    function isValidESSymbolDeclaration(node) {
        return ts.isVariableDeclaration(node) ? isVarConst(node) && ts.isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) :
            ts.isPropertyDeclaration(node) ? hasReadonlyModifier(node) && hasStaticModifier(node) :
                ts.isPropertySignature(node) && hasReadonlyModifier(node);
    }
    ts.isValidESSymbolDeclaration = isValidESSymbolDeclaration;
    function introducesArgumentsExoticObject(node) {
        switch (node.kind) {
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
                return true;
        }
        return false;
    }
    ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject;
    function unwrapInnermostStatementOfLabel(node, beforeUnwrapLabelCallback) {
        while (true) {
            if (beforeUnwrapLabelCallback) {
                beforeUnwrapLabelCallback(node);
            }
            if (node.statement.kind !== 238 /* LabeledStatement */) {
                return node.statement;
            }
            node = node.statement;
        }
    }
    ts.unwrapInnermostStatementOfLabel = unwrapInnermostStatementOfLabel;
    function isFunctionBlock(node) {
        return node && node.kind === 223 /* Block */ && ts.isFunctionLike(node.parent);
    }
    ts.isFunctionBlock = isFunctionBlock;
    function isObjectLiteralMethod(node) {
        return node && node.kind === 161 /* MethodDeclaration */ && node.parent.kind === 193 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralMethod = isObjectLiteralMethod;
    function isObjectLiteralOrClassExpressionMethod(node) {
        return node.kind === 161 /* MethodDeclaration */ &&
            (node.parent.kind === 193 /* ObjectLiteralExpression */ ||
                node.parent.kind === 214 /* ClassExpression */);
    }
    ts.isObjectLiteralOrClassExpressionMethod = isObjectLiteralOrClassExpressionMethod;
    function isIdentifierTypePredicate(predicate) {
        return predicate && predicate.kind === 1 /* Identifier */;
    }
    ts.isIdentifierTypePredicate = isIdentifierTypePredicate;
    function isThisTypePredicate(predicate) {
        return predicate && predicate.kind === 0 /* This */;
    }
    ts.isThisTypePredicate = isThisTypePredicate;
    function getPropertyAssignment(objectLiteral, key, key2) {
        return objectLiteral.properties.filter(function (property) {
            if (property.kind === 281 /* PropertyAssignment */) {
                var propName = getTextOfPropertyName(property.name);
                return key === propName || (!!key2 && key2 === propName);
            }
            return false;
        });
    }
    ts.getPropertyAssignment = getPropertyAssignment;
    function getTsConfigObjectLiteralExpression(tsConfigSourceFile) {
        if (tsConfigSourceFile && tsConfigSourceFile.statements.length) {
            var expression = tsConfigSourceFile.statements[0].expression;
            return ts.tryCast(expression, ts.isObjectLiteralExpression);
        }
    }
    ts.getTsConfigObjectLiteralExpression = getTsConfigObjectLiteralExpression;
    function getTsConfigPropArrayElementValue(tsConfigSourceFile, propKey, elementValue) {
        return ts.firstDefined(getTsConfigPropArray(tsConfigSourceFile, propKey), function (property) {
            return ts.isArrayLiteralExpression(property.initializer) ?
                ts.find(property.initializer.elements, function (element) { return ts.isStringLiteral(element) && element.text === elementValue; }) :
                undefined;
        });
    }
    ts.getTsConfigPropArrayElementValue = getTsConfigPropArrayElementValue;
    function getTsConfigPropArray(tsConfigSourceFile, propKey) {
        var jsonObjectLiteral = getTsConfigObjectLiteralExpression(tsConfigSourceFile);
        return jsonObjectLiteral ? getPropertyAssignment(jsonObjectLiteral, propKey) : ts.emptyArray;
    }
    ts.getTsConfigPropArray = getTsConfigPropArray;
    function getContainingFunction(node) {
        return findAncestor(node.parent, ts.isFunctionLike);
    }
    ts.getContainingFunction = getContainingFunction;
    function getContainingFunctionDeclaration(node) {
        return findAncestor(node.parent, ts.isFunctionLikeDeclaration);
    }
    ts.getContainingFunctionDeclaration = getContainingFunctionDeclaration;
    function getContainingClass(node) {
        return findAncestor(node.parent, ts.isClassLike);
    }
    ts.getContainingClass = getContainingClass;
    function getThisContainer(node, includeArrowFunctions) {
        ts.Debug.assert(node.kind !== 290 /* SourceFile */);
        while (true) {
            node = node.parent;
            if (!node) {
                return ts.Debug.fail(); // If we never pass in a SourceFile, this should be unreachable, since we'll stop when we reach that.
            }
            switch (node.kind) {
                case 154 /* ComputedPropertyName */:
                    // If the grandparent node is an object literal (as opposed to a class),
                    // then the computed property is not a 'this' container.
                    // A computed property name in a class needs to be a this container
                    // so that we can error on it.
                    if (ts.isClassLike(node.parent.parent)) {
                        return node;
                    }
                    // If this is a computed property, then the parent should not
                    // make it a this container. The parent might be a property
                    // in an object literal, like a method or accessor. But in order for
                    // such a parent to be a this container, the reference must be in
                    // the *body* of the container.
                    node = node.parent;
                    break;
                case 157 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 156 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
                        // If the decorator's parent is a Parameter, we resolve the this container from
                        // the grandparent class declaration.
                        node = node.parent.parent;
                    }
                    else if (ts.isClassElement(node.parent)) {
                        // If the decorator's parent is a class element, we resolve the 'this' container
                        // from the parent class declaration.
                        node = node.parent;
                    }
                    break;
                case 202 /* ArrowFunction */:
                    if (!includeArrowFunctions) {
                        continue;
                    }
                // falls through
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 249 /* ModuleDeclaration */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 162 /* Constructor */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 167 /* IndexSignature */:
                case 248 /* EnumDeclaration */:
                case 290 /* SourceFile */:
                    return node;
            }
        }
    }
    ts.getThisContainer = getThisContainer;
    function getNewTargetContainer(node) {
        var container = getThisContainer(node, /*includeArrowFunctions*/ false);
        if (container) {
            switch (container.kind) {
                case 162 /* Constructor */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                    return container;
            }
        }
        return undefined;
    }
    ts.getNewTargetContainer = getNewTargetContainer;
    /**
     * Given an super call/property node, returns the closest node where
     * - a super call/property access is legal in the node and not legal in the parent node the node.
     *   i.e. super call is legal in constructor but not legal in the class body.
     * - the container is an arrow function (so caller might need to call getSuperContainer again in case it needs to climb higher)
     * - a super call/property is definitely illegal in the container (but might be legal in some subnode)
     *   i.e. super property access is illegal in function declaration but can be legal in the statement list
     */
    function getSuperContainer(node, stopOnFunctions) {
        while (true) {
            node = node.parent;
            if (!node) {
                return node;
            }
            switch (node.kind) {
                case 154 /* ComputedPropertyName */:
                    node = node.parent;
                    break;
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    if (!stopOnFunctions) {
                        continue;
                    }
                // falls through
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 162 /* Constructor */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return node;
                case 157 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 156 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
                        // If the decorator's parent is a Parameter, we resolve the this container from
                        // the grandparent class declaration.
                        node = node.parent.parent;
                    }
                    else if (ts.isClassElement(node.parent)) {
                        // If the decorator's parent is a class element, we resolve the 'this' container
                        // from the parent class declaration.
                        node = node.parent;
                    }
                    break;
            }
        }
    }
    ts.getSuperContainer = getSuperContainer;
    function getImmediatelyInvokedFunctionExpression(func) {
        if (func.kind === 201 /* FunctionExpression */ || func.kind === 202 /* ArrowFunction */) {
            var prev = func;
            var parent = func.parent;
            while (parent.kind === 200 /* ParenthesizedExpression */) {
                prev = parent;
                parent = parent.parent;
            }
            if (parent.kind === 196 /* CallExpression */ && parent.expression === prev) {
                return parent;
            }
        }
    }
    ts.getImmediatelyInvokedFunctionExpression = getImmediatelyInvokedFunctionExpression;
    function isSuperOrSuperProperty(node) {
        return node.kind === 102 /* SuperKeyword */
            || isSuperProperty(node);
    }
    ts.isSuperOrSuperProperty = isSuperOrSuperProperty;
    /**
     * Determines whether a node is a property or element access expression for `super`.
     */
    function isSuperProperty(node) {
        var kind = node.kind;
        return (kind === 194 /* PropertyAccessExpression */ || kind === 195 /* ElementAccessExpression */)
            && node.expression.kind === 102 /* SuperKeyword */;
    }
    ts.isSuperProperty = isSuperProperty;
    /**
     * Determines whether a node is a property or element access expression for `this`.
     */
    function isThisProperty(node) {
        var kind = node.kind;
        return (kind === 194 /* PropertyAccessExpression */ || kind === 195 /* ElementAccessExpression */)
            && node.expression.kind === 104 /* ThisKeyword */;
    }
    ts.isThisProperty = isThisProperty;
    function getEntityNameFromTypeNode(node) {
        switch (node.kind) {
            case 169 /* TypeReference */:
                return node.typeName;
            case 216 /* ExpressionWithTypeArguments */:
                return isEntityNameExpression(node.expression)
                    ? node.expression
                    : undefined;
            case 75 /* Identifier */:
            case 153 /* QualifiedName */:
                return node;
        }
        return undefined;
    }
    ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode;
    function getInvokedExpression(node) {
        switch (node.kind) {
            case 198 /* TaggedTemplateExpression */:
                return node.tag;
            case 268 /* JsxOpeningElement */:
            case 267 /* JsxSelfClosingElement */:
                return node.tagName;
            default:
                return node.expression;
        }
    }
    ts.getInvokedExpression = getInvokedExpression;
    function nodeCanBeDecorated(node, parent, grandparent) {
        // private names cannot be used with decorators yet
        if (ts.isNamedDeclaration(node) && ts.isPrivateIdentifier(node.name)) {
            return false;
        }
        switch (node.kind) {
            case 245 /* ClassDeclaration */:
                // classes are valid targets
                return true;
            case 159 /* PropertyDeclaration */:
                // property declarations are valid if their parent is a class declaration.
                return parent.kind === 245 /* ClassDeclaration */;
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 161 /* MethodDeclaration */:
                // if this method has a body and its parent is a class declaration, this is a valid target.
                return node.body !== undefined
                    && parent.kind === 245 /* ClassDeclaration */;
            case 156 /* Parameter */:
                // if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
                return parent.body !== undefined
                    && (parent.kind === 162 /* Constructor */
                        || parent.kind === 161 /* MethodDeclaration */
                        || parent.kind === 164 /* SetAccessor */)
                    && grandparent.kind === 245 /* ClassDeclaration */;
        }
        return false;
    }
    ts.nodeCanBeDecorated = nodeCanBeDecorated;
    function nodeIsDecorated(node, parent, grandparent) {
        return node.decorators !== undefined
            && nodeCanBeDecorated(node, parent, grandparent); // TODO: GH#18217
    }
    ts.nodeIsDecorated = nodeIsDecorated;
    function nodeOrChildIsDecorated(node, parent, grandparent) {
        return nodeIsDecorated(node, parent, grandparent) || childIsDecorated(node, parent); // TODO: GH#18217
    }
    ts.nodeOrChildIsDecorated = nodeOrChildIsDecorated;
    function childIsDecorated(node, parent) {
        switch (node.kind) {
            case 245 /* ClassDeclaration */:
                return ts.some(node.members, function (m) { return nodeOrChildIsDecorated(m, node, parent); }); // TODO: GH#18217
            case 161 /* MethodDeclaration */:
            case 164 /* SetAccessor */:
                return ts.some(node.parameters, function (p) { return nodeIsDecorated(p, node, parent); }); // TODO: GH#18217
            default:
                return false;
        }
    }
    ts.childIsDecorated = childIsDecorated;
    function isJSXTagName(node) {
        var parent = node.parent;
        if (parent.kind === 268 /* JsxOpeningElement */ ||
            parent.kind === 267 /* JsxSelfClosingElement */ ||
            parent.kind === 269 /* JsxClosingElement */) {
            return parent.tagName === node;
        }
        return false;
    }
    ts.isJSXTagName = isJSXTagName;
    function isExpressionNode(node) {
        switch (node.kind) {
            case 102 /* SuperKeyword */:
            case 100 /* NullKeyword */:
            case 106 /* TrueKeyword */:
            case 91 /* FalseKeyword */:
            case 13 /* RegularExpressionLiteral */:
            case 192 /* ArrayLiteralExpression */:
            case 193 /* ObjectLiteralExpression */:
            case 194 /* PropertyAccessExpression */:
            case 195 /* ElementAccessExpression */:
            case 196 /* CallExpression */:
            case 197 /* NewExpression */:
            case 198 /* TaggedTemplateExpression */:
            case 217 /* AsExpression */:
            case 199 /* TypeAssertionExpression */:
            case 218 /* NonNullExpression */:
            case 200 /* ParenthesizedExpression */:
            case 201 /* FunctionExpression */:
            case 214 /* ClassExpression */:
            case 202 /* ArrowFunction */:
            case 205 /* VoidExpression */:
            case 203 /* DeleteExpression */:
            case 204 /* TypeOfExpression */:
            case 207 /* PrefixUnaryExpression */:
            case 208 /* PostfixUnaryExpression */:
            case 209 /* BinaryExpression */:
            case 210 /* ConditionalExpression */:
            case 213 /* SpreadElement */:
            case 211 /* TemplateExpression */:
            case 215 /* OmittedExpression */:
            case 266 /* JsxElement */:
            case 267 /* JsxSelfClosingElement */:
            case 270 /* JsxFragment */:
            case 212 /* YieldExpression */:
            case 206 /* AwaitExpression */:
            case 219 /* MetaProperty */:
                return true;
            case 153 /* QualifiedName */:
                while (node.parent.kind === 153 /* QualifiedName */) {
                    node = node.parent;
                }
                return node.parent.kind === 172 /* TypeQuery */ || isJSXTagName(node);
            case 75 /* Identifier */:
                if (node.parent.kind === 172 /* TypeQuery */ || isJSXTagName(node)) {
                    return true;
                }
            // falls through
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 104 /* ThisKeyword */:
                return isInExpressionContext(node);
            default:
                return false;
        }
    }
    ts.isExpressionNode = isExpressionNode;
    function isInExpressionContext(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 242 /* VariableDeclaration */:
            case 156 /* Parameter */:
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 284 /* EnumMember */:
            case 281 /* PropertyAssignment */:
            case 191 /* BindingElement */:
                return parent.initializer === node;
            case 226 /* ExpressionStatement */:
            case 227 /* IfStatement */:
            case 228 /* DoStatement */:
            case 229 /* WhileStatement */:
            case 235 /* ReturnStatement */:
            case 236 /* WithStatement */:
            case 237 /* SwitchStatement */:
            case 277 /* CaseClause */:
            case 239 /* ThrowStatement */:
                return parent.expression === node;
            case 230 /* ForStatement */:
                var forStatement = parent;
                return (forStatement.initializer === node && forStatement.initializer.kind !== 243 /* VariableDeclarationList */) ||
                    forStatement.condition === node ||
                    forStatement.incrementor === node;
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
                var forInStatement = parent;
                return (forInStatement.initializer === node && forInStatement.initializer.kind !== 243 /* VariableDeclarationList */) ||
                    forInStatement.expression === node;
            case 199 /* TypeAssertionExpression */:
            case 217 /* AsExpression */:
                return node === parent.expression;
            case 221 /* TemplateSpan */:
                return node === parent.expression;
            case 154 /* ComputedPropertyName */:
                return node === parent.expression;
            case 157 /* Decorator */:
            case 276 /* JsxExpression */:
            case 275 /* JsxSpreadAttribute */:
            case 283 /* SpreadAssignment */:
                return true;
            case 216 /* ExpressionWithTypeArguments */:
                return parent.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
            case 282 /* ShorthandPropertyAssignment */:
                return parent.objectAssignmentInitializer === node;
            default:
                return isExpressionNode(parent);
        }
    }
    ts.isInExpressionContext = isInExpressionContext;
    function isPartOfTypeQuery(node) {
        while (node.kind === 153 /* QualifiedName */ || node.kind === 75 /* Identifier */) {
            node = node.parent;
        }
        return node.kind === 172 /* TypeQuery */;
    }
    ts.isPartOfTypeQuery = isPartOfTypeQuery;
    function isExternalModuleImportEqualsDeclaration(node) {
        return node.kind === 253 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 265 /* ExternalModuleReference */;
    }
    ts.isExternalModuleImportEqualsDeclaration = isExternalModuleImportEqualsDeclaration;
    function getExternalModuleImportEqualsDeclarationExpression(node) {
        ts.Debug.assert(isExternalModuleImportEqualsDeclaration(node));
        return node.moduleReference.expression;
    }
    ts.getExternalModuleImportEqualsDeclarationExpression = getExternalModuleImportEqualsDeclarationExpression;
    function isInternalModuleImportEqualsDeclaration(node) {
        return node.kind === 253 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 265 /* ExternalModuleReference */;
    }
    ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
    function isSourceFileJS(file) {
        return isInJSFile(file);
    }
    ts.isSourceFileJS = isSourceFileJS;
    function isSourceFileNotJS(file) {
        return !isInJSFile(file);
    }
    ts.isSourceFileNotJS = isSourceFileNotJS;
    function isInJSFile(node) {
        return !!node && !!(node.flags & 131072 /* JavaScriptFile */);
    }
    ts.isInJSFile = isInJSFile;
    function isInJsonFile(node) {
        return !!node && !!(node.flags & 33554432 /* JsonFile */);
    }
    ts.isInJsonFile = isInJsonFile;
    function isSourceFileNotJson(file) {
        return !isJsonSourceFile(file);
    }
    ts.isSourceFileNotJson = isSourceFileNotJson;
    function isInJSDoc(node) {
        return !!node && !!(node.flags & 4194304 /* JSDoc */);
    }
    ts.isInJSDoc = isInJSDoc;
    function isJSDocIndexSignature(node) {
        return ts.isTypeReferenceNode(node) &&
            ts.isIdentifier(node.typeName) &&
            node.typeName.escapedText === "Object" &&
            node.typeArguments && node.typeArguments.length === 2 &&
            (node.typeArguments[0].kind === 143 /* StringKeyword */ || node.typeArguments[0].kind === 140 /* NumberKeyword */);
    }
    ts.isJSDocIndexSignature = isJSDocIndexSignature;
    function isRequireCall(callExpression, requireStringLiteralLikeArgument) {
        if (callExpression.kind !== 196 /* CallExpression */) {
            return false;
        }
        var _a = callExpression, expression = _a.expression, args = _a.arguments;
        if (expression.kind !== 75 /* Identifier */ || expression.escapedText !== "require") {
            return false;
        }
        if (args.length !== 1) {
            return false;
        }
        var arg = args[0];
        return !requireStringLiteralLikeArgument || ts.isStringLiteralLike(arg);
    }
    ts.isRequireCall = isRequireCall;
    function isRequireVariableDeclaration(node, requireStringLiteralLikeArgument) {
        return ts.isVariableDeclaration(node) && !!node.initializer && isRequireCall(node.initializer, requireStringLiteralLikeArgument);
    }
    ts.isRequireVariableDeclaration = isRequireVariableDeclaration;
    function isRequireVariableDeclarationStatement(node, requireStringLiteralLikeArgument) {
        if (requireStringLiteralLikeArgument === void 0) { requireStringLiteralLikeArgument = true; }
        return ts.isVariableStatement(node) && ts.every(node.declarationList.declarations, function (decl) { return isRequireVariableDeclaration(decl, requireStringLiteralLikeArgument); });
    }
    ts.isRequireVariableDeclarationStatement = isRequireVariableDeclarationStatement;
    function isSingleOrDoubleQuote(charCode) {
        return charCode === 39 /* singleQuote */ || charCode === 34 /* doubleQuote */;
    }
    ts.isSingleOrDoubleQuote = isSingleOrDoubleQuote;
    function isStringDoubleQuoted(str, sourceFile) {
        return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === 34 /* doubleQuote */;
    }
    ts.isStringDoubleQuoted = isStringDoubleQuoted;
    function getDeclarationOfExpando(node) {
        if (!node.parent) {
            return undefined;
        }
        var name;
        var decl;
        if (ts.isVariableDeclaration(node.parent) && node.parent.initializer === node) {
            if (!isInJSFile(node) && !isVarConst(node.parent)) {
                return undefined;
            }
            name = node.parent.name;
            decl = node.parent;
        }
        else if (ts.isBinaryExpression(node.parent)) {
            var parentNode = node.parent;
            var parentNodeOperator = node.parent.operatorToken.kind;
            if (parentNodeOperator === 62 /* EqualsToken */ && parentNode.right === node) {
                name = parentNode.left;
                decl = name;
            }
            else if (parentNodeOperator === 56 /* BarBarToken */ || parentNodeOperator === 60 /* QuestionQuestionToken */) {
                if (ts.isVariableDeclaration(parentNode.parent) && parentNode.parent.initializer === parentNode) {
                    name = parentNode.parent.name;
                    decl = parentNode.parent;
                }
                else if (ts.isBinaryExpression(parentNode.parent) && parentNode.parent.operatorToken.kind === 62 /* EqualsToken */ && parentNode.parent.right === parentNode) {
                    name = parentNode.parent.left;
                    decl = name;
                }
                if (!name || !isBindableStaticNameExpression(name) || !isSameEntityName(name, parentNode.left)) {
                    return undefined;
                }
            }
        }
        if (!name || !getExpandoInitializer(node, isPrototypeAccess(name))) {
            return undefined;
        }
        return decl;
    }
    ts.getDeclarationOfExpando = getDeclarationOfExpando;
    function isAssignmentDeclaration(decl) {
        return ts.isBinaryExpression(decl) || isAccessExpression(decl) || ts.isIdentifier(decl) || ts.isCallExpression(decl);
    }
    ts.isAssignmentDeclaration = isAssignmentDeclaration;
    /** Get the initializer, taking into account defaulted Javascript initializers */
    function getEffectiveInitializer(node) {
        if (isInJSFile(node) && node.initializer &&
            ts.isBinaryExpression(node.initializer) &&
            (node.initializer.operatorToken.kind === 56 /* BarBarToken */ || node.initializer.operatorToken.kind === 60 /* QuestionQuestionToken */) &&
            node.name && isEntityNameExpression(node.name) && isSameEntityName(node.name, node.initializer.left)) {
            return node.initializer.right;
        }
        return node.initializer;
    }
    ts.getEffectiveInitializer = getEffectiveInitializer;
    /** Get the declaration initializer when it is container-like (See getExpandoInitializer). */
    function getDeclaredExpandoInitializer(node) {
        var init = getEffectiveInitializer(node);
        return init && getExpandoInitializer(init, isPrototypeAccess(node.name));
    }
    ts.getDeclaredExpandoInitializer = getDeclaredExpandoInitializer;
    function hasExpandoValueProperty(node, isPrototypeAssignment) {
        return ts.forEach(node.properties, function (p) {
            return ts.isPropertyAssignment(p) &&
                ts.isIdentifier(p.name) &&
                p.name.escapedText === "value" &&
                p.initializer &&
                getExpandoInitializer(p.initializer, isPrototypeAssignment);
        });
    }
    /**
     * Get the assignment 'initializer' -- the righthand side-- when the initializer is container-like (See getExpandoInitializer).
     * We treat the right hand side of assignments with container-like initalizers as declarations.
     */
    function getAssignedExpandoInitializer(node) {
        if (node && node.parent && ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 62 /* EqualsToken */) {
            var isPrototypeAssignment = isPrototypeAccess(node.parent.left);
            return getExpandoInitializer(node.parent.right, isPrototypeAssignment) ||
                getDefaultedExpandoInitializer(node.parent.left, node.parent.right, isPrototypeAssignment);
        }
        if (node && ts.isCallExpression(node) && isBindableObjectDefinePropertyCall(node)) {
            var result = hasExpandoValueProperty(node.arguments[2], node.arguments[1].text === "prototype");
            if (result) {
                return result;
            }
        }
    }
    ts.getAssignedExpandoInitializer = getAssignedExpandoInitializer;
    /**
     * Recognized expando initializers are:
     * 1. (function() {})() -- IIFEs
     * 2. function() { } -- Function expressions
     * 3. class { } -- Class expressions
     * 4. {} -- Empty object literals
     * 5. { ... } -- Non-empty object literals, when used to initialize a prototype, like `C.prototype = { m() { } }`
     *
     * This function returns the provided initializer, or undefined if it is not valid.
     */
    function getExpandoInitializer(initializer, isPrototypeAssignment) {
        if (ts.isCallExpression(initializer)) {
            var e = skipParentheses(initializer.expression);
            return e.kind === 201 /* FunctionExpression */ || e.kind === 202 /* ArrowFunction */ ? initializer : undefined;
        }
        if (initializer.kind === 201 /* FunctionExpression */ ||
            initializer.kind === 214 /* ClassExpression */ ||
            initializer.kind === 202 /* ArrowFunction */) {
            return initializer;
        }
        if (ts.isObjectLiteralExpression(initializer) && (initializer.properties.length === 0 || isPrototypeAssignment)) {
            return initializer;
        }
    }
    ts.getExpandoInitializer = getExpandoInitializer;
    /**
     * A defaulted expando initializer matches the pattern
     * `Lhs = Lhs || ExpandoInitializer`
     * or `var Lhs = Lhs || ExpandoInitializer`
     *
     * The second Lhs is required to be the same as the first except that it may be prefixed with
     * 'window.', 'global.' or 'self.' The second Lhs is otherwise ignored by the binder and checker.
     */
    function getDefaultedExpandoInitializer(name, initializer, isPrototypeAssignment) {
        var e = ts.isBinaryExpression(initializer)
            && (initializer.operatorToken.kind === 56 /* BarBarToken */ || initializer.operatorToken.kind === 60 /* QuestionQuestionToken */)
            && getExpandoInitializer(initializer.right, isPrototypeAssignment);
        if (e && isSameEntityName(name, initializer.left)) {
            return e;
        }
    }
    function isDefaultedExpandoInitializer(node) {
        var name = ts.isVariableDeclaration(node.parent) ? node.parent.name :
            ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 62 /* EqualsToken */ ? node.parent.left :
                undefined;
        return name && getExpandoInitializer(node.right, isPrototypeAccess(name)) && isEntityNameExpression(name) && isSameEntityName(name, node.left);
    }
    ts.isDefaultedExpandoInitializer = isDefaultedExpandoInitializer;
    /** Given an expando initializer, return its declaration name, or the left-hand side of the assignment if it's part of an assignment declaration. */
    function getNameOfExpando(node) {
        if (ts.isBinaryExpression(node.parent)) {
            var parent = ((node.parent.operatorToken.kind === 56 /* BarBarToken */ || node.parent.operatorToken.kind === 60 /* QuestionQuestionToken */) && ts.isBinaryExpression(node.parent.parent)) ? node.parent.parent : node.parent;
            if (parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isIdentifier(parent.left)) {
                return parent.left;
            }
        }
        else if (ts.isVariableDeclaration(node.parent)) {
            return node.parent.name;
        }
    }
    ts.getNameOfExpando = getNameOfExpando;
    /**
     * Is the 'declared' name the same as the one in the initializer?
     * @return true for identical entity names, as well as ones where the initializer is prefixed with
     * 'window', 'self' or 'global'. For example:
     *
     * var my = my || {}
     * var min = window.min || {}
     * my.app = self.my.app || class { }
     */
    function isSameEntityName(name, initializer) {
        if (isPropertyNameLiteral(name) && isPropertyNameLiteral(initializer)) {
            return getTextOfIdentifierOrLiteral(name) === getTextOfIdentifierOrLiteral(name);
        }
        if (ts.isIdentifier(name) && isLiteralLikeAccess(initializer) &&
            (initializer.expression.kind === 104 /* ThisKeyword */ ||
                ts.isIdentifier(initializer.expression) &&
                    (initializer.expression.escapedText === "window" ||
                        initializer.expression.escapedText === "self" ||
                        initializer.expression.escapedText === "global"))) {
            var nameOrArgument = getNameOrArgument(initializer);
            if (ts.isPrivateIdentifier(nameOrArgument)) {
                ts.Debug.fail("Unexpected PrivateIdentifier in name expression with literal-like access.");
            }
            return isSameEntityName(name, nameOrArgument);
        }
        if (isLiteralLikeAccess(name) && isLiteralLikeAccess(initializer)) {
            return getElementOrPropertyAccessName(name) === getElementOrPropertyAccessName(initializer)
                && isSameEntityName(name.expression, initializer.expression);
        }
        return false;
    }
    function getRightMostAssignedExpression(node) {
        while (isAssignmentExpression(node, /*excludeCompoundAssignments*/ true)) {
            node = node.right;
        }
        return node;
    }
    ts.getRightMostAssignedExpression = getRightMostAssignedExpression;
    function isExportsIdentifier(node) {
        return ts.isIdentifier(node) && node.escapedText === "exports";
    }
    ts.isExportsIdentifier = isExportsIdentifier;
    function isModuleIdentifier(node) {
        return ts.isIdentifier(node) && node.escapedText === "module";
    }
    ts.isModuleIdentifier = isModuleIdentifier;
    function isModuleExportsAccessExpression(node) {
        return (ts.isPropertyAccessExpression(node) || isLiteralLikeElementAccess(node))
            && isModuleIdentifier(node.expression)
            && getElementOrPropertyAccessName(node) === "exports";
    }
    ts.isModuleExportsAccessExpression = isModuleExportsAccessExpression;
    /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
    /// assignments we treat as special in the binder
    function getAssignmentDeclarationKind(expr) {
        var special = getAssignmentDeclarationKindWorker(expr);
        return special === 5 /* Property */ || isInJSFile(expr) ? special : 0 /* None */;
    }
    ts.getAssignmentDeclarationKind = getAssignmentDeclarationKind;
    function isBindableObjectDefinePropertyCall(expr) {
        return ts.length(expr.arguments) === 3 &&
            ts.isPropertyAccessExpression(expr.expression) &&
            ts.isIdentifier(expr.expression.expression) &&
            ts.idText(expr.expression.expression) === "Object" &&
            ts.idText(expr.expression.name) === "defineProperty" &&
            isStringOrNumericLiteralLike(expr.arguments[1]) &&
            isBindableStaticNameExpression(expr.arguments[0], /*excludeThisKeyword*/ true);
    }
    ts.isBindableObjectDefinePropertyCall = isBindableObjectDefinePropertyCall;
    /** x.y OR x[0] */
    function isLiteralLikeAccess(node) {
        return ts.isPropertyAccessExpression(node) || isLiteralLikeElementAccess(node);
    }
    ts.isLiteralLikeAccess = isLiteralLikeAccess;
    /** x[0] OR x['a'] OR x[Symbol.y] */
    function isLiteralLikeElementAccess(node) {
        return ts.isElementAccessExpression(node) && (isStringOrNumericLiteralLike(node.argumentExpression) ||
            isWellKnownSymbolSyntactically(node.argumentExpression));
    }
    ts.isLiteralLikeElementAccess = isLiteralLikeElementAccess;
    /** Any series of property and element accesses. */
    function isBindableStaticAccessExpression(node, excludeThisKeyword) {
        return ts.isPropertyAccessExpression(node) && (!excludeThisKeyword && node.expression.kind === 104 /* ThisKeyword */ || ts.isIdentifier(node.name) && isBindableStaticNameExpression(node.expression, /*excludeThisKeyword*/ true))
            || isBindableStaticElementAccessExpression(node, excludeThisKeyword);
    }
    ts.isBindableStaticAccessExpression = isBindableStaticAccessExpression;
    /** Any series of property and element accesses, ending in a literal element access */
    function isBindableStaticElementAccessExpression(node, excludeThisKeyword) {
        return isLiteralLikeElementAccess(node)
            && ((!excludeThisKeyword && node.expression.kind === 104 /* ThisKeyword */) ||
                isEntityNameExpression(node.expression) ||
                isBindableStaticAccessExpression(node.expression, /*excludeThisKeyword*/ true));
    }
    ts.isBindableStaticElementAccessExpression = isBindableStaticElementAccessExpression;
    function isBindableStaticNameExpression(node, excludeThisKeyword) {
        return isEntityNameExpression(node) || isBindableStaticAccessExpression(node, excludeThisKeyword);
    }
    ts.isBindableStaticNameExpression = isBindableStaticNameExpression;
    function getNameOrArgument(expr) {
        if (ts.isPropertyAccessExpression(expr)) {
            return expr.name;
        }
        return expr.argumentExpression;
    }
    ts.getNameOrArgument = getNameOrArgument;
    function getAssignmentDeclarationKindWorker(expr) {
        if (ts.isCallExpression(expr)) {
            if (!isBindableObjectDefinePropertyCall(expr)) {
                return 0 /* None */;
            }
            var entityName = expr.arguments[0];
            if (isExportsIdentifier(entityName) || isModuleExportsAccessExpression(entityName)) {
                return 8 /* ObjectDefinePropertyExports */;
            }
            if (isBindableStaticAccessExpression(entityName) && getElementOrPropertyAccessName(entityName) === "prototype") {
                return 9 /* ObjectDefinePrototypeProperty */;
            }
            return 7 /* ObjectDefinePropertyValue */;
        }
        if (expr.operatorToken.kind !== 62 /* EqualsToken */ || !isAccessExpression(expr.left)) {
            return 0 /* None */;
        }
        if (isBindableStaticNameExpression(expr.left.expression, /*excludeThisKeyword*/ true) && getElementOrPropertyAccessName(expr.left) === "prototype" && ts.isObjectLiteralExpression(getInitializerOfBinaryExpression(expr))) {
            // F.prototype = { ... }
            return 6 /* Prototype */;
        }
        return getAssignmentDeclarationPropertyAccessKind(expr.left);
    }
    /**
     * Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions
     * throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand)
     */
    /* @internal */
    function getElementOrPropertyAccessArgumentExpressionOrName(node) {
        if (ts.isPropertyAccessExpression(node)) {
            return node.name;
        }
        var arg = skipParentheses(node.argumentExpression);
        if (ts.isNumericLiteral(arg) || ts.isStringLiteralLike(arg)) {
            return arg;
        }
        return node;
    }
    ts.getElementOrPropertyAccessArgumentExpressionOrName = getElementOrPropertyAccessArgumentExpressionOrName;
    function getElementOrPropertyAccessName(node) {
        var name = getElementOrPropertyAccessArgumentExpressionOrName(node);
        if (name) {
            if (ts.isIdentifier(name)) {
                return name.escapedText;
            }
            if (ts.isStringLiteralLike(name) || ts.isNumericLiteral(name)) {
                return ts.escapeLeadingUnderscores(name.text);
            }
        }
        if (ts.isElementAccessExpression(node) && isWellKnownSymbolSyntactically(node.argumentExpression)) {
            return getPropertyNameForKnownSymbolName(ts.idText(node.argumentExpression.name));
        }
        return undefined;
    }
    ts.getElementOrPropertyAccessName = getElementOrPropertyAccessName;
    function getAssignmentDeclarationPropertyAccessKind(lhs) {
        if (lhs.expression.kind === 104 /* ThisKeyword */) {
            return 4 /* ThisProperty */;
        }
        else if (isModuleExportsAccessExpression(lhs)) {
            // module.exports = expr
            return 2 /* ModuleExports */;
        }
        else if (isBindableStaticNameExpression(lhs.expression, /*excludeThisKeyword*/ true)) {
            if (isPrototypeAccess(lhs.expression)) {
                // F.G....prototype.x = expr
                return 3 /* PrototypeProperty */;
            }
            var nextToLast = lhs;
            while (!ts.isIdentifier(nextToLast.expression)) {
                nextToLast = nextToLast.expression;
            }
            var id = nextToLast.expression;
            if ((id.escapedText === "exports" ||
                id.escapedText === "module" && getElementOrPropertyAccessName(nextToLast) === "exports") &&
                // ExportsProperty does not support binding with computed names
                isBindableStaticAccessExpression(lhs)) {
                // exports.name = expr OR module.exports.name = expr OR exports["name"] = expr ...
                return 1 /* ExportsProperty */;
            }
            if (isBindableStaticNameExpression(lhs, /*excludeThisKeyword*/ true) || (ts.isElementAccessExpression(lhs) && isDynamicName(lhs))) {
                // F.G...x = expr
                return 5 /* Property */;
            }
        }
        return 0 /* None */;
    }
    ts.getAssignmentDeclarationPropertyAccessKind = getAssignmentDeclarationPropertyAccessKind;
    function getInitializerOfBinaryExpression(expr) {
        while (ts.isBinaryExpression(expr.right)) {
            expr = expr.right;
        }
        return expr.right;
    }
    ts.getInitializerOfBinaryExpression = getInitializerOfBinaryExpression;
    function isPrototypePropertyAssignment(node) {
        return ts.isBinaryExpression(node) && getAssignmentDeclarationKind(node) === 3 /* PrototypeProperty */;
    }
    ts.isPrototypePropertyAssignment = isPrototypePropertyAssignment;
    function isSpecialPropertyDeclaration(expr) {
        return isInJSFile(expr) &&
            expr.parent && expr.parent.kind === 226 /* ExpressionStatement */ &&
            (!ts.isElementAccessExpression(expr) || isLiteralLikeElementAccess(expr)) &&
            !!ts.getJSDocTypeTag(expr.parent);
    }
    ts.isSpecialPropertyDeclaration = isSpecialPropertyDeclaration;
    function setValueDeclaration(symbol, node) {
        var valueDeclaration = symbol.valueDeclaration;
        if (!valueDeclaration ||
            !(node.flags & 8388608 /* Ambient */ && !(valueDeclaration.flags & 8388608 /* Ambient */)) &&
                (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
            (valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
            // other kinds of value declarations take precedence over modules and assignment declarations
            symbol.valueDeclaration = node;
        }
    }
    ts.setValueDeclaration = setValueDeclaration;
    function isFunctionSymbol(symbol) {
        if (!symbol || !symbol.valueDeclaration) {
            return false;
        }
        var decl = symbol.valueDeclaration;
        return decl.kind === 244 /* FunctionDeclaration */ || ts.isVariableDeclaration(decl) && decl.initializer && ts.isFunctionLike(decl.initializer);
    }
    ts.isFunctionSymbol = isFunctionSymbol;
    function importFromModuleSpecifier(node) {
        return tryGetImportFromModuleSpecifier(node) || ts.Debug.failBadSyntaxKind(node.parent);
    }
    ts.importFromModuleSpecifier = importFromModuleSpecifier;
    function tryGetImportFromModuleSpecifier(node) {
        switch (node.parent.kind) {
            case 254 /* ImportDeclaration */:
            case 260 /* ExportDeclaration */:
                return node.parent;
            case 265 /* ExternalModuleReference */:
                return node.parent.parent;
            case 196 /* CallExpression */:
                return isImportCall(node.parent) || isRequireCall(node.parent, /*checkArg*/ false) ? node.parent : undefined;
            case 187 /* LiteralType */:
                ts.Debug.assert(ts.isStringLiteral(node));
                return ts.tryCast(node.parent.parent, ts.isImportTypeNode);
            default:
                return undefined;
        }
    }
    ts.tryGetImportFromModuleSpecifier = tryGetImportFromModuleSpecifier;
    function getExternalModuleName(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
            case 260 /* ExportDeclaration */:
                return node.moduleSpecifier;
            case 253 /* ImportEqualsDeclaration */:
                return node.moduleReference.kind === 265 /* ExternalModuleReference */ ? node.moduleReference.expression : undefined;
            case 188 /* ImportType */:
                return isLiteralImportTypeNode(node) ? node.argument.literal : undefined;
            default:
                return ts.Debug.assertNever(node);
        }
    }
    ts.getExternalModuleName = getExternalModuleName;
    function getNamespaceDeclarationNode(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
                return node.importClause && ts.tryCast(node.importClause.namedBindings, ts.isNamespaceImport);
            case 253 /* ImportEqualsDeclaration */:
                return node;
            case 260 /* ExportDeclaration */:
                return node.exportClause && ts.tryCast(node.exportClause, ts.isNamespaceExport);
            default:
                return ts.Debug.assertNever(node);
        }
    }
    ts.getNamespaceDeclarationNode = getNamespaceDeclarationNode;
    function isDefaultImport(node) {
        return node.kind === 254 /* ImportDeclaration */ && !!node.importClause && !!node.importClause.name;
    }
    ts.isDefaultImport = isDefaultImport;
    function forEachImportClauseDeclaration(node, action) {
        if (node.name) {
            var result = action(node);
            if (result)
                return result;
        }
        if (node.namedBindings) {
            var result = ts.isNamespaceImport(node.namedBindings)
                ? action(node.namedBindings)
                : ts.forEach(node.namedBindings.elements, action);
            if (result)
                return result;
        }
    }
    ts.forEachImportClauseDeclaration = forEachImportClauseDeclaration;
    function hasQuestionToken(node) {
        if (node) {
            switch (node.kind) {
                case 156 /* Parameter */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 282 /* ShorthandPropertyAssignment */:
                case 281 /* PropertyAssignment */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    return node.questionToken !== undefined;
            }
        }
        return false;
    }
    ts.hasQuestionToken = hasQuestionToken;
    function isJSDocConstructSignature(node) {
        var param = ts.isJSDocFunctionType(node) ? ts.firstOrUndefined(node.parameters) : undefined;
        var name = ts.tryCast(param && param.name, ts.isIdentifier);
        return !!name && name.escapedText === "new";
    }
    ts.isJSDocConstructSignature = isJSDocConstructSignature;
    function isJSDocTypeAlias(node) {
        return node.kind === 322 /* JSDocTypedefTag */ || node.kind === 315 /* JSDocCallbackTag */ || node.kind === 316 /* JSDocEnumTag */;
    }
    ts.isJSDocTypeAlias = isJSDocTypeAlias;
    function isTypeAlias(node) {
        return isJSDocTypeAlias(node) || ts.isTypeAliasDeclaration(node);
    }
    ts.isTypeAlias = isTypeAlias;
    function getSourceOfAssignment(node) {
        return ts.isExpressionStatement(node) &&
            ts.isBinaryExpression(node.expression) &&
            node.expression.operatorToken.kind === 62 /* EqualsToken */
            ? getRightMostAssignedExpression(node.expression)
            : undefined;
    }
    function getSourceOfDefaultedAssignment(node) {
        return ts.isExpressionStatement(node) &&
            ts.isBinaryExpression(node.expression) &&
            getAssignmentDeclarationKind(node.expression) !== 0 /* None */ &&
            ts.isBinaryExpression(node.expression.right) &&
            (node.expression.right.operatorToken.kind === 56 /* BarBarToken */ || node.expression.right.operatorToken.kind === 60 /* QuestionQuestionToken */)
            ? node.expression.right.right
            : undefined;
    }
    function getSingleInitializerOfVariableStatementOrPropertyDeclaration(node) {
        switch (node.kind) {
            case 225 /* VariableStatement */:
                var v = getSingleVariableOfVariableStatement(node);
                return v && v.initializer;
            case 159 /* PropertyDeclaration */:
                return node.initializer;
            case 281 /* PropertyAssignment */:
                return node.initializer;
        }
    }
    ts.getSingleInitializerOfVariableStatementOrPropertyDeclaration = getSingleInitializerOfVariableStatementOrPropertyDeclaration;
    function getSingleVariableOfVariableStatement(node) {
        return ts.isVariableStatement(node) ? ts.firstOrUndefined(node.declarationList.declarations) : undefined;
    }
    function getNestedModuleDeclaration(node) {
        return ts.isModuleDeclaration(node) &&
            node.body &&
            node.body.kind === 249 /* ModuleDeclaration */
            ? node.body
            : undefined;
    }
    function getJSDocCommentsAndTags(hostNode) {
        var result;
        // Pull parameter comments from declaring function as well
        if (isVariableLike(hostNode) && ts.hasInitializer(hostNode) && ts.hasJSDocNodes(hostNode.initializer)) {
            result = ts.append(result, ts.last(hostNode.initializer.jsDoc));
        }
        var node = hostNode;
        while (node && node.parent) {
            if (ts.hasJSDocNodes(node)) {
                result = ts.append(result, ts.last(node.jsDoc));
            }
            if (node.kind === 156 /* Parameter */) {
                result = ts.addRange(result, ts.getJSDocParameterTags(node));
                break;
            }
            if (node.kind === 155 /* TypeParameter */) {
                result = ts.addRange(result, ts.getJSDocTypeParameterTags(node));
                break;
            }
            node = getNextJSDocCommentLocation(node);
        }
        return result || ts.emptyArray;
    }
    ts.getJSDocCommentsAndTags = getJSDocCommentsAndTags;
    function getNextJSDocCommentLocation(node) {
        var parent = node.parent;
        if (parent.kind === 281 /* PropertyAssignment */ ||
            parent.kind === 259 /* ExportAssignment */ ||
            parent.kind === 159 /* PropertyDeclaration */ ||
            parent.kind === 226 /* ExpressionStatement */ && node.kind === 194 /* PropertyAccessExpression */ ||
            getNestedModuleDeclaration(parent) ||
            ts.isBinaryExpression(node) && node.operatorToken.kind === 62 /* EqualsToken */) {
            return parent;
        }
        // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
        // /**
        //   * @param {number} name
        //   * @returns {number}
        //   */
        // var x = function(name) { return name.length; }
        else if (parent.parent &&
            (getSingleVariableOfVariableStatement(parent.parent) === node ||
                ts.isBinaryExpression(parent) && parent.operatorToken.kind === 62 /* EqualsToken */)) {
            return parent.parent;
        }
        else if (parent.parent && parent.parent.parent &&
            (getSingleVariableOfVariableStatement(parent.parent.parent) ||
                getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node ||
                getSourceOfDefaultedAssignment(parent.parent.parent))) {
            return parent.parent.parent;
        }
    }
    /** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
    function getParameterSymbolFromJSDoc(node) {
        if (node.symbol) {
            return node.symbol;
        }
        if (!ts.isIdentifier(node.name)) {
            return undefined;
        }
        var name = node.name.escapedText;
        var decl = getHostSignatureFromJSDoc(node);
        if (!decl) {
            return undefined;
        }
        var parameter = ts.find(decl.parameters, function (p) { return p.name.kind === 75 /* Identifier */ && p.name.escapedText === name; });
        return parameter && parameter.symbol;
    }
    ts.getParameterSymbolFromJSDoc = getParameterSymbolFromJSDoc;
    function getHostSignatureFromJSDoc(node) {
        var host = getEffectiveJSDocHost(node);
        return host && ts.isFunctionLike(host) ? host : undefined;
    }
    ts.getHostSignatureFromJSDoc = getHostSignatureFromJSDoc;
    function getEffectiveJSDocHost(node) {
        var host = getJSDocHost(node);
        var decl = getSourceOfDefaultedAssignment(host) ||
            getSourceOfAssignment(host) ||
            getSingleInitializerOfVariableStatementOrPropertyDeclaration(host) ||
            getSingleVariableOfVariableStatement(host) ||
            getNestedModuleDeclaration(host) ||
            host;
        return decl;
    }
    ts.getEffectiveJSDocHost = getEffectiveJSDocHost;
    /** Use getEffectiveJSDocHost if you additionally need to look for jsdoc on parent nodes, like assignments.  */
    function getJSDocHost(node) {
        return ts.Debug.checkDefined(findAncestor(node.parent, ts.isJSDoc)).parent;
    }
    ts.getJSDocHost = getJSDocHost;
    function getTypeParameterFromJsDoc(node) {
        var name = node.name.escapedText;
        var typeParameters = node.parent.parent.parent.typeParameters;
        return typeParameters && ts.find(typeParameters, function (p) { return p.name.escapedText === name; });
    }
    ts.getTypeParameterFromJsDoc = getTypeParameterFromJsDoc;
    function hasRestParameter(s) {
        var last = ts.lastOrUndefined(s.parameters);
        return !!last && isRestParameter(last);
    }
    ts.hasRestParameter = hasRestParameter;
    function isRestParameter(node) {
        var type = ts.isJSDocParameterTag(node) ? (node.typeExpression && node.typeExpression.type) : node.type;
        return node.dotDotDotToken !== undefined || !!type && type.kind === 301 /* JSDocVariadicType */;
    }
    ts.isRestParameter = isRestParameter;
    function hasTypeArguments(node) {
        return !!node.typeArguments;
    }
    ts.hasTypeArguments = hasTypeArguments;
    var AssignmentKind;
    (function (AssignmentKind) {
        AssignmentKind[AssignmentKind["None"] = 0] = "None";
        AssignmentKind[AssignmentKind["Definite"] = 1] = "Definite";
        AssignmentKind[AssignmentKind["Compound"] = 2] = "Compound";
    })(AssignmentKind = ts.AssignmentKind || (ts.AssignmentKind = {}));
    function getAssignmentTargetKind(node) {
        var parent = node.parent;
        while (true) {
            switch (parent.kind) {
                case 209 /* BinaryExpression */:
                    var binaryOperator = parent.operatorToken.kind;
                    return isAssignmentOperator(binaryOperator) && parent.left === node ?
                        binaryOperator === 62 /* EqualsToken */ ? 1 /* Definite */ : 2 /* Compound */ :
                        0 /* None */;
                case 207 /* PrefixUnaryExpression */:
                case 208 /* PostfixUnaryExpression */:
                    var unaryOperator = parent.operator;
                    return unaryOperator === 45 /* PlusPlusToken */ || unaryOperator === 46 /* MinusMinusToken */ ? 2 /* Compound */ : 0 /* None */;
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                    return parent.initializer === node ? 1 /* Definite */ : 0 /* None */;
                case 200 /* ParenthesizedExpression */:
                case 192 /* ArrayLiteralExpression */:
                case 213 /* SpreadElement */:
                case 218 /* NonNullExpression */:
                    node = parent;
                    break;
                case 282 /* ShorthandPropertyAssignment */:
                    if (parent.name !== node) {
                        return 0 /* None */;
                    }
                    node = parent.parent;
                    break;
                case 281 /* PropertyAssignment */:
                    if (parent.name === node) {
                        return 0 /* None */;
                    }
                    node = parent.parent;
                    break;
                default:
                    return 0 /* None */;
            }
            parent = node.parent;
        }
    }
    ts.getAssignmentTargetKind = getAssignmentTargetKind;
    // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property
    // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is
    // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'.
    // (Note that `p` is not a target in the above examples, only `a`.)
    function isAssignmentTarget(node) {
        return getAssignmentTargetKind(node) !== 0 /* None */;
    }
    ts.isAssignmentTarget = isAssignmentTarget;
    /**
     * Indicates whether a node could contain a `var` VariableDeclarationList that contributes to
     * the same `var` declaration scope as the node's parent.
     */
    function isNodeWithPossibleHoistedDeclaration(node) {
        switch (node.kind) {
            case 223 /* Block */:
            case 225 /* VariableStatement */:
            case 236 /* WithStatement */:
            case 227 /* IfStatement */:
            case 237 /* SwitchStatement */:
            case 251 /* CaseBlock */:
            case 277 /* CaseClause */:
            case 278 /* DefaultClause */:
            case 238 /* LabeledStatement */:
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
            case 228 /* DoStatement */:
            case 229 /* WhileStatement */:
            case 240 /* TryStatement */:
            case 280 /* CatchClause */:
                return true;
        }
        return false;
    }
    ts.isNodeWithPossibleHoistedDeclaration = isNodeWithPossibleHoistedDeclaration;
    function isValueSignatureDeclaration(node) {
        return ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodOrAccessor(node) || ts.isFunctionDeclaration(node) || ts.isConstructorDeclaration(node);
    }
    ts.isValueSignatureDeclaration = isValueSignatureDeclaration;
    function walkUp(node, kind) {
        while (node && node.kind === kind) {
            node = node.parent;
        }
        return node;
    }
    function walkUpParenthesizedTypes(node) {
        return walkUp(node, 182 /* ParenthesizedType */);
    }
    ts.walkUpParenthesizedTypes = walkUpParenthesizedTypes;
    function walkUpParenthesizedExpressions(node) {
        return walkUp(node, 200 /* ParenthesizedExpression */);
    }
    ts.walkUpParenthesizedExpressions = walkUpParenthesizedExpressions;
    function skipParentheses(node) {
        return ts.skipOuterExpressions(node, 1 /* Parentheses */);
    }
    ts.skipParentheses = skipParentheses;
    function skipParenthesesUp(node) {
        while (node.kind === 200 /* ParenthesizedExpression */) {
            node = node.parent;
        }
        return node;
    }
    // a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped
    function isDeleteTarget(node) {
        if (node.kind !== 194 /* PropertyAccessExpression */ && node.kind !== 195 /* ElementAccessExpression */) {
            return false;
        }
        node = walkUpParenthesizedExpressions(node.parent);
        return node && node.kind === 203 /* DeleteExpression */;
    }
    ts.isDeleteTarget = isDeleteTarget;
    function isNodeDescendantOf(node, ancestor) {
        while (node) {
            if (node === ancestor)
                return true;
            node = node.parent;
        }
        return false;
    }
    ts.isNodeDescendantOf = isNodeDescendantOf;
    // True if `name` is the name of a declaration node
    function isDeclarationName(name) {
        return !ts.isSourceFile(name) && !ts.isBindingPattern(name) && ts.isDeclaration(name.parent) && name.parent.name === name;
    }
    ts.isDeclarationName = isDeclarationName;
    // See GH#16030
    function getDeclarationFromName(name) {
        var parent = name.parent;
        switch (name.kind) {
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 8 /* NumericLiteral */:
                if (ts.isComputedPropertyName(parent))
                    return parent.parent;
            // falls through
            case 75 /* Identifier */:
                if (ts.isDeclaration(parent)) {
                    return parent.name === name ? parent : undefined;
                }
                else if (ts.isQualifiedName(parent)) {
                    var tag = parent.parent;
                    return ts.isJSDocParameterTag(tag) && tag.name === parent ? tag : undefined;
                }
                else {
                    var binExp = parent.parent;
                    return ts.isBinaryExpression(binExp) &&
                        getAssignmentDeclarationKind(binExp) !== 0 /* None */ &&
                        (binExp.left.symbol || binExp.symbol) &&
                        ts.getNameOfDeclaration(binExp) === name
                        ? binExp
                        : undefined;
                }
            case 76 /* PrivateIdentifier */:
                return ts.isDeclaration(parent) && parent.name === name ? parent : undefined;
            default:
                return undefined;
        }
    }
    ts.getDeclarationFromName = getDeclarationFromName;
    function isLiteralComputedPropertyDeclarationName(node) {
        return isStringOrNumericLiteralLike(node) &&
            node.parent.kind === 154 /* ComputedPropertyName */ &&
            ts.isDeclaration(node.parent.parent);
    }
    ts.isLiteralComputedPropertyDeclarationName = isLiteralComputedPropertyDeclarationName;
    // Return true if the given identifier is classified as an IdentifierName
    function isIdentifierName(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 284 /* EnumMember */:
            case 281 /* PropertyAssignment */:
            case 194 /* PropertyAccessExpression */:
                // Name in member declaration or property name in property access
                return parent.name === node;
            case 153 /* QualifiedName */:
                // Name on right hand side of dot in a type query or type reference
                if (parent.right === node) {
                    while (parent.kind === 153 /* QualifiedName */) {
                        parent = parent.parent;
                    }
                    return parent.kind === 172 /* TypeQuery */ || parent.kind === 169 /* TypeReference */;
                }
                return false;
            case 191 /* BindingElement */:
            case 258 /* ImportSpecifier */:
                // Property name in binding element or import specifier
                return parent.propertyName === node;
            case 263 /* ExportSpecifier */:
            case 273 /* JsxAttribute */:
                // Any name in an export specifier or JSX Attribute
                return true;
        }
        return false;
    }
    ts.isIdentifierName = isIdentifierName;
    // An alias symbol is created by one of the following declarations:
    // import <symbol> = ...
    // import <symbol> from ...
    // import * as <symbol> from ...
    // import { x as <symbol> } from ...
    // export { x as <symbol> } from ...
    // export * as ns <symbol> from ...
    // export = <EntityNameExpression>
    // export default <EntityNameExpression>
    // module.exports = <EntityNameExpression>
    // {<Identifier>}
    // {name: <EntityNameExpression>}
    function isAliasSymbolDeclaration(node) {
        return node.kind === 253 /* ImportEqualsDeclaration */ ||
            node.kind === 252 /* NamespaceExportDeclaration */ ||
            node.kind === 255 /* ImportClause */ && !!node.name ||
            node.kind === 256 /* NamespaceImport */ ||
            node.kind === 262 /* NamespaceExport */ ||
            node.kind === 258 /* ImportSpecifier */ ||
            node.kind === 263 /* ExportSpecifier */ ||
            node.kind === 259 /* ExportAssignment */ && exportAssignmentIsAlias(node) ||
            ts.isBinaryExpression(node) && getAssignmentDeclarationKind(node) === 2 /* ModuleExports */ && exportAssignmentIsAlias(node) ||
            ts.isPropertyAccessExpression(node) && ts.isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === 62 /* EqualsToken */ && isAliasableExpression(node.parent.right) ||
            node.kind === 282 /* ShorthandPropertyAssignment */ ||
            node.kind === 281 /* PropertyAssignment */ && isAliasableExpression(node.initializer);
    }
    ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration;
    function getAliasDeclarationFromName(node) {
        switch (node.parent.kind) {
            case 255 /* ImportClause */:
            case 258 /* ImportSpecifier */:
            case 256 /* NamespaceImport */:
            case 263 /* ExportSpecifier */:
            case 259 /* ExportAssignment */:
            case 253 /* ImportEqualsDeclaration */:
                return node.parent;
            case 153 /* QualifiedName */:
                do {
                    node = node.parent;
                } while (node.parent.kind === 153 /* QualifiedName */);
                return getAliasDeclarationFromName(node);
        }
    }
    ts.getAliasDeclarationFromName = getAliasDeclarationFromName;
    function isAliasableExpression(e) {
        return isEntityNameExpression(e) || ts.isClassExpression(e);
    }
    ts.isAliasableExpression = isAliasableExpression;
    function exportAssignmentIsAlias(node) {
        var e = getExportAssignmentExpression(node);
        return isAliasableExpression(e);
    }
    ts.exportAssignmentIsAlias = exportAssignmentIsAlias;
    function getExportAssignmentExpression(node) {
        return ts.isExportAssignment(node) ? node.expression : node.right;
    }
    ts.getExportAssignmentExpression = getExportAssignmentExpression;
    function getPropertyAssignmentAliasLikeExpression(node) {
        return node.kind === 282 /* ShorthandPropertyAssignment */ ? node.name : node.kind === 281 /* PropertyAssignment */ ? node.initializer :
            node.parent.right;
    }
    ts.getPropertyAssignmentAliasLikeExpression = getPropertyAssignmentAliasLikeExpression;
    function getEffectiveBaseTypeNode(node) {
        var baseType = getClassExtendsHeritageElement(node);
        if (baseType && isInJSFile(node)) {
            // Prefer an @augments tag because it may have type parameters.
            var tag = ts.getJSDocAugmentsTag(node);
            if (tag) {
                return tag.class;
            }
        }
        return baseType;
    }
    ts.getEffectiveBaseTypeNode = getEffectiveBaseTypeNode;
    function getClassExtendsHeritageElement(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 90 /* ExtendsKeyword */);
        return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
    }
    ts.getClassExtendsHeritageElement = getClassExtendsHeritageElement;
    function getEffectiveImplementsTypeNodes(node) {
        if (isInJSFile(node)) {
            return ts.getJSDocImplementsTags(node).map(function (n) { return n.class; });
        }
        else {
            var heritageClause = getHeritageClause(node.heritageClauses, 113 /* ImplementsKeyword */);
            return heritageClause === null || heritageClause === void 0 ? void 0 : heritageClause.types;
        }
    }
    ts.getEffectiveImplementsTypeNodes = getEffectiveImplementsTypeNodes;
    /** Returns the node in an `extends` or `implements` clause of a class or interface. */
    function getAllSuperTypeNodes(node) {
        return ts.isInterfaceDeclaration(node) ? getInterfaceBaseTypeNodes(node) || ts.emptyArray :
            ts.isClassLike(node) ? ts.concatenate(ts.singleElementArray(getEffectiveBaseTypeNode(node)), getEffectiveImplementsTypeNodes(node)) || ts.emptyArray :
                ts.emptyArray;
    }
    ts.getAllSuperTypeNodes = getAllSuperTypeNodes;
    function getInterfaceBaseTypeNodes(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 90 /* ExtendsKeyword */);
        return heritageClause ? heritageClause.types : undefined;
    }
    ts.getInterfaceBaseTypeNodes = getInterfaceBaseTypeNodes;
    function getHeritageClause(clauses, kind) {
        if (clauses) {
            for (var _i = 0, clauses_1 = clauses; _i < clauses_1.length; _i++) {
                var clause = clauses_1[_i];
                if (clause.token === kind) {
                    return clause;
                }
            }
        }
        return undefined;
    }
    ts.getHeritageClause = getHeritageClause;
    function getAncestor(node, kind) {
        while (node) {
            if (node.kind === kind) {
                return node;
            }
            node = node.parent;
        }
        return undefined;
    }
    ts.getAncestor = getAncestor;
    function isKeyword(token) {
        return 77 /* FirstKeyword */ <= token && token <= 152 /* LastKeyword */;
    }
    ts.isKeyword = isKeyword;
    function isContextualKeyword(token) {
        return 122 /* FirstContextualKeyword */ <= token && token <= 152 /* LastContextualKeyword */;
    }
    ts.isContextualKeyword = isContextualKeyword;
    function isNonContextualKeyword(token) {
        return isKeyword(token) && !isContextualKeyword(token);
    }
    ts.isNonContextualKeyword = isNonContextualKeyword;
    function isFutureReservedKeyword(token) {
        return 113 /* FirstFutureReservedWord */ <= token && token <= 121 /* LastFutureReservedWord */;
    }
    ts.isFutureReservedKeyword = isFutureReservedKeyword;
    function isStringANonContextualKeyword(name) {
        var token = ts.stringToToken(name);
        return token !== undefined && isNonContextualKeyword(token);
    }
    ts.isStringANonContextualKeyword = isStringANonContextualKeyword;
    function isStringAKeyword(name) {
        var token = ts.stringToToken(name);
        return token !== undefined && isKeyword(token);
    }
    ts.isStringAKeyword = isStringAKeyword;
    function isIdentifierANonContextualKeyword(_a) {
        var originalKeywordKind = _a.originalKeywordKind;
        return !!originalKeywordKind && !isContextualKeyword(originalKeywordKind);
    }
    ts.isIdentifierANonContextualKeyword = isIdentifierANonContextualKeyword;
    function isTrivia(token) {
        return 2 /* FirstTriviaToken */ <= token && token <= 7 /* LastTriviaToken */;
    }
    ts.isTrivia = isTrivia;
    var FunctionFlags;
    (function (FunctionFlags) {
        FunctionFlags[FunctionFlags["Normal"] = 0] = "Normal";
        FunctionFlags[FunctionFlags["Generator"] = 1] = "Generator";
        FunctionFlags[FunctionFlags["Async"] = 2] = "Async";
        FunctionFlags[FunctionFlags["Invalid"] = 4] = "Invalid";
        FunctionFlags[FunctionFlags["AsyncGenerator"] = 3] = "AsyncGenerator";
    })(FunctionFlags = ts.FunctionFlags || (ts.FunctionFlags = {}));
    function getFunctionFlags(node) {
        if (!node) {
            return 4 /* Invalid */;
        }
        var flags = 0 /* Normal */;
        switch (node.kind) {
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 161 /* MethodDeclaration */:
                if (node.asteriskToken) {
                    flags |= 1 /* Generator */;
                }
            // falls through
            case 202 /* ArrowFunction */:
                if (hasModifier(node, 256 /* Async */)) {
                    flags |= 2 /* Async */;
                }
                break;
        }
        if (!node.body) {
            flags |= 4 /* Invalid */;
        }
        return flags;
    }
    ts.getFunctionFlags = getFunctionFlags;
    function isAsyncFunction(node) {
        switch (node.kind) {
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
            case 161 /* MethodDeclaration */:
                return node.body !== undefined
                    && node.asteriskToken === undefined
                    && hasModifier(node, 256 /* Async */);
        }
        return false;
    }
    ts.isAsyncFunction = isAsyncFunction;
    function isStringOrNumericLiteralLike(node) {
        return ts.isStringLiteralLike(node) || ts.isNumericLiteral(node);
    }
    ts.isStringOrNumericLiteralLike = isStringOrNumericLiteralLike;
    function isSignedNumericLiteral(node) {
        return ts.isPrefixUnaryExpression(node) && (node.operator === 39 /* PlusToken */ || node.operator === 40 /* MinusToken */) && ts.isNumericLiteral(node.operand);
    }
    ts.isSignedNumericLiteral = isSignedNumericLiteral;
    /**
     * A declaration has a dynamic name if all of the following are true:
     *   1. The declaration has a computed property name.
     *   2. The computed name is *not* expressed as a StringLiteral.
     *   3. The computed name is *not* expressed as a NumericLiteral.
     *   4. The computed name is *not* expressed as a PlusToken or MinusToken
     *      immediately followed by a NumericLiteral.
     *   5. The computed name is *not* expressed as `Symbol.<name>`, where `<name>`
     *      is a property of the Symbol constructor that denotes a built-in
     *      Symbol.
     */
    function hasDynamicName(declaration) {
        var name = ts.getNameOfDeclaration(declaration);
        return !!name && isDynamicName(name);
    }
    ts.hasDynamicName = hasDynamicName;
    function isDynamicName(name) {
        if (!(name.kind === 154 /* ComputedPropertyName */ || name.kind === 195 /* ElementAccessExpression */)) {
            return false;
        }
        var expr = ts.isElementAccessExpression(name) ? skipParentheses(name.argumentExpression) : name.expression;
        return !isStringOrNumericLiteralLike(expr) &&
            !isSignedNumericLiteral(expr) &&
            !isWellKnownSymbolSyntactically(expr);
    }
    ts.isDynamicName = isDynamicName;
    /**
     * Checks if the expression is of the form:
     *    Symbol.name
     * where Symbol is literally the word "Symbol", and name is any identifierName
     */
    function isWellKnownSymbolSyntactically(node) {
        return ts.isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
    }
    ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically;
    function getPropertyNameForPropertyNameNode(name) {
        switch (name.kind) {
            case 75 /* Identifier */:
            case 76 /* PrivateIdentifier */:
                return name.escapedText;
            case 10 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                return ts.escapeLeadingUnderscores(name.text);
            case 154 /* ComputedPropertyName */:
                var nameExpression = name.expression;
                if (isWellKnownSymbolSyntactically(nameExpression)) {
                    return getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
                }
                else if (isStringOrNumericLiteralLike(nameExpression)) {
                    return ts.escapeLeadingUnderscores(nameExpression.text);
                }
                return undefined;
            default:
                return ts.Debug.assertNever(name);
        }
    }
    ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode;
    function isPropertyNameLiteral(node) {
        switch (node.kind) {
            case 75 /* Identifier */:
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 8 /* NumericLiteral */:
                return true;
            default:
                return false;
        }
    }
    ts.isPropertyNameLiteral = isPropertyNameLiteral;
    function getTextOfIdentifierOrLiteral(node) {
        return ts.isIdentifierOrPrivateIdentifier(node) ? ts.idText(node) : node.text;
    }
    ts.getTextOfIdentifierOrLiteral = getTextOfIdentifierOrLiteral;
    function getEscapedTextOfIdentifierOrLiteral(node) {
        return ts.isIdentifierOrPrivateIdentifier(node) ? node.escapedText : ts.escapeLeadingUnderscores(node.text);
    }
    ts.getEscapedTextOfIdentifierOrLiteral = getEscapedTextOfIdentifierOrLiteral;
    function getPropertyNameForUniqueESSymbol(symbol) {
        return "__@" + ts.getSymbolId(symbol) + "@" + symbol.escapedName;
    }
    ts.getPropertyNameForUniqueESSymbol = getPropertyNameForUniqueESSymbol;
    function getPropertyNameForKnownSymbolName(symbolName) {
        return "__@" + symbolName;
    }
    ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName;
    function getSymbolNameForPrivateIdentifier(containingClassSymbol, description) {
        return "__#" + ts.getSymbolId(containingClassSymbol) + "@" + description;
    }
    ts.getSymbolNameForPrivateIdentifier = getSymbolNameForPrivateIdentifier;
    function isKnownSymbol(symbol) {
        return ts.startsWith(symbol.escapedName, "__@");
    }
    ts.isKnownSymbol = isKnownSymbol;
    /**
     * Includes the word "Symbol" with unicode escapes
     */
    function isESSymbolIdentifier(node) {
        return node.kind === 75 /* Identifier */ && node.escapedText === "Symbol";
    }
    ts.isESSymbolIdentifier = isESSymbolIdentifier;
    function isPushOrUnshiftIdentifier(node) {
        return node.escapedText === "push" || node.escapedText === "unshift";
    }
    ts.isPushOrUnshiftIdentifier = isPushOrUnshiftIdentifier;
    function isParameterDeclaration(node) {
        var root = getRootDeclaration(node);
        return root.kind === 156 /* Parameter */;
    }
    ts.isParameterDeclaration = isParameterDeclaration;
    function getRootDeclaration(node) {
        while (node.kind === 191 /* BindingElement */) {
            node = node.parent.parent;
        }
        return node;
    }
    ts.getRootDeclaration = getRootDeclaration;
    function nodeStartsNewLexicalEnvironment(node) {
        var kind = node.kind;
        return kind === 162 /* Constructor */
            || kind === 201 /* FunctionExpression */
            || kind === 244 /* FunctionDeclaration */
            || kind === 202 /* ArrowFunction */
            || kind === 161 /* MethodDeclaration */
            || kind === 163 /* GetAccessor */
            || kind === 164 /* SetAccessor */
            || kind === 249 /* ModuleDeclaration */
            || kind === 290 /* SourceFile */;
    }
    ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
    function nodeIsSynthesized(range) {
        return positionIsSynthesized(range.pos)
            || positionIsSynthesized(range.end);
    }
    ts.nodeIsSynthesized = nodeIsSynthesized;
    function getOriginalSourceFile(sourceFile) {
        return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile;
    }
    ts.getOriginalSourceFile = getOriginalSourceFile;
    var Associativity;
    (function (Associativity) {
        Associativity[Associativity["Left"] = 0] = "Left";
        Associativity[Associativity["Right"] = 1] = "Right";
    })(Associativity = ts.Associativity || (ts.Associativity = {}));
    function getExpressionAssociativity(expression) {
        var operator = getOperator(expression);
        var hasArguments = expression.kind === 197 /* NewExpression */ && expression.arguments !== undefined;
        return getOperatorAssociativity(expression.kind, operator, hasArguments);
    }
    ts.getExpressionAssociativity = getExpressionAssociativity;
    function getOperatorAssociativity(kind, operator, hasArguments) {
        switch (kind) {
            case 197 /* NewExpression */:
                return hasArguments ? 0 /* Left */ : 1 /* Right */;
            case 207 /* PrefixUnaryExpression */:
            case 204 /* TypeOfExpression */:
            case 205 /* VoidExpression */:
            case 203 /* DeleteExpression */:
            case 206 /* AwaitExpression */:
            case 210 /* ConditionalExpression */:
            case 212 /* YieldExpression */:
                return 1 /* Right */;
            case 209 /* BinaryExpression */:
                switch (operator) {
                    case 42 /* AsteriskAsteriskToken */:
                    case 62 /* EqualsToken */:
                    case 63 /* PlusEqualsToken */:
                    case 64 /* MinusEqualsToken */:
                    case 66 /* AsteriskAsteriskEqualsToken */:
                    case 65 /* AsteriskEqualsToken */:
                    case 67 /* SlashEqualsToken */:
                    case 68 /* PercentEqualsToken */:
                    case 69 /* LessThanLessThanEqualsToken */:
                    case 70 /* GreaterThanGreaterThanEqualsToken */:
                    case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 72 /* AmpersandEqualsToken */:
                    case 74 /* CaretEqualsToken */:
                    case 73 /* BarEqualsToken */:
                        return 1 /* Right */;
                }
        }
        return 0 /* Left */;
    }
    ts.getOperatorAssociativity = getOperatorAssociativity;
    function getExpressionPrecedence(expression) {
        var operator = getOperator(expression);
        var hasArguments = expression.kind === 197 /* NewExpression */ && expression.arguments !== undefined;
        return getOperatorPrecedence(expression.kind, operator, hasArguments);
    }
    ts.getExpressionPrecedence = getExpressionPrecedence;
    function getOperator(expression) {
        if (expression.kind === 209 /* BinaryExpression */) {
            return expression.operatorToken.kind;
        }
        else if (expression.kind === 207 /* PrefixUnaryExpression */ || expression.kind === 208 /* PostfixUnaryExpression */) {
            return expression.operator;
        }
        else {
            return expression.kind;
        }
    }
    ts.getOperator = getOperator;
    function getOperatorPrecedence(nodeKind, operatorKind, hasArguments) {
        switch (nodeKind) {
            case 327 /* CommaListExpression */:
                return 0;
            case 213 /* SpreadElement */:
                return 1;
            case 212 /* YieldExpression */:
                return 2;
            case 210 /* ConditionalExpression */:
                return 4;
            case 209 /* BinaryExpression */:
                switch (operatorKind) {
                    case 27 /* CommaToken */:
                        return 0;
                    case 62 /* EqualsToken */:
                    case 63 /* PlusEqualsToken */:
                    case 64 /* MinusEqualsToken */:
                    case 66 /* AsteriskAsteriskEqualsToken */:
                    case 65 /* AsteriskEqualsToken */:
                    case 67 /* SlashEqualsToken */:
                    case 68 /* PercentEqualsToken */:
                    case 69 /* LessThanLessThanEqualsToken */:
                    case 70 /* GreaterThanGreaterThanEqualsToken */:
                    case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 72 /* AmpersandEqualsToken */:
                    case 74 /* CaretEqualsToken */:
                    case 73 /* BarEqualsToken */:
                        return 3;
                    default:
                        return getBinaryOperatorPrecedence(operatorKind);
                }
            case 207 /* PrefixUnaryExpression */:
            case 204 /* TypeOfExpression */:
            case 205 /* VoidExpression */:
            case 203 /* DeleteExpression */:
            case 206 /* AwaitExpression */:
                return 16;
            case 208 /* PostfixUnaryExpression */:
                return 17;
            case 196 /* CallExpression */:
                return 18;
            case 197 /* NewExpression */:
                return hasArguments ? 19 : 18;
            case 198 /* TaggedTemplateExpression */:
            case 194 /* PropertyAccessExpression */:
            case 195 /* ElementAccessExpression */:
                return 19;
            case 104 /* ThisKeyword */:
            case 102 /* SuperKeyword */:
            case 75 /* Identifier */:
            case 100 /* NullKeyword */:
            case 106 /* TrueKeyword */:
            case 91 /* FalseKeyword */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 192 /* ArrayLiteralExpression */:
            case 193 /* ObjectLiteralExpression */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
            case 214 /* ClassExpression */:
            case 266 /* JsxElement */:
            case 267 /* JsxSelfClosingElement */:
            case 270 /* JsxFragment */:
            case 13 /* RegularExpressionLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 211 /* TemplateExpression */:
            case 200 /* ParenthesizedExpression */:
            case 215 /* OmittedExpression */:
                return 20;
            default:
                return -1;
        }
    }
    ts.getOperatorPrecedence = getOperatorPrecedence;
    function getBinaryOperatorPrecedence(kind) {
        switch (kind) {
            case 60 /* QuestionQuestionToken */:
                return 4;
            case 56 /* BarBarToken */:
                return 5;
            case 55 /* AmpersandAmpersandToken */:
                return 6;
            case 51 /* BarToken */:
                return 7;
            case 52 /* CaretToken */:
                return 8;
            case 50 /* AmpersandToken */:
                return 9;
            case 34 /* EqualsEqualsToken */:
            case 35 /* ExclamationEqualsToken */:
            case 36 /* EqualsEqualsEqualsToken */:
            case 37 /* ExclamationEqualsEqualsToken */:
                return 10;
            case 29 /* LessThanToken */:
            case 31 /* GreaterThanToken */:
            case 32 /* LessThanEqualsToken */:
            case 33 /* GreaterThanEqualsToken */:
            case 98 /* InstanceOfKeyword */:
            case 97 /* InKeyword */:
            case 123 /* AsKeyword */:
                return 11;
            case 47 /* LessThanLessThanToken */:
            case 48 /* GreaterThanGreaterThanToken */:
            case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                return 12;
            case 39 /* PlusToken */:
            case 40 /* MinusToken */:
                return 13;
            case 41 /* AsteriskToken */:
            case 43 /* SlashToken */:
            case 44 /* PercentToken */:
                return 14;
            case 42 /* AsteriskAsteriskToken */:
                return 15;
        }
        // -1 is lower than all other precedences.  Returning it will cause binary expression
        // parsing to stop.
        return -1;
    }
    ts.getBinaryOperatorPrecedence = getBinaryOperatorPrecedence;
    function createDiagnosticCollection() {
        var nonFileDiagnostics = []; // See GH#19873
        var filesWithDiagnostics = [];
        var fileDiagnostics = ts.createMap();
        var hasReadNonFileDiagnostics = false;
        return {
            add: add,
            lookup: lookup,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getDiagnostics: getDiagnostics,
            reattachFileDiagnostics: reattachFileDiagnostics
        };
        function reattachFileDiagnostics(newFile) {
            ts.forEach(fileDiagnostics.get(newFile.fileName), function (diagnostic) { return diagnostic.file = newFile; });
        }
        function lookup(diagnostic) {
            var diagnostics;
            if (diagnostic.file) {
                diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
            }
            else {
                diagnostics = nonFileDiagnostics;
            }
            if (!diagnostics) {
                return undefined;
            }
            var result = ts.binarySearch(diagnostics, diagnostic, ts.identity, compareDiagnosticsSkipRelatedInformation);
            if (result >= 0) {
                return diagnostics[result];
            }
            return undefined;
        }
        function add(diagnostic) {
            var diagnostics;
            if (diagnostic.file) {
                diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
                if (!diagnostics) {
                    diagnostics = []; // See GH#19873
                    fileDiagnostics.set(diagnostic.file.fileName, diagnostics);
                    ts.insertSorted(filesWithDiagnostics, diagnostic.file.fileName, ts.compareStringsCaseSensitive);
                }
            }
            else {
                // If we've already read the non-file diagnostics, do not modify the existing array.
                if (hasReadNonFileDiagnostics) {
                    hasReadNonFileDiagnostics = false;
                    nonFileDiagnostics = nonFileDiagnostics.slice();
                }
                diagnostics = nonFileDiagnostics;
            }
            ts.insertSorted(diagnostics, diagnostic, compareDiagnostics);
        }
        function getGlobalDiagnostics() {
            hasReadNonFileDiagnostics = true;
            return nonFileDiagnostics;
        }
        function getDiagnostics(fileName) {
            if (fileName) {
                return fileDiagnostics.get(fileName) || [];
            }
            var fileDiags = ts.flatMapToMutable(filesWithDiagnostics, function (f) { return fileDiagnostics.get(f); });
            if (!nonFileDiagnostics.length) {
                return fileDiags;
            }
            fileDiags.unshift.apply(fileDiags, nonFileDiagnostics);
            return fileDiags;
        }
    }
    ts.createDiagnosticCollection = createDiagnosticCollection;
    var templateSubstitutionRegExp = /\$\{/g;
    function escapeTemplateSubstitution(str) {
        return str.replace(templateSubstitutionRegExp, "\\${");
    }
    /** @internal */
    function hasInvalidEscape(template) {
        return template && !!(ts.isNoSubstitutionTemplateLiteral(template)
            ? template.templateFlags
            : (template.head.templateFlags || ts.some(template.templateSpans, function (span) { return !!span.literal.templateFlags; })));
    }
    ts.hasInvalidEscape = hasInvalidEscape;
    // This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
    // paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
    // the language service. These characters should be escaped when printing, and if any characters are added,
    // the map below must be updated. Note that this regexp *does not* include the 'delete' character.
    // There is no reason for this other than that JSON.stringify does not handle it either.
    var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    // Template strings should be preserved as much as possible
    var backtickQuoteEscapedCharsRegExp = /[\\`]/g;
    var escapedCharsMap = ts.createMapFromTemplate({
        "\t": "\\t",
        "\v": "\\v",
        "\f": "\\f",
        "\b": "\\b",
        "\r": "\\r",
        "\n": "\\n",
        "\\": "\\\\",
        "\"": "\\\"",
        "\'": "\\\'",
        "\`": "\\\`",
        "\u2028": "\\u2028",
        "\u2029": "\\u2029",
        "\u0085": "\\u0085" // nextLine
    });
    function encodeUtf16EscapeSequence(charCode) {
        var hexCharCode = charCode.toString(16).toUpperCase();
        var paddedHexCode = ("0000" + hexCharCode).slice(-4);
        return "\\u" + paddedHexCode;
    }
    function getReplacement(c, offset, input) {
        if (c.charCodeAt(0) === 0 /* nullCharacter */) {
            var lookAhead = input.charCodeAt(offset + c.length);
            if (lookAhead >= 48 /* _0 */ && lookAhead <= 57 /* _9 */) {
                // If the null character is followed by digits, print as a hex escape to prevent the result from parsing as an octal (which is forbidden in strict mode)
                return "\\x00";
            }
            // Otherwise, keep printing a literal \0 for the null character
            return "\\0";
        }
        return escapedCharsMap.get(c) || encodeUtf16EscapeSequence(c.charCodeAt(0));
    }
    /**
     * Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
     * but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine)
     * Note that this doesn't actually wrap the input in double quotes.
     */
    function escapeString(s, quoteChar) {
        var escapedCharsRegExp = quoteChar === 96 /* backtick */ ? backtickQuoteEscapedCharsRegExp :
            quoteChar === 39 /* singleQuote */ ? singleQuoteEscapedCharsRegExp :
                doubleQuoteEscapedCharsRegExp;
        return s.replace(escapedCharsRegExp, getReplacement);
    }
    ts.escapeString = escapeString;
    var nonAsciiCharacters = /[^\u0000-\u007F]/g;
    function escapeNonAsciiString(s, quoteChar) {
        s = escapeString(s, quoteChar);
        // Replace non-ASCII characters with '\uNNNN' escapes if any exist.
        // Otherwise just return the original string.
        return nonAsciiCharacters.test(s) ?
            s.replace(nonAsciiCharacters, function (c) { return encodeUtf16EscapeSequence(c.charCodeAt(0)); }) :
            s;
    }
    ts.escapeNonAsciiString = escapeNonAsciiString;
    // This consists of the first 19 unprintable ASCII characters, JSX canonical escapes, lineSeparator,
    // paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
    // the language service. These characters should be escaped when printing, and if any characters are added,
    // the map below must be updated.
    var jsxDoubleQuoteEscapedCharsRegExp = /[\"\u0000-\u001f\u2028\u2029\u0085]/g;
    var jsxSingleQuoteEscapedCharsRegExp = /[\'\u0000-\u001f\u2028\u2029\u0085]/g;
    var jsxEscapedCharsMap = ts.createMapFromTemplate({
        "\"": "&quot;",
        "\'": "&apos;"
    });
    function encodeJsxCharacterEntity(charCode) {
        var hexCharCode = charCode.toString(16).toUpperCase();
        return "&#x" + hexCharCode + ";";
    }
    function getJsxAttributeStringReplacement(c) {
        if (c.charCodeAt(0) === 0 /* nullCharacter */) {
            return "&#0;";
        }
        return jsxEscapedCharsMap.get(c) || encodeJsxCharacterEntity(c.charCodeAt(0));
    }
    function escapeJsxAttributeString(s, quoteChar) {
        var escapedCharsRegExp = quoteChar === 39 /* singleQuote */ ? jsxSingleQuoteEscapedCharsRegExp :
            jsxDoubleQuoteEscapedCharsRegExp;
        return s.replace(escapedCharsRegExp, getJsxAttributeStringReplacement);
    }
    ts.escapeJsxAttributeString = escapeJsxAttributeString;
    /**
     * Strip off existed surrounding single quotes, double quotes, or backticks from a given string
     *
     * @return non-quoted string
     */
    function stripQuotes(name) {
        var length = name.length;
        if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && isQuoteOrBacktick(name.charCodeAt(0))) {
            return name.substring(1, length - 1);
        }
        return name;
    }
    ts.stripQuotes = stripQuotes;
    function isQuoteOrBacktick(charCode) {
        return charCode === 39 /* singleQuote */ ||
            charCode === 34 /* doubleQuote */ ||
            charCode === 96 /* backtick */;
    }
    function isIntrinsicJsxName(name) {
        var ch = name.charCodeAt(0);
        return (ch >= 97 /* a */ && ch <= 122 /* z */) || ts.stringContains(name, "-");
    }
    ts.isIntrinsicJsxName = isIntrinsicJsxName;
    var indentStrings = ["", "    "];
    function getIndentString(level) {
        if (indentStrings[level] === undefined) {
            indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
        }
        return indentStrings[level];
    }
    ts.getIndentString = getIndentString;
    function getIndentSize() {
        return indentStrings[1].length;
    }
    ts.getIndentSize = getIndentSize;
    function createTextWriter(newLine) {
        var output;
        var indent;
        var lineStart;
        var lineCount;
        var linePos;
        var hasTrailingComment = false;
        function updateLineCountAndPosFor(s) {
            var lineStartsOfS = ts.computeLineStarts(s);
            if (lineStartsOfS.length > 1) {
                lineCount = lineCount + lineStartsOfS.length - 1;
                linePos = output.length - s.length + ts.last(lineStartsOfS);
                lineStart = (linePos - output.length) === 0;
            }
            else {
                lineStart = false;
            }
        }
        function writeText(s) {
            if (s && s.length) {
                if (lineStart) {
                    s = getIndentString(indent) + s;
                    lineStart = false;
                }
                output += s;
                updateLineCountAndPosFor(s);
            }
        }
        function write(s) {
            if (s)
                hasTrailingComment = false;
            writeText(s);
        }
        function writeComment(s) {
            if (s)
                hasTrailingComment = true;
            writeText(s);
        }
        function reset() {
            output = "";
            indent = 0;
            lineStart = true;
            lineCount = 0;
            linePos = 0;
            hasTrailingComment = false;
        }
        function rawWrite(s) {
            if (s !== undefined) {
                output += s;
                updateLineCountAndPosFor(s);
                hasTrailingComment = false;
            }
        }
        function writeLiteral(s) {
            if (s && s.length) {
                write(s);
            }
        }
        function writeLine(force) {
            if (!lineStart || force) {
                output += newLine;
                lineCount++;
                linePos = output.length;
                lineStart = true;
                hasTrailingComment = false;
            }
        }
        function getTextPosWithWriteLine() {
            return lineStart ? output.length : (output.length + newLine.length);
        }
        reset();
        return {
            write: write,
            rawWrite: rawWrite,
            writeLiteral: writeLiteral,
            writeLine: writeLine,
            increaseIndent: function () { indent++; },
            decreaseIndent: function () { indent--; },
            getIndent: function () { return indent; },
            getTextPos: function () { return output.length; },
            getLine: function () { return lineCount; },
            getColumn: function () { return lineStart ? indent * getIndentSize() : output.length - linePos; },
            getText: function () { return output; },
            isAtStartOfLine: function () { return lineStart; },
            hasTrailingComment: function () { return hasTrailingComment; },
            hasTrailingWhitespace: function () { return !!output.length && ts.isWhiteSpaceLike(output.charCodeAt(output.length - 1)); },
            clear: reset,
            reportInaccessibleThisError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
            reportInaccessibleUniqueSymbolError: ts.noop,
            trackSymbol: ts.noop,
            writeKeyword: write,
            writeOperator: write,
            writeParameter: write,
            writeProperty: write,
            writePunctuation: write,
            writeSpace: write,
            writeStringLiteral: write,
            writeSymbol: function (s, _) { return write(s); },
            writeTrailingSemicolon: write,
            writeComment: writeComment,
            getTextPosWithWriteLine: getTextPosWithWriteLine
        };
    }
    ts.createTextWriter = createTextWriter;
    function getTrailingSemicolonDeferringWriter(writer) {
        var pendingTrailingSemicolon = false;
        function commitPendingTrailingSemicolon() {
            if (pendingTrailingSemicolon) {
                writer.writeTrailingSemicolon(";");
                pendingTrailingSemicolon = false;
            }
        }
        return __assign(__assign({}, writer), { writeTrailingSemicolon: function () {
                pendingTrailingSemicolon = true;
            },
            writeLiteral: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeLiteral(s);
            },
            writeStringLiteral: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeStringLiteral(s);
            },
            writeSymbol: function (s, sym) {
                commitPendingTrailingSemicolon();
                writer.writeSymbol(s, sym);
            },
            writePunctuation: function (s) {
                commitPendingTrailingSemicolon();
                writer.writePunctuation(s);
            },
            writeKeyword: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeKeyword(s);
            },
            writeOperator: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeOperator(s);
            },
            writeParameter: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeParameter(s);
            },
            writeSpace: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeSpace(s);
            },
            writeProperty: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeProperty(s);
            },
            writeComment: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeComment(s);
            },
            writeLine: function () {
                commitPendingTrailingSemicolon();
                writer.writeLine();
            },
            increaseIndent: function () {
                commitPendingTrailingSemicolon();
                writer.increaseIndent();
            },
            decreaseIndent: function () {
                commitPendingTrailingSemicolon();
                writer.decreaseIndent();
            } });
    }
    ts.getTrailingSemicolonDeferringWriter = getTrailingSemicolonDeferringWriter;
    function hostUsesCaseSensitiveFileNames(host) {
        return host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false;
    }
    ts.hostUsesCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames;
    function hostGetCanonicalFileName(host) {
        return ts.createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host));
    }
    ts.hostGetCanonicalFileName = hostGetCanonicalFileName;
    function getResolvedExternalModuleName(host, file, referenceFile) {
        return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName);
    }
    ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
    function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
        var file = resolver.getExternalModuleFileFromDeclaration(declaration);
        if (!file || file.isDeclarationFile) {
            return undefined;
        }
        return getResolvedExternalModuleName(host, file);
    }
    ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
    /**
     * Resolves a local path to a path which is absolute to the base of the emit
     */
    function getExternalModuleNameFromPath(host, fileName, referencePath) {
        var getCanonicalFileName = function (f) { return host.getCanonicalFileName(f); };
        var dir = ts.toPath(referencePath ? ts.getDirectoryPath(referencePath) : host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName);
        var filePath = ts.getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
        var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
        var extensionless = removeFileExtension(relativePath);
        return referencePath ? ts.ensurePathIsNonModuleName(extensionless) : extensionless;
    }
    ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
    function getOwnEmitOutputFilePath(fileName, host, extension) {
        var compilerOptions = host.getCompilerOptions();
        var emitOutputFilePathWithoutExtension;
        if (compilerOptions.outDir) {
            emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(fileName, host, compilerOptions.outDir));
        }
        else {
            emitOutputFilePathWithoutExtension = removeFileExtension(fileName);
        }
        return emitOutputFilePathWithoutExtension + extension;
    }
    ts.getOwnEmitOutputFilePath = getOwnEmitOutputFilePath;
    function getDeclarationEmitOutputFilePath(fileName, host) {
        return getDeclarationEmitOutputFilePathWorker(fileName, host.getCompilerOptions(), host.getCurrentDirectory(), host.getCommonSourceDirectory(), function (f) { return host.getCanonicalFileName(f); });
    }
    ts.getDeclarationEmitOutputFilePath = getDeclarationEmitOutputFilePath;
    function getDeclarationEmitOutputFilePathWorker(fileName, options, currentDirectory, commonSourceDirectory, getCanonicalFileName) {
        var outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified
        var path = outputDir
            ? getSourceFilePathInNewDirWorker(fileName, outputDir, currentDirectory, commonSourceDirectory, getCanonicalFileName)
            : fileName;
        return removeFileExtension(path) + ".d.ts" /* Dts */;
    }
    ts.getDeclarationEmitOutputFilePathWorker = getDeclarationEmitOutputFilePathWorker;
    /**
     * Gets the source files that are expected to have an emit output.
     *
     * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support
     * transformations.
     *
     * @param host An EmitHost.
     * @param targetSourceFile An optional target source file to emit.
     */
    function getSourceFilesToEmit(host, targetSourceFile, forceDtsEmit) {
        var options = host.getCompilerOptions();
        if (options.outFile || options.out) {
            var moduleKind = getEmitModuleKind(options);
            var moduleEmitEnabled_1 = options.emitDeclarationOnly || moduleKind === ts.ModuleKind.AMD || moduleKind === ts.ModuleKind.System;
            // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
            return ts.filter(host.getSourceFiles(), function (sourceFile) {
                return (moduleEmitEnabled_1 || !ts.isExternalModule(sourceFile)) &&
                    sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit);
            });
        }
        else {
            var sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
            return ts.filter(sourceFiles, function (sourceFile) { return sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit); });
        }
    }
    ts.getSourceFilesToEmit = getSourceFilesToEmit;
    /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */
    function sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) {
        var options = host.getCompilerOptions();
        return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) &&
            !sourceFile.isDeclarationFile &&
            !host.isSourceFileFromExternalLibrary(sourceFile) &&
            !(isJsonSourceFile(sourceFile) && host.getResolvedProjectReferenceToRedirect(sourceFile.fileName)) &&
            (forceDtsEmit || !host.isSourceOfProjectReferenceRedirect(sourceFile.fileName));
    }
    ts.sourceFileMayBeEmitted = sourceFileMayBeEmitted;
    function getSourceFilePathInNewDir(fileName, host, newDirPath) {
        return getSourceFilePathInNewDirWorker(fileName, newDirPath, host.getCurrentDirectory(), host.getCommonSourceDirectory(), function (f) { return host.getCanonicalFileName(f); });
    }
    ts.getSourceFilePathInNewDir = getSourceFilePathInNewDir;
    function getSourceFilePathInNewDirWorker(fileName, newDirPath, currentDirectory, commonSourceDirectory, getCanonicalFileName) {
        var sourceFilePath = ts.getNormalizedAbsolutePath(fileName, currentDirectory);
        var isSourceFileInCommonSourceDirectory = getCanonicalFileName(sourceFilePath).indexOf(getCanonicalFileName(commonSourceDirectory)) === 0;
        sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
        return ts.combinePaths(newDirPath, sourceFilePath);
    }
    ts.getSourceFilePathInNewDirWorker = getSourceFilePathInNewDirWorker;
    function writeFile(host, diagnostics, fileName, data, writeByteOrderMark, sourceFiles) {
        host.writeFile(fileName, data, writeByteOrderMark, function (hostErrorMessage) {
            diagnostics.add(createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
        }, sourceFiles);
    }
    ts.writeFile = writeFile;
    function ensureDirectoriesExist(directoryPath, createDirectory, directoryExists) {
        if (directoryPath.length > ts.getRootLength(directoryPath) && !directoryExists(directoryPath)) {
            var parentDirectory = ts.getDirectoryPath(directoryPath);
            ensureDirectoriesExist(parentDirectory, createDirectory, directoryExists);
            createDirectory(directoryPath);
        }
    }
    function writeFileEnsuringDirectories(path, data, writeByteOrderMark, writeFile, createDirectory, directoryExists) {
        // PERF: Checking for directory existence is expensive.  Instead, assume the directory exists
        // and fall back to creating it if the file write fails.
        try {
            writeFile(path, data, writeByteOrderMark);
        }
        catch (_a) {
            ensureDirectoriesExist(ts.getDirectoryPath(ts.normalizePath(path)), createDirectory, directoryExists);
            writeFile(path, data, writeByteOrderMark);
        }
    }
    ts.writeFileEnsuringDirectories = writeFileEnsuringDirectories;
    function getLineOfLocalPosition(sourceFile, pos) {
        var lineStarts = ts.getLineStarts(sourceFile);
        return ts.computeLineOfPosition(lineStarts, pos);
    }
    ts.getLineOfLocalPosition = getLineOfLocalPosition;
    function getLineOfLocalPositionFromLineMap(lineMap, pos) {
        return ts.computeLineOfPosition(lineMap, pos);
    }
    ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
    function getFirstConstructorWithBody(node) {
        return ts.find(node.members, function (member) { return ts.isConstructorDeclaration(member) && nodeIsPresent(member.body); });
    }
    ts.getFirstConstructorWithBody = getFirstConstructorWithBody;
    function getSetAccessorValueParameter(accessor) {
        if (accessor && accessor.parameters.length > 0) {
            var hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
            return accessor.parameters[hasThis ? 1 : 0];
        }
    }
    ts.getSetAccessorValueParameter = getSetAccessorValueParameter;
    /** Get the type annotation for the value parameter. */
    function getSetAccessorTypeAnnotationNode(accessor) {
        var parameter = getSetAccessorValueParameter(accessor);
        return parameter && parameter.type;
    }
    ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode;
    function getThisParameter(signature) {
        // callback tags do not currently support this parameters
        if (signature.parameters.length && !ts.isJSDocSignature(signature)) {
            var thisParameter = signature.parameters[0];
            if (parameterIsThisKeyword(thisParameter)) {
                return thisParameter;
            }
        }
    }
    ts.getThisParameter = getThisParameter;
    function parameterIsThisKeyword(parameter) {
        return isThisIdentifier(parameter.name);
    }
    ts.parameterIsThisKeyword = parameterIsThisKeyword;
    function isThisIdentifier(node) {
        return !!node && node.kind === 75 /* Identifier */ && identifierIsThisKeyword(node);
    }
    ts.isThisIdentifier = isThisIdentifier;
    function identifierIsThisKeyword(id) {
        return id.originalKeywordKind === 104 /* ThisKeyword */;
    }
    ts.identifierIsThisKeyword = identifierIsThisKeyword;
    function getAllAccessorDeclarations(declarations, accessor) {
        // TODO: GH#18217
        var firstAccessor;
        var secondAccessor;
        var getAccessor;
        var setAccessor;
        if (hasDynamicName(accessor)) {
            firstAccessor = accessor;
            if (accessor.kind === 163 /* GetAccessor */) {
                getAccessor = accessor;
            }
            else if (accessor.kind === 164 /* SetAccessor */) {
                setAccessor = accessor;
            }
            else {
                ts.Debug.fail("Accessor has wrong kind");
            }
        }
        else {
            ts.forEach(declarations, function (member) {
                if (ts.isAccessor(member)
                    && hasModifier(member, 32 /* Static */) === hasModifier(accessor, 32 /* Static */)) {
                    var memberName = getPropertyNameForPropertyNameNode(member.name);
                    var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
                    if (memberName === accessorName) {
                        if (!firstAccessor) {
                            firstAccessor = member;
                        }
                        else if (!secondAccessor) {
                            secondAccessor = member;
                        }
                        if (member.kind === 163 /* GetAccessor */ && !getAccessor) {
                            // eslint-disable-next-line
                            getAccessor = member;
                        }
                        if (member.kind === 164 /* SetAccessor */ && !setAccessor) {
                            // eslint-disable-next-line
                            setAccessor = member;
                        }
                    }
                }
            });
        }
        return {
            firstAccessor: firstAccessor,
            secondAccessor: secondAccessor,
            getAccessor: getAccessor,
            setAccessor: setAccessor
        };
    }
    ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
    /**
     * Gets the effective type annotation of a variable, parameter, or property. If the node was
     * parsed in a JavaScript file, gets the type annotation from JSDoc.  Also gets the type of
     * functions only the JSDoc case.
     */
    function getEffectiveTypeAnnotationNode(node) {
        if (!isInJSFile(node) && ts.isFunctionDeclaration(node))
            return undefined;
        var type = node.type;
        if (type || !isInJSFile(node))
            return type;
        return ts.isJSDocPropertyLikeTag(node) ? node.typeExpression && node.typeExpression.type : ts.getJSDocType(node);
    }
    ts.getEffectiveTypeAnnotationNode = getEffectiveTypeAnnotationNode;
    function getTypeAnnotationNode(node) {
        return node.type;
    }
    ts.getTypeAnnotationNode = getTypeAnnotationNode;
    /**
     * Gets the effective return type annotation of a signature. If the node was parsed in a
     * JavaScript file, gets the return type annotation from JSDoc.
     */
    function getEffectiveReturnTypeNode(node) {
        return ts.isJSDocSignature(node) ?
            node.type && node.type.typeExpression && node.type.typeExpression.type :
            node.type || (isInJSFile(node) ? ts.getJSDocReturnType(node) : undefined);
    }
    ts.getEffectiveReturnTypeNode = getEffectiveReturnTypeNode;
    function getJSDocTypeParameterDeclarations(node) {
        return ts.flatMap(ts.getJSDocTags(node), function (tag) { return isNonTypeAliasTemplate(tag) ? tag.typeParameters : undefined; });
    }
    ts.getJSDocTypeParameterDeclarations = getJSDocTypeParameterDeclarations;
    /** template tags are only available when a typedef isn't already using them */
    function isNonTypeAliasTemplate(tag) {
        return ts.isJSDocTemplateTag(tag) && !(tag.parent.kind === 303 /* JSDocComment */ && tag.parent.tags.some(isJSDocTypeAlias));
    }
    /**
     * Gets the effective type annotation of the value parameter of a set accessor. If the node
     * was parsed in a JavaScript file, gets the type annotation from JSDoc.
     */
    function getEffectiveSetAccessorTypeAnnotationNode(node) {
        var parameter = getSetAccessorValueParameter(node);
        return parameter && getEffectiveTypeAnnotationNode(parameter);
    }
    ts.getEffectiveSetAccessorTypeAnnotationNode = getEffectiveSetAccessorTypeAnnotationNode;
    function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
        emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
    }
    ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
    function emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, pos, leadingComments) {
        // If the leading comments start on different line than the start of node, write new line
        if (leadingComments && leadingComments.length && pos !== leadingComments[0].pos &&
            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingCommentsOfPosition = emitNewLineBeforeLeadingCommentsOfPosition;
    function emitNewLineBeforeLeadingCommentOfPosition(lineMap, writer, pos, commentPos) {
        // If the leading comments start on different line than the start of node, write new line
        if (pos !== commentPos &&
            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, commentPos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingCommentOfPosition = emitNewLineBeforeLeadingCommentOfPosition;
    function emitComments(text, lineMap, writer, comments, leadingSeparator, trailingSeparator, newLine, writeComment) {
        if (comments && comments.length > 0) {
            if (leadingSeparator) {
                writer.writeSpace(" ");
            }
            var emitInterveningSeparator = false;
            for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
                var comment = comments_1[_i];
                if (emitInterveningSeparator) {
                    writer.writeSpace(" ");
                    emitInterveningSeparator = false;
                }
                writeComment(text, lineMap, writer, comment.pos, comment.end, newLine);
                if (comment.hasTrailingNewLine) {
                    writer.writeLine();
                }
                else {
                    emitInterveningSeparator = true;
                }
            }
            if (emitInterveningSeparator && trailingSeparator) {
                writer.writeSpace(" ");
            }
        }
    }
    ts.emitComments = emitComments;
    /**
     * Detached comment is a comment at the top of file or function body that is separated from
     * the next statement by space.
     */
    function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
        var leadingComments;
        var currentDetachedCommentInfo;
        if (removeComments) {
            // removeComments is true, only reserve pinned comment at the top of file
            // For example:
            //      /*! Pinned Comment */
            //
            //      var x = 10;
            if (node.pos === 0) {
                leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal);
            }
        }
        else {
            // removeComments is false, just get detached as normal and bypass the process to filter comment
            leadingComments = ts.getLeadingCommentRanges(text, node.pos);
        }
        if (leadingComments) {
            var detachedComments = [];
            var lastComment = void 0;
            for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
                var comment = leadingComments_1[_i];
                if (lastComment) {
                    var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
                    var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
                    if (commentLine >= lastCommentLine + 2) {
                        // There was a blank line between the last comment and this comment.  This
                        // comment is not part of the copyright comments.  Return what we have so
                        // far.
                        break;
                    }
                }
                detachedComments.push(comment);
                lastComment = comment;
            }
            if (detachedComments.length) {
                // All comments look like they could have been part of the copyright header.  Make
                // sure there is at least one blank line between it and the node.  If not, it's not
                // a copyright header.
                var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.last(detachedComments).end);
                var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
                if (nodeLine >= lastCommentLine + 2) {
                    // Valid detachedComments
                    emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
                    emitComments(text, lineMap, writer, detachedComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
                    currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.last(detachedComments).end };
                }
            }
        }
        return currentDetachedCommentInfo;
        function isPinnedCommentLocal(comment) {
            return isPinnedComment(text, comment.pos);
        }
    }
    ts.emitDetachedComments = emitDetachedComments;
    function writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine) {
        if (text.charCodeAt(commentPos + 1) === 42 /* asterisk */) {
            var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, commentPos);
            var lineCount = lineMap.length;
            var firstCommentLineIndent = void 0;
            for (var pos = commentPos, currentLine = firstCommentLineAndCharacter.line; pos < commentEnd; currentLine++) {
                var nextLineStart = (currentLine + 1) === lineCount
                    ? text.length + 1
                    : lineMap[currentLine + 1];
                if (pos !== commentPos) {
                    // If we are not emitting first line, we need to write the spaces to adjust the alignment
                    if (firstCommentLineIndent === undefined) {
                        firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], commentPos);
                    }
                    // These are number of spaces writer is going to write at current indent
                    var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
                    // Number of spaces we want to be writing
                    // eg: Assume writer indent
                    // module m {
                    //         /* starts at character 9 this is line 1
                    //    * starts at character pos 4 line                        --1  = 8 - 8 + 3
                    //   More left indented comment */                            --2  = 8 - 8 + 2
                    //     class c { }
                    // }
                    // module m {
                    //     /* this is line 1 -- Assume current writer indent 8
                    //      * line                                                --3 = 8 - 4 + 5
                    //            More right indented comment */                  --4 = 8 - 4 + 11
                    //     class c { }
                    // }
                    var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
                    if (spacesToEmit > 0) {
                        var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
                        var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
                        // Write indent size string ( in eg 1: = "", 2: "" , 3: string with 8 spaces 4: string with 12 spaces
                        writer.rawWrite(indentSizeSpaceString);
                        // Emit the single spaces (in eg: 1: 3 spaces, 2: 2 spaces, 3: 1 space, 4: 3 spaces)
                        while (numberOfSingleSpacesToEmit) {
                            writer.rawWrite(" ");
                            numberOfSingleSpacesToEmit--;
                        }
                    }
                    else {
                        // No spaces to emit write empty string
                        writer.rawWrite("");
                    }
                }
                // Write the comment line text
                writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart);
                pos = nextLineStart;
            }
        }
        else {
            // Single line comment of style //....
            writer.writeComment(text.substring(commentPos, commentEnd));
        }
    }
    ts.writeCommentRange = writeCommentRange;
    function writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart) {
        var end = Math.min(commentEnd, nextLineStart - 1);
        var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
        if (currentLineText) {
            // trimmed forward and ending spaces text
            writer.writeComment(currentLineText);
            if (end !== commentEnd) {
                writer.writeLine();
            }
        }
        else {
            // Empty string - make sure we write empty line
            writer.rawWrite(newLine);
        }
    }
    function calculateIndent(text, pos, end) {
        var currentLineIndent = 0;
        for (; pos < end && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++) {
            if (text.charCodeAt(pos) === 9 /* tab */) {
                // Tabs = TabSize = indent size and go to next tabStop
                currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
            }
            else {
                // Single space
                currentLineIndent++;
            }
        }
        return currentLineIndent;
    }
    function hasModifiers(node) {
        return getModifierFlags(node) !== 0 /* None */;
    }
    ts.hasModifiers = hasModifiers;
    function hasModifier(node, flags) {
        return !!getSelectedModifierFlags(node, flags);
    }
    ts.hasModifier = hasModifier;
    function hasStaticModifier(node) {
        return hasModifier(node, 32 /* Static */);
    }
    ts.hasStaticModifier = hasStaticModifier;
    function hasReadonlyModifier(node) {
        return hasModifier(node, 64 /* Readonly */);
    }
    ts.hasReadonlyModifier = hasReadonlyModifier;
    function getSelectedModifierFlags(node, flags) {
        return getModifierFlags(node) & flags;
    }
    ts.getSelectedModifierFlags = getSelectedModifierFlags;
    function getModifierFlags(node) {
        if (node.kind >= 0 /* FirstToken */ && node.kind <= 152 /* LastToken */) {
            return 0 /* None */;
        }
        if (node.modifierFlagsCache & 536870912 /* HasComputedFlags */) {
            return node.modifierFlagsCache & ~536870912 /* HasComputedFlags */;
        }
        var flags = getModifierFlagsNoCache(node);
        node.modifierFlagsCache = flags | 536870912 /* HasComputedFlags */;
        return flags;
    }
    ts.getModifierFlags = getModifierFlags;
    function getModifierFlagsNoCache(node) {
        var flags = 0 /* None */;
        if (node.modifiers) {
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                flags |= modifierToFlag(modifier.kind);
            }
        }
        if (isInJSFile(node) && !!node.parent) {
            // getModifierFlagsNoCache should only be called when parent pointers are set,
            // or when !(node.flags & NodeFlags.Synthesized) && node.kind !== SyntaxKind.SourceFile)
            var tags = (ts.getJSDocPublicTag(node) ? 4 /* Public */ : 0 /* None */)
                | (ts.getJSDocPrivateTag(node) ? 8 /* Private */ : 0 /* None */)
                | (ts.getJSDocProtectedTag(node) ? 16 /* Protected */ : 0 /* None */)
                | (ts.getJSDocReadonlyTag(node) ? 64 /* Readonly */ : 0 /* None */);
            flags |= tags;
        }
        if (node.flags & 4 /* NestedNamespace */ || (node.kind === 75 /* Identifier */ && node.isInJSDocNamespace)) {
            flags |= 1 /* Export */;
        }
        return flags;
    }
    ts.getModifierFlagsNoCache = getModifierFlagsNoCache;
    function modifierToFlag(token) {
        switch (token) {
            case 120 /* StaticKeyword */: return 32 /* Static */;
            case 119 /* PublicKeyword */: return 4 /* Public */;
            case 118 /* ProtectedKeyword */: return 16 /* Protected */;
            case 117 /* PrivateKeyword */: return 8 /* Private */;
            case 122 /* AbstractKeyword */: return 128 /* Abstract */;
            case 89 /* ExportKeyword */: return 1 /* Export */;
            case 130 /* DeclareKeyword */: return 2 /* Ambient */;
            case 81 /* ConstKeyword */: return 2048 /* Const */;
            case 84 /* DefaultKeyword */: return 512 /* Default */;
            case 126 /* AsyncKeyword */: return 256 /* Async */;
            case 138 /* ReadonlyKeyword */: return 64 /* Readonly */;
        }
        return 0 /* None */;
    }
    ts.modifierToFlag = modifierToFlag;
    function isLogicalOperator(token) {
        return token === 56 /* BarBarToken */
            || token === 55 /* AmpersandAmpersandToken */
            || token === 53 /* ExclamationToken */;
    }
    ts.isLogicalOperator = isLogicalOperator;
    function isAssignmentOperator(token) {
        return token >= 62 /* FirstAssignment */ && token <= 74 /* LastAssignment */;
    }
    ts.isAssignmentOperator = isAssignmentOperator;
    /** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
    function tryGetClassExtendingExpressionWithTypeArguments(node) {
        var cls = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
        return cls && !cls.isImplements ? cls.class : undefined;
    }
    ts.tryGetClassExtendingExpressionWithTypeArguments = tryGetClassExtendingExpressionWithTypeArguments;
    function tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node) {
        return ts.isExpressionWithTypeArguments(node)
            && ts.isHeritageClause(node.parent)
            && ts.isClassLike(node.parent.parent)
            ? { class: node.parent.parent, isImplements: node.parent.token === 113 /* ImplementsKeyword */ }
            : undefined;
    }
    ts.tryGetClassImplementingOrExtendingExpressionWithTypeArguments = tryGetClassImplementingOrExtendingExpressionWithTypeArguments;
    function isAssignmentExpression(node, excludeCompoundAssignment) {
        return ts.isBinaryExpression(node)
            && (excludeCompoundAssignment
                ? node.operatorToken.kind === 62 /* EqualsToken */
                : isAssignmentOperator(node.operatorToken.kind))
            && ts.isLeftHandSideExpression(node.left);
    }
    ts.isAssignmentExpression = isAssignmentExpression;
    function isDestructuringAssignment(node) {
        if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
            var kind = node.left.kind;
            return kind === 193 /* ObjectLiteralExpression */
                || kind === 192 /* ArrayLiteralExpression */;
        }
        return false;
    }
    ts.isDestructuringAssignment = isDestructuringAssignment;
    function isExpressionWithTypeArgumentsInClassExtendsClause(node) {
        return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
    }
    ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause;
    function isEntityNameExpression(node) {
        return node.kind === 75 /* Identifier */ || isPropertyAccessEntityNameExpression(node);
    }
    ts.isEntityNameExpression = isEntityNameExpression;
    function getFirstIdentifier(node) {
        switch (node.kind) {
            case 75 /* Identifier */:
                return node;
            case 153 /* QualifiedName */:
                do {
                    node = node.left;
                } while (node.kind !== 75 /* Identifier */);
                return node;
            case 194 /* PropertyAccessExpression */:
                do {
                    node = node.expression;
                } while (node.kind !== 75 /* Identifier */);
                return node;
        }
    }
    ts.getFirstIdentifier = getFirstIdentifier;
    function isDottedName(node) {
        return node.kind === 75 /* Identifier */ || node.kind === 104 /* ThisKeyword */ || node.kind === 102 /* SuperKeyword */ ||
            node.kind === 194 /* PropertyAccessExpression */ && isDottedName(node.expression) ||
            node.kind === 200 /* ParenthesizedExpression */ && isDottedName(node.expression);
    }
    ts.isDottedName = isDottedName;
    function isPropertyAccessEntityNameExpression(node) {
        return ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && isEntityNameExpression(node.expression);
    }
    ts.isPropertyAccessEntityNameExpression = isPropertyAccessEntityNameExpression;
    function tryGetPropertyAccessOrIdentifierToString(expr) {
        if (ts.isPropertyAccessExpression(expr)) {
            var baseStr = tryGetPropertyAccessOrIdentifierToString(expr.expression);
            if (baseStr !== undefined) {
                return baseStr + "." + expr.name;
            }
        }
        else if (ts.isIdentifier(expr)) {
            return ts.unescapeLeadingUnderscores(expr.escapedText);
        }
        return undefined;
    }
    ts.tryGetPropertyAccessOrIdentifierToString = tryGetPropertyAccessOrIdentifierToString;
    function isPrototypeAccess(node) {
        return isBindableStaticAccessExpression(node) && getElementOrPropertyAccessName(node) === "prototype";
    }
    ts.isPrototypeAccess = isPrototypeAccess;
    function isRightSideOfQualifiedNameOrPropertyAccess(node) {
        return (node.parent.kind === 153 /* QualifiedName */ && node.parent.right === node) ||
            (node.parent.kind === 194 /* PropertyAccessExpression */ && node.parent.name === node);
    }
    ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess;
    function isEmptyObjectLiteral(expression) {
        return expression.kind === 193 /* ObjectLiteralExpression */ &&
            expression.properties.length === 0;
    }
    ts.isEmptyObjectLiteral = isEmptyObjectLiteral;
    function isEmptyArrayLiteral(expression) {
        return expression.kind === 192 /* ArrayLiteralExpression */ &&
            expression.elements.length === 0;
    }
    ts.isEmptyArrayLiteral = isEmptyArrayLiteral;
    function getLocalSymbolForExportDefault(symbol) {
        return isExportDefaultSymbol(symbol) ? symbol.declarations[0].localSymbol : undefined;
    }
    ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
    function isExportDefaultSymbol(symbol) {
        return symbol && ts.length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], 512 /* Default */);
    }
    /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
    function tryExtractTSExtension(fileName) {
        return ts.find(ts.supportedTSExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.tryExtractTSExtension = tryExtractTSExtension;
    /**
     * Replace each instance of non-ascii characters by one, two, three, or four escape sequences
     * representing the UTF-8 encoding of the character, and return the expanded char code list.
     */
    function getExpandedCharCodes(input) {
        var output = [];
        var length = input.length;
        for (var i = 0; i < length; i++) {
            var charCode = input.charCodeAt(i);
            // handle utf8
            if (charCode < 0x80) {
                output.push(charCode);
            }
            else if (charCode < 0x800) {
                output.push((charCode >> 6) | 192);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x10000) {
                output.push((charCode >> 12) | 224);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x20000) {
                output.push((charCode >> 18) | 240);
                output.push(((charCode >> 12) & 63) | 128);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else {
                ts.Debug.assert(false, "Unexpected code point");
            }
        }
        return output;
    }
    var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    /**
     * Converts a string to a base-64 encoded ASCII string.
     */
    function convertToBase64(input) {
        var result = "";
        var charCodes = getExpandedCharCodes(input);
        var i = 0;
        var length = charCodes.length;
        var byte1, byte2, byte3, byte4;
        while (i < length) {
            // Convert every 6-bits in the input 3 character points
            // into a base64 digit
            byte1 = charCodes[i] >> 2;
            byte2 = (charCodes[i] & 3) << 4 | charCodes[i + 1] >> 4;
            byte3 = (charCodes[i + 1] & 15) << 2 | charCodes[i + 2] >> 6;
            byte4 = charCodes[i + 2] & 63;
            // We are out of characters in the input, set the extra
            // digits to 64 (padding character).
            if (i + 1 >= length) {
                byte3 = byte4 = 64;
            }
            else if (i + 2 >= length) {
                byte4 = 64;
            }
            // Write to the output
            result += base64Digits.charAt(byte1) + base64Digits.charAt(byte2) + base64Digits.charAt(byte3) + base64Digits.charAt(byte4);
            i += 3;
        }
        return result;
    }
    ts.convertToBase64 = convertToBase64;
    function getStringFromExpandedCharCodes(codes) {
        var output = "";
        var i = 0;
        var length = codes.length;
        while (i < length) {
            var charCode = codes[i];
            if (charCode < 0x80) {
                output += String.fromCharCode(charCode);
                i++;
            }
            else if ((charCode & 192) === 192) {
                var value = charCode & 63;
                i++;
                var nextCode = codes[i];
                while ((nextCode & 192) === 128) {
                    value = (value << 6) | (nextCode & 63);
                    i++;
                    nextCode = codes[i];
                }
                // `value` may be greater than 10FFFF (the maximum unicode codepoint) - JS will just make this into an invalid character for us
                output += String.fromCharCode(value);
            }
            else {
                // We don't want to kill the process when decoding fails (due to a following char byte not
                // following a leading char), so we just print the (bad) value
                output += String.fromCharCode(charCode);
                i++;
            }
        }
        return output;
    }
    function base64encode(host, input) {
        if (host && host.base64encode) {
            return host.base64encode(input);
        }
        return convertToBase64(input);
    }
    ts.base64encode = base64encode;
    function base64decode(host, input) {
        if (host && host.base64decode) {
            return host.base64decode(input);
        }
        var length = input.length;
        var expandedCharCodes = [];
        var i = 0;
        while (i < length) {
            // Stop decoding once padding characters are present
            if (input.charCodeAt(i) === base64Digits.charCodeAt(64)) {
                break;
            }
            // convert 4 input digits into three characters, ignoring padding characters at the end
            var ch1 = base64Digits.indexOf(input[i]);
            var ch2 = base64Digits.indexOf(input[i + 1]);
            var ch3 = base64Digits.indexOf(input[i + 2]);
            var ch4 = base64Digits.indexOf(input[i + 3]);
            var code1 = ((ch1 & 63) << 2) | ((ch2 >> 4) & 3);
            var code2 = ((ch2 & 15) << 4) | ((ch3 >> 2) & 15);
            var code3 = ((ch3 & 3) << 6) | (ch4 & 63);
            if (code2 === 0 && ch3 !== 0) { // code2 decoded to zero, but ch3 was padding - elide code2 and code3
                expandedCharCodes.push(code1);
            }
            else if (code3 === 0 && ch4 !== 0) { // code3 decoded to zero, but ch4 was padding, elide code3
                expandedCharCodes.push(code1, code2);
            }
            else {
                expandedCharCodes.push(code1, code2, code3);
            }
            i += 4;
        }
        return getStringFromExpandedCharCodes(expandedCharCodes);
    }
    ts.base64decode = base64decode;
    function readJson(path, host) {
        try {
            var jsonText = host.readFile(path);
            if (!jsonText)
                return {};
            var result = ts.parseConfigFileTextToJson(path, jsonText);
            if (result.error) {
                return {};
            }
            return result.config;
        }
        catch (e) {
            // gracefully handle if readFile fails or returns not JSON
            return {};
        }
    }
    ts.readJson = readJson;
    function directoryProbablyExists(directoryName, host) {
        // if host does not support 'directoryExists' assume that directory will exist
        return !host.directoryExists || host.directoryExists(directoryName);
    }
    ts.directoryProbablyExists = directoryProbablyExists;
    var carriageReturnLineFeed = "\r\n";
    var lineFeed = "\n";
    function getNewLineCharacter(options, getNewLine) {
        switch (options.newLine) {
            case 0 /* CarriageReturnLineFeed */:
                return carriageReturnLineFeed;
            case 1 /* LineFeed */:
                return lineFeed;
        }
        return getNewLine ? getNewLine() : ts.sys ? ts.sys.newLine : carriageReturnLineFeed;
    }
    ts.getNewLineCharacter = getNewLineCharacter;
    /**
     * Creates a new TextRange from the provided pos and end.
     *
     * @param pos The start position.
     * @param end The end position.
     */
    function createRange(pos, end) {
        if (end === void 0) { end = pos; }
        ts.Debug.assert(end >= pos || end === -1);
        return { pos: pos, end: end };
    }
    ts.createRange = createRange;
    /**
     * Creates a new TextRange from a provided range with a new end position.
     *
     * @param range A TextRange.
     * @param end The new end position.
     */
    function moveRangeEnd(range, end) {
        return createRange(range.pos, end);
    }
    ts.moveRangeEnd = moveRangeEnd;
    /**
     * Creates a new TextRange from a provided range with a new start position.
     *
     * @param range A TextRange.
     * @param pos The new Start position.
     */
    function moveRangePos(range, pos) {
        return createRange(pos, range.end);
    }
    ts.moveRangePos = moveRangePos;
    /**
     * Moves the start position of a range past any decorators.
     */
    function moveRangePastDecorators(node) {
        return node.decorators && node.decorators.length > 0
            ? moveRangePos(node, node.decorators.end)
            : node;
    }
    ts.moveRangePastDecorators = moveRangePastDecorators;
    /**
     * Moves the start position of a range past any decorators or modifiers.
     */
    function moveRangePastModifiers(node) {
        return node.modifiers && node.modifiers.length > 0
            ? moveRangePos(node, node.modifiers.end)
            : moveRangePastDecorators(node);
    }
    ts.moveRangePastModifiers = moveRangePastModifiers;
    /**
     * Determines whether a TextRange has the same start and end positions.
     *
     * @param range A TextRange.
     */
    function isCollapsedRange(range) {
        return range.pos === range.end;
    }
    ts.isCollapsedRange = isCollapsedRange;
    /**
     * Creates a new TextRange for a token at the provides start position.
     *
     * @param pos The start position.
     * @param token The token.
     */
    function createTokenRange(pos, token) {
        return createRange(pos, pos + ts.tokenToString(token).length);
    }
    ts.createTokenRange = createTokenRange;
    function rangeIsOnSingleLine(range, sourceFile) {
        return rangeStartIsOnSameLineAsRangeEnd(range, range, sourceFile);
    }
    ts.rangeIsOnSingleLine = rangeIsOnSingleLine;
    function rangeStartPositionsAreOnSameLine(range1, range2, sourceFile) {
        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile, /*includeComments*/ false), getStartPositionOfRange(range2, sourceFile, /*includeComments*/ false), sourceFile);
    }
    ts.rangeStartPositionsAreOnSameLine = rangeStartPositionsAreOnSameLine;
    function rangeEndPositionsAreOnSameLine(range1, range2, sourceFile) {
        return positionsAreOnSameLine(range1.end, range2.end, sourceFile);
    }
    ts.rangeEndPositionsAreOnSameLine = rangeEndPositionsAreOnSameLine;
    function rangeStartIsOnSameLineAsRangeEnd(range1, range2, sourceFile) {
        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile, /*includeComments*/ false), range2.end, sourceFile);
    }
    ts.rangeStartIsOnSameLineAsRangeEnd = rangeStartIsOnSameLineAsRangeEnd;
    function rangeEndIsOnSameLineAsRangeStart(range1, range2, sourceFile) {
        return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile, /*includeComments*/ false), sourceFile);
    }
    ts.rangeEndIsOnSameLineAsRangeStart = rangeEndIsOnSameLineAsRangeStart;
    function getLinesBetweenRangeEndAndRangeStart(range1, range2, sourceFile, includeSecondRangeComments) {
        var range2Start = getStartPositionOfRange(range2, sourceFile, includeSecondRangeComments);
        return ts.getLinesBetweenPositions(sourceFile, range1.end, range2Start);
    }
    ts.getLinesBetweenRangeEndAndRangeStart = getLinesBetweenRangeEndAndRangeStart;
    function getLinesBetweenRangeEndPositions(range1, range2, sourceFile) {
        return ts.getLinesBetweenPositions(sourceFile, range1.end, range2.end);
    }
    ts.getLinesBetweenRangeEndPositions = getLinesBetweenRangeEndPositions;
    function isNodeArrayMultiLine(list, sourceFile) {
        return !positionsAreOnSameLine(list.pos, list.end, sourceFile);
    }
    ts.isNodeArrayMultiLine = isNodeArrayMultiLine;
    function positionsAreOnSameLine(pos1, pos2, sourceFile) {
        return ts.getLinesBetweenPositions(sourceFile, pos1, pos2) === 0;
    }
    ts.positionsAreOnSameLine = positionsAreOnSameLine;
    function getStartPositionOfRange(range, sourceFile, includeComments) {
        return positionIsSynthesized(range.pos) ? -1 : ts.skipTrivia(sourceFile.text, range.pos, /*stopAfterLineBreak*/ false, includeComments);
    }
    ts.getStartPositionOfRange = getStartPositionOfRange;
    function getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(pos, stopPos, sourceFile, includeComments) {
        var startPos = ts.skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments);
        var prevPos = getPreviousNonWhitespacePosition(startPos, stopPos, sourceFile);
        return ts.getLinesBetweenPositions(sourceFile, prevPos !== null && prevPos !== void 0 ? prevPos : stopPos, startPos);
    }
    ts.getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter = getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter;
    function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos, stopPos, sourceFile, includeComments) {
        var nextPos = ts.skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments);
        return ts.getLinesBetweenPositions(sourceFile, pos, Math.min(stopPos, nextPos));
    }
    ts.getLinesBetweenPositionAndNextNonWhitespaceCharacter = getLinesBetweenPositionAndNextNonWhitespaceCharacter;
    function getPreviousNonWhitespacePosition(pos, stopPos, sourceFile) {
        if (stopPos === void 0) { stopPos = 0; }
        while (pos-- > stopPos) {
            if (!ts.isWhiteSpaceLike(sourceFile.text.charCodeAt(pos))) {
                return pos;
            }
        }
    }
    /**
     * Determines whether a name was originally the declaration name of an enum or namespace
     * declaration.
     */
    function isDeclarationNameOfEnumOrNamespace(node) {
        var parseNode = ts.getParseTreeNode(node);
        if (parseNode) {
            switch (parseNode.parent.kind) {
                case 248 /* EnumDeclaration */:
                case 249 /* ModuleDeclaration */:
                    return parseNode === parseNode.parent.name;
            }
        }
        return false;
    }
    ts.isDeclarationNameOfEnumOrNamespace = isDeclarationNameOfEnumOrNamespace;
    function getInitializedVariables(node) {
        return ts.filter(node.declarations, isInitializedVariable);
    }
    ts.getInitializedVariables = getInitializedVariables;
    function isInitializedVariable(node) {
        return node.initializer !== undefined;
    }
    function isWatchSet(options) {
        // Firefox has Object.prototype.watch
        return options.watch && options.hasOwnProperty("watch");
    }
    ts.isWatchSet = isWatchSet;
    function closeFileWatcher(watcher) {
        watcher.close();
    }
    ts.closeFileWatcher = closeFileWatcher;
    function getCheckFlags(symbol) {
        return symbol.flags & 33554432 /* Transient */ ? symbol.checkFlags : 0;
    }
    ts.getCheckFlags = getCheckFlags;
    function getDeclarationModifierFlagsFromSymbol(s) {
        if (s.valueDeclaration) {
            var flags = ts.getCombinedModifierFlags(s.valueDeclaration);
            return s.parent && s.parent.flags & 32 /* Class */ ? flags : flags & ~28 /* AccessibilityModifier */;
        }
        if (getCheckFlags(s) & 6 /* Synthetic */) {
            var checkFlags = s.checkFlags;
            var accessModifier = checkFlags & 1024 /* ContainsPrivate */ ? 8 /* Private */ :
                checkFlags & 256 /* ContainsPublic */ ? 4 /* Public */ :
                    16 /* Protected */;
            var staticModifier = checkFlags & 2048 /* ContainsStatic */ ? 32 /* Static */ : 0;
            return accessModifier | staticModifier;
        }
        if (s.flags & 4194304 /* Prototype */) {
            return 4 /* Public */ | 32 /* Static */;
        }
        return 0;
    }
    ts.getDeclarationModifierFlagsFromSymbol = getDeclarationModifierFlagsFromSymbol;
    function skipAlias(symbol, checker) {
        return symbol.flags & 2097152 /* Alias */ ? checker.getAliasedSymbol(symbol) : symbol;
    }
    ts.skipAlias = skipAlias;
    /** See comment on `declareModuleMember` in `binder.ts`. */
    function getCombinedLocalAndExportSymbolFlags(symbol) {
        return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
    }
    ts.getCombinedLocalAndExportSymbolFlags = getCombinedLocalAndExportSymbolFlags;
    function isWriteOnlyAccess(node) {
        return accessKind(node) === 1 /* Write */;
    }
    ts.isWriteOnlyAccess = isWriteOnlyAccess;
    function isWriteAccess(node) {
        return accessKind(node) !== 0 /* Read */;
    }
    ts.isWriteAccess = isWriteAccess;
    var AccessKind;
    (function (AccessKind) {
        /** Only reads from a variable. */
        AccessKind[AccessKind["Read"] = 0] = "Read";
        /** Only writes to a variable without using the result. E.g.: `x++;`. */
        AccessKind[AccessKind["Write"] = 1] = "Write";
        /** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */
        AccessKind[AccessKind["ReadWrite"] = 2] = "ReadWrite";
    })(AccessKind || (AccessKind = {}));
    function accessKind(node) {
        var parent = node.parent;
        if (!parent)
            return 0 /* Read */;
        switch (parent.kind) {
            case 200 /* ParenthesizedExpression */:
                return accessKind(parent);
            case 208 /* PostfixUnaryExpression */:
            case 207 /* PrefixUnaryExpression */:
                var operator = parent.operator;
                return operator === 45 /* PlusPlusToken */ || operator === 46 /* MinusMinusToken */ ? writeOrReadWrite() : 0 /* Read */;
            case 209 /* BinaryExpression */:
                var _a = parent, left = _a.left, operatorToken = _a.operatorToken;
                return left === node && isAssignmentOperator(operatorToken.kind) ?
                    operatorToken.kind === 62 /* EqualsToken */ ? 1 /* Write */ : writeOrReadWrite()
                    : 0 /* Read */;
            case 194 /* PropertyAccessExpression */:
                return parent.name !== node ? 0 /* Read */ : accessKind(parent);
            case 281 /* PropertyAssignment */: {
                var parentAccess = accessKind(parent.parent);
                // In `({ x: varname }) = { x: 1 }`, the left `x` is a read, the right `x` is a write.
                return node === parent.name ? reverseAccessKind(parentAccess) : parentAccess;
            }
            case 282 /* ShorthandPropertyAssignment */:
                // Assume it's the local variable being accessed, since we don't check public properties for --noUnusedLocals.
                return node === parent.objectAssignmentInitializer ? 0 /* Read */ : accessKind(parent.parent);
            case 192 /* ArrayLiteralExpression */:
                return accessKind(parent);
            default:
                return 0 /* Read */;
        }
        function writeOrReadWrite() {
            // If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect.
            return parent.parent && skipParenthesesUp(parent.parent).kind === 226 /* ExpressionStatement */ ? 1 /* Write */ : 2 /* ReadWrite */;
        }
    }
    function reverseAccessKind(a) {
        switch (a) {
            case 0 /* Read */:
                return 1 /* Write */;
            case 1 /* Write */:
                return 0 /* Read */;
            case 2 /* ReadWrite */:
                return 2 /* ReadWrite */;
            default:
                return ts.Debug.assertNever(a);
        }
    }
    function compareDataObjects(dst, src) {
        if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) {
            return false;
        }
        for (var e in dst) {
            if (typeof dst[e] === "object") {
                if (!compareDataObjects(dst[e], src[e])) {
                    return false;
                }
            }
            else if (typeof dst[e] !== "function") {
                if (dst[e] !== src[e]) {
                    return false;
                }
            }
        }
        return true;
    }
    ts.compareDataObjects = compareDataObjects;
    /**
     * clears already present map by calling onDeleteExistingValue callback before deleting that key/value
     */
    function clearMap(map, onDeleteValue) {
        // Remove all
        map.forEach(onDeleteValue);
        map.clear();
    }
    ts.clearMap = clearMap;
    /**
     * Mutates the map with newMap such that keys in map will be same as newMap.
     */
    function mutateMapSkippingNewValues(map, newMap, options) {
        var onDeleteValue = options.onDeleteValue, onExistingValue = options.onExistingValue;
        // Needs update
        map.forEach(function (existingValue, key) {
            var valueInNewMap = newMap.get(key);
            // Not present any more in new map, remove it
            if (valueInNewMap === undefined) {
                map.delete(key);
                onDeleteValue(existingValue, key);
            }
            // If present notify about existing values
            else if (onExistingValue) {
                onExistingValue(existingValue, valueInNewMap, key);
            }
        });
    }
    ts.mutateMapSkippingNewValues = mutateMapSkippingNewValues;
    /**
     * Mutates the map with newMap such that keys in map will be same as newMap.
     */
    function mutateMap(map, newMap, options) {
        // Needs update
        mutateMapSkippingNewValues(map, newMap, options);
        var createNewValue = options.createNewValue;
        // Add new values that are not already present
        newMap.forEach(function (valueInNewMap, key) {
            if (!map.has(key)) {
                // New values
                map.set(key, createNewValue(key, valueInNewMap));
            }
        });
    }
    ts.mutateMap = mutateMap;
    // Return true if the given type is the constructor type for an abstract class
    function isAbstractConstructorType(type) {
        return !!(getObjectFlags(type) & 16 /* Anonymous */) && !!type.symbol && isAbstractConstructorSymbol(type.symbol);
    }
    ts.isAbstractConstructorType = isAbstractConstructorType;
    function isAbstractConstructorSymbol(symbol) {
        if (symbol.flags & 32 /* Class */) {
            var declaration = getClassLikeDeclarationOfSymbol(symbol);
            return !!declaration && hasModifier(declaration, 128 /* Abstract */);
        }
        return false;
    }
    ts.isAbstractConstructorSymbol = isAbstractConstructorSymbol;
    function getClassLikeDeclarationOfSymbol(symbol) {
        return ts.find(symbol.declarations, ts.isClassLike);
    }
    ts.getClassLikeDeclarationOfSymbol = getClassLikeDeclarationOfSymbol;
    function getObjectFlags(type) {
        return type.flags & 3899393 /* ObjectFlagsType */ ? type.objectFlags : 0;
    }
    ts.getObjectFlags = getObjectFlags;
    function typeHasCallOrConstructSignatures(type, checker) {
        return checker.getSignaturesOfType(type, 0 /* Call */).length !== 0 || checker.getSignaturesOfType(type, 1 /* Construct */).length !== 0;
    }
    ts.typeHasCallOrConstructSignatures = typeHasCallOrConstructSignatures;
    function forSomeAncestorDirectory(directory, callback) {
        return !!ts.forEachAncestorDirectory(directory, function (d) { return callback(d) ? true : undefined; });
    }
    ts.forSomeAncestorDirectory = forSomeAncestorDirectory;
    function isUMDExportSymbol(symbol) {
        return !!symbol && !!symbol.declarations && !!symbol.declarations[0] && ts.isNamespaceExportDeclaration(symbol.declarations[0]);
    }
    ts.isUMDExportSymbol = isUMDExportSymbol;
    function showModuleSpecifier(_a) {
        var moduleSpecifier = _a.moduleSpecifier;
        return ts.isStringLiteral(moduleSpecifier) ? moduleSpecifier.text : getTextOfNode(moduleSpecifier);
    }
    ts.showModuleSpecifier = showModuleSpecifier;
    function getLastChild(node) {
        var lastChild;
        ts.forEachChild(node, function (child) {
            if (nodeIsPresent(child))
                lastChild = child;
        }, function (children) {
            // As an optimization, jump straight to the end of the list.
            for (var i = children.length - 1; i >= 0; i--) {
                if (nodeIsPresent(children[i])) {
                    lastChild = children[i];
                    break;
                }
            }
        });
        return lastChild;
    }
    ts.getLastChild = getLastChild;
    function addToSeen(seen, key, value) {
        if (value === void 0) { value = true; }
        key = String(key);
        if (seen.has(key)) {
            return false;
        }
        seen.set(key, value);
        return true;
    }
    ts.addToSeen = addToSeen;
    function isObjectTypeDeclaration(node) {
        return ts.isClassLike(node) || ts.isInterfaceDeclaration(node) || ts.isTypeLiteralNode(node);
    }
    ts.isObjectTypeDeclaration = isObjectTypeDeclaration;
    function isTypeNodeKind(kind) {
        return (kind >= 168 /* FirstTypeNode */ && kind <= 188 /* LastTypeNode */)
            || kind === 125 /* AnyKeyword */
            || kind === 148 /* UnknownKeyword */
            || kind === 140 /* NumberKeyword */
            || kind === 151 /* BigIntKeyword */
            || kind === 141 /* ObjectKeyword */
            || kind === 128 /* BooleanKeyword */
            || kind === 143 /* StringKeyword */
            || kind === 144 /* SymbolKeyword */
            || kind === 104 /* ThisKeyword */
            || kind === 110 /* VoidKeyword */
            || kind === 146 /* UndefinedKeyword */
            || kind === 100 /* NullKeyword */
            || kind === 137 /* NeverKeyword */
            || kind === 216 /* ExpressionWithTypeArguments */
            || kind === 295 /* JSDocAllType */
            || kind === 296 /* JSDocUnknownType */
            || kind === 297 /* JSDocNullableType */
            || kind === 298 /* JSDocNonNullableType */
            || kind === 299 /* JSDocOptionalType */
            || kind === 300 /* JSDocFunctionType */
            || kind === 301 /* JSDocVariadicType */;
    }
    ts.isTypeNodeKind = isTypeNodeKind;
    function isAccessExpression(node) {
        return node.kind === 194 /* PropertyAccessExpression */ || node.kind === 195 /* ElementAccessExpression */;
    }
    ts.isAccessExpression = isAccessExpression;
    function getNameOfAccessExpression(node) {
        if (node.kind === 194 /* PropertyAccessExpression */) {
            return node.name;
        }
        ts.Debug.assert(node.kind === 195 /* ElementAccessExpression */);
        return node.argumentExpression;
    }
    ts.getNameOfAccessExpression = getNameOfAccessExpression;
    function isBundleFileTextLike(section) {
        switch (section.kind) {
            case "text" /* Text */:
            case "internal" /* Internal */:
                return true;
            default:
                return false;
        }
    }
    ts.isBundleFileTextLike = isBundleFileTextLike;
    function isNamedImportsOrExports(node) {
        return node.kind === 257 /* NamedImports */ || node.kind === 261 /* NamedExports */;
    }
    ts.isNamedImportsOrExports = isNamedImportsOrExports;
    function Symbol(flags, name) {
        this.flags = flags;
        this.escapedName = name;
        this.declarations = undefined;
        this.valueDeclaration = undefined;
        this.id = undefined;
        this.mergeId = undefined;
        this.parent = undefined;
    }
    function Type(checker, flags) {
        this.flags = flags;
        if (ts.Debug.isDebugging) {
            this.checker = checker;
        }
    }
    function Signature(checker, flags) {
        this.flags = flags;
        if (ts.Debug.isDebugging) {
            this.checker = checker;
        }
    }
    function Node(kind, pos, end) {
        this.pos = pos;
        this.end = end;
        this.kind = kind;
        this.id = 0;
        this.flags = 0 /* None */;
        this.modifierFlagsCache = 0 /* None */;
        this.transformFlags = 0 /* None */;
        this.parent = undefined;
        this.original = undefined;
    }
    function Token(kind, pos, end) {
        this.pos = pos;
        this.end = end;
        this.kind = kind;
        this.id = 0;
        this.flags = 0 /* None */;
        this.transformFlags = 0 /* None */;
        this.parent = undefined;
    }
    function Identifier(kind, pos, end) {
        this.pos = pos;
        this.end = end;
        this.kind = kind;
        this.id = 0;
        this.flags = 0 /* None */;
        this.transformFlags = 0 /* None */;
        this.parent = undefined;
        this.original = undefined;
        this.flowNode = undefined;
    }
    function SourceMapSource(fileName, text, skipTrivia) {
        this.fileName = fileName;
        this.text = text;
        this.skipTrivia = skipTrivia || (function (pos) { return pos; });
    }
    // eslint-disable-next-line prefer-const
    ts.objectAllocator = {
        getNodeConstructor: function () { return Node; },
        getTokenConstructor: function () { return Token; },
        getIdentifierConstructor: function () { return Identifier; },
        getPrivateIdentifierConstructor: function () { return Node; },
        getSourceFileConstructor: function () { return Node; },
        getSymbolConstructor: function () { return Symbol; },
        getTypeConstructor: function () { return Type; },
        getSignatureConstructor: function () { return Signature; },
        getSourceMapSourceConstructor: function () { return SourceMapSource; },
    };
    function setObjectAllocator(alloc) {
        ts.objectAllocator = alloc;
    }
    ts.setObjectAllocator = setObjectAllocator;
    function formatStringFromArgs(text, args, baseIndex) {
        if (baseIndex === void 0) { baseIndex = 0; }
        return text.replace(/{(\d+)}/g, function (_match, index) { return "" + ts.Debug.checkDefined(args[+index + baseIndex]); });
    }
    ts.formatStringFromArgs = formatStringFromArgs;
    /* @internal */
    function setLocalizedDiagnosticMessages(messages) {
        ts.localizedDiagnosticMessages = messages;
    }
    ts.setLocalizedDiagnosticMessages = setLocalizedDiagnosticMessages;
    function getLocaleSpecificMessage(message) {
        return ts.localizedDiagnosticMessages && ts.localizedDiagnosticMessages[message.key] || message.message;
    }
    ts.getLocaleSpecificMessage = getLocaleSpecificMessage;
    function createFileDiagnostic(file, start, length, message) {
        ts.Debug.assertGreaterThanOrEqual(start, 0);
        ts.Debug.assertGreaterThanOrEqual(length, 0);
        if (file) {
            ts.Debug.assertLessThanOrEqual(start, file.text.length);
            ts.Debug.assertLessThanOrEqual(start + length, file.text.length);
        }
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 4) {
            text = formatStringFromArgs(text, arguments, 4);
        }
        return {
            file: file,
            start: start,
            length: length,
            messageText: text,
            category: message.category,
            code: message.code,
            reportsUnnecessary: message.reportsUnnecessary,
        };
    }
    ts.createFileDiagnostic = createFileDiagnostic;
    function formatMessage(_dummy, message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 2) {
            text = formatStringFromArgs(text, arguments, 2);
        }
        return text;
    }
    ts.formatMessage = formatMessage;
    function createCompilerDiagnostic(message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 1) {
            text = formatStringFromArgs(text, arguments, 1);
        }
        return {
            file: undefined,
            start: undefined,
            length: undefined,
            messageText: text,
            category: message.category,
            code: message.code,
            reportsUnnecessary: message.reportsUnnecessary,
        };
    }
    ts.createCompilerDiagnostic = createCompilerDiagnostic;
    function createCompilerDiagnosticFromMessageChain(chain) {
        return {
            file: undefined,
            start: undefined,
            length: undefined,
            code: chain.code,
            category: chain.category,
            messageText: chain.next ? chain : chain.messageText,
        };
    }
    ts.createCompilerDiagnosticFromMessageChain = createCompilerDiagnosticFromMessageChain;
    function chainDiagnosticMessages(details, message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 2) {
            text = formatStringFromArgs(text, arguments, 2);
        }
        return {
            messageText: text,
            category: message.category,
            code: message.code,
            next: details === undefined || Array.isArray(details) ? details : [details]
        };
    }
    ts.chainDiagnosticMessages = chainDiagnosticMessages;
    function concatenateDiagnosticMessageChains(headChain, tailChain) {
        var lastChain = headChain;
        while (lastChain.next) {
            lastChain = lastChain.next[0];
        }
        lastChain.next = [tailChain];
    }
    ts.concatenateDiagnosticMessageChains = concatenateDiagnosticMessageChains;
    function getDiagnosticFilePath(diagnostic) {
        return diagnostic.file ? diagnostic.file.path : undefined;
    }
    function compareDiagnostics(d1, d2) {
        return compareDiagnosticsSkipRelatedInformation(d1, d2) ||
            compareRelatedInformation(d1, d2) ||
            0 /* EqualTo */;
    }
    ts.compareDiagnostics = compareDiagnostics;
    function compareDiagnosticsSkipRelatedInformation(d1, d2) {
        return ts.compareStringsCaseSensitive(getDiagnosticFilePath(d1), getDiagnosticFilePath(d2)) ||
            ts.compareValues(d1.start, d2.start) ||
            ts.compareValues(d1.length, d2.length) ||
            ts.compareValues(d1.code, d2.code) ||
            compareMessageText(d1.messageText, d2.messageText) ||
            0 /* EqualTo */;
    }
    ts.compareDiagnosticsSkipRelatedInformation = compareDiagnosticsSkipRelatedInformation;
    function compareRelatedInformation(d1, d2) {
        if (!d1.relatedInformation && !d2.relatedInformation) {
            return 0 /* EqualTo */;
        }
        if (d1.relatedInformation && d2.relatedInformation) {
            return ts.compareValues(d1.relatedInformation.length, d2.relatedInformation.length) || ts.forEach(d1.relatedInformation, function (d1i, index) {
                var d2i = d2.relatedInformation[index];
                return compareDiagnostics(d1i, d2i); // EqualTo is 0, so falsy, and will cause the next item to be compared
            }) || 0 /* EqualTo */;
        }
        return d1.relatedInformation ? -1 /* LessThan */ : 1 /* GreaterThan */;
    }
    function compareMessageText(t1, t2) {
        if (typeof t1 === "string" && typeof t2 === "string") {
            return ts.compareStringsCaseSensitive(t1, t2);
        }
        else if (typeof t1 === "string") {
            return -1 /* LessThan */;
        }
        else if (typeof t2 === "string") {
            return 1 /* GreaterThan */;
        }
        var res = ts.compareStringsCaseSensitive(t1.messageText, t2.messageText);
        if (res) {
            return res;
        }
        if (!t1.next && !t2.next) {
            return 0 /* EqualTo */;
        }
        if (!t1.next) {
            return -1 /* LessThan */;
        }
        if (!t2.next) {
            return 1 /* GreaterThan */;
        }
        var len = Math.min(t1.next.length, t2.next.length);
        for (var i = 0; i < len; i++) {
            res = compareMessageText(t1.next[i], t2.next[i]);
            if (res) {
                return res;
            }
        }
        if (t1.next.length < t2.next.length) {
            return -1 /* LessThan */;
        }
        else if (t1.next.length > t2.next.length) {
            return 1 /* GreaterThan */;
        }
        return 0 /* EqualTo */;
    }
    function getEmitScriptTarget(compilerOptions) {
        return compilerOptions.target || 0 /* ES3 */;
    }
    ts.getEmitScriptTarget = getEmitScriptTarget;
    function getEmitModuleKind(compilerOptions) {
        return typeof compilerOptions.module === "number" ?
            compilerOptions.module :
            getEmitScriptTarget(compilerOptions) >= 2 /* ES2015 */ ? ts.ModuleKind.ES2015 : ts.ModuleKind.CommonJS;
    }
    ts.getEmitModuleKind = getEmitModuleKind;
    function getEmitModuleResolutionKind(compilerOptions) {
        var moduleResolution = compilerOptions.moduleResolution;
        if (moduleResolution === undefined) {
            moduleResolution = getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
        }
        return moduleResolution;
    }
    ts.getEmitModuleResolutionKind = getEmitModuleResolutionKind;
    function hasJsonModuleEmitEnabled(options) {
        switch (getEmitModuleKind(options)) {
            case ts.ModuleKind.CommonJS:
            case ts.ModuleKind.AMD:
            case ts.ModuleKind.ES2015:
            case ts.ModuleKind.ES2020:
            case ts.ModuleKind.ESNext:
                return true;
            default:
                return false;
        }
    }
    ts.hasJsonModuleEmitEnabled = hasJsonModuleEmitEnabled;
    function unreachableCodeIsError(options) {
        return options.allowUnreachableCode === false;
    }
    ts.unreachableCodeIsError = unreachableCodeIsError;
    function unusedLabelIsError(options) {
        return options.allowUnusedLabels === false;
    }
    ts.unusedLabelIsError = unusedLabelIsError;
    function getAreDeclarationMapsEnabled(options) {
        return !!(getEmitDeclarations(options) && options.declarationMap);
    }
    ts.getAreDeclarationMapsEnabled = getAreDeclarationMapsEnabled;
    function getAllowSyntheticDefaultImports(compilerOptions) {
        var moduleKind = getEmitModuleKind(compilerOptions);
        return compilerOptions.allowSyntheticDefaultImports !== undefined
            ? compilerOptions.allowSyntheticDefaultImports
            : compilerOptions.esModuleInterop ||
                moduleKind === ts.ModuleKind.System;
    }
    ts.getAllowSyntheticDefaultImports = getAllowSyntheticDefaultImports;
    function getEmitDeclarations(compilerOptions) {
        return !!(compilerOptions.declaration || compilerOptions.composite);
    }
    ts.getEmitDeclarations = getEmitDeclarations;
    function isIncrementalCompilation(options) {
        return !!(options.incremental || options.composite);
    }
    ts.isIncrementalCompilation = isIncrementalCompilation;
    function getStrictOptionValue(compilerOptions, flag) {
        return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
    }
    ts.getStrictOptionValue = getStrictOptionValue;
    function compilerOptionsAffectSemanticDiagnostics(newOptions, oldOptions) {
        return oldOptions !== newOptions &&
            ts.semanticDiagnosticsOptionDeclarations.some(function (option) { return !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)); });
    }
    ts.compilerOptionsAffectSemanticDiagnostics = compilerOptionsAffectSemanticDiagnostics;
    function compilerOptionsAffectEmit(newOptions, oldOptions) {
        return oldOptions !== newOptions &&
            ts.affectsEmitOptionDeclarations.some(function (option) { return !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)); });
    }
    ts.compilerOptionsAffectEmit = compilerOptionsAffectEmit;
    function getCompilerOptionValue(options, option) {
        return option.strictFlag ? getStrictOptionValue(options, option.name) : options[option.name];
    }
    ts.getCompilerOptionValue = getCompilerOptionValue;
    function hasZeroOrOneAsteriskCharacter(str) {
        var seenAsterisk = false;
        for (var i = 0; i < str.length; i++) {
            if (str.charCodeAt(i) === 42 /* asterisk */) {
                if (!seenAsterisk) {
                    seenAsterisk = true;
                }
                else {
                    // have already seen asterisk
                    return false;
                }
            }
        }
        return true;
    }
    ts.hasZeroOrOneAsteriskCharacter = hasZeroOrOneAsteriskCharacter;
    function discoverProbableSymlinks(files, getCanonicalFileName, cwd) {
        var result = ts.createMap();
        var symlinks = ts.flatten(ts.mapDefined(files, function (sf) {
            return sf.resolvedModules && ts.compact(ts.arrayFrom(ts.mapIterator(sf.resolvedModules.values(), function (res) {
                return res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined;
            })));
        }));
        for (var _i = 0, symlinks_1 = symlinks; _i < symlinks_1.length; _i++) {
            var _a = symlinks_1[_i], resolvedPath = _a[0], originalPath = _a[1];
            var _b = guessDirectorySymlink(resolvedPath, originalPath, cwd, getCanonicalFileName), commonResolved = _b[0], commonOriginal = _b[1];
            result.set(commonOriginal, commonResolved);
        }
        return result;
    }
    ts.discoverProbableSymlinks = discoverProbableSymlinks;
    function guessDirectorySymlink(a, b, cwd, getCanonicalFileName) {
        var aParts = ts.getPathComponents(ts.toPath(a, cwd, getCanonicalFileName));
        var bParts = ts.getPathComponents(ts.toPath(b, cwd, getCanonicalFileName));
        while (!isNodeModulesOrScopedPackageDirectory(aParts[aParts.length - 2], getCanonicalFileName) &&
            !isNodeModulesOrScopedPackageDirectory(bParts[bParts.length - 2], getCanonicalFileName) &&
            getCanonicalFileName(aParts[aParts.length - 1]) === getCanonicalFileName(bParts[bParts.length - 1])) {
            aParts.pop();
            bParts.pop();
        }
        return [ts.getPathFromPathComponents(aParts), ts.getPathFromPathComponents(bParts)];
    }
    // KLUDGE: Don't assume one 'node_modules' links to another. More likely a single directory inside the node_modules is the symlink.
    // ALso, don't assume that an `@foo` directory is linked. More likely the contents of that are linked.
    function isNodeModulesOrScopedPackageDirectory(s, getCanonicalFileName) {
        return getCanonicalFileName(s) === "node_modules" || ts.startsWith(s, "@");
    }
    function stripLeadingDirectorySeparator(s) {
        return ts.isAnyDirectorySeparator(s.charCodeAt(0)) ? s.slice(1) : undefined;
    }
    function tryRemoveDirectoryPrefix(path, dirPath, getCanonicalFileName) {
        var withoutPrefix = ts.tryRemovePrefix(path, dirPath, getCanonicalFileName);
        return withoutPrefix === undefined ? undefined : stripLeadingDirectorySeparator(withoutPrefix);
    }
    ts.tryRemoveDirectoryPrefix = tryRemoveDirectoryPrefix;
    // Reserved characters, forces escaping of any non-word (or digit), non-whitespace character.
    // It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future
    // proof.
    var reservedCharacterPattern = /[^\w\s\/]/g;
    function regExpEscape(text) {
        return text.replace(reservedCharacterPattern, escapeRegExpCharacter);
    }
    ts.regExpEscape = regExpEscape;
    function escapeRegExpCharacter(match) {
        return "\\" + match;
    }
    var wildcardCharCodes = [42 /* asterisk */, 63 /* question */];
    ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"];
    var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))";
    var filesMatcher = {
        /**
         * Matches any single directory segment unless it is the last segment and a .min.js file
         * Breakdown:
         *  [^./]                   # matches everything up to the first . character (excluding directory separators)
         *  (\\.(?!min\\.js$))?     # matches . characters but not if they are part of the .min.js file extension
         */
        singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
        /**
         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
         * files or directories, does not match subdirectories that start with a . character
         */
        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); }
    };
    var directoriesMatcher = {
        singleAsteriskRegexFragment: "[^/]*",
        /**
         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
         * files or directories, does not match subdirectories that start with a . character
         */
        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); }
    };
    var excludeMatcher = {
        singleAsteriskRegexFragment: "[^/]*",
        doubleAsteriskRegexFragment: "(/.+?)?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); }
    };
    var wildcardMatchers = {
        files: filesMatcher,
        directories: directoriesMatcher,
        exclude: excludeMatcher
    };
    function getRegularExpressionForWildcard(specs, basePath, usage) {
        var patterns = getRegularExpressionsForWildcards(specs, basePath, usage);
        if (!patterns || !patterns.length) {
            return undefined;
        }
        var pattern = patterns.map(function (pattern) { return "(" + pattern + ")"; }).join("|");
        // If excluding, match "foo/bar/baz...", but if including, only allow "foo".
        var terminator = usage === "exclude" ? "($|/)" : "$";
        return "^(" + pattern + ")" + terminator;
    }
    ts.getRegularExpressionForWildcard = getRegularExpressionForWildcard;
    function getRegularExpressionsForWildcards(specs, basePath, usage) {
        if (specs === undefined || specs.length === 0) {
            return undefined;
        }
        return ts.flatMap(specs, function (spec) {
            return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]);
        });
    }
    ts.getRegularExpressionsForWildcards = getRegularExpressionsForWildcards;
    /**
     * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
     * and does not contain any glob characters itself.
     */
    function isImplicitGlob(lastPathComponent) {
        return !/[.*?]/.test(lastPathComponent);
    }
    ts.isImplicitGlob = isImplicitGlob;
    function getSubPatternFromSpec(spec, basePath, usage, _a) {
        var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter;
        var subpattern = "";
        var hasWrittenComponent = false;
        var components = ts.getNormalizedPathComponents(spec, basePath);
        var lastComponent = ts.last(components);
        if (usage !== "exclude" && lastComponent === "**") {
            return undefined;
        }
        // getNormalizedPathComponents includes the separator for the root component.
        // We need to remove to create our regex correctly.
        components[0] = ts.removeTrailingDirectorySeparator(components[0]);
        if (isImplicitGlob(lastComponent)) {
            components.push("**", "*");
        }
        var optionalCount = 0;
        for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
            var component = components_1[_i];
            if (component === "**") {
                subpattern += doubleAsteriskRegexFragment;
            }
            else {
                if (usage === "directories") {
                    subpattern += "(";
                    optionalCount++;
                }
                if (hasWrittenComponent) {
                    subpattern += ts.directorySeparator;
                }
                if (usage !== "exclude") {
                    var componentPattern = "";
                    // The * and ? wildcards should not match directories or files that start with . if they
                    // appear first in a component. Dotted directories and files can be included explicitly
                    // like so: **/.*/.*
                    if (component.charCodeAt(0) === 42 /* asterisk */) {
                        componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?";
                        component = component.substr(1);
                    }
                    else if (component.charCodeAt(0) === 63 /* question */) {
                        componentPattern += "[^./]";
                        component = component.substr(1);
                    }
                    componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                    // Patterns should not include subfolders like node_modules unless they are
                    // explicitly included as part of the path.
                    //
                    // As an optimization, if the component pattern is the same as the component,
                    // then there definitely were no wildcard characters and we do not need to
                    // add the exclusion pattern.
                    if (componentPattern !== component) {
                        subpattern += implicitExcludePathRegexPattern;
                    }
                    subpattern += componentPattern;
                }
                else {
                    subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                }
            }
            hasWrittenComponent = true;
        }
        while (optionalCount > 0) {
            subpattern += ")?";
            optionalCount--;
        }
        return subpattern;
    }
    function replaceWildcardCharacter(match, singleAsteriskRegexFragment) {
        return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match;
    }
    /** @param path directory of the tsconfig.json */
    function getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory) {
        path = ts.normalizePath(path);
        currentDirectory = ts.normalizePath(currentDirectory);
        var absolutePath = ts.combinePaths(currentDirectory, path);
        return {
            includeFilePatterns: ts.map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), function (pattern) { return "^" + pattern + "$"; }),
            includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"),
            includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"),
            excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"),
            basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames)
        };
    }
    ts.getFileMatcherPatterns = getFileMatcherPatterns;
    function getRegexFromPattern(pattern, useCaseSensitiveFileNames) {
        return new RegExp(pattern, useCaseSensitiveFileNames ? "" : "i");
    }
    ts.getRegexFromPattern = getRegexFromPattern;
    /** @param path directory of the tsconfig.json */
    function matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath) {
        path = ts.normalizePath(path);
        currentDirectory = ts.normalizePath(currentDirectory);
        var patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
        var includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(function (pattern) { return getRegexFromPattern(pattern, useCaseSensitiveFileNames); });
        var includeDirectoryRegex = patterns.includeDirectoryPattern && getRegexFromPattern(patterns.includeDirectoryPattern, useCaseSensitiveFileNames);
        var excludeRegex = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, useCaseSensitiveFileNames);
        // Associate an array of results with each include regex. This keeps results in order of the "include" order.
        // If there are no "includes", then just put everything in results[0].
        var results = includeFileRegexes ? includeFileRegexes.map(function () { return []; }) : [[]];
        var visited = ts.createMap();
        var toCanonical = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        for (var _i = 0, _a = patterns.basePaths; _i < _a.length; _i++) {
            var basePath = _a[_i];
            visitDirectory(basePath, ts.combinePaths(currentDirectory, basePath), depth);
        }
        return ts.flatten(results);
        function visitDirectory(path, absolutePath, depth) {
            var canonicalPath = toCanonical(realpath(absolutePath));
            if (visited.has(canonicalPath))
                return;
            visited.set(canonicalPath, true);
            var _a = getFileSystemEntries(path), files = _a.files, directories = _a.directories;
            var _loop_1 = function (current) {
                var name = ts.combinePaths(path, current);
                var absoluteName = ts.combinePaths(absolutePath, current);
                if (extensions && !ts.fileExtensionIsOneOf(name, extensions))
                    return "continue";
                if (excludeRegex && excludeRegex.test(absoluteName))
                    return "continue";
                if (!includeFileRegexes) {
                    results[0].push(name);
                }
                else {
                    var includeIndex = ts.findIndex(includeFileRegexes, function (re) { return re.test(absoluteName); });
                    if (includeIndex !== -1) {
                        results[includeIndex].push(name);
                    }
                }
            };
            for (var _i = 0, _b = ts.sort(files, ts.compareStringsCaseSensitive); _i < _b.length; _i++) {
                var current = _b[_i];
                _loop_1(current);
            }
            if (depth !== undefined) {
                depth--;
                if (depth === 0) {
                    return;
                }
            }
            for (var _c = 0, _d = ts.sort(directories, ts.compareStringsCaseSensitive); _c < _d.length; _c++) {
                var current = _d[_c];
                var name = ts.combinePaths(path, current);
                var absoluteName = ts.combinePaths(absolutePath, current);
                if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
                    (!excludeRegex || !excludeRegex.test(absoluteName))) {
                    visitDirectory(name, absoluteName, depth);
                }
            }
        }
    }
    ts.matchFiles = matchFiles;
    /**
     * Computes the unique non-wildcard base paths amongst the provided include patterns.
     */
    function getBasePaths(path, includes, useCaseSensitiveFileNames) {
        // Storage for our results in the form of literal paths (e.g. the paths as written by the user).
        var basePaths = [path];
        if (includes) {
            // Storage for literal base paths amongst the include patterns.
            var includeBasePaths = [];
            for (var _i = 0, includes_1 = includes; _i < includes_1.length; _i++) {
                var include = includes_1[_i];
                // We also need to check the relative paths by converting them to absolute and normalizing
                // in case they escape the base path (e.g "..\somedirectory")
                var absolute = ts.isRootedDiskPath(include) ? include : ts.normalizePath(ts.combinePaths(path, include));
                // Append the literal and canonical candidate base paths.
                includeBasePaths.push(getIncludeBasePath(absolute));
            }
            // Sort the offsets array using either the literal or canonical path representations.
            includeBasePaths.sort(ts.getStringComparer(!useCaseSensitiveFileNames));
            var _loop_2 = function (includeBasePath) {
                if (ts.every(basePaths, function (basePath) { return !ts.containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames); })) {
                    basePaths.push(includeBasePath);
                }
            };
            // Iterate over each include base path and include unique base paths that are not a
            // subpath of an existing base path
            for (var _a = 0, includeBasePaths_1 = includeBasePaths; _a < includeBasePaths_1.length; _a++) {
                var includeBasePath = includeBasePaths_1[_a];
                _loop_2(includeBasePath);
            }
        }
        return basePaths;
    }
    function getIncludeBasePath(absolute) {
        var wildcardOffset = ts.indexOfAnyCharCode(absolute, wildcardCharCodes);
        if (wildcardOffset < 0) {
            // No "*" or "?" in the path
            return !ts.hasExtension(absolute)
                ? absolute
                : ts.removeTrailingDirectorySeparator(ts.getDirectoryPath(absolute));
        }
        return absolute.substring(0, absolute.lastIndexOf(ts.directorySeparator, wildcardOffset));
    }
    function ensureScriptKind(fileName, scriptKind) {
        // Using scriptKind as a condition handles both:
        // - 'scriptKind' is unspecified and thus it is `undefined`
        // - 'scriptKind' is set and it is `Unknown` (0)
        // If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt
        // to get the ScriptKind from the file name. If it cannot be resolved
        // from the file name then the default 'TS' script kind is returned.
        return scriptKind || getScriptKindFromFileName(fileName) || 3 /* TS */;
    }
    ts.ensureScriptKind = ensureScriptKind;
    function getScriptKindFromFileName(fileName) {
        var ext = fileName.substr(fileName.lastIndexOf("."));
        switch (ext.toLowerCase()) {
            case ".js" /* Js */:
                return 1 /* JS */;
            case ".jsx" /* Jsx */:
                return 2 /* JSX */;
            case ".ts" /* Ts */:
                return 3 /* TS */;
            case ".tsx" /* Tsx */:
                return 4 /* TSX */;
            case ".json" /* Json */:
                return 6 /* JSON */;
            default:
                return 0 /* Unknown */;
        }
    }
    ts.getScriptKindFromFileName = getScriptKindFromFileName;
    /**
     *  List of supported extensions in order of file resolution precedence.
     */
    ts.supportedTSExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */];
    ts.supportedTSExtensionsWithJson = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */, ".json" /* Json */];
    /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
    ts.supportedTSExtensionsForExtractExtension = [".d.ts" /* Dts */, ".ts" /* Ts */, ".tsx" /* Tsx */];
    ts.supportedJSExtensions = [".js" /* Js */, ".jsx" /* Jsx */];
    ts.supportedJSAndJsonExtensions = [".js" /* Js */, ".jsx" /* Jsx */, ".json" /* Json */];
    var allSupportedExtensions = __spreadArrays(ts.supportedTSExtensions, ts.supportedJSExtensions);
    var allSupportedExtensionsWithJson = __spreadArrays(ts.supportedTSExtensions, ts.supportedJSExtensions, [".json" /* Json */]);
    function getSupportedExtensions(options, extraFileExtensions) {
        var needJsExtensions = options && options.allowJs;
        if (!extraFileExtensions || extraFileExtensions.length === 0) {
            return needJsExtensions ? allSupportedExtensions : ts.supportedTSExtensions;
        }
        var extensions = __spreadArrays(needJsExtensions ? allSupportedExtensions : ts.supportedTSExtensions, ts.mapDefined(extraFileExtensions, function (x) { return x.scriptKind === 7 /* Deferred */ || needJsExtensions && isJSLike(x.scriptKind) ? x.extension : undefined; }));
        return ts.deduplicate(extensions, ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive);
    }
    ts.getSupportedExtensions = getSupportedExtensions;
    function getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions) {
        if (!options || !options.resolveJsonModule) {
            return supportedExtensions;
        }
        if (supportedExtensions === allSupportedExtensions) {
            return allSupportedExtensionsWithJson;
        }
        if (supportedExtensions === ts.supportedTSExtensions) {
            return ts.supportedTSExtensionsWithJson;
        }
        return __spreadArrays(supportedExtensions, [".json" /* Json */]);
    }
    ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule;
    function isJSLike(scriptKind) {
        return scriptKind === 1 /* JS */ || scriptKind === 2 /* JSX */;
    }
    function hasJSFileExtension(fileName) {
        return ts.some(ts.supportedJSExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.hasJSFileExtension = hasJSFileExtension;
    function hasTSFileExtension(fileName) {
        return ts.some(ts.supportedTSExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.hasTSFileExtension = hasTSFileExtension;
    function isSupportedSourceFileName(fileName, compilerOptions, extraFileExtensions) {
        if (!fileName) {
            return false;
        }
        var supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions);
        for (var _i = 0, _a = getSuppoertedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions); _i < _a.length; _i++) {
            var extension = _a[_i];
            if (ts.fileExtensionIs(fileName, extension)) {
                return true;
            }
        }
        return false;
    }
    ts.isSupportedSourceFileName = isSupportedSourceFileName;
    /**
     * Extension boundaries by priority. Lower numbers indicate higher priorities, and are
     * aligned to the offset of the highest priority extension in the
     * allSupportedExtensions array.
     */
    var ExtensionPriority;
    (function (ExtensionPriority) {
        ExtensionPriority[ExtensionPriority["TypeScriptFiles"] = 0] = "TypeScriptFiles";
        ExtensionPriority[ExtensionPriority["DeclarationAndJavaScriptFiles"] = 2] = "DeclarationAndJavaScriptFiles";
        ExtensionPriority[ExtensionPriority["Highest"] = 0] = "Highest";
        ExtensionPriority[ExtensionPriority["Lowest"] = 2] = "Lowest";
    })(ExtensionPriority = ts.ExtensionPriority || (ts.ExtensionPriority = {}));
    function getExtensionPriority(path, supportedExtensions) {
        for (var i = supportedExtensions.length - 1; i >= 0; i--) {
            if (ts.fileExtensionIs(path, supportedExtensions[i])) {
                return adjustExtensionPriority(i, supportedExtensions);
            }
        }
        // If its not in the list of supported extensions, this is likely a
        // TypeScript file with a non-ts extension
        return 0 /* Highest */;
    }
    ts.getExtensionPriority = getExtensionPriority;
    /**
     * Adjusts an extension priority to be the highest priority within the same range.
     */
    function adjustExtensionPriority(extensionPriority, supportedExtensions) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 0 /* TypeScriptFiles */;
        }
        else if (extensionPriority < supportedExtensions.length) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return supportedExtensions.length;
        }
    }
    ts.adjustExtensionPriority = adjustExtensionPriority;
    /**
     * Gets the next lowest extension priority for a given priority.
     */
    function getNextLowestExtensionPriority(extensionPriority, supportedExtensions) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return supportedExtensions.length;
        }
    }
    ts.getNextLowestExtensionPriority = getNextLowestExtensionPriority;
    var extensionsToRemove = [".d.ts" /* Dts */, ".ts" /* Ts */, ".js" /* Js */, ".tsx" /* Tsx */, ".jsx" /* Jsx */, ".json" /* Json */];
    function removeFileExtension(path) {
        for (var _i = 0, extensionsToRemove_1 = extensionsToRemove; _i < extensionsToRemove_1.length; _i++) {
            var ext = extensionsToRemove_1[_i];
            var extensionless = tryRemoveExtension(path, ext);
            if (extensionless !== undefined) {
                return extensionless;
            }
        }
        return path;
    }
    ts.removeFileExtension = removeFileExtension;
    function tryRemoveExtension(path, extension) {
        return ts.fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined;
    }
    ts.tryRemoveExtension = tryRemoveExtension;
    function removeExtension(path, extension) {
        return path.substring(0, path.length - extension.length);
    }
    ts.removeExtension = removeExtension;
    function changeExtension(path, newExtension) {
        return ts.changeAnyExtension(path, newExtension, extensionsToRemove, /*ignoreCase*/ false);
    }
    ts.changeExtension = changeExtension;
    function tryParsePattern(pattern) {
        // This should be verified outside of here and a proper error thrown.
        ts.Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
        var indexOfStar = pattern.indexOf("*");
        return indexOfStar === -1 ? undefined : {
            prefix: pattern.substr(0, indexOfStar),
            suffix: pattern.substr(indexOfStar + 1)
        };
    }
    ts.tryParsePattern = tryParsePattern;
    function positionIsSynthesized(pos) {
        // This is a fast way of testing the following conditions:
        //  pos === undefined || pos === null || isNaN(pos) || pos < 0;
        return !(pos >= 0);
    }
    ts.positionIsSynthesized = positionIsSynthesized;
    /** True if an extension is one of the supported TypeScript extensions. */
    function extensionIsTS(ext) {
        return ext === ".ts" /* Ts */ || ext === ".tsx" /* Tsx */ || ext === ".d.ts" /* Dts */;
    }
    ts.extensionIsTS = extensionIsTS;
    function resolutionExtensionIsTSOrJson(ext) {
        return extensionIsTS(ext) || ext === ".json" /* Json */;
    }
    ts.resolutionExtensionIsTSOrJson = resolutionExtensionIsTSOrJson;
    /**
     * Gets the extension from a path.
     * Path must have a valid extension.
     */
    function extensionFromPath(path) {
        var ext = tryGetExtensionFromPath(path);
        return ext !== undefined ? ext : ts.Debug.fail("File " + path + " has unknown extension.");
    }
    ts.extensionFromPath = extensionFromPath;
    function isAnySupportedFileExtension(path) {
        return tryGetExtensionFromPath(path) !== undefined;
    }
    ts.isAnySupportedFileExtension = isAnySupportedFileExtension;
    function tryGetExtensionFromPath(path) {
        return ts.find(extensionsToRemove, function (e) { return ts.fileExtensionIs(path, e); });
    }
    ts.tryGetExtensionFromPath = tryGetExtensionFromPath;
    function isCheckJsEnabledForFile(sourceFile, compilerOptions) {
        return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
    }
    ts.isCheckJsEnabledForFile = isCheckJsEnabledForFile;
    ts.emptyFileSystemEntries = {
        files: ts.emptyArray,
        directories: ts.emptyArray
    };
    /**
     * patternStrings contains both pattern strings (containing "*") and regular strings.
     * Return an exact match if possible, or a pattern match, or undefined.
     * (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
     */
    function matchPatternOrExact(patternStrings, candidate) {
        var patterns = [];
        for (var _i = 0, patternStrings_1 = patternStrings; _i < patternStrings_1.length; _i++) {
            var patternString = patternStrings_1[_i];
            if (!hasZeroOrOneAsteriskCharacter(patternString))
                continue;
            var pattern = tryParsePattern(patternString);
            if (pattern) {
                patterns.push(pattern);
            }
            else if (patternString === candidate) {
                // pattern was matched as is - no need to search further
                return patternString;
            }
        }
        return ts.findBestPatternMatch(patterns, function (_) { return _; }, candidate);
    }
    ts.matchPatternOrExact = matchPatternOrExact;
    function sliceAfter(arr, value) {
        var index = arr.indexOf(value);
        ts.Debug.assert(index !== -1);
        return arr.slice(index);
    }
    ts.sliceAfter = sliceAfter;
    function addRelatedInfo(diagnostic) {
        var _a;
        var relatedInformation = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            relatedInformation[_i - 1] = arguments[_i];
        }
        if (!relatedInformation.length) {
            return diagnostic;
        }
        if (!diagnostic.relatedInformation) {
            diagnostic.relatedInformation = [];
        }
        (_a = diagnostic.relatedInformation).push.apply(_a, relatedInformation);
        return diagnostic;
    }
    ts.addRelatedInfo = addRelatedInfo;
    function minAndMax(arr, getValue) {
        ts.Debug.assert(arr.length !== 0);
        var min = getValue(arr[0]);
        var max = min;
        for (var i = 1; i < arr.length; i++) {
            var value = getValue(arr[i]);
            if (value < min) {
                min = value;
            }
            else if (value > max) {
                max = value;
            }
        }
        return { min: min, max: max };
    }
    ts.minAndMax = minAndMax;
    var NodeSet = /** @class */ (function () {
        function NodeSet() {
            this.map = ts.createMap();
        }
        NodeSet.prototype.add = function (node) {
            this.map.set(String(ts.getNodeId(node)), node);
        };
        NodeSet.prototype.tryAdd = function (node) {
            if (this.has(node))
                return false;
            this.add(node);
            return true;
        };
        NodeSet.prototype.has = function (node) {
            return this.map.has(String(ts.getNodeId(node)));
        };
        NodeSet.prototype.forEach = function (cb) {
            this.map.forEach(cb);
        };
        NodeSet.prototype.some = function (pred) {
            return forEachEntry(this.map, pred) || false;
        };
        return NodeSet;
    }());
    ts.NodeSet = NodeSet;
    var NodeMap = /** @class */ (function () {
        function NodeMap() {
            this.map = ts.createMap();
        }
        NodeMap.prototype.get = function (node) {
            var res = this.map.get(String(ts.getNodeId(node)));
            return res && res.value;
        };
        NodeMap.prototype.getOrUpdate = function (node, setValue) {
            var res = this.get(node);
            if (res)
                return res;
            var value = setValue();
            this.set(node, value);
            return value;
        };
        NodeMap.prototype.set = function (node, value) {
            this.map.set(String(ts.getNodeId(node)), { node: node, value: value });
        };
        NodeMap.prototype.has = function (node) {
            return this.map.has(String(ts.getNodeId(node)));
        };
        NodeMap.prototype.forEach = function (cb) {
            this.map.forEach(function (_a) {
                var node = _a.node, value = _a.value;
                return cb(value, node);
            });
        };
        return NodeMap;
    }());
    ts.NodeMap = NodeMap;
    function rangeOfNode(node) {
        return { pos: getTokenPosOfNode(node), end: node.end };
    }
    ts.rangeOfNode = rangeOfNode;
    function rangeOfTypeParameters(typeParameters) {
        // Include the `<>`
        return { pos: typeParameters.pos - 1, end: typeParameters.end + 1 };
    }
    ts.rangeOfTypeParameters = rangeOfTypeParameters;
    function skipTypeChecking(sourceFile, options, host) {
        // If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
        // If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
        // '/// <reference no-default-lib="true"/>' directive.
        return (options.skipLibCheck && sourceFile.isDeclarationFile ||
            options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) ||
            host.isSourceOfProjectReferenceRedirect(sourceFile.fileName);
    }
    ts.skipTypeChecking = skipTypeChecking;
    function isJsonEqual(a, b) {
        // eslint-disable-next-line no-null/no-null
        return a === b || typeof a === "object" && a !== null && typeof b === "object" && b !== null && ts.equalOwnProperties(a, b, isJsonEqual);
    }
    ts.isJsonEqual = isJsonEqual;
    function getOrUpdate(map, key, getDefault) {
        var got = map.get(key);
        if (got === undefined) {
            var value = getDefault();
            map.set(key, value);
            return value;
        }
        else {
            return got;
        }
    }
    ts.getOrUpdate = getOrUpdate;
    /**
     * Converts a bigint literal string, e.g. `0x1234n`,
     * to its decimal string representation, e.g. `4660`.
     */
    function parsePseudoBigInt(stringValue) {
        var log2Base;
        switch (stringValue.charCodeAt(1)) { // "x" in "0x123"
            case 98 /* b */:
            case 66 /* B */: // 0b or 0B
                log2Base = 1;
                break;
            case 111 /* o */:
            case 79 /* O */: // 0o or 0O
                log2Base = 3;
                break;
            case 120 /* x */:
            case 88 /* X */: // 0x or 0X
                log2Base = 4;
                break;
            default: // already in decimal; omit trailing "n"
                var nIndex = stringValue.length - 1;
                // Skip leading 0s
                var nonZeroStart = 0;
                while (stringValue.charCodeAt(nonZeroStart) === 48 /* _0 */) {
                    nonZeroStart++;
                }
                return stringValue.slice(nonZeroStart, nIndex) || "0";
        }
        // Omit leading "0b", "0o", or "0x", and trailing "n"
        var startIndex = 2, endIndex = stringValue.length - 1;
        var bitsNeeded = (endIndex - startIndex) * log2Base;
        // Stores the value specified by the string as a LE array of 16-bit integers
        // using Uint16 instead of Uint32 so combining steps can use bitwise operators
        var segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
        // Add the digits, one at a time
        for (var i = endIndex - 1, bitOffset = 0; i >= startIndex; i--, bitOffset += log2Base) {
            var segment = bitOffset >>> 4;
            var digitChar = stringValue.charCodeAt(i);
            // Find character range: 0-9 < A-F < a-f
            var digit = digitChar <= 57 /* _9 */
                ? digitChar - 48 /* _0 */
                : 10 + digitChar -
                    (digitChar <= 70 /* F */ ? 65 /* A */ : 97 /* a */);
            var shiftedDigit = digit << (bitOffset & 15);
            segments[segment] |= shiftedDigit;
            var residual = shiftedDigit >>> 16;
            if (residual)
                segments[segment + 1] |= residual; // overflows segment
        }
        // Repeatedly divide segments by 10 and add remainder to base10Value
        var base10Value = "";
        var firstNonzeroSegment = segments.length - 1;
        var segmentsRemaining = true;
        while (segmentsRemaining) {
            var mod10 = 0;
            segmentsRemaining = false;
            for (var segment = firstNonzeroSegment; segment >= 0; segment--) {
                var newSegment = mod10 << 16 | segments[segment];
                var segmentValue = (newSegment / 10) | 0;
                segments[segment] = segmentValue;
                mod10 = newSegment - segmentValue * 10;
                if (segmentValue && !segmentsRemaining) {
                    firstNonzeroSegment = segment;
                    segmentsRemaining = true;
                }
            }
            base10Value = mod10 + base10Value;
        }
        return base10Value;
    }
    ts.parsePseudoBigInt = parsePseudoBigInt;
    function pseudoBigIntToString(_a) {
        var negative = _a.negative, base10Value = _a.base10Value;
        return (negative && base10Value !== "0" ? "-" : "") + base10Value;
    }
    ts.pseudoBigIntToString = pseudoBigIntToString;
    function isValidTypeOnlyAliasUseSite(useSite) {
        return !!(useSite.flags & 8388608 /* Ambient */)
            || isPartOfTypeQuery(useSite)
            || isIdentifierInNonEmittingHeritageClause(useSite)
            || isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite)
            || !isExpressionNode(useSite);
    }
    ts.isValidTypeOnlyAliasUseSite = isValidTypeOnlyAliasUseSite;
    function typeOnlyDeclarationIsExport(typeOnlyDeclaration) {
        return typeOnlyDeclaration.kind === 263 /* ExportSpecifier */;
    }
    ts.typeOnlyDeclarationIsExport = typeOnlyDeclarationIsExport;
    function isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(node) {
        while (node.kind === 75 /* Identifier */ || node.kind === 194 /* PropertyAccessExpression */) {
            node = node.parent;
        }
        if (node.kind !== 154 /* ComputedPropertyName */) {
            return false;
        }
        if (hasModifier(node.parent, 128 /* Abstract */)) {
            return true;
        }
        var containerKind = node.parent.parent.kind;
        return containerKind === 246 /* InterfaceDeclaration */ || containerKind === 173 /* TypeLiteral */;
    }
    /** Returns true for an identifier in 1) an `implements` clause, and 2) an `extends` clause of an interface. */
    function isIdentifierInNonEmittingHeritageClause(node) {
        if (node.kind !== 75 /* Identifier */)
            return false;
        var heritageClause = findAncestor(node.parent, function (parent) {
            switch (parent.kind) {
                case 279 /* HeritageClause */:
                    return true;
                case 194 /* PropertyAccessExpression */:
                case 216 /* ExpressionWithTypeArguments */:
                    return false;
                default:
                    return "quit";
            }
        });
        return (heritageClause === null || heritageClause === void 0 ? void 0 : heritageClause.token) === 113 /* ImplementsKeyword */ || (heritageClause === null || heritageClause === void 0 ? void 0 : heritageClause.parent.kind) === 246 /* InterfaceDeclaration */;
    }
    function isIdentifierTypeReference(node) {
        return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName);
    }
    ts.isIdentifierTypeReference = isIdentifierTypeReference;
    function arrayIsHomogeneous(array, comparer) {
        if (comparer === void 0) { comparer = ts.equateValues; }
        if (array.length < 2)
            return true;
        var first = array[0];
        for (var i = 1, length_1 = array.length; i < length_1; i++) {
            var target = array[i];
            if (!comparer(first, target))
                return false;
        }
        return true;
    }
    ts.arrayIsHomogeneous = arrayIsHomogeneous;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var SignatureFlags;
    (function (SignatureFlags) {
        SignatureFlags[SignatureFlags["None"] = 0] = "None";
        SignatureFlags[SignatureFlags["Yield"] = 1] = "Yield";
        SignatureFlags[SignatureFlags["Await"] = 2] = "Await";
        SignatureFlags[SignatureFlags["Type"] = 4] = "Type";
        SignatureFlags[SignatureFlags["IgnoreMissingOpenBrace"] = 16] = "IgnoreMissingOpenBrace";
        SignatureFlags[SignatureFlags["JSDoc"] = 32] = "JSDoc";
    })(SignatureFlags || (SignatureFlags = {}));
    var NodeConstructor;
    var TokenConstructor;
    var IdentifierConstructor;
    var PrivateIdentifierConstructor;
    var SourceFileConstructor;
    function createNode(kind, pos, end) {
        if (kind === 290 /* SourceFile */) {
            return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
        }
        else if (kind === 75 /* Identifier */) {
            return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end);
        }
        else if (kind === 76 /* PrivateIdentifier */) {
            return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = ts.objectAllocator.getPrivateIdentifierConstructor()))(kind, pos, end);
        }
        else if (!ts.isNodeKind(kind)) {
            return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end);
        }
        else {
            return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
        }
    }
    ts.createNode = createNode;
    function visitNode(cbNode, node) {
        return node && cbNode(node);
    }
    function visitNodes(cbNode, cbNodes, nodes) {
        if (nodes) {
            if (cbNodes) {
                return cbNodes(nodes);
            }
            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
                var node = nodes_1[_i];
                var result = cbNode(node);
                if (result) {
                    return result;
                }
            }
        }
    }
    /*@internal*/
    function isJSDocLikeText(text, start) {
        return text.charCodeAt(start + 1) === 42 /* asterisk */ &&
            text.charCodeAt(start + 2) === 42 /* asterisk */ &&
            text.charCodeAt(start + 3) !== 47 /* slash */;
    }
    ts.isJSDocLikeText = isJSDocLikeText;
    /**
     * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
     * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
     * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
     * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
     *
     * @param node a given node to visit its children
     * @param cbNode a callback to be invoked for all child nodes
     * @param cbNodes a callback to be invoked for embedded array
     *
     * @remarks `forEachChild` must visit the children of a node in the order
     * that they appear in the source code. The language service depends on this property to locate nodes by position.
     */
    function forEachChild(node, cbNode, cbNodes) {
        if (!node || node.kind <= 152 /* LastToken */) {
            return;
        }
        switch (node.kind) {
            case 153 /* QualifiedName */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.right);
            case 155 /* TypeParameter */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.constraint) ||
                    visitNode(cbNode, node.default) ||
                    visitNode(cbNode, node.expression);
            case 282 /* ShorthandPropertyAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.equalsToken) ||
                    visitNode(cbNode, node.objectAssignmentInitializer);
            case 283 /* SpreadAssignment */:
                return visitNode(cbNode, node.expression);
            case 156 /* Parameter */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 159 /* PropertyDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 158 /* PropertySignature */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 281 /* PropertyAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.initializer);
            case 242 /* VariableDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 191 /* BindingElement */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
            case 165 /* CallSignature */:
            case 166 /* ConstructSignature */:
            case 167 /* IndexSignature */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 201 /* FunctionExpression */:
            case 244 /* FunctionDeclaration */:
            case 202 /* ArrowFunction */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.equalsGreaterThanToken) ||
                    visitNode(cbNode, node.body);
            case 169 /* TypeReference */:
                return visitNode(cbNode, node.typeName) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 168 /* TypePredicate */:
                return visitNode(cbNode, node.assertsModifier) ||
                    visitNode(cbNode, node.parameterName) ||
                    visitNode(cbNode, node.type);
            case 172 /* TypeQuery */:
                return visitNode(cbNode, node.exprName);
            case 173 /* TypeLiteral */:
                return visitNodes(cbNode, cbNodes, node.members);
            case 174 /* ArrayType */:
                return visitNode(cbNode, node.elementType);
            case 175 /* TupleType */:
                return visitNodes(cbNode, cbNodes, node.elementTypes);
            case 178 /* UnionType */:
            case 179 /* IntersectionType */:
                return visitNodes(cbNode, cbNodes, node.types);
            case 180 /* ConditionalType */:
                return visitNode(cbNode, node.checkType) ||
                    visitNode(cbNode, node.extendsType) ||
                    visitNode(cbNode, node.trueType) ||
                    visitNode(cbNode, node.falseType);
            case 181 /* InferType */:
                return visitNode(cbNode, node.typeParameter);
            case 188 /* ImportType */:
                return visitNode(cbNode, node.argument) ||
                    visitNode(cbNode, node.qualifier) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 182 /* ParenthesizedType */:
            case 184 /* TypeOperator */:
                return visitNode(cbNode, node.type);
            case 185 /* IndexedAccessType */:
                return visitNode(cbNode, node.objectType) ||
                    visitNode(cbNode, node.indexType);
            case 186 /* MappedType */:
                return visitNode(cbNode, node.readonlyToken) ||
                    visitNode(cbNode, node.typeParameter) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type);
            case 187 /* LiteralType */:
                return visitNode(cbNode, node.literal);
            case 189 /* ObjectBindingPattern */:
            case 190 /* ArrayBindingPattern */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 192 /* ArrayLiteralExpression */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 193 /* ObjectLiteralExpression */:
                return visitNodes(cbNode, cbNodes, node.properties);
            case 194 /* PropertyAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.questionDotToken) ||
                    visitNode(cbNode, node.name);
            case 195 /* ElementAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.questionDotToken) ||
                    visitNode(cbNode, node.argumentExpression);
            case 196 /* CallExpression */:
            case 197 /* NewExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.questionDotToken) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNodes(cbNode, cbNodes, node.arguments);
            case 198 /* TaggedTemplateExpression */:
                return visitNode(cbNode, node.tag) ||
                    visitNode(cbNode, node.questionDotToken) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNode(cbNode, node.template);
            case 199 /* TypeAssertionExpression */:
                return visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.expression);
            case 200 /* ParenthesizedExpression */:
                return visitNode(cbNode, node.expression);
            case 203 /* DeleteExpression */:
                return visitNode(cbNode, node.expression);
            case 204 /* TypeOfExpression */:
                return visitNode(cbNode, node.expression);
            case 205 /* VoidExpression */:
                return visitNode(cbNode, node.expression);
            case 207 /* PrefixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 212 /* YieldExpression */:
                return visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.expression);
            case 206 /* AwaitExpression */:
                return visitNode(cbNode, node.expression);
            case 208 /* PostfixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 209 /* BinaryExpression */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.operatorToken) ||
                    visitNode(cbNode, node.right);
            case 217 /* AsExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.type);
            case 218 /* NonNullExpression */:
                return visitNode(cbNode, node.expression);
            case 219 /* MetaProperty */:
                return visitNode(cbNode, node.name);
            case 210 /* ConditionalExpression */:
                return visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.whenTrue) ||
                    visitNode(cbNode, node.colonToken) ||
                    visitNode(cbNode, node.whenFalse);
            case 213 /* SpreadElement */:
                return visitNode(cbNode, node.expression);
            case 223 /* Block */:
            case 250 /* ModuleBlock */:
                return visitNodes(cbNode, cbNodes, node.statements);
            case 290 /* SourceFile */:
                return visitNodes(cbNode, cbNodes, node.statements) ||
                    visitNode(cbNode, node.endOfFileToken);
            case 225 /* VariableStatement */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.declarationList);
            case 243 /* VariableDeclarationList */:
                return visitNodes(cbNode, cbNodes, node.declarations);
            case 226 /* ExpressionStatement */:
                return visitNode(cbNode, node.expression);
            case 227 /* IfStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.thenStatement) ||
                    visitNode(cbNode, node.elseStatement);
            case 228 /* DoStatement */:
                return visitNode(cbNode, node.statement) ||
                    visitNode(cbNode, node.expression);
            case 229 /* WhileStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 230 /* ForStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.incrementor) ||
                    visitNode(cbNode, node.statement);
            case 231 /* ForInStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 232 /* ForOfStatement */:
                return visitNode(cbNode, node.awaitModifier) ||
                    visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 233 /* ContinueStatement */:
            case 234 /* BreakStatement */:
                return visitNode(cbNode, node.label);
            case 235 /* ReturnStatement */:
                return visitNode(cbNode, node.expression);
            case 236 /* WithStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 237 /* SwitchStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.caseBlock);
            case 251 /* CaseBlock */:
                return visitNodes(cbNode, cbNodes, node.clauses);
            case 277 /* CaseClause */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.statements);
            case 278 /* DefaultClause */:
                return visitNodes(cbNode, cbNodes, node.statements);
            case 238 /* LabeledStatement */:
                return visitNode(cbNode, node.label) ||
                    visitNode(cbNode, node.statement);
            case 239 /* ThrowStatement */:
                return visitNode(cbNode, node.expression);
            case 240 /* TryStatement */:
                return visitNode(cbNode, node.tryBlock) ||
                    visitNode(cbNode, node.catchClause) ||
                    visitNode(cbNode, node.finallyBlock);
            case 280 /* CatchClause */:
                return visitNode(cbNode, node.variableDeclaration) ||
                    visitNode(cbNode, node.block);
            case 157 /* Decorator */:
                return visitNode(cbNode, node.expression);
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 246 /* InterfaceDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 247 /* TypeAliasDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNode(cbNode, node.type);
            case 248 /* EnumDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 284 /* EnumMember */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 249 /* ModuleDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.body);
            case 253 /* ImportEqualsDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.moduleReference);
            case 254 /* ImportDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.importClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 255 /* ImportClause */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.namedBindings);
            case 252 /* NamespaceExportDeclaration */:
                return visitNode(cbNode, node.name);
            case 256 /* NamespaceImport */:
                return visitNode(cbNode, node.name);
            case 262 /* NamespaceExport */:
                return visitNode(cbNode, node.name);
            case 257 /* NamedImports */:
            case 261 /* NamedExports */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 260 /* ExportDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.exportClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
                return visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.name);
            case 259 /* ExportAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.expression);
            case 211 /* TemplateExpression */:
                return visitNode(cbNode, node.head) || visitNodes(cbNode, cbNodes, node.templateSpans);
            case 221 /* TemplateSpan */:
                return visitNode(cbNode, node.expression) || visitNode(cbNode, node.literal);
            case 154 /* ComputedPropertyName */:
                return visitNode(cbNode, node.expression);
            case 279 /* HeritageClause */:
                return visitNodes(cbNode, cbNodes, node.types);
            case 216 /* ExpressionWithTypeArguments */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 265 /* ExternalModuleReference */:
                return visitNode(cbNode, node.expression);
            case 264 /* MissingDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators);
            case 327 /* CommaListExpression */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 266 /* JsxElement */:
                return visitNode(cbNode, node.openingElement) ||
                    visitNodes(cbNode, cbNodes, node.children) ||
                    visitNode(cbNode, node.closingElement);
            case 270 /* JsxFragment */:
                return visitNode(cbNode, node.openingFragment) ||
                    visitNodes(cbNode, cbNodes, node.children) ||
                    visitNode(cbNode, node.closingFragment);
            case 267 /* JsxSelfClosingElement */:
            case 268 /* JsxOpeningElement */:
                return visitNode(cbNode, node.tagName) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNode(cbNode, node.attributes);
            case 274 /* JsxAttributes */:
                return visitNodes(cbNode, cbNodes, node.properties);
            case 273 /* JsxAttribute */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 275 /* JsxSpreadAttribute */:
                return visitNode(cbNode, node.expression);
            case 276 /* JsxExpression */:
                return visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.expression);
            case 269 /* JsxClosingElement */:
                return visitNode(cbNode, node.tagName);
            case 176 /* OptionalType */:
            case 177 /* RestType */:
            case 294 /* JSDocTypeExpression */:
            case 298 /* JSDocNonNullableType */:
            case 297 /* JSDocNullableType */:
            case 299 /* JSDocOptionalType */:
            case 301 /* JSDocVariadicType */:
                return visitNode(cbNode, node.type);
            case 300 /* JSDocFunctionType */:
                return visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 303 /* JSDocComment */:
                return visitNodes(cbNode, cbNodes, node.tags);
            case 317 /* JSDocParameterTag */:
            case 323 /* JSDocPropertyTag */:
                return visitNode(cbNode, node.tagName) ||
                    (node.isNameFirst
                        ? visitNode(cbNode, node.name) ||
                            visitNode(cbNode, node.typeExpression)
                        : visitNode(cbNode, node.typeExpression) ||
                            visitNode(cbNode, node.name));
            case 309 /* JSDocAuthorTag */:
                return visitNode(cbNode, node.tagName);
            case 308 /* JSDocImplementsTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.class);
            case 307 /* JSDocAugmentsTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.class);
            case 321 /* JSDocTemplateTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.constraint) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters);
            case 322 /* JSDocTypedefTag */:
                return visitNode(cbNode, node.tagName) ||
                    (node.typeExpression &&
                        node.typeExpression.kind === 294 /* JSDocTypeExpression */
                        ? visitNode(cbNode, node.typeExpression) ||
                            visitNode(cbNode, node.fullName)
                        : visitNode(cbNode, node.fullName) ||
                            visitNode(cbNode, node.typeExpression));
            case 315 /* JSDocCallbackTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.fullName) ||
                    visitNode(cbNode, node.typeExpression);
            case 318 /* JSDocReturnTag */:
            case 320 /* JSDocTypeTag */:
            case 319 /* JSDocThisTag */:
            case 316 /* JSDocEnumTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.typeExpression);
            case 305 /* JSDocSignature */:
                return ts.forEach(node.typeParameters, cbNode) ||
                    ts.forEach(node.parameters, cbNode) ||
                    visitNode(cbNode, node.type);
            case 304 /* JSDocTypeLiteral */:
                return ts.forEach(node.jsDocPropertyTags, cbNode);
            case 306 /* JSDocTag */:
            case 310 /* JSDocClassTag */:
            case 311 /* JSDocPublicTag */:
            case 312 /* JSDocPrivateTag */:
            case 313 /* JSDocProtectedTag */:
            case 314 /* JSDocReadonlyTag */:
                return visitNode(cbNode, node.tagName);
            case 326 /* PartiallyEmittedExpression */:
                return visitNode(cbNode, node.expression);
        }
    }
    ts.forEachChild = forEachChild;
    /** @internal */
    /**
     * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
     * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; additionally,
     * unlike `forEachChild`, embedded arrays are flattened and the 'cbNode' callback is invoked for each element.
     *  If a callback returns a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
     *
     * @param node a given node to visit its children
     * @param cbNode a callback to be invoked for all child nodes
     * @param cbNodes a callback to be invoked for embedded array
     *
     * @remarks Unlike `forEachChild`, `forEachChildRecursively` handles recursively invoking the traversal on each child node found,
     * and while doing so, handles traversing the structure without relying on the callstack to encode the tree structure.
     */
    function forEachChildRecursively(rootNode, cbNode, cbNodes) {
        var stack = [rootNode];
        while (stack.length) {
            var parent = stack.pop();
            var res = visitAllPossibleChildren(parent, gatherPossibleChildren(parent));
            if (res) {
                return res;
            }
        }
        return;
        function gatherPossibleChildren(node) {
            var children = [];
            forEachChild(node, addWorkItem, addWorkItem); // By using a stack above and `unshift` here, we emulate a depth-first preorder traversal
            return children;
            function addWorkItem(n) {
                children.unshift(n);
            }
        }
        function visitAllPossibleChildren(parent, children) {
            for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
                var child = children_1[_i];
                if (ts.isArray(child)) {
                    if (cbNodes) {
                        var res = cbNodes(child, parent);
                        if (res) {
                            if (res === "skip")
                                continue;
                            return res;
                        }
                    }
                    for (var i = child.length - 1; i >= 0; i--) {
                        var realChild = child[i];
                        var res = cbNode(realChild, parent);
                        if (res) {
                            if (res === "skip")
                                continue;
                            return res;
                        }
                        stack.push(realChild);
                    }
                }
                else {
                    stack.push(child);
                    var res = cbNode(child, parent);
                    if (res) {
                        if (res === "skip")
                            continue;
                        return res;
                    }
                }
            }
        }
    }
    ts.forEachChildRecursively = forEachChildRecursively;
    function createSourceFile(fileName, sourceText, languageVersion, setParentNodes, scriptKind) {
        if (setParentNodes === void 0) { setParentNodes = false; }
        ts.performance.mark("beforeParse");
        var result;
        ts.perfLogger.logStartParseSourceFile(fileName);
        if (languageVersion === 100 /* JSON */) {
            result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, 6 /* JSON */);
        }
        else {
            result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
        }
        ts.perfLogger.logStopParseSourceFile();
        ts.performance.mark("afterParse");
        ts.performance.measure("Parse", "beforeParse", "afterParse");
        return result;
    }
    ts.createSourceFile = createSourceFile;
    function parseIsolatedEntityName(text, languageVersion) {
        return Parser.parseIsolatedEntityName(text, languageVersion);
    }
    ts.parseIsolatedEntityName = parseIsolatedEntityName;
    /**
     * Parse json text into SyntaxTree and return node and parse errors if any
     * @param fileName
     * @param sourceText
     */
    function parseJsonText(fileName, sourceText) {
        return Parser.parseJsonText(fileName, sourceText);
    }
    ts.parseJsonText = parseJsonText;
    // See also `isExternalOrCommonJsModule` in utilities.ts
    function isExternalModule(file) {
        return file.externalModuleIndicator !== undefined;
    }
    ts.isExternalModule = isExternalModule;
    // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter
    // indicates what changed between the 'text' that this SourceFile has and the 'newText'.
    // The SourceFile will be created with the compiler attempting to reuse as many nodes from
    // this file as possible.
    //
    // Note: this function mutates nodes from this SourceFile. That means any existing nodes
    // from this SourceFile that are being held onto may change as a result (including
    // becoming detached from any SourceFile).  It is recommended that this SourceFile not
    // be used once 'update' is called on it.
    function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
        if (aggressiveChecks === void 0) { aggressiveChecks = false; }
        var newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
        // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
        // We will manually port the flag to the new source file.
        newSourceFile.flags |= (sourceFile.flags & 3145728 /* PermanentlySetIncrementalFlags */);
        return newSourceFile;
    }
    ts.updateSourceFile = updateSourceFile;
    /* @internal */
    function parseIsolatedJSDocComment(content, start, length) {
        var result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length);
        if (result && result.jsDoc) {
            // because the jsDocComment was parsed out of the source file, it might
            // not be covered by the fixupParentReferences.
            Parser.fixupParentReferences(result.jsDoc);
        }
        return result;
    }
    ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
    /* @internal */
    // Exposed only for testing.
    function parseJSDocTypeExpressionForTests(content, start, length) {
        return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length);
    }
    ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
    // Implement the parser as a singleton module.  We do this for perf reasons because creating
    // parser instances can actually be expensive enough to impact us on projects with many source
    // files.
    var Parser;
    (function (Parser) {
        // Share a single scanner across all calls to parse a source file.  This helps speed things
        // up by avoiding the cost of creating/compiling scanners over and over again.
        var scanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ true);
        var disallowInAndDecoratorContext = 4096 /* DisallowInContext */ | 16384 /* DecoratorContext */;
        // capture constructors in 'initializeState' to avoid null checks
        var NodeConstructor;
        var TokenConstructor;
        var IdentifierConstructor;
        var PrivateIdentifierConstructor;
        var SourceFileConstructor;
        var sourceFile;
        var parseDiagnostics;
        var syntaxCursor;
        var currentToken;
        var sourceText;
        var nodeCount;
        var identifiers;
        var privateIdentifiers;
        var identifierCount;
        var parsingContext;
        var notParenthesizedArrow;
        // Flags that dictate what parsing context we're in.  For example:
        // Whether or not we are in strict parsing mode.  All that changes in strict parsing mode is
        // that some tokens that would be considered identifiers may be considered keywords.
        //
        // When adding more parser context flags, consider which is the more common case that the
        // flag will be in.  This should be the 'false' state for that flag.  The reason for this is
        // that we don't store data in our nodes unless the value is in the *non-default* state.  So,
        // for example, more often than code 'allows-in' (or doesn't 'disallow-in').  We opt for
        // 'disallow-in' set to 'false'.  Otherwise, if we had 'allowsIn' set to 'true', then almost
        // all nodes would need extra state on them to store this info.
        //
        // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6
        // grammar specification.
        //
        // An important thing about these context concepts.  By default they are effectively inherited
        // while parsing through every grammar production.  i.e. if you don't change them, then when
        // you parse a sub-production, it will have the same context values as the parent production.
        // This is great most of the time.  After all, consider all the 'expression' grammar productions
        // and how nearly all of them pass along the 'in' and 'yield' context values:
        //
        // EqualityExpression[In, Yield] :
        //      RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield]
        //
        // Where you have to be careful is then understanding what the points are in the grammar
        // where the values are *not* passed along.  For example:
        //
        // SingleNameBinding[Yield,GeneratorParameter]
        //      [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt
        //      [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
        //
        // Here this is saying that if the GeneratorParameter context flag is set, that we should
        // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier
        // and we should explicitly unset the 'yield' context flag before calling into the Initializer.
        // production.  Conversely, if the GeneratorParameter context flag is not set, then we
        // should leave the 'yield' context flag alone.
        //
        // Getting this all correct is tricky and requires careful reading of the grammar to
        // understand when these values should be changed versus when they should be inherited.
        //
        // Note: it should not be necessary to save/restore these flags during speculative/lookahead
        // parsing.  These context flags are naturally stored and restored through normal recursive
        // descent parsing and unwinding.
        var contextFlags;
        // Whether or not we've had a parse error since creating the last AST node.  If we have
        // encountered an error, it will be stored on the next AST node we create.  Parse errors
        // can be broken down into three categories:
        //
        // 1) An error that occurred during scanning.  For example, an unterminated literal, or a
        //    character that was completely not understood.
        //
        // 2) A token was expected, but was not present.  This type of error is commonly produced
        //    by the 'parseExpected' function.
        //
        // 3) A token was present that no parsing function was able to consume.  This type of error
        //    only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser
        //    decides to skip the token.
        //
        // In all of these cases, we want to mark the next node as having had an error before it.
        // With this mark, we can know in incremental settings if this node can be reused, or if
        // we have to reparse it.  If we don't keep this information around, we may just reuse the
        // node.  in that event we would then not produce the same errors as we did before, causing
        // significant confusion problems.
        //
        // Note: it is necessary that this value be saved/restored during speculative/lookahead
        // parsing.  During lookahead parsing, we will often create a node.  That node will have
        // this value attached, and then this value will be set back to 'false'.  If we decide to
        // rewind, we must get back to the same value we had prior to the lookahead.
        //
        // Note: any errors at the end of the file that do not precede a regular node, should get
        // attached to the EOF token.
        var parseErrorBeforeNextFinishedNode = false;
        function parseSourceFile(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes, scriptKind) {
            if (setParentNodes === void 0) { setParentNodes = false; }
            scriptKind = ts.ensureScriptKind(fileName, scriptKind);
            if (scriptKind === 6 /* JSON */) {
                var result_2 = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes);
                ts.convertToObjectWorker(result_2, result_2.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
                result_2.referencedFiles = ts.emptyArray;
                result_2.typeReferenceDirectives = ts.emptyArray;
                result_2.libReferenceDirectives = ts.emptyArray;
                result_2.amdDependencies = ts.emptyArray;
                result_2.hasNoDefaultLib = false;
                result_2.pragmas = ts.emptyMap;
                return result_2;
            }
            initializeState(sourceText, languageVersion, syntaxCursor, scriptKind);
            var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
            clearState();
            return result;
        }
        Parser.parseSourceFile = parseSourceFile;
        function parseIsolatedEntityName(content, languageVersion) {
            // Choice of `isDeclarationFile` should be arbitrary
            initializeState(content, languageVersion, /*syntaxCursor*/ undefined, 1 /* JS */);
            // Prime the scanner.
            nextToken();
            var entityName = parseEntityName(/*allowReservedWords*/ true);
            var isInvalid = token() === 1 /* EndOfFileToken */ && !parseDiagnostics.length;
            clearState();
            return isInvalid ? entityName : undefined;
        }
        Parser.parseIsolatedEntityName = parseIsolatedEntityName;
        function parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes) {
            if (languageVersion === void 0) { languageVersion = 2 /* ES2015 */; }
            initializeState(sourceText, languageVersion, syntaxCursor, 6 /* JSON */);
            // Set source file so that errors will be reported with this file name
            sourceFile = createSourceFile(fileName, 2 /* ES2015 */, 6 /* JSON */, /*isDeclaration*/ false);
            sourceFile.flags = contextFlags;
            // Prime the scanner.
            nextToken();
            var pos = getNodePos();
            if (token() === 1 /* EndOfFileToken */) {
                sourceFile.statements = createNodeArray([], pos, pos);
                sourceFile.endOfFileToken = parseTokenNode();
            }
            else {
                var statement = createNode(226 /* ExpressionStatement */);
                switch (token()) {
                    case 22 /* OpenBracketToken */:
                        statement.expression = parseArrayLiteralExpression();
                        break;
                    case 106 /* TrueKeyword */:
                    case 91 /* FalseKeyword */:
                    case 100 /* NullKeyword */:
                        statement.expression = parseTokenNode();
                        break;
                    case 40 /* MinusToken */:
                        if (lookAhead(function () { return nextToken() === 8 /* NumericLiteral */ && nextToken() !== 58 /* ColonToken */; })) {
                            statement.expression = parsePrefixUnaryExpression();
                        }
                        else {
                            statement.expression = parseObjectLiteralExpression();
                        }
                        break;
                    case 8 /* NumericLiteral */:
                    case 10 /* StringLiteral */:
                        if (lookAhead(function () { return nextToken() !== 58 /* ColonToken */; })) {
                            statement.expression = parseLiteralNode();
                            break;
                        }
                    // falls through
                    default:
                        statement.expression = parseObjectLiteralExpression();
                        break;
                }
                finishNode(statement);
                sourceFile.statements = createNodeArray([statement], pos);
                sourceFile.endOfFileToken = parseExpectedToken(1 /* EndOfFileToken */, ts.Diagnostics.Unexpected_token);
            }
            if (setParentNodes) {
                fixupParentReferences(sourceFile);
            }
            sourceFile.nodeCount = nodeCount;
            sourceFile.identifierCount = identifierCount;
            sourceFile.identifiers = identifiers;
            sourceFile.parseDiagnostics = parseDiagnostics;
            var result = sourceFile;
            clearState();
            return result;
        }
        Parser.parseJsonText = parseJsonText;
        function getLanguageVariant(scriptKind) {
            // .tsx and .jsx files are treated as jsx language variant.
            return scriptKind === 4 /* TSX */ || scriptKind === 2 /* JSX */ || scriptKind === 1 /* JS */ || scriptKind === 6 /* JSON */ ? 1 /* JSX */ : 0 /* Standard */;
        }
        function initializeState(_sourceText, languageVersion, _syntaxCursor, scriptKind) {
            NodeConstructor = ts.objectAllocator.getNodeConstructor();
            TokenConstructor = ts.objectAllocator.getTokenConstructor();
            IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor();
            PrivateIdentifierConstructor = ts.objectAllocator.getPrivateIdentifierConstructor();
            SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
            sourceText = _sourceText;
            syntaxCursor = _syntaxCursor;
            parseDiagnostics = [];
            parsingContext = 0;
            identifiers = ts.createMap();
            privateIdentifiers = ts.createMap();
            identifierCount = 0;
            nodeCount = 0;
            switch (scriptKind) {
                case 1 /* JS */:
                case 2 /* JSX */:
                    contextFlags = 131072 /* JavaScriptFile */;
                    break;
                case 6 /* JSON */:
                    contextFlags = 131072 /* JavaScriptFile */ | 33554432 /* JsonFile */;
                    break;
                default:
                    contextFlags = 0 /* None */;
                    break;
            }
            parseErrorBeforeNextFinishedNode = false;
            // Initialize and prime the scanner before parsing the source elements.
            scanner.setText(sourceText);
            scanner.setOnError(scanError);
            scanner.setScriptTarget(languageVersion);
            scanner.setLanguageVariant(getLanguageVariant(scriptKind));
        }
        function clearState() {
            // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily.
            scanner.clearCommentDirectives();
            scanner.setText("");
            scanner.setOnError(undefined);
            // Clear any data.  We don't want to accidentally hold onto it for too long.
            parseDiagnostics = undefined;
            sourceFile = undefined;
            identifiers = undefined;
            syntaxCursor = undefined;
            sourceText = undefined;
            notParenthesizedArrow = undefined;
        }
        function parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind) {
            var isDeclarationFile = isDeclarationFileName(fileName);
            if (isDeclarationFile) {
                contextFlags |= 8388608 /* Ambient */;
            }
            sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile);
            sourceFile.flags = contextFlags;
            // Prime the scanner.
            nextToken();
            // A member of ReadonlyArray<T> isn't assignable to a member of T[] (and prevents a direct cast) - but this is where we set up those members so they can be readonly in the future
            processCommentPragmas(sourceFile, sourceText);
            processPragmasIntoFields(sourceFile, reportPragmaDiagnostic);
            sourceFile.statements = parseList(0 /* SourceElements */, parseStatement);
            ts.Debug.assert(token() === 1 /* EndOfFileToken */);
            sourceFile.endOfFileToken = addJSDocComment(parseTokenNode());
            setExternalModuleIndicator(sourceFile);
            sourceFile.commentDirectives = scanner.getCommentDirectives();
            sourceFile.nodeCount = nodeCount;
            sourceFile.identifierCount = identifierCount;
            sourceFile.identifiers = identifiers;
            sourceFile.parseDiagnostics = parseDiagnostics;
            if (setParentNodes) {
                fixupParentReferences(sourceFile);
            }
            return sourceFile;
            function reportPragmaDiagnostic(pos, end, diagnostic) {
                parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, pos, end, diagnostic));
            }
        }
        function addJSDocComment(node) {
            ts.Debug.assert(!node.jsDoc); // Should only be called once per node
            var jsDoc = ts.mapDefined(ts.getJSDocCommentRanges(node, sourceFile.text), function (comment) { return JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); });
            if (jsDoc.length)
                node.jsDoc = jsDoc;
            return node;
        }
        function fixupParentReferences(rootNode) {
            // normally parent references are set during binding. However, for clients that only need
            // a syntax tree, and no semantic features, then the binding process is an unnecessary
            // overhead.  This functions allows us to set all the parents, without all the expense of
            // binding.
            forEachChildRecursively(rootNode, bindParentToChild);
            function bindParentToChild(child, parent) {
                child.parent = parent;
                if (ts.hasJSDocNodes(child)) {
                    for (var _i = 0, _a = child.jsDoc; _i < _a.length; _i++) {
                        var doc = _a[_i];
                        bindParentToChild(doc, child);
                        forEachChildRecursively(doc, bindParentToChild);
                    }
                }
            }
        }
        Parser.fixupParentReferences = fixupParentReferences;
        function createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile) {
            // code from createNode is inlined here so createNode won't have to deal with special case of creating source files
            // this is quite rare comparing to other nodes and createNode should be as fast as possible
            var sourceFile = new SourceFileConstructor(290 /* SourceFile */, /*pos*/ 0, /* end */ sourceText.length);
            nodeCount++;
            sourceFile.text = sourceText;
            sourceFile.bindDiagnostics = [];
            sourceFile.bindSuggestionDiagnostics = undefined;
            sourceFile.languageVersion = languageVersion;
            sourceFile.fileName = ts.normalizePath(fileName);
            sourceFile.languageVariant = getLanguageVariant(scriptKind);
            sourceFile.isDeclarationFile = isDeclarationFile;
            sourceFile.scriptKind = scriptKind;
            return sourceFile;
        }
        function setContextFlag(val, flag) {
            if (val) {
                contextFlags |= flag;
            }
            else {
                contextFlags &= ~flag;
            }
        }
        function setDisallowInContext(val) {
            setContextFlag(val, 4096 /* DisallowInContext */);
        }
        function setYieldContext(val) {
            setContextFlag(val, 8192 /* YieldContext */);
        }
        function setDecoratorContext(val) {
            setContextFlag(val, 16384 /* DecoratorContext */);
        }
        function setAwaitContext(val) {
            setContextFlag(val, 32768 /* AwaitContext */);
        }
        function doOutsideOfContext(context, func) {
            // contextFlagsToClear will contain only the context flags that are
            // currently set that we need to temporarily clear
            // We don't just blindly reset to the previous flags to ensure
            // that we do not mutate cached flags for the incremental
            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
            // HasAggregatedChildData).
            var contextFlagsToClear = context & contextFlags;
            if (contextFlagsToClear) {
                // clear the requested context flags
                setContextFlag(/*val*/ false, contextFlagsToClear);
                var result = func();
                // restore the context flags we just cleared
                setContextFlag(/*val*/ true, contextFlagsToClear);
                return result;
            }
            // no need to do anything special as we are not in any of the requested contexts
            return func();
        }
        function doInsideOfContext(context, func) {
            // contextFlagsToSet will contain only the context flags that
            // are not currently set that we need to temporarily enable.
            // We don't just blindly reset to the previous flags to ensure
            // that we do not mutate cached flags for the incremental
            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
            // HasAggregatedChildData).
            var contextFlagsToSet = context & ~contextFlags;
            if (contextFlagsToSet) {
                // set the requested context flags
                setContextFlag(/*val*/ true, contextFlagsToSet);
                var result = func();
                // reset the context flags we just set
                setContextFlag(/*val*/ false, contextFlagsToSet);
                return result;
            }
            // no need to do anything special as we are already in all of the requested contexts
            return func();
        }
        function allowInAnd(func) {
            return doOutsideOfContext(4096 /* DisallowInContext */, func);
        }
        function disallowInAnd(func) {
            return doInsideOfContext(4096 /* DisallowInContext */, func);
        }
        function doInYieldContext(func) {
            return doInsideOfContext(8192 /* YieldContext */, func);
        }
        function doInDecoratorContext(func) {
            return doInsideOfContext(16384 /* DecoratorContext */, func);
        }
        function doInAwaitContext(func) {
            return doInsideOfContext(32768 /* AwaitContext */, func);
        }
        function doOutsideOfAwaitContext(func) {
            return doOutsideOfContext(32768 /* AwaitContext */, func);
        }
        function doInYieldAndAwaitContext(func) {
            return doInsideOfContext(8192 /* YieldContext */ | 32768 /* AwaitContext */, func);
        }
        function doOutsideOfYieldAndAwaitContext(func) {
            return doOutsideOfContext(8192 /* YieldContext */ | 32768 /* AwaitContext */, func);
        }
        function inContext(flags) {
            return (contextFlags & flags) !== 0;
        }
        function inYieldContext() {
            return inContext(8192 /* YieldContext */);
        }
        function inDisallowInContext() {
            return inContext(4096 /* DisallowInContext */);
        }
        function inDecoratorContext() {
            return inContext(16384 /* DecoratorContext */);
        }
        function inAwaitContext() {
            return inContext(32768 /* AwaitContext */);
        }
        function parseErrorAtCurrentToken(message, arg0) {
            parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
        }
        function parseErrorAtPosition(start, length, message, arg0) {
            // Don't report another error if it would just be at the same position as the last error.
            var lastError = ts.lastOrUndefined(parseDiagnostics);
            if (!lastError || start !== lastError.start) {
                parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0));
            }
            // Mark that we've encountered an error.  We'll set an appropriate bit on the next
            // node we finish so that it can't be reused incrementally.
            parseErrorBeforeNextFinishedNode = true;
        }
        function parseErrorAt(start, end, message, arg0) {
            parseErrorAtPosition(start, end - start, message, arg0);
        }
        function parseErrorAtRange(range, message, arg0) {
            parseErrorAt(range.pos, range.end, message, arg0);
        }
        function scanError(message, length) {
            parseErrorAtPosition(scanner.getTextPos(), length, message);
        }
        function getNodePos() {
            return scanner.getStartPos();
        }
        // Use this function to access the current token instead of reading the currentToken
        // variable. Since function results aren't narrowed in control flow analysis, this ensures
        // that the type checker doesn't make wrong assumptions about the type of the current
        // token (e.g. a call to nextToken() changes the current token but the checker doesn't
        // reason about this side effect).  Mainstream VMs inline simple functions like this, so
        // there is no performance penalty.
        function token() {
            return currentToken;
        }
        function nextTokenWithoutCheck() {
            return currentToken = scanner.scan();
        }
        function nextToken() {
            // if the keyword had an escape
            if (ts.isKeyword(currentToken) && (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape())) {
                // issue a parse error for the escape
                parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), ts.Diagnostics.Keywords_cannot_contain_escape_characters);
            }
            return nextTokenWithoutCheck();
        }
        function nextTokenJSDoc() {
            return currentToken = scanner.scanJsDocToken();
        }
        function reScanGreaterToken() {
            return currentToken = scanner.reScanGreaterToken();
        }
        function reScanSlashToken() {
            return currentToken = scanner.reScanSlashToken();
        }
        function reScanTemplateToken(isTaggedTemplate) {
            return currentToken = scanner.reScanTemplateToken(isTaggedTemplate);
        }
        function reScanTemplateHeadOrNoSubstitutionTemplate() {
            return currentToken = scanner.reScanTemplateHeadOrNoSubstitutionTemplate();
        }
        function reScanLessThanToken() {
            return currentToken = scanner.reScanLessThanToken();
        }
        function scanJsxIdentifier() {
            return currentToken = scanner.scanJsxIdentifier();
        }
        function scanJsxText() {
            return currentToken = scanner.scanJsxToken();
        }
        function scanJsxAttributeValue() {
            return currentToken = scanner.scanJsxAttributeValue();
        }
        function speculationHelper(callback, isLookAhead) {
            // Keep track of the state we'll need to rollback to if lookahead fails (or if the
            // caller asked us to always reset our state).
            var saveToken = currentToken;
            var saveParseDiagnosticsLength = parseDiagnostics.length;
            var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
            // Note: it is not actually necessary to save/restore the context flags here.  That's
            // because the saving/restoring of these flags happens naturally through the recursive
            // descent nature of our parser.  However, we still store this here just so we can
            // assert that invariant holds.
            var saveContextFlags = contextFlags;
            // If we're only looking ahead, then tell the scanner to only lookahead as well.
            // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the
            // same.
            var result = isLookAhead
                ? scanner.lookAhead(callback)
                : scanner.tryScan(callback);
            ts.Debug.assert(saveContextFlags === contextFlags);
            // If our callback returned something 'falsy' or we're just looking ahead,
            // then unconditionally restore us to where we were.
            if (!result || isLookAhead) {
                currentToken = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
            }
            return result;
        }
        /** Invokes the provided callback then unconditionally restores the parser to the state it
         * was in immediately prior to invoking the callback.  The result of invoking the callback
         * is returned from this function.
         */
        function lookAhead(callback) {
            return speculationHelper(callback, /*isLookAhead*/ true);
        }
        /** Invokes the provided callback.  If the callback returns something falsy, then it restores
         * the parser to the state it was in immediately prior to invoking the callback.  If the
         * callback returns something truthy, then the parser state is not rolled back.  The result
         * of invoking the callback is returned from this function.
         */
        function tryParse(callback) {
            return speculationHelper(callback, /*isLookAhead*/ false);
        }
        // Ignore strict mode flag because we will report an error in type checker instead.
        function isIdentifier() {
            if (token() === 75 /* Identifier */) {
                return true;
            }
            // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is
            // considered a keyword and is not an identifier.
            if (token() === 121 /* YieldKeyword */ && inYieldContext()) {
                return false;
            }
            // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is
            // considered a keyword and is not an identifier.
            if (token() === 127 /* AwaitKeyword */ && inAwaitContext()) {
                return false;
            }
            return token() > 112 /* LastReservedWord */;
        }
        function parseExpected(kind, diagnosticMessage, shouldAdvance) {
            if (shouldAdvance === void 0) { shouldAdvance = true; }
            if (token() === kind) {
                if (shouldAdvance) {
                    nextToken();
                }
                return true;
            }
            // Report specific message if provided with one.  Otherwise, report generic fallback message.
            if (diagnosticMessage) {
                parseErrorAtCurrentToken(diagnosticMessage);
            }
            else {
                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind));
            }
            return false;
        }
        function parseExpectedJSDoc(kind) {
            if (token() === kind) {
                nextTokenJSDoc();
                return true;
            }
            parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind));
            return false;
        }
        function parseOptional(t) {
            if (token() === t) {
                nextToken();
                return true;
            }
            return false;
        }
        function parseOptionalToken(t) {
            if (token() === t) {
                return parseTokenNode();
            }
            return undefined;
        }
        function parseOptionalTokenJSDoc(t) {
            if (token() === t) {
                return parseTokenNodeJSDoc();
            }
            return undefined;
        }
        function parseExpectedToken(t, diagnosticMessage, arg0) {
            return parseOptionalToken(t) ||
                createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || ts.Diagnostics._0_expected, arg0 || ts.tokenToString(t));
        }
        function parseExpectedTokenJSDoc(t) {
            return parseOptionalTokenJSDoc(t) ||
                createMissingNode(t, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(t));
        }
        function parseTokenNode() {
            var node = createNode(token());
            nextToken();
            return finishNode(node);
        }
        function parseTokenNodeJSDoc() {
            var node = createNode(token());
            nextTokenJSDoc();
            return finishNode(node);
        }
        function canParseSemicolon() {
            // If there's a real semicolon, then we can always parse it out.
            if (token() === 26 /* SemicolonToken */) {
                return true;
            }
            // We can parse out an optional semicolon in ASI cases in the following cases.
            return token() === 19 /* CloseBraceToken */ || token() === 1 /* EndOfFileToken */ || scanner.hasPrecedingLineBreak();
        }
        function parseSemicolon() {
            if (canParseSemicolon()) {
                if (token() === 26 /* SemicolonToken */) {
                    // consume the semicolon if it was explicitly provided.
                    nextToken();
                }
                return true;
            }
            else {
                return parseExpected(26 /* SemicolonToken */);
            }
        }
        function createNode(kind, pos) {
            nodeCount++;
            var p = pos >= 0 ? pos : scanner.getStartPos();
            return ts.isNodeKind(kind) || kind === 0 /* Unknown */ ? new NodeConstructor(kind, p, p) :
                kind === 75 /* Identifier */ ? new IdentifierConstructor(kind, p, p) :
                    kind === 76 /* PrivateIdentifier */ ? new PrivateIdentifierConstructor(kind, p, p) :
                        new TokenConstructor(kind, p, p);
        }
        function createNodeWithJSDoc(kind, pos) {
            var node = createNode(kind, pos);
            if (scanner.getTokenFlags() & 2 /* PrecedingJSDocComment */ && (kind !== 226 /* ExpressionStatement */ || token() !== 20 /* OpenParenToken */)) {
                addJSDocComment(node);
            }
            return node;
        }
        function createNodeArray(elements, pos, end) {
            // Since the element list of a node array is typically created by starting with an empty array and
            // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for
            // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation.
            var length = elements.length;
            var array = (length >= 1 && length <= 4 ? elements.slice() : elements);
            array.pos = pos;
            array.end = end === undefined ? scanner.getStartPos() : end;
            return array;
        }
        function finishNode(node, end) {
            node.end = end === undefined ? scanner.getStartPos() : end;
            if (contextFlags) {
                node.flags |= contextFlags;
            }
            // Keep track on the node if we encountered an error while parsing it.  If we did, then
            // we cannot reuse the node incrementally.  Once we've marked this node, clear out the
            // flag so that we don't mark any subsequent nodes.
            if (parseErrorBeforeNextFinishedNode) {
                parseErrorBeforeNextFinishedNode = false;
                node.flags |= 65536 /* ThisNodeHasError */;
            }
            return node;
        }
        function createMissingNode(kind, reportAtCurrentPosition, diagnosticMessage, arg0) {
            if (reportAtCurrentPosition) {
                parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
            }
            else if (diagnosticMessage) {
                parseErrorAtCurrentToken(diagnosticMessage, arg0);
            }
            var result = createNode(kind);
            if (kind === 75 /* Identifier */) {
                result.escapedText = "";
            }
            else if (ts.isLiteralKind(kind) || ts.isTemplateLiteralKind(kind)) {
                result.text = "";
            }
            return finishNode(result);
        }
        function internIdentifier(text) {
            var identifier = identifiers.get(text);
            if (identifier === undefined) {
                identifiers.set(text, identifier = text);
            }
            return identifier;
        }
        // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues
        // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for
        // each identifier in order to reduce memory consumption.
        function createIdentifier(isIdentifier, diagnosticMessage, privateIdentifierDiagnosticMessage) {
            identifierCount++;
            if (isIdentifier) {
                var node = createNode(75 /* Identifier */);
                // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
                if (token() !== 75 /* Identifier */) {
                    node.originalKeywordKind = token();
                }
                node.escapedText = ts.escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
                nextTokenWithoutCheck();
                return finishNode(node);
            }
            if (token() === 76 /* PrivateIdentifier */) {
                parseErrorAtCurrentToken(privateIdentifierDiagnosticMessage || ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
                return createIdentifier(/*isIdentifier*/ true);
            }
            // Only for end of file because the error gets reported incorrectly on embedded script tags.
            var reportAtCurrentPosition = token() === 1 /* EndOfFileToken */;
            var isReservedWord = scanner.isReservedWord();
            var msgArg = scanner.getTokenText();
            var defaultMessage = isReservedWord ?
                ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here :
                ts.Diagnostics.Identifier_expected;
            return createMissingNode(75 /* Identifier */, reportAtCurrentPosition, diagnosticMessage || defaultMessage, msgArg);
        }
        function parseIdentifier(diagnosticMessage, privateIdentifierDiagnosticMessage) {
            return createIdentifier(isIdentifier(), diagnosticMessage, privateIdentifierDiagnosticMessage);
        }
        function parseIdentifierName(diagnosticMessage) {
            return createIdentifier(ts.tokenIsIdentifierOrKeyword(token()), diagnosticMessage);
        }
        function isLiteralPropertyName() {
            return ts.tokenIsIdentifierOrKeyword(token()) ||
                token() === 10 /* StringLiteral */ ||
                token() === 8 /* NumericLiteral */;
        }
        function parsePropertyNameWorker(allowComputedPropertyNames) {
            if (token() === 10 /* StringLiteral */ || token() === 8 /* NumericLiteral */) {
                var node = parseLiteralNode();
                node.text = internIdentifier(node.text);
                return node;
            }
            if (allowComputedPropertyNames && token() === 22 /* OpenBracketToken */) {
                return parseComputedPropertyName();
            }
            if (token() === 76 /* PrivateIdentifier */) {
                return parsePrivateIdentifier();
            }
            return parseIdentifierName();
        }
        function parsePropertyName() {
            return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
        }
        function parseComputedPropertyName() {
            // PropertyName [Yield]:
            //      LiteralPropertyName
            //      ComputedPropertyName[?Yield]
            var node = createNode(154 /* ComputedPropertyName */);
            parseExpected(22 /* OpenBracketToken */);
            // We parse any expression (including a comma expression). But the grammar
            // says that only an assignment expression is allowed, so the grammar checker
            // will error if it sees a comma expression.
            node.expression = allowInAnd(parseExpression);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function internPrivateIdentifier(text) {
            var privateIdentifier = privateIdentifiers.get(text);
            if (privateIdentifier === undefined) {
                privateIdentifiers.set(text, privateIdentifier = text);
            }
            return privateIdentifier;
        }
        function parsePrivateIdentifier() {
            var node = createNode(76 /* PrivateIdentifier */);
            node.escapedText = ts.escapeLeadingUnderscores(internPrivateIdentifier(scanner.getTokenText()));
            nextToken();
            return finishNode(node);
        }
        function parseContextualModifier(t) {
            return token() === t && tryParse(nextTokenCanFollowModifier);
        }
        function nextTokenIsOnSameLineAndCanFollowModifier() {
            nextToken();
            if (scanner.hasPrecedingLineBreak()) {
                return false;
            }
            return canFollowModifier();
        }
        function nextTokenCanFollowModifier() {
            switch (token()) {
                case 81 /* ConstKeyword */:
                    // 'const' is only a modifier if followed by 'enum'.
                    return nextToken() === 88 /* EnumKeyword */;
                case 89 /* ExportKeyword */:
                    nextToken();
                    if (token() === 84 /* DefaultKeyword */) {
                        return lookAhead(nextTokenCanFollowDefaultKeyword);
                    }
                    if (token() === 145 /* TypeKeyword */) {
                        return lookAhead(nextTokenCanFollowExportModifier);
                    }
                    return canFollowExportModifier();
                case 84 /* DefaultKeyword */:
                    return nextTokenCanFollowDefaultKeyword();
                case 120 /* StaticKeyword */:
                case 131 /* GetKeyword */:
                case 142 /* SetKeyword */:
                    nextToken();
                    return canFollowModifier();
                default:
                    return nextTokenIsOnSameLineAndCanFollowModifier();
            }
        }
        function canFollowExportModifier() {
            return token() !== 41 /* AsteriskToken */
                && token() !== 123 /* AsKeyword */
                && token() !== 18 /* OpenBraceToken */
                && canFollowModifier();
        }
        function nextTokenCanFollowExportModifier() {
            nextToken();
            return canFollowExportModifier();
        }
        function parseAnyContextualModifier() {
            return ts.isModifierKind(token()) && tryParse(nextTokenCanFollowModifier);
        }
        function canFollowModifier() {
            return token() === 22 /* OpenBracketToken */
                || token() === 18 /* OpenBraceToken */
                || token() === 41 /* AsteriskToken */
                || token() === 25 /* DotDotDotToken */
                || isLiteralPropertyName();
        }
        function nextTokenCanFollowDefaultKeyword() {
            nextToken();
            return token() === 80 /* ClassKeyword */ || token() === 94 /* FunctionKeyword */ ||
                token() === 114 /* InterfaceKeyword */ ||
                (token() === 122 /* AbstractKeyword */ && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
                (token() === 126 /* AsyncKeyword */ && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
        }
        // True if positioned at the start of a list element
        function isListElement(parsingContext, inErrorRecovery) {
            var node = currentNode(parsingContext);
            if (node) {
                return true;
            }
            switch (parsingContext) {
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                    // If we're in error recovery, then we don't want to treat ';' as an empty statement.
                    // The problem is that ';' can show up in far too many contexts, and if we see one
                    // and assume it's a statement, then we may bail out inappropriately from whatever
                    // we're parsing.  For example, if we have a semicolon in the middle of a class, then
                    // we really don't want to assume the class is over and we're on a statement in the
                    // outer module.  We just want to consume and move on.
                    return !(token() === 26 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement();
                case 2 /* SwitchClauses */:
                    return token() === 78 /* CaseKeyword */ || token() === 84 /* DefaultKeyword */;
                case 4 /* TypeMembers */:
                    return lookAhead(isTypeMemberStart);
                case 5 /* ClassMembers */:
                    // We allow semicolons as class elements (as specified by ES6) as long as we're
                    // not in error recovery.  If we're in error recovery, we don't want an errant
                    // semicolon to be treated as a class member (since they're almost always used
                    // for statements.
                    return lookAhead(isClassMemberStart) || (token() === 26 /* SemicolonToken */ && !inErrorRecovery);
                case 6 /* EnumMembers */:
                    // Include open bracket computed properties. This technically also lets in indexers,
                    // which would be a candidate for improved error reporting.
                    return token() === 22 /* OpenBracketToken */ || isLiteralPropertyName();
                case 12 /* ObjectLiteralMembers */:
                    switch (token()) {
                        case 22 /* OpenBracketToken */:
                        case 41 /* AsteriskToken */:
                        case 25 /* DotDotDotToken */:
                        case 24 /* DotToken */: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`)
                            return true;
                        default:
                            return isLiteralPropertyName();
                    }
                case 18 /* RestProperties */:
                    return isLiteralPropertyName();
                case 9 /* ObjectBindingElements */:
                    return token() === 22 /* OpenBracketToken */ || token() === 25 /* DotDotDotToken */ || isLiteralPropertyName();
                case 7 /* HeritageClauseElement */:
                    // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{`
                    // That way we won't consume the body of a class in its heritage clause.
                    if (token() === 18 /* OpenBraceToken */) {
                        return lookAhead(isValidHeritageClauseObjectLiteral);
                    }
                    if (!inErrorRecovery) {
                        return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword();
                    }
                    else {
                        // If we're in error recovery we tighten up what we're willing to match.
                        // That way we don't treat something like "this" as a valid heritage clause
                        // element during recovery.
                        return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword();
                    }
                case 8 /* VariableDeclarations */:
                    return isIdentifierOrPrivateIdentifierOrPattern();
                case 10 /* ArrayBindingElements */:
                    return token() === 27 /* CommaToken */ || token() === 25 /* DotDotDotToken */ || isIdentifierOrPrivateIdentifierOrPattern();
                case 19 /* TypeParameters */:
                    return isIdentifier();
                case 15 /* ArrayLiteralMembers */:
                    switch (token()) {
                        case 27 /* CommaToken */:
                        case 24 /* DotToken */: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`)
                            return true;
                    }
                // falls through
                case 11 /* ArgumentExpressions */:
                    return token() === 25 /* DotDotDotToken */ || isStartOfExpression();
                case 16 /* Parameters */:
                    return isStartOfParameter(/*isJSDocParameter*/ false);
                case 17 /* JSDocParameters */:
                    return isStartOfParameter(/*isJSDocParameter*/ true);
                case 20 /* TypeArguments */:
                case 21 /* TupleElementTypes */:
                    return token() === 27 /* CommaToken */ || isStartOfType();
                case 22 /* HeritageClauses */:
                    return isHeritageClause();
                case 23 /* ImportOrExportSpecifiers */:
                    return ts.tokenIsIdentifierOrKeyword(token());
                case 13 /* JsxAttributes */:
                    return ts.tokenIsIdentifierOrKeyword(token()) || token() === 18 /* OpenBraceToken */;
                case 14 /* JsxChildren */:
                    return true;
            }
            return ts.Debug.fail("Non-exhaustive case in 'isListElement'.");
        }
        function isValidHeritageClauseObjectLiteral() {
            ts.Debug.assert(token() === 18 /* OpenBraceToken */);
            if (nextToken() === 19 /* CloseBraceToken */) {
                // if we see "extends {}" then only treat the {} as what we're extending (and not
                // the class body) if we have:
                //
                //      extends {} {
                //      extends {},
                //      extends {} extends
                //      extends {} implements
                var next = nextToken();
                return next === 27 /* CommaToken */ || next === 18 /* OpenBraceToken */ || next === 90 /* ExtendsKeyword */ || next === 113 /* ImplementsKeyword */;
            }
            return true;
        }
        function nextTokenIsIdentifier() {
            nextToken();
            return isIdentifier();
        }
        function nextTokenIsIdentifierOrKeyword() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token());
        }
        function nextTokenIsIdentifierOrKeywordOrGreaterThan() {
            nextToken();
            return ts.tokenIsIdentifierOrKeywordOrGreaterThan(token());
        }
        function isHeritageClauseExtendsOrImplementsKeyword() {
            if (token() === 113 /* ImplementsKeyword */ ||
                token() === 90 /* ExtendsKeyword */) {
                return lookAhead(nextTokenIsStartOfExpression);
            }
            return false;
        }
        function nextTokenIsStartOfExpression() {
            nextToken();
            return isStartOfExpression();
        }
        function nextTokenIsStartOfType() {
            nextToken();
            return isStartOfType();
        }
        // True if positioned at a list terminator
        function isListTerminator(kind) {
            if (token() === 1 /* EndOfFileToken */) {
                // Being at the end of the file ends all lists.
                return true;
            }
            switch (kind) {
                case 1 /* BlockStatements */:
                case 2 /* SwitchClauses */:
                case 4 /* TypeMembers */:
                case 5 /* ClassMembers */:
                case 6 /* EnumMembers */:
                case 12 /* ObjectLiteralMembers */:
                case 9 /* ObjectBindingElements */:
                case 23 /* ImportOrExportSpecifiers */:
                    return token() === 19 /* CloseBraceToken */;
                case 3 /* SwitchClauseStatements */:
                    return token() === 19 /* CloseBraceToken */ || token() === 78 /* CaseKeyword */ || token() === 84 /* DefaultKeyword */;
                case 7 /* HeritageClauseElement */:
                    return token() === 18 /* OpenBraceToken */ || token() === 90 /* ExtendsKeyword */ || token() === 113 /* ImplementsKeyword */;
                case 8 /* VariableDeclarations */:
                    return isVariableDeclaratorListTerminator();
                case 19 /* TypeParameters */:
                    // Tokens other than '>' are here for better error recovery
                    return token() === 31 /* GreaterThanToken */ || token() === 20 /* OpenParenToken */ || token() === 18 /* OpenBraceToken */ || token() === 90 /* ExtendsKeyword */ || token() === 113 /* ImplementsKeyword */;
                case 11 /* ArgumentExpressions */:
                    // Tokens other than ')' are here for better error recovery
                    return token() === 21 /* CloseParenToken */ || token() === 26 /* SemicolonToken */;
                case 15 /* ArrayLiteralMembers */:
                case 21 /* TupleElementTypes */:
                case 10 /* ArrayBindingElements */:
                    return token() === 23 /* CloseBracketToken */;
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                case 18 /* RestProperties */:
                    // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
                    return token() === 21 /* CloseParenToken */ || token() === 23 /* CloseBracketToken */ /*|| token === SyntaxKind.OpenBraceToken*/;
                case 20 /* TypeArguments */:
                    // All other tokens should cause the type-argument to terminate except comma token
                    return token() !== 27 /* CommaToken */;
                case 22 /* HeritageClauses */:
                    return token() === 18 /* OpenBraceToken */ || token() === 19 /* CloseBraceToken */;
                case 13 /* JsxAttributes */:
                    return token() === 31 /* GreaterThanToken */ || token() === 43 /* SlashToken */;
                case 14 /* JsxChildren */:
                    return token() === 29 /* LessThanToken */ && lookAhead(nextTokenIsSlash);
                default:
                    return false;
            }
        }
        function isVariableDeclaratorListTerminator() {
            // If we can consume a semicolon (either explicitly, or with ASI), then consider us done
            // with parsing the list of variable declarators.
            if (canParseSemicolon()) {
                return true;
            }
            // in the case where we're parsing the variable declarator of a 'for-in' statement, we
            // are done if we see an 'in' keyword in front of us. Same with for-of
            if (isInOrOfKeyword(token())) {
                return true;
            }
            // ERROR RECOVERY TWEAK:
            // For better error recovery, if we see an '=>' then we just stop immediately.  We've got an
            // arrow function here and it's going to be very unlikely that we'll resynchronize and get
            // another variable declaration.
            if (token() === 38 /* EqualsGreaterThanToken */) {
                return true;
            }
            // Keep trying to parse out variable declarators.
            return false;
        }
        // True if positioned at element or terminator of the current list or any enclosing list
        function isInSomeParsingContext() {
            for (var kind = 0; kind < 24 /* Count */; kind++) {
                if (parsingContext & (1 << kind)) {
                    if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        // Parses a list of elements
        function parseList(kind, parseElement) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var list = [];
            var listPos = getNodePos();
            while (!isListTerminator(kind)) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var element = parseListElement(kind, parseElement);
                    list.push(element);
                    continue;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            parsingContext = saveParsingContext;
            return createNodeArray(list, listPos);
        }
        function parseListElement(parsingContext, parseElement) {
            var node = currentNode(parsingContext);
            if (node) {
                return consumeNode(node);
            }
            return parseElement();
        }
        function currentNode(parsingContext) {
            // If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse.
            //
            // If there is an outstanding parse error that we've encountered, but not attached to
            // some node, then we cannot get a node from the old source tree.  This is because we
            // want to mark the next node we encounter as being unusable.
            //
            // Note: This may be too conservative.  Perhaps we could reuse the node and set the bit
            // on it (or its leftmost child) as having the error.  For now though, being conservative
            // is nice and likely won't ever affect perf.
            if (!syntaxCursor || !isReusableParsingContext(parsingContext) || parseErrorBeforeNextFinishedNode) {
                return undefined;
            }
            var node = syntaxCursor.currentNode(scanner.getStartPos());
            // Can't reuse a missing node.
            // Can't reuse a node that intersected the change range.
            // Can't reuse a node that contains a parse error.  This is necessary so that we
            // produce the same set of errors again.
            if (ts.nodeIsMissing(node) || node.intersectsChange || ts.containsParseError(node)) {
                return undefined;
            }
            // We can only reuse a node if it was parsed under the same strict mode that we're
            // currently in.  i.e. if we originally parsed a node in non-strict mode, but then
            // the user added 'using strict' at the top of the file, then we can't use that node
            // again as the presence of strict mode may cause us to parse the tokens in the file
            // differently.
            //
            // Note: we *can* reuse tokens when the strict mode changes.  That's because tokens
            // are unaffected by strict mode.  It's just the parser will decide what to do with it
            // differently depending on what mode it is in.
            //
            // This also applies to all our other context flags as well.
            var nodeContextFlags = node.flags & 25358336 /* ContextFlags */;
            if (nodeContextFlags !== contextFlags) {
                return undefined;
            }
            // Ok, we have a node that looks like it could be reused.  Now verify that it is valid
            // in the current list parsing context that we're currently at.
            if (!canReuseNode(node, parsingContext)) {
                return undefined;
            }
            if (node.jsDocCache) {
                // jsDocCache may include tags from parent nodes, which might have been modified.
                node.jsDocCache = undefined;
            }
            return node;
        }
        function consumeNode(node) {
            // Move the scanner so it is after the node we just consumed.
            scanner.setTextPos(node.end);
            nextToken();
            return node;
        }
        function isReusableParsingContext(parsingContext) {
            switch (parsingContext) {
                case 5 /* ClassMembers */:
                case 2 /* SwitchClauses */:
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                case 6 /* EnumMembers */:
                case 4 /* TypeMembers */:
                case 8 /* VariableDeclarations */:
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                    return true;
            }
            return false;
        }
        function canReuseNode(node, parsingContext) {
            switch (parsingContext) {
                case 5 /* ClassMembers */:
                    return isReusableClassMember(node);
                case 2 /* SwitchClauses */:
                    return isReusableSwitchClause(node);
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                    return isReusableStatement(node);
                case 6 /* EnumMembers */:
                    return isReusableEnumMember(node);
                case 4 /* TypeMembers */:
                    return isReusableTypeMember(node);
                case 8 /* VariableDeclarations */:
                    return isReusableVariableDeclaration(node);
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                    return isReusableParameter(node);
                // Any other lists we do not care about reusing nodes in.  But feel free to add if
                // you can do so safely.  Danger areas involve nodes that may involve speculative
                // parsing.  If speculative parsing is involved with the node, then the range the
                // parser reached while looking ahead might be in the edited range (see the example
                // in canReuseVariableDeclaratorNode for a good case of this).
                // case ParsingContext.HeritageClauses:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // heritage clauses.
                // case ParsingContext.TypeParameters:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // type parameters.  Note that that's because type *parameters* only occur in
                // unambiguous *type* contexts.  While type *arguments* occur in very ambiguous
                // *expression* contexts.
                // case ParsingContext.TupleElementTypes:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // tuple types.
                // Technically, type argument list types are probably safe to reuse.  While
                // speculative parsing is involved with them (since type argument lists are only
                // produced from speculative parsing a < as a type argument list), we only have
                // the types because speculative parsing succeeded.  Thus, the lookahead never
                // went past the end of the list and rewound.
                // case ParsingContext.TypeArguments:
                // Note: these are almost certainly not safe to ever reuse.  Expressions commonly
                // need a large amount of lookahead, and we should not reuse them as they may
                // have actually intersected the edit.
                // case ParsingContext.ArgumentExpressions:
                // This is not safe to reuse for the same reason as the 'AssignmentExpression'
                // cases.  i.e. a property assignment may end with an expression, and thus might
                // have lookahead far beyond it's old node.
                // case ParsingContext.ObjectLiteralMembers:
                // This is probably not safe to reuse.  There can be speculative parsing with
                // type names in a heritage clause.  There can be generic names in the type
                // name list, and there can be left hand side expressions (which can have type
                // arguments.)
                // case ParsingContext.HeritageClauseElement:
                // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
                // on any given element. Same for children.
                // case ParsingContext.JsxAttributes:
                // case ParsingContext.JsxChildren:
            }
            return false;
        }
        function isReusableClassMember(node) {
            if (node) {
                switch (node.kind) {
                    case 162 /* Constructor */:
                    case 167 /* IndexSignature */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 159 /* PropertyDeclaration */:
                    case 222 /* SemicolonClassElement */:
                        return true;
                    case 161 /* MethodDeclaration */:
                        // Method declarations are not necessarily reusable.  An object-literal
                        // may have a method calls "constructor(...)" and we must reparse that
                        // into an actual .ConstructorDeclaration.
                        var methodDeclaration = node;
                        var nameIsConstructor = methodDeclaration.name.kind === 75 /* Identifier */ &&
                            methodDeclaration.name.originalKeywordKind === 129 /* ConstructorKeyword */;
                        return !nameIsConstructor;
                }
            }
            return false;
        }
        function isReusableSwitchClause(node) {
            if (node) {
                switch (node.kind) {
                    case 277 /* CaseClause */:
                    case 278 /* DefaultClause */:
                        return true;
                }
            }
            return false;
        }
        function isReusableStatement(node) {
            if (node) {
                switch (node.kind) {
                    case 244 /* FunctionDeclaration */:
                    case 225 /* VariableStatement */:
                    case 223 /* Block */:
                    case 227 /* IfStatement */:
                    case 226 /* ExpressionStatement */:
                    case 239 /* ThrowStatement */:
                    case 235 /* ReturnStatement */:
                    case 237 /* SwitchStatement */:
                    case 234 /* BreakStatement */:
                    case 233 /* ContinueStatement */:
                    case 231 /* ForInStatement */:
                    case 232 /* ForOfStatement */:
                    case 230 /* ForStatement */:
                    case 229 /* WhileStatement */:
                    case 236 /* WithStatement */:
                    case 224 /* EmptyStatement */:
                    case 240 /* TryStatement */:
                    case 238 /* LabeledStatement */:
                    case 228 /* DoStatement */:
                    case 241 /* DebuggerStatement */:
                    case 254 /* ImportDeclaration */:
                    case 253 /* ImportEqualsDeclaration */:
                    case 260 /* ExportDeclaration */:
                    case 259 /* ExportAssignment */:
                    case 249 /* ModuleDeclaration */:
                    case 245 /* ClassDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                    case 248 /* EnumDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                        return true;
                }
            }
            return false;
        }
        function isReusableEnumMember(node) {
            return node.kind === 284 /* EnumMember */;
        }
        function isReusableTypeMember(node) {
            if (node) {
                switch (node.kind) {
                    case 166 /* ConstructSignature */:
                    case 160 /* MethodSignature */:
                    case 167 /* IndexSignature */:
                    case 158 /* PropertySignature */:
                    case 165 /* CallSignature */:
                        return true;
                }
            }
            return false;
        }
        function isReusableVariableDeclaration(node) {
            if (node.kind !== 242 /* VariableDeclaration */) {
                return false;
            }
            // Very subtle incremental parsing bug.  Consider the following code:
            //
            //      let v = new List < A, B
            //
            // This is actually legal code.  It's a list of variable declarators "v = new List<A"
            // on one side and "B" on the other. If you then change that to:
            //
            //      let v = new List < A, B >()
            //
            // then we have a problem.  "v = new List<A" doesn't intersect the change range, so we
            // start reparsing at "B" and we completely fail to handle this properly.
            //
            // In order to prevent this, we do not allow a variable declarator to be reused if it
            // has an initializer.
            var variableDeclarator = node;
            return variableDeclarator.initializer === undefined;
        }
        function isReusableParameter(node) {
            if (node.kind !== 156 /* Parameter */) {
                return false;
            }
            // See the comment in isReusableVariableDeclaration for why we do this.
            var parameter = node;
            return parameter.initializer === undefined;
        }
        // Returns true if we should abort parsing.
        function abortParsingListOrMoveToNextToken(kind) {
            parseErrorAtCurrentToken(parsingContextErrors(kind));
            if (isInSomeParsingContext()) {
                return true;
            }
            nextToken();
            return false;
        }
        function parsingContextErrors(context) {
            switch (context) {
                case 0 /* SourceElements */: return ts.Diagnostics.Declaration_or_statement_expected;
                case 1 /* BlockStatements */: return ts.Diagnostics.Declaration_or_statement_expected;
                case 2 /* SwitchClauses */: return ts.Diagnostics.case_or_default_expected;
                case 3 /* SwitchClauseStatements */: return ts.Diagnostics.Statement_expected;
                case 18 /* RestProperties */: // fallthrough
                case 4 /* TypeMembers */: return ts.Diagnostics.Property_or_signature_expected;
                case 5 /* ClassMembers */: return ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
                case 6 /* EnumMembers */: return ts.Diagnostics.Enum_member_expected;
                case 7 /* HeritageClauseElement */: return ts.Diagnostics.Expression_expected;
                case 8 /* VariableDeclarations */: return ts.Diagnostics.Variable_declaration_expected;
                case 9 /* ObjectBindingElements */: return ts.Diagnostics.Property_destructuring_pattern_expected;
                case 10 /* ArrayBindingElements */: return ts.Diagnostics.Array_element_destructuring_pattern_expected;
                case 11 /* ArgumentExpressions */: return ts.Diagnostics.Argument_expression_expected;
                case 12 /* ObjectLiteralMembers */: return ts.Diagnostics.Property_assignment_expected;
                case 15 /* ArrayLiteralMembers */: return ts.Diagnostics.Expression_or_comma_expected;
                case 17 /* JSDocParameters */: return ts.Diagnostics.Parameter_declaration_expected;
                case 16 /* Parameters */: return ts.Diagnostics.Parameter_declaration_expected;
                case 19 /* TypeParameters */: return ts.Diagnostics.Type_parameter_declaration_expected;
                case 20 /* TypeArguments */: return ts.Diagnostics.Type_argument_expected;
                case 21 /* TupleElementTypes */: return ts.Diagnostics.Type_expected;
                case 22 /* HeritageClauses */: return ts.Diagnostics.Unexpected_token_expected;
                case 23 /* ImportOrExportSpecifiers */: return ts.Diagnostics.Identifier_expected;
                case 13 /* JsxAttributes */: return ts.Diagnostics.Identifier_expected;
                case 14 /* JsxChildren */: return ts.Diagnostics.Identifier_expected;
                default: return undefined; // TODO: GH#18217 `default: Debug.assertNever(context);`
            }
        }
        // Parses a comma-delimited list of elements
        function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimiter) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var list = [];
            var listPos = getNodePos();
            var commaStart = -1; // Meaning the previous token was not a comma
            while (true) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var startPos = scanner.getStartPos();
                    list.push(parseListElement(kind, parseElement));
                    commaStart = scanner.getTokenPos();
                    if (parseOptional(27 /* CommaToken */)) {
                        // No need to check for a zero length node since we know we parsed a comma
                        continue;
                    }
                    commaStart = -1; // Back to the state where the last token was not a comma
                    if (isListTerminator(kind)) {
                        break;
                    }
                    // We didn't get a comma, and the list wasn't terminated, explicitly parse
                    // out a comma so we give a good error message.
                    parseExpected(27 /* CommaToken */, getExpectedCommaDiagnostic(kind));
                    // If the token was a semicolon, and the caller allows that, then skip it and
                    // continue.  This ensures we get back on track and don't result in tons of
                    // parse errors.  For example, this can happen when people do things like use
                    // a semicolon to delimit object literal members.   Note: we'll have already
                    // reported an error when we called parseExpected above.
                    if (considerSemicolonAsDelimiter && token() === 26 /* SemicolonToken */ && !scanner.hasPrecedingLineBreak()) {
                        nextToken();
                    }
                    if (startPos === scanner.getStartPos()) {
                        // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever
                        // Consume a token to advance the parser in some way and avoid an infinite loop
                        // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions,
                        // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied
                        nextToken();
                    }
                    continue;
                }
                if (isListTerminator(kind)) {
                    break;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            parsingContext = saveParsingContext;
            var result = createNodeArray(list, listPos);
            // Recording the trailing comma is deliberately done after the previous
            // loop, and not just if we see a list terminator. This is because the list
            // may have ended incorrectly, but it is still important to know if there
            // was a trailing comma.
            // Check if the last token was a comma.
            if (commaStart >= 0) {
                // Always preserve a trailing comma by marking it on the NodeArray
                result.hasTrailingComma = true;
            }
            return result;
        }
        function getExpectedCommaDiagnostic(kind) {
            return kind === 6 /* EnumMembers */ ? ts.Diagnostics.An_enum_member_name_must_be_followed_by_a_or : undefined;
        }
        function createMissingList() {
            var list = createNodeArray([], getNodePos());
            list.isMissingList = true;
            return list;
        }
        function isMissingList(arr) {
            return !!arr.isMissingList;
        }
        function parseBracketedList(kind, parseElement, open, close) {
            if (parseExpected(open)) {
                var result = parseDelimitedList(kind, parseElement);
                parseExpected(close);
                return result;
            }
            return createMissingList();
        }
        function parseEntityName(allowReservedWords, diagnosticMessage) {
            var entity = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage);
            var dotPos = scanner.getStartPos();
            while (parseOptional(24 /* DotToken */)) {
                if (token() === 29 /* LessThanToken */) {
                    // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting
                    entity.jsdocDotPos = dotPos;
                    break;
                }
                dotPos = scanner.getStartPos();
                entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false));
            }
            return entity;
        }
        function createQualifiedName(entity, name) {
            var node = createNode(153 /* QualifiedName */, entity.pos);
            node.left = entity;
            node.right = name;
            return finishNode(node);
        }
        function parseRightSideOfDot(allowIdentifierNames, allowPrivateIdentifiers) {
            // Technically a keyword is valid here as all identifiers and keywords are identifier names.
            // However, often we'll encounter this in error situations when the identifier or keyword
            // is actually starting another valid construct.
            //
            // So, we check for the following specific case:
            //
            //      name.
            //      identifierOrKeyword identifierNameOrKeyword
            //
            // Note: the newlines are important here.  For example, if that above code
            // were rewritten into:
            //
            //      name.identifierOrKeyword
            //      identifierNameOrKeyword
            //
            // Then we would consider it valid.  That's because ASI would take effect and
            // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
            // In the first case though, ASI will not take effect because there is not a
            // line terminator after the identifier or keyword.
            if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token())) {
                var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
                if (matchesPattern) {
                    // Report that we need an identifier.  However, report it right after the dot,
                    // and not on the next token.  This is because the next token might actually
                    // be an identifier and the error would be quite confusing.
                    return createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
                }
            }
            if (token() === 76 /* PrivateIdentifier */) {
                var node = parsePrivateIdentifier();
                return allowPrivateIdentifiers ? node : createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
            }
            return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
        }
        function parseTemplateExpression(isTaggedTemplate) {
            var template = createNode(211 /* TemplateExpression */);
            template.head = parseTemplateHead(isTaggedTemplate);
            ts.Debug.assert(template.head.kind === 15 /* TemplateHead */, "Template head has wrong token kind");
            var list = [];
            var listPos = getNodePos();
            do {
                list.push(parseTemplateSpan(isTaggedTemplate));
            } while (ts.last(list).literal.kind === 16 /* TemplateMiddle */);
            template.templateSpans = createNodeArray(list, listPos);
            return finishNode(template);
        }
        function parseTemplateSpan(isTaggedTemplate) {
            var span = createNode(221 /* TemplateSpan */);
            span.expression = allowInAnd(parseExpression);
            var literal;
            if (token() === 19 /* CloseBraceToken */) {
                reScanTemplateToken(isTaggedTemplate);
                literal = parseTemplateMiddleOrTemplateTail();
            }
            else {
                literal = parseExpectedToken(17 /* TemplateTail */, ts.Diagnostics._0_expected, ts.tokenToString(19 /* CloseBraceToken */));
            }
            span.literal = literal;
            return finishNode(span);
        }
        function parseLiteralNode() {
            return parseLiteralLikeNode(token());
        }
        function parseTemplateHead(isTaggedTemplate) {
            if (isTaggedTemplate) {
                reScanTemplateHeadOrNoSubstitutionTemplate();
            }
            var fragment = parseLiteralLikeNode(token());
            ts.Debug.assert(fragment.kind === 15 /* TemplateHead */, "Template head has wrong token kind");
            return fragment;
        }
        function parseTemplateMiddleOrTemplateTail() {
            var fragment = parseLiteralLikeNode(token());
            ts.Debug.assert(fragment.kind === 16 /* TemplateMiddle */ || fragment.kind === 17 /* TemplateTail */, "Template fragment has wrong token kind");
            return fragment;
        }
        function parseLiteralLikeNode(kind) {
            var node = createNode(kind);
            node.text = scanner.getTokenValue();
            switch (kind) {
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 15 /* TemplateHead */:
                case 16 /* TemplateMiddle */:
                case 17 /* TemplateTail */:
                    var isLast = kind === 14 /* NoSubstitutionTemplateLiteral */ || kind === 17 /* TemplateTail */;
                    var tokenText = scanner.getTokenText();
                    node.rawText = tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2));
                    break;
            }
            if (scanner.hasExtendedUnicodeEscape()) {
                node.hasExtendedUnicodeEscape = true;
            }
            if (scanner.isUnterminated()) {
                node.isUnterminated = true;
            }
            // Octal literals are not allowed in strict mode or ES5
            // Note that theoretically the following condition would hold true literals like 009,
            // which is not octal.But because of how the scanner separates the tokens, we would
            // never get a token like this. Instead, we would get 00 and 9 as two separate tokens.
            // We also do not need to check for negatives because any prefix operator would be part of a
            // parent unary expression.
            if (node.kind === 8 /* NumericLiteral */) {
                node.numericLiteralFlags = scanner.getTokenFlags() & 1008 /* NumericLiteralFlags */;
            }
            if (ts.isTemplateLiteralKind(node.kind)) {
                node.templateFlags = scanner.getTokenFlags() & 2048 /* ContainsInvalidEscape */;
            }
            nextToken();
            finishNode(node);
            return node;
        }
        // TYPES
        function parseTypeReference() {
            var node = createNode(169 /* TypeReference */);
            node.typeName = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected);
            if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === 29 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(20 /* TypeArguments */, parseType, 29 /* LessThanToken */, 31 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        // If true, we should abort parsing an error function.
        function typeHasArrowFunctionBlockingParseError(node) {
            switch (node.kind) {
                case 169 /* TypeReference */:
                    return ts.nodeIsMissing(node.typeName);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */: {
                    var _a = node, parameters = _a.parameters, type = _a.type;
                    return isMissingList(parameters) || typeHasArrowFunctionBlockingParseError(type);
                }
                case 182 /* ParenthesizedType */:
                    return typeHasArrowFunctionBlockingParseError(node.type);
                default:
                    return false;
            }
        }
        function parseThisTypePredicate(lhs) {
            nextToken();
            var node = createNode(168 /* TypePredicate */, lhs.pos);
            node.parameterName = lhs;
            node.type = parseType();
            return finishNode(node);
        }
        function parseThisTypeNode() {
            var node = createNode(183 /* ThisType */);
            nextToken();
            return finishNode(node);
        }
        function parseJSDocAllType(postFixEquals) {
            var result = createNode(295 /* JSDocAllType */);
            if (postFixEquals) {
                return createPostfixType(299 /* JSDocOptionalType */, result);
            }
            else {
                nextToken();
            }
            return finishNode(result);
        }
        function parseJSDocNonNullableType() {
            var result = createNode(298 /* JSDocNonNullableType */);
            nextToken();
            result.type = parseNonArrayType();
            return finishNode(result);
        }
        function parseJSDocUnknownOrNullableType() {
            var pos = scanner.getStartPos();
            // skip the ?
            nextToken();
            // Need to lookahead to decide if this is a nullable or unknown type.
            // Here are cases where we'll pick the unknown type:
            //
            //      Foo(?,
            //      { a: ? }
            //      Foo(?)
            //      Foo<?>
            //      Foo(?=
            //      (?|
            if (token() === 27 /* CommaToken */ ||
                token() === 19 /* CloseBraceToken */ ||
                token() === 21 /* CloseParenToken */ ||
                token() === 31 /* GreaterThanToken */ ||
                token() === 62 /* EqualsToken */ ||
                token() === 51 /* BarToken */) {
                var result = createNode(296 /* JSDocUnknownType */, pos);
                return finishNode(result);
            }
            else {
                var result = createNode(297 /* JSDocNullableType */, pos);
                result.type = parseType();
                return finishNode(result);
            }
        }
        function parseJSDocFunctionType() {
            if (lookAhead(nextTokenIsOpenParen)) {
                var result = createNodeWithJSDoc(300 /* JSDocFunctionType */);
                nextToken();
                fillSignature(58 /* ColonToken */, 4 /* Type */ | 32 /* JSDoc */, result);
                return finishNode(result);
            }
            var node = createNode(169 /* TypeReference */);
            node.typeName = parseIdentifierName();
            return finishNode(node);
        }
        function parseJSDocParameter() {
            var parameter = createNode(156 /* Parameter */);
            if (token() === 104 /* ThisKeyword */ || token() === 99 /* NewKeyword */) {
                parameter.name = parseIdentifierName();
                parseExpected(58 /* ColonToken */);
            }
            parameter.type = parseJSDocType();
            return finishNode(parameter);
        }
        function parseJSDocType() {
            scanner.setInJSDocType(true);
            var moduleSpecifier = parseOptionalToken(135 /* ModuleKeyword */);
            if (moduleSpecifier) {
                var moduleTag = createNode(302 /* JSDocNamepathType */, moduleSpecifier.pos);
                terminate: while (true) {
                    switch (token()) {
                        case 19 /* CloseBraceToken */:
                        case 1 /* EndOfFileToken */:
                        case 27 /* CommaToken */:
                        case 5 /* WhitespaceTrivia */:
                            break terminate;
                        default:
                            nextTokenJSDoc();
                    }
                }
                scanner.setInJSDocType(false);
                return finishNode(moduleTag);
            }
            var dotdotdot = parseOptionalToken(25 /* DotDotDotToken */);
            var type = parseTypeOrTypePredicate();
            scanner.setInJSDocType(false);
            if (dotdotdot) {
                var variadic = createNode(301 /* JSDocVariadicType */, dotdotdot.pos);
                variadic.type = type;
                type = finishNode(variadic);
            }
            if (token() === 62 /* EqualsToken */) {
                return createPostfixType(299 /* JSDocOptionalType */, type);
            }
            return type;
        }
        function parseTypeQuery() {
            var node = createNode(172 /* TypeQuery */);
            parseExpected(108 /* TypeOfKeyword */);
            node.exprName = parseEntityName(/*allowReservedWords*/ true);
            return finishNode(node);
        }
        function parseTypeParameter() {
            var node = createNode(155 /* TypeParameter */);
            node.name = parseIdentifier();
            if (parseOptional(90 /* ExtendsKeyword */)) {
                // It's not uncommon for people to write improper constraints to a generic.  If the
                // user writes a constraint that is an expression and not an actual type, then parse
                // it out as an expression (so we can recover well), but report that a type is needed
                // instead.
                if (isStartOfType() || !isStartOfExpression()) {
                    node.constraint = parseType();
                }
                else {
                    // It was not a type, and it looked like an expression.  Parse out an expression
                    // here so we recover well.  Note: it is important that we call parseUnaryExpression
                    // and not parseExpression here.  If the user has:
                    //
                    //      <T extends "">
                    //
                    // We do *not* want to consume the `>` as we're consuming the expression for "".
                    node.expression = parseUnaryExpressionOrHigher();
                }
            }
            if (parseOptional(62 /* EqualsToken */)) {
                node.default = parseType();
            }
            return finishNode(node);
        }
        function parseTypeParameters() {
            if (token() === 29 /* LessThanToken */) {
                return parseBracketedList(19 /* TypeParameters */, parseTypeParameter, 29 /* LessThanToken */, 31 /* GreaterThanToken */);
            }
        }
        function parseParameterType() {
            if (parseOptional(58 /* ColonToken */)) {
                return parseType();
            }
            return undefined;
        }
        function isStartOfParameter(isJSDocParameter) {
            return token() === 25 /* DotDotDotToken */ ||
                isIdentifierOrPrivateIdentifierOrPattern() ||
                ts.isModifierKind(token()) ||
                token() === 59 /* AtToken */ ||
                isStartOfType(/*inStartOfParameter*/ !isJSDocParameter);
        }
        function parseParameter() {
            var node = createNodeWithJSDoc(156 /* Parameter */);
            if (token() === 104 /* ThisKeyword */) {
                node.name = createIdentifier(/*isIdentifier*/ true);
                node.type = parseParameterType();
                return finishNode(node);
            }
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            // FormalParameter [Yield,Await]:
            //      BindingElement[?Yield,?Await]
            node.name = parseIdentifierOrPattern(ts.Diagnostics.Private_identifiers_cannot_be_used_as_parameters);
            if (ts.getFullWidth(node.name) === 0 && !node.modifiers && ts.isModifierKind(token())) {
                // in cases like
                // 'use strict'
                // function foo(static)
                // isParameter('static') === true, because of isModifier('static')
                // however 'static' is not a legal identifier in a strict mode.
                // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined)
                // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM)
                // to avoid this we'll advance cursor to the next token.
                nextToken();
            }
            node.questionToken = parseOptionalToken(57 /* QuestionToken */);
            node.type = parseParameterType();
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        /**
         * Note: If returnToken is EqualsGreaterThanToken, `signature.type` will always be defined.
         * @returns If return type parsing succeeds
         */
        function fillSignature(returnToken, flags, signature) {
            if (!(flags & 32 /* JSDoc */)) {
                signature.typeParameters = parseTypeParameters();
            }
            var parametersParsedSuccessfully = parseParameterList(signature, flags);
            if (shouldParseReturnType(returnToken, !!(flags & 4 /* Type */))) {
                signature.type = parseTypeOrTypePredicate();
                if (typeHasArrowFunctionBlockingParseError(signature.type))
                    return false;
            }
            return parametersParsedSuccessfully;
        }
        function shouldParseReturnType(returnToken, isType) {
            if (returnToken === 38 /* EqualsGreaterThanToken */) {
                parseExpected(returnToken);
                return true;
            }
            else if (parseOptional(58 /* ColonToken */)) {
                return true;
            }
            else if (isType && token() === 38 /* EqualsGreaterThanToken */) {
                // This is easy to get backward, especially in type contexts, so parse the type anyway
                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(58 /* ColonToken */));
                nextToken();
                return true;
            }
            return false;
        }
        // Returns true on success.
        function parseParameterList(signature, flags) {
            // FormalParameters [Yield,Await]: (modified)
            //      [empty]
            //      FormalParameterList[?Yield,Await]
            //
            // FormalParameter[Yield,Await]: (modified)
            //      BindingElement[?Yield,Await]
            //
            // BindingElement [Yield,Await]: (modified)
            //      SingleNameBinding[?Yield,?Await]
            //      BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
            //
            // SingleNameBinding [Yield,Await]:
            //      BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
            if (!parseExpected(20 /* OpenParenToken */)) {
                signature.parameters = createMissingList();
                return false;
            }
            var savedYieldContext = inYieldContext();
            var savedAwaitContext = inAwaitContext();
            setYieldContext(!!(flags & 1 /* Yield */));
            setAwaitContext(!!(flags & 2 /* Await */));
            signature.parameters = flags & 32 /* JSDoc */ ?
                parseDelimitedList(17 /* JSDocParameters */, parseJSDocParameter) :
                parseDelimitedList(16 /* Parameters */, parseParameter);
            setYieldContext(savedYieldContext);
            setAwaitContext(savedAwaitContext);
            return parseExpected(21 /* CloseParenToken */);
        }
        function parseTypeMemberSemicolon() {
            // We allow type members to be separated by commas or (possibly ASI) semicolons.
            // First check if it was a comma.  If so, we're done with the member.
            if (parseOptional(27 /* CommaToken */)) {
                return;
            }
            // Didn't have a comma.  We must have a (possible ASI) semicolon.
            parseSemicolon();
        }
        function parseSignatureMember(kind) {
            var node = createNodeWithJSDoc(kind);
            if (kind === 166 /* ConstructSignature */) {
                parseExpected(99 /* NewKeyword */);
            }
            fillSignature(58 /* ColonToken */, 4 /* Type */, node);
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function isIndexSignature() {
            return token() === 22 /* OpenBracketToken */ && lookAhead(isUnambiguouslyIndexSignature);
        }
        function isUnambiguouslyIndexSignature() {
            // The only allowed sequence is:
            //
            //   [id:
            //
            // However, for error recovery, we also check the following cases:
            //
            //   [...
            //   [id,
            //   [id?,
            //   [id?:
            //   [id?]
            //   [public id
            //   [private id
            //   [protected id
            //   []
            //
            nextToken();
            if (token() === 25 /* DotDotDotToken */ || token() === 23 /* CloseBracketToken */) {
                return true;
            }
            if (ts.isModifierKind(token())) {
                nextToken();
                if (isIdentifier()) {
                    return true;
                }
            }
            else if (!isIdentifier()) {
                return false;
            }
            else {
                // Skip the identifier
                nextToken();
            }
            // A colon signifies a well formed indexer
            // A comma should be a badly formed indexer because comma expressions are not allowed
            // in computed properties.
            if (token() === 58 /* ColonToken */ || token() === 27 /* CommaToken */) {
                return true;
            }
            // Question mark could be an indexer with an optional property,
            // or it could be a conditional expression in a computed property.
            if (token() !== 57 /* QuestionToken */) {
                return false;
            }
            // If any of the following tokens are after the question mark, it cannot
            // be a conditional expression, so treat it as an indexer.
            nextToken();
            return token() === 58 /* ColonToken */ || token() === 27 /* CommaToken */ || token() === 23 /* CloseBracketToken */;
        }
        function parseIndexSignatureDeclaration(node) {
            node.kind = 167 /* IndexSignature */;
            node.parameters = parseBracketedList(16 /* Parameters */, parseParameter, 22 /* OpenBracketToken */, 23 /* CloseBracketToken */);
            node.type = parseTypeAnnotation();
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function parsePropertyOrMethodSignature(node) {
            node.name = parsePropertyName();
            node.questionToken = parseOptionalToken(57 /* QuestionToken */);
            if (token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                node.kind = 160 /* MethodSignature */;
                // Method signatures don't exist in expression contexts.  So they have neither
                // [Yield] nor [Await]
                fillSignature(58 /* ColonToken */, 4 /* Type */, node);
            }
            else {
                node.kind = 158 /* PropertySignature */;
                node.type = parseTypeAnnotation();
                if (token() === 62 /* EqualsToken */) {
                    // Although type literal properties cannot not have initializers, we attempt
                    // to parse an initializer so we can report in the checker that an interface
                    // property or type literal property cannot have an initializer.
                    node.initializer = parseInitializer();
                }
            }
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function isTypeMemberStart() {
            // Return true if we have the start of a signature member
            if (token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                return true;
            }
            var idToken = false;
            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier
            while (ts.isModifierKind(token())) {
                idToken = true;
                nextToken();
            }
            // Index signatures and computed property names are type members
            if (token() === 22 /* OpenBracketToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers
            if (isLiteralPropertyName()) {
                idToken = true;
                nextToken();
            }
            // If we were able to get any potential identifier, check that it is
            // the start of a member declaration
            if (idToken) {
                return token() === 20 /* OpenParenToken */ ||
                    token() === 29 /* LessThanToken */ ||
                    token() === 57 /* QuestionToken */ ||
                    token() === 58 /* ColonToken */ ||
                    token() === 27 /* CommaToken */ ||
                    canParseSemicolon();
            }
            return false;
        }
        function parseTypeMember() {
            if (token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                return parseSignatureMember(165 /* CallSignature */);
            }
            if (token() === 99 /* NewKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) {
                return parseSignatureMember(166 /* ConstructSignature */);
            }
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.modifiers = parseModifiers();
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(node);
            }
            return parsePropertyOrMethodSignature(node);
        }
        function nextTokenIsOpenParenOrLessThan() {
            nextToken();
            return token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */;
        }
        function nextTokenIsDot() {
            return nextToken() === 24 /* DotToken */;
        }
        function nextTokenIsOpenParenOrLessThanOrDot() {
            switch (nextToken()) {
                case 20 /* OpenParenToken */:
                case 29 /* LessThanToken */:
                case 24 /* DotToken */:
                    return true;
            }
            return false;
        }
        function parseTypeLiteral() {
            var node = createNode(173 /* TypeLiteral */);
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseObjectTypeMembers() {
            var members;
            if (parseExpected(18 /* OpenBraceToken */)) {
                members = parseList(4 /* TypeMembers */, parseTypeMember);
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                members = createMissingList();
            }
            return members;
        }
        function isStartOfMappedType() {
            nextToken();
            if (token() === 39 /* PlusToken */ || token() === 40 /* MinusToken */) {
                return nextToken() === 138 /* ReadonlyKeyword */;
            }
            if (token() === 138 /* ReadonlyKeyword */) {
                nextToken();
            }
            return token() === 22 /* OpenBracketToken */ && nextTokenIsIdentifier() && nextToken() === 97 /* InKeyword */;
        }
        function parseMappedTypeParameter() {
            var node = createNode(155 /* TypeParameter */);
            node.name = parseIdentifier();
            parseExpected(97 /* InKeyword */);
            node.constraint = parseType();
            return finishNode(node);
        }
        function parseMappedType() {
            var node = createNode(186 /* MappedType */);
            parseExpected(18 /* OpenBraceToken */);
            if (token() === 138 /* ReadonlyKeyword */ || token() === 39 /* PlusToken */ || token() === 40 /* MinusToken */) {
                node.readonlyToken = parseTokenNode();
                if (node.readonlyToken.kind !== 138 /* ReadonlyKeyword */) {
                    parseExpectedToken(138 /* ReadonlyKeyword */);
                }
            }
            parseExpected(22 /* OpenBracketToken */);
            node.typeParameter = parseMappedTypeParameter();
            parseExpected(23 /* CloseBracketToken */);
            if (token() === 57 /* QuestionToken */ || token() === 39 /* PlusToken */ || token() === 40 /* MinusToken */) {
                node.questionToken = parseTokenNode();
                if (node.questionToken.kind !== 57 /* QuestionToken */) {
                    parseExpectedToken(57 /* QuestionToken */);
                }
            }
            node.type = parseTypeAnnotation();
            parseSemicolon();
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseTupleElementType() {
            var pos = getNodePos();
            if (parseOptional(25 /* DotDotDotToken */)) {
                var node = createNode(177 /* RestType */, pos);
                node.type = parseType();
                return finishNode(node);
            }
            var type = parseType();
            if (!(contextFlags & 4194304 /* JSDoc */) && type.kind === 297 /* JSDocNullableType */ && type.pos === type.type.pos) {
                type.kind = 176 /* OptionalType */;
            }
            return type;
        }
        function parseTupleType() {
            var node = createNode(175 /* TupleType */);
            node.elementTypes = parseBracketedList(21 /* TupleElementTypes */, parseTupleElementType, 22 /* OpenBracketToken */, 23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseParenthesizedType() {
            var node = createNode(182 /* ParenthesizedType */);
            parseExpected(20 /* OpenParenToken */);
            node.type = parseType();
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseFunctionOrConstructorType() {
            var pos = getNodePos();
            var kind = parseOptional(99 /* NewKeyword */) ? 171 /* ConstructorType */ : 170 /* FunctionType */;
            var node = createNodeWithJSDoc(kind, pos);
            fillSignature(38 /* EqualsGreaterThanToken */, 4 /* Type */, node);
            return finishNode(node);
        }
        function parseKeywordAndNoDot() {
            var node = parseTokenNode();
            return token() === 24 /* DotToken */ ? undefined : node;
        }
        function parseLiteralTypeNode(negative) {
            var node = createNode(187 /* LiteralType */);
            var unaryMinusExpression;
            if (negative) {
                unaryMinusExpression = createNode(207 /* PrefixUnaryExpression */);
                unaryMinusExpression.operator = 40 /* MinusToken */;
                nextToken();
            }
            var expression = token() === 106 /* TrueKeyword */ || token() === 91 /* FalseKeyword */
                ? parseTokenNode()
                : parseLiteralLikeNode(token());
            if (negative) {
                unaryMinusExpression.operand = expression;
                finishNode(unaryMinusExpression);
                expression = unaryMinusExpression;
            }
            node.literal = expression;
            return finishNode(node);
        }
        function isStartOfTypeOfImportType() {
            nextToken();
            return token() === 96 /* ImportKeyword */;
        }
        function parseImportType() {
            sourceFile.flags |= 1048576 /* PossiblyContainsDynamicImport */;
            var node = createNode(188 /* ImportType */);
            if (parseOptional(108 /* TypeOfKeyword */)) {
                node.isTypeOf = true;
            }
            parseExpected(96 /* ImportKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.argument = parseType();
            parseExpected(21 /* CloseParenToken */);
            if (parseOptional(24 /* DotToken */)) {
                node.qualifier = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected);
            }
            if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === 29 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(20 /* TypeArguments */, parseType, 29 /* LessThanToken */, 31 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        function nextTokenIsNumericOrBigIntLiteral() {
            nextToken();
            return token() === 8 /* NumericLiteral */ || token() === 9 /* BigIntLiteral */;
        }
        function parseNonArrayType() {
            switch (token()) {
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 143 /* StringKeyword */:
                case 140 /* NumberKeyword */:
                case 151 /* BigIntKeyword */:
                case 144 /* SymbolKeyword */:
                case 128 /* BooleanKeyword */:
                case 146 /* UndefinedKeyword */:
                case 137 /* NeverKeyword */:
                case 141 /* ObjectKeyword */:
                    // If these are followed by a dot, then parse these out as a dotted type reference instead.
                    return tryParse(parseKeywordAndNoDot) || parseTypeReference();
                case 41 /* AsteriskToken */:
                    return parseJSDocAllType(/*postfixEquals*/ false);
                case 65 /* AsteriskEqualsToken */:
                    return parseJSDocAllType(/*postfixEquals*/ true);
                case 60 /* QuestionQuestionToken */:
                    // If there is '??', consider that is prefix '?' in JSDoc type.
                    scanner.reScanQuestionToken();
                // falls through
                case 57 /* QuestionToken */:
                    return parseJSDocUnknownOrNullableType();
                case 94 /* FunctionKeyword */:
                    return parseJSDocFunctionType();
                case 53 /* ExclamationToken */:
                    return parseJSDocNonNullableType();
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                    return parseLiteralTypeNode();
                case 40 /* MinusToken */:
                    return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
                case 110 /* VoidKeyword */:
                case 100 /* NullKeyword */:
                    return parseTokenNode();
                case 104 /* ThisKeyword */: {
                    var thisKeyword = parseThisTypeNode();
                    if (token() === 133 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                        return parseThisTypePredicate(thisKeyword);
                    }
                    else {
                        return thisKeyword;
                    }
                }
                case 108 /* TypeOfKeyword */:
                    return lookAhead(isStartOfTypeOfImportType) ? parseImportType() : parseTypeQuery();
                case 18 /* OpenBraceToken */:
                    return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral();
                case 22 /* OpenBracketToken */:
                    return parseTupleType();
                case 20 /* OpenParenToken */:
                    return parseParenthesizedType();
                case 96 /* ImportKeyword */:
                    return parseImportType();
                case 124 /* AssertsKeyword */:
                    return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? parseAssertsTypePredicate() : parseTypeReference();
                default:
                    return parseTypeReference();
            }
        }
        function isStartOfType(inStartOfParameter) {
            switch (token()) {
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 143 /* StringKeyword */:
                case 140 /* NumberKeyword */:
                case 151 /* BigIntKeyword */:
                case 128 /* BooleanKeyword */:
                case 138 /* ReadonlyKeyword */:
                case 144 /* SymbolKeyword */:
                case 147 /* UniqueKeyword */:
                case 110 /* VoidKeyword */:
                case 146 /* UndefinedKeyword */:
                case 100 /* NullKeyword */:
                case 104 /* ThisKeyword */:
                case 108 /* TypeOfKeyword */:
                case 137 /* NeverKeyword */:
                case 18 /* OpenBraceToken */:
                case 22 /* OpenBracketToken */:
                case 29 /* LessThanToken */:
                case 51 /* BarToken */:
                case 50 /* AmpersandToken */:
                case 99 /* NewKeyword */:
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 141 /* ObjectKeyword */:
                case 41 /* AsteriskToken */:
                case 57 /* QuestionToken */:
                case 53 /* ExclamationToken */:
                case 25 /* DotDotDotToken */:
                case 132 /* InferKeyword */:
                case 96 /* ImportKeyword */:
                case 124 /* AssertsKeyword */:
                    return true;
                case 94 /* FunctionKeyword */:
                    return !inStartOfParameter;
                case 40 /* MinusToken */:
                    return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral);
                case 20 /* OpenParenToken */:
                    // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
                    // or something that starts a type. We don't want to consider things like '(1)' a type.
                    return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfParenthesizedOrFunctionType() {
            nextToken();
            return token() === 21 /* CloseParenToken */ || isStartOfParameter(/*isJSDocParameter*/ false) || isStartOfType();
        }
        function parsePostfixTypeOrHigher() {
            var type = parseNonArrayType();
            while (!scanner.hasPrecedingLineBreak()) {
                switch (token()) {
                    case 53 /* ExclamationToken */:
                        type = createPostfixType(298 /* JSDocNonNullableType */, type);
                        break;
                    case 57 /* QuestionToken */:
                        // If not in JSDoc and next token is start of a type we have a conditional type
                        if (!(contextFlags & 4194304 /* JSDoc */) && lookAhead(nextTokenIsStartOfType)) {
                            return type;
                        }
                        type = createPostfixType(297 /* JSDocNullableType */, type);
                        break;
                    case 22 /* OpenBracketToken */:
                        parseExpected(22 /* OpenBracketToken */);
                        if (isStartOfType()) {
                            var node = createNode(185 /* IndexedAccessType */, type.pos);
                            node.objectType = type;
                            node.indexType = parseType();
                            parseExpected(23 /* CloseBracketToken */);
                            type = finishNode(node);
                        }
                        else {
                            var node = createNode(174 /* ArrayType */, type.pos);
                            node.elementType = type;
                            parseExpected(23 /* CloseBracketToken */);
                            type = finishNode(node);
                        }
                        break;
                    default:
                        return type;
                }
            }
            return type;
        }
        function createPostfixType(kind, type) {
            nextToken();
            var postfix = createNode(kind, type.pos);
            postfix.type = type;
            return finishNode(postfix);
        }
        function parseTypeOperator(operator) {
            var node = createNode(184 /* TypeOperator */);
            parseExpected(operator);
            node.operator = operator;
            node.type = parseTypeOperatorOrHigher();
            return finishNode(node);
        }
        function parseInferType() {
            var node = createNode(181 /* InferType */);
            parseExpected(132 /* InferKeyword */);
            var typeParameter = createNode(155 /* TypeParameter */);
            typeParameter.name = parseIdentifier();
            node.typeParameter = finishNode(typeParameter);
            return finishNode(node);
        }
        function parseTypeOperatorOrHigher() {
            var operator = token();
            switch (operator) {
                case 134 /* KeyOfKeyword */:
                case 147 /* UniqueKeyword */:
                case 138 /* ReadonlyKeyword */:
                    return parseTypeOperator(operator);
                case 132 /* InferKeyword */:
                    return parseInferType();
            }
            return parsePostfixTypeOrHigher();
        }
        function parseUnionOrIntersectionType(kind, parseConstituentType, operator) {
            var start = scanner.getStartPos();
            var hasLeadingOperator = parseOptional(operator);
            var type = parseConstituentType();
            if (token() === operator || hasLeadingOperator) {
                var types = [type];
                while (parseOptional(operator)) {
                    types.push(parseConstituentType());
                }
                var node = createNode(kind, start);
                node.types = createNodeArray(types, start);
                type = finishNode(node);
            }
            return type;
        }
        function parseIntersectionTypeOrHigher() {
            return parseUnionOrIntersectionType(179 /* IntersectionType */, parseTypeOperatorOrHigher, 50 /* AmpersandToken */);
        }
        function parseUnionTypeOrHigher() {
            return parseUnionOrIntersectionType(178 /* UnionType */, parseIntersectionTypeOrHigher, 51 /* BarToken */);
        }
        function isStartOfFunctionType() {
            if (token() === 29 /* LessThanToken */) {
                return true;
            }
            return token() === 20 /* OpenParenToken */ && lookAhead(isUnambiguouslyStartOfFunctionType);
        }
        function skipParameterStart() {
            if (ts.isModifierKind(token())) {
                // Skip modifiers
                parseModifiers();
            }
            if (isIdentifier() || token() === 104 /* ThisKeyword */) {
                nextToken();
                return true;
            }
            if (token() === 22 /* OpenBracketToken */ || token() === 18 /* OpenBraceToken */) {
                // Return true if we can parse an array or object binding pattern with no errors
                var previousErrorCount = parseDiagnostics.length;
                parseIdentifierOrPattern();
                return previousErrorCount === parseDiagnostics.length;
            }
            return false;
        }
        function isUnambiguouslyStartOfFunctionType() {
            nextToken();
            if (token() === 21 /* CloseParenToken */ || token() === 25 /* DotDotDotToken */) {
                // ( )
                // ( ...
                return true;
            }
            if (skipParameterStart()) {
                // We successfully skipped modifiers (if any) and an identifier or binding pattern,
                // now see if we have something that indicates a parameter declaration
                if (token() === 58 /* ColonToken */ || token() === 27 /* CommaToken */ ||
                    token() === 57 /* QuestionToken */ || token() === 62 /* EqualsToken */) {
                    // ( xxx :
                    // ( xxx ,
                    // ( xxx ?
                    // ( xxx =
                    return true;
                }
                if (token() === 21 /* CloseParenToken */) {
                    nextToken();
                    if (token() === 38 /* EqualsGreaterThanToken */) {
                        // ( xxx ) =>
                        return true;
                    }
                }
            }
            return false;
        }
        function parseTypeOrTypePredicate() {
            var typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix);
            var type = parseType();
            if (typePredicateVariable) {
                var node = createNode(168 /* TypePredicate */, typePredicateVariable.pos);
                node.assertsModifier = undefined;
                node.parameterName = typePredicateVariable;
                node.type = type;
                return finishNode(node);
            }
            else {
                return type;
            }
        }
        function parseTypePredicatePrefix() {
            var id = parseIdentifier();
            if (token() === 133 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                nextToken();
                return id;
            }
        }
        function parseAssertsTypePredicate() {
            var node = createNode(168 /* TypePredicate */);
            node.assertsModifier = parseExpectedToken(124 /* AssertsKeyword */);
            node.parameterName = token() === 104 /* ThisKeyword */ ? parseThisTypeNode() : parseIdentifier();
            node.type = parseOptional(133 /* IsKeyword */) ? parseType() : undefined;
            return finishNode(node);
        }
        function parseType() {
            // The rules about 'yield' only apply to actual code/expression contexts.  They don't
            // apply to 'type' contexts.  So we disable these parameters here before moving on.
            return doOutsideOfContext(40960 /* TypeExcludesFlags */, parseTypeWorker);
        }
        function parseTypeWorker(noConditionalTypes) {
            if (isStartOfFunctionType() || token() === 99 /* NewKeyword */) {
                return parseFunctionOrConstructorType();
            }
            var type = parseUnionTypeOrHigher();
            if (!noConditionalTypes && !scanner.hasPrecedingLineBreak() && parseOptional(90 /* ExtendsKeyword */)) {
                var node = createNode(180 /* ConditionalType */, type.pos);
                node.checkType = type;
                // The type following 'extends' is not permitted to be another conditional type
                node.extendsType = parseTypeWorker(/*noConditionalTypes*/ true);
                parseExpected(57 /* QuestionToken */);
                node.trueType = parseTypeWorker();
                parseExpected(58 /* ColonToken */);
                node.falseType = parseTypeWorker();
                return finishNode(node);
            }
            return type;
        }
        function parseTypeAnnotation() {
            return parseOptional(58 /* ColonToken */) ? parseType() : undefined;
        }
        // EXPRESSIONS
        function isStartOfLeftHandSideExpression() {
            switch (token()) {
                case 104 /* ThisKeyword */:
                case 102 /* SuperKeyword */:
                case 100 /* NullKeyword */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 15 /* TemplateHead */:
                case 20 /* OpenParenToken */:
                case 22 /* OpenBracketToken */:
                case 18 /* OpenBraceToken */:
                case 94 /* FunctionKeyword */:
                case 80 /* ClassKeyword */:
                case 99 /* NewKeyword */:
                case 43 /* SlashToken */:
                case 67 /* SlashEqualsToken */:
                case 75 /* Identifier */:
                    return true;
                case 96 /* ImportKeyword */:
                    return lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfExpression() {
            if (isStartOfLeftHandSideExpression()) {
                return true;
            }
            switch (token()) {
                case 39 /* PlusToken */:
                case 40 /* MinusToken */:
                case 54 /* TildeToken */:
                case 53 /* ExclamationToken */:
                case 85 /* DeleteKeyword */:
                case 108 /* TypeOfKeyword */:
                case 110 /* VoidKeyword */:
                case 45 /* PlusPlusToken */:
                case 46 /* MinusMinusToken */:
                case 29 /* LessThanToken */:
                case 127 /* AwaitKeyword */:
                case 121 /* YieldKeyword */:
                case 76 /* PrivateIdentifier */:
                    // Yield/await always starts an expression.  Either it is an identifier (in which case
                    // it is definitely an expression).  Or it's a keyword (either because we're in
                    // a generator or async function, or in strict mode (or both)) and it started a yield or await expression.
                    return true;
                default:
                    // Error tolerance.  If we see the start of some binary operator, we consider
                    // that the start of an expression.  That way we'll parse out a missing identifier,
                    // give a good message about an identifier being missing, and then consume the
                    // rest of the binary expression.
                    if (isBinaryOperator()) {
                        return true;
                    }
                    return isIdentifier();
            }
        }
        function isStartOfExpressionStatement() {
            // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement.
            return token() !== 18 /* OpenBraceToken */ &&
                token() !== 94 /* FunctionKeyword */ &&
                token() !== 80 /* ClassKeyword */ &&
                token() !== 59 /* AtToken */ &&
                isStartOfExpression();
        }
        function parseExpression() {
            // Expression[in]:
            //      AssignmentExpression[in]
            //      Expression[in] , AssignmentExpression[in]
            // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var expr = parseAssignmentExpressionOrHigher();
            var operatorToken;
            while ((operatorToken = parseOptionalToken(27 /* CommaToken */))) {
                expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
            }
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return expr;
        }
        function parseInitializer() {
            return parseOptional(62 /* EqualsToken */) ? parseAssignmentExpressionOrHigher() : undefined;
        }
        function parseAssignmentExpressionOrHigher() {
            //  AssignmentExpression[in,yield]:
            //      1) ConditionalExpression[?in,?yield]
            //      2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
            //      3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield]
            //      4) ArrowFunctionExpression[?in,?yield]
            //      5) AsyncArrowFunctionExpression[in,yield,await]
            //      6) [+Yield] YieldExpression[?In]
            //
            // Note: for ease of implementation we treat productions '2' and '3' as the same thing.
            // (i.e. they're both BinaryExpressions with an assignment operator in it).
            // First, do the simple check if we have a YieldExpression (production '6').
            if (isYieldExpression()) {
                return parseYieldExpression();
            }
            // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized
            // parameter list or is an async arrow function.
            // AsyncArrowFunctionExpression:
            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
            // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression".
            // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression".
            //
            // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
            // not a LeftHandSideExpression, nor does it start a ConditionalExpression.  So we are done
            // with AssignmentExpression if we see one.
            var arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression();
            if (arrowExpression) {
                return arrowExpression;
            }
            // Now try to see if we're in production '1', '2' or '3'.  A conditional expression can
            // start with a LogicalOrExpression, while the assignment productions can only start with
            // LeftHandSideExpressions.
            //
            // So, first, we try to just parse out a BinaryExpression.  If we get something that is a
            // LeftHandSide or higher, then we can try to parse out the assignment expression part.
            // Otherwise, we try to parse out the conditional expression bit.  We want to allow any
            // binary expression here, so we pass in the 'lowest' precedence here so that it matches
            // and consumes anything.
            var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
            // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized
            // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
            // identifier and the current token is an arrow.
            if (expr.kind === 75 /* Identifier */ && token() === 38 /* EqualsGreaterThanToken */) {
                return parseSimpleArrowFunctionExpression(expr);
            }
            // Now see if we might be in cases '2' or '3'.
            // If the expression was a LHS expression, and we have an assignment operator, then
            // we're in '2' or '3'. Consume the assignment and return.
            //
            // Note: we call reScanGreaterToken so that we get an appropriately merged token
            // for cases like `> > =` becoming `>>=`
            if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) {
                return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
            }
            // It wasn't an assignment or a lambda.  This is a conditional expression:
            return parseConditionalExpressionRest(expr);
        }
        function isYieldExpression() {
            if (token() === 121 /* YieldKeyword */) {
                // If we have a 'yield' keyword, and this is a context where yield expressions are
                // allowed, then definitely parse out a yield expression.
                if (inYieldContext()) {
                    return true;
                }
                // We're in a context where 'yield expr' is not allowed.  However, if we can
                // definitely tell that the user was trying to parse a 'yield expr' and not
                // just a normal expr that start with a 'yield' identifier, then parse out
                // a 'yield expr'.  We can then report an error later that they are only
                // allowed in generator expressions.
                //
                // for example, if we see 'yield(foo)', then we'll have to treat that as an
                // invocation expression of something called 'yield'.  However, if we have
                // 'yield foo' then that is not legal as a normal expression, so we can
                // definitely recognize this as a yield expression.
                //
                // for now we just check if the next token is an identifier.  More heuristics
                // can be added here later as necessary.  We just need to make sure that we
                // don't accidentally consume something legal.
                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
            }
            return false;
        }
        function nextTokenIsIdentifierOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && isIdentifier();
        }
        function parseYieldExpression() {
            var node = createNode(212 /* YieldExpression */);
            // YieldExpression[In] :
            //      yield
            //      yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
            //      yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
            nextToken();
            if (!scanner.hasPrecedingLineBreak() &&
                (token() === 41 /* AsteriskToken */ || isStartOfExpression())) {
                node.asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
                node.expression = parseAssignmentExpressionOrHigher();
                return finishNode(node);
            }
            else {
                // if the next token is not on the same line as yield.  or we don't have an '*' or
                // the start of an expression, then this is just a simple "yield" expression.
                return finishNode(node);
            }
        }
        function parseSimpleArrowFunctionExpression(identifier, asyncModifier) {
            ts.Debug.assert(token() === 38 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
            var node;
            if (asyncModifier) {
                node = createNode(202 /* ArrowFunction */, asyncModifier.pos);
                node.modifiers = asyncModifier;
            }
            else {
                node = createNode(202 /* ArrowFunction */, identifier.pos);
            }
            var parameter = createNode(156 /* Parameter */, identifier.pos);
            parameter.name = identifier;
            finishNode(parameter);
            node.parameters = createNodeArray([parameter], parameter.pos, parameter.end);
            node.equalsGreaterThanToken = parseExpectedToken(38 /* EqualsGreaterThanToken */);
            node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
            return addJSDocComment(finishNode(node));
        }
        function tryParseParenthesizedArrowFunctionExpression() {
            var triState = isParenthesizedArrowFunctionExpression();
            if (triState === 0 /* False */) {
                // It's definitely not a parenthesized arrow function expression.
                return undefined;
            }
            // If we definitely have an arrow function, then we can just parse one, not requiring a
            // following => or { token. Otherwise, we *might* have an arrow function.  Try to parse
            // it out, but don't allow any ambiguity, and return 'undefined' if this could be an
            // expression instead.
            var arrowFunction = triState === 1 /* True */
                ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true)
                : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead);
            if (!arrowFunction) {
                // Didn't appear to actually be a parenthesized arrow function.  Just bail out.
                return undefined;
            }
            var isAsync = hasModifierOfKind(arrowFunction, 126 /* AsyncKeyword */);
            // If we have an arrow, then try to parse the body. Even if not, try to parse if we
            // have an opening brace, just in case we're in an error state.
            var lastToken = token();
            arrowFunction.equalsGreaterThanToken = parseExpectedToken(38 /* EqualsGreaterThanToken */);
            arrowFunction.body = (lastToken === 38 /* EqualsGreaterThanToken */ || lastToken === 18 /* OpenBraceToken */)
                ? parseArrowFunctionExpressionBody(isAsync)
                : parseIdentifier();
            return finishNode(arrowFunction);
        }
        //  True        -> We definitely expect a parenthesized arrow function here.
        //  False       -> There *cannot* be a parenthesized arrow function here.
        //  Unknown     -> There *might* be a parenthesized arrow function here.
        //                 Speculatively look ahead to be sure, and rollback if not.
        function isParenthesizedArrowFunctionExpression() {
            if (token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */ || token() === 126 /* AsyncKeyword */) {
                return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
            }
            if (token() === 38 /* EqualsGreaterThanToken */) {
                // ERROR RECOVERY TWEAK:
                // If we see a standalone => try to parse it as an arrow function expression as that's
                // likely what the user intended to write.
                return 1 /* True */;
            }
            // Definitely not a parenthesized arrow function.
            return 0 /* False */;
        }
        function isParenthesizedArrowFunctionExpressionWorker() {
            if (token() === 126 /* AsyncKeyword */) {
                nextToken();
                if (scanner.hasPrecedingLineBreak()) {
                    return 0 /* False */;
                }
                if (token() !== 20 /* OpenParenToken */ && token() !== 29 /* LessThanToken */) {
                    return 0 /* False */;
                }
            }
            var first = token();
            var second = nextToken();
            if (first === 20 /* OpenParenToken */) {
                if (second === 21 /* CloseParenToken */) {
                    // Simple cases: "() =>", "(): ", and "() {".
                    // This is an arrow function with no parameters.
                    // The last one is not actually an arrow function,
                    // but this is probably what the user intended.
                    var third = nextToken();
                    switch (third) {
                        case 38 /* EqualsGreaterThanToken */:
                        case 58 /* ColonToken */:
                        case 18 /* OpenBraceToken */:
                            return 1 /* True */;
                        default:
                            return 0 /* False */;
                    }
                }
                // If encounter "([" or "({", this could be the start of a binding pattern.
                // Examples:
                //      ([ x ]) => { }
                //      ({ x }) => { }
                //      ([ x ])
                //      ({ x })
                if (second === 22 /* OpenBracketToken */ || second === 18 /* OpenBraceToken */) {
                    return 2 /* Unknown */;
                }
                // Simple case: "(..."
                // This is an arrow function with a rest parameter.
                if (second === 25 /* DotDotDotToken */) {
                    return 1 /* True */;
                }
                // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This
                // isn't actually allowed, but we want to treat it as a lambda so we can provide
                // a good error message.
                if (ts.isModifierKind(second) && second !== 126 /* AsyncKeyword */ && lookAhead(nextTokenIsIdentifier)) {
                    return 1 /* True */;
                }
                // If we had "(" followed by something that's not an identifier,
                // then this definitely doesn't look like a lambda.  "this" is not
                // valid, but we want to parse it and then give a semantic error.
                if (!isIdentifier() && second !== 104 /* ThisKeyword */) {
                    return 0 /* False */;
                }
                switch (nextToken()) {
                    case 58 /* ColonToken */:
                        // If we have something like "(a:", then we must have a
                        // type-annotated parameter in an arrow function expression.
                        return 1 /* True */;
                    case 57 /* QuestionToken */:
                        nextToken();
                        // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda.
                        if (token() === 58 /* ColonToken */ || token() === 27 /* CommaToken */ || token() === 62 /* EqualsToken */ || token() === 21 /* CloseParenToken */) {
                            return 1 /* True */;
                        }
                        // Otherwise it is definitely not a lambda.
                        return 0 /* False */;
                    case 27 /* CommaToken */:
                    case 62 /* EqualsToken */:
                    case 21 /* CloseParenToken */:
                        // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function
                        return 2 /* Unknown */;
                }
                // It is definitely not an arrow function
                return 0 /* False */;
            }
            else {
                ts.Debug.assert(first === 29 /* LessThanToken */);
                // If we have "<" not followed by an identifier,
                // then this definitely is not an arrow function.
                if (!isIdentifier()) {
                    return 0 /* False */;
                }
                // JSX overrides
                if (sourceFile.languageVariant === 1 /* JSX */) {
                    var isArrowFunctionInJsx = lookAhead(function () {
                        var third = nextToken();
                        if (third === 90 /* ExtendsKeyword */) {
                            var fourth = nextToken();
                            switch (fourth) {
                                case 62 /* EqualsToken */:
                                case 31 /* GreaterThanToken */:
                                    return false;
                                default:
                                    return true;
                            }
                        }
                        else if (third === 27 /* CommaToken */) {
                            return true;
                        }
                        return false;
                    });
                    if (isArrowFunctionInJsx) {
                        return 1 /* True */;
                    }
                    return 0 /* False */;
                }
                // This *could* be a parenthesized arrow function.
                return 2 /* Unknown */;
            }
        }
        function parsePossibleParenthesizedArrowFunctionExpressionHead() {
            var tokenPos = scanner.getTokenPos();
            if (notParenthesizedArrow && notParenthesizedArrow.has(tokenPos.toString())) {
                return undefined;
            }
            var result = parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false);
            if (!result) {
                (notParenthesizedArrow || (notParenthesizedArrow = ts.createMap())).set(tokenPos.toString(), true);
            }
            return result;
        }
        function tryParseAsyncSimpleArrowFunctionExpression() {
            // We do a check here so that we won't be doing unnecessarily call to "lookAhead"
            if (token() === 126 /* AsyncKeyword */) {
                if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === 1 /* True */) {
                    var asyncModifier = parseModifiersForArrowFunction();
                    var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                    return parseSimpleArrowFunctionExpression(expr, asyncModifier);
                }
            }
            return undefined;
        }
        function isUnParenthesizedAsyncArrowFunctionWorker() {
            // AsyncArrowFunctionExpression:
            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
            if (token() === 126 /* AsyncKeyword */) {
                nextToken();
                // If the "async" is followed by "=>" token then it is not a beginning of an async arrow-function
                // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher"
                if (scanner.hasPrecedingLineBreak() || token() === 38 /* EqualsGreaterThanToken */) {
                    return 0 /* False */;
                }
                // Check for un-parenthesized AsyncArrowFunction
                var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                if (!scanner.hasPrecedingLineBreak() && expr.kind === 75 /* Identifier */ && token() === 38 /* EqualsGreaterThanToken */) {
                    return 1 /* True */;
                }
            }
            return 0 /* False */;
        }
        function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) {
            var node = createNodeWithJSDoc(202 /* ArrowFunction */);
            node.modifiers = parseModifiersForArrowFunction();
            var isAsync = hasModifierOfKind(node, 126 /* AsyncKeyword */) ? 2 /* Await */ : 0 /* None */;
            // Arrow functions are never generators.
            //
            // If we're speculatively parsing a signature for a parenthesized arrow function, then
            // we have to have a complete parameter list.  Otherwise we might see something like
            // a => (b => c)
            // And think that "(b =>" was actually a parenthesized arrow function with a missing
            // close paren.
            if (!fillSignature(58 /* ColonToken */, isAsync, node) && !allowAmbiguity) {
                return undefined;
            }
            // Parsing a signature isn't enough.
            // Parenthesized arrow signatures often look like other valid expressions.
            // For instance:
            //  - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value.
            //  - "(x,y)" is a comma expression parsed as a signature with two parameters.
            //  - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
            //  - "a ? (b): function() {}" will too, since function() is a valid JSDoc function type.
            //
            // So we need just a bit of lookahead to ensure that it can only be a signature.
            var hasJSDocFunctionType = node.type && ts.isJSDocFunctionType(node.type);
            if (!allowAmbiguity && token() !== 38 /* EqualsGreaterThanToken */ && (hasJSDocFunctionType || token() !== 18 /* OpenBraceToken */)) {
                // Returning undefined here will cause our caller to rewind to where we started from.
                return undefined;
            }
            return node;
        }
        function parseArrowFunctionExpressionBody(isAsync) {
            if (token() === 18 /* OpenBraceToken */) {
                return parseFunctionBlock(isAsync ? 2 /* Await */ : 0 /* None */);
            }
            if (token() !== 26 /* SemicolonToken */ &&
                token() !== 94 /* FunctionKeyword */ &&
                token() !== 80 /* ClassKeyword */ &&
                isStartOfStatement() &&
                !isStartOfExpressionStatement()) {
                // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations)
                //
                // Here we try to recover from a potential error situation in the case where the
                // user meant to supply a block. For example, if the user wrote:
                //
                //  a =>
                //      let v = 0;
                //  }
                //
                // they may be missing an open brace.  Check to see if that's the case so we can
                // try to recover better.  If we don't do this, then the next close curly we see may end
                // up preemptively closing the containing construct.
                //
                // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error.
                return parseFunctionBlock(16 /* IgnoreMissingOpenBrace */ | (isAsync ? 2 /* Await */ : 0 /* None */));
            }
            return isAsync
                ? doInAwaitContext(parseAssignmentExpressionOrHigher)
                : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
        }
        function parseConditionalExpressionRest(leftOperand) {
            // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher.
            var questionToken = parseOptionalToken(57 /* QuestionToken */);
            if (!questionToken) {
                return leftOperand;
            }
            // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
            // we do not that for the 'whenFalse' part.
            var node = createNode(210 /* ConditionalExpression */, leftOperand.pos);
            node.condition = leftOperand;
            node.questionToken = questionToken;
            node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
            node.colonToken = parseExpectedToken(58 /* ColonToken */);
            node.whenFalse = ts.nodeIsPresent(node.colonToken)
                ? parseAssignmentExpressionOrHigher()
                : createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(58 /* ColonToken */));
            return finishNode(node);
        }
        function parseBinaryExpressionOrHigher(precedence) {
            var leftOperand = parseUnaryExpressionOrHigher();
            return parseBinaryExpressionRest(precedence, leftOperand);
        }
        function isInOrOfKeyword(t) {
            return t === 97 /* InKeyword */ || t === 152 /* OfKeyword */;
        }
        function parseBinaryExpressionRest(precedence, leftOperand) {
            while (true) {
                // We either have a binary operator here, or we're finished.  We call
                // reScanGreaterToken so that we merge token sequences like > and = into >=
                reScanGreaterToken();
                var newPrecedence = ts.getBinaryOperatorPrecedence(token());
                // Check the precedence to see if we should "take" this operator
                // - For left associative operator (all operator but **), consume the operator,
                //   recursively call the function below, and parse binaryExpression as a rightOperand
                //   of the caller if the new precedence of the operator is greater then or equal to the current precedence.
                //   For example:
                //      a - b - c;
                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
                //      a * b - c
                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
                //      a - b * c;
                //            ^token; leftOperand = b. Return b * c to the caller as a rightOperand
                // - For right associative operator (**), consume the operator, recursively call the function
                //   and parse binaryExpression as a rightOperand of the caller if the new precedence of
                //   the operator is strictly grater than the current precedence
                //   For example:
                //      a ** b ** c;
                //             ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
                //      a - b ** c;
                //            ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
                //      a ** b - c
                //             ^token; leftOperand = b. Return b to the caller as a rightOperand
                var consumeCurrentOperator = token() === 42 /* AsteriskAsteriskToken */ ?
                    newPrecedence >= precedence :
                    newPrecedence > precedence;
                if (!consumeCurrentOperator) {
                    break;
                }
                if (token() === 97 /* InKeyword */ && inDisallowInContext()) {
                    break;
                }
                if (token() === 123 /* AsKeyword */) {
                    // Make sure we *do* perform ASI for constructs like this:
                    //    var x = foo
                    //    as (Bar)
                    // This should be parsed as an initialized variable, followed
                    // by a function call to 'as' with the argument 'Bar'
                    if (scanner.hasPrecedingLineBreak()) {
                        break;
                    }
                    else {
                        nextToken();
                        leftOperand = makeAsExpression(leftOperand, parseType());
                    }
                }
                else {
                    leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
                }
            }
            return leftOperand;
        }
        function isBinaryOperator() {
            if (inDisallowInContext() && token() === 97 /* InKeyword */) {
                return false;
            }
            return ts.getBinaryOperatorPrecedence(token()) > 0;
        }
        function makeBinaryExpression(left, operatorToken, right) {
            var node = createNode(209 /* BinaryExpression */, left.pos);
            node.left = left;
            node.operatorToken = operatorToken;
            node.right = right;
            return finishNode(node);
        }
        function makeAsExpression(left, right) {
            var node = createNode(217 /* AsExpression */, left.pos);
            node.expression = left;
            node.type = right;
            return finishNode(node);
        }
        function parsePrefixUnaryExpression() {
            var node = createNode(207 /* PrefixUnaryExpression */);
            node.operator = token();
            nextToken();
            node.operand = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseDeleteExpression() {
            var node = createNode(203 /* DeleteExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseTypeOfExpression() {
            var node = createNode(204 /* TypeOfExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseVoidExpression() {
            var node = createNode(205 /* VoidExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function isAwaitExpression() {
            if (token() === 127 /* AwaitKeyword */) {
                if (inAwaitContext()) {
                    return true;
                }
                // here we are using similar heuristics as 'isYieldExpression'
                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
            }
            return false;
        }
        function parseAwaitExpression() {
            var node = createNode(206 /* AwaitExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        /**
         * Parse ES7 exponential expression and await expression
         *
         * ES7 ExponentiationExpression:
         *      1) UnaryExpression[?Yield]
         *      2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield]
         *
         */
        function parseUnaryExpressionOrHigher() {
            /**
             * ES7 UpdateExpression:
             *      1) LeftHandSideExpression[?Yield]
             *      2) LeftHandSideExpression[?Yield][no LineTerminator here]++
             *      3) LeftHandSideExpression[?Yield][no LineTerminator here]--
             *      4) ++UnaryExpression[?Yield]
             *      5) --UnaryExpression[?Yield]
             */
            if (isUpdateExpression()) {
                var updateExpression = parseUpdateExpression();
                return token() === 42 /* AsteriskAsteriskToken */ ?
                    parseBinaryExpressionRest(ts.getBinaryOperatorPrecedence(token()), updateExpression) :
                    updateExpression;
            }
            /**
             * ES7 UnaryExpression:
             *      1) UpdateExpression[?yield]
             *      2) delete UpdateExpression[?yield]
             *      3) void UpdateExpression[?yield]
             *      4) typeof UpdateExpression[?yield]
             *      5) + UpdateExpression[?yield]
             *      6) - UpdateExpression[?yield]
             *      7) ~ UpdateExpression[?yield]
             *      8) ! UpdateExpression[?yield]
             */
            var unaryOperator = token();
            var simpleUnaryExpression = parseSimpleUnaryExpression();
            if (token() === 42 /* AsteriskAsteriskToken */) {
                var pos = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
                var end = simpleUnaryExpression.end;
                if (simpleUnaryExpression.kind === 199 /* TypeAssertionExpression */) {
                    parseErrorAt(pos, end, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
                }
                else {
                    parseErrorAt(pos, end, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
                }
            }
            return simpleUnaryExpression;
        }
        /**
         * Parse ES7 simple-unary expression or higher:
         *
         * ES7 UnaryExpression:
         *      1) UpdateExpression[?yield]
         *      2) delete UnaryExpression[?yield]
         *      3) void UnaryExpression[?yield]
         *      4) typeof UnaryExpression[?yield]
         *      5) + UnaryExpression[?yield]
         *      6) - UnaryExpression[?yield]
         *      7) ~ UnaryExpression[?yield]
         *      8) ! UnaryExpression[?yield]
         *      9) [+Await] await UnaryExpression[?yield]
         */
        function parseSimpleUnaryExpression() {
            switch (token()) {
                case 39 /* PlusToken */:
                case 40 /* MinusToken */:
                case 54 /* TildeToken */:
                case 53 /* ExclamationToken */:
                    return parsePrefixUnaryExpression();
                case 85 /* DeleteKeyword */:
                    return parseDeleteExpression();
                case 108 /* TypeOfKeyword */:
                    return parseTypeOfExpression();
                case 110 /* VoidKeyword */:
                    return parseVoidExpression();
                case 29 /* LessThanToken */:
                    // This is modified UnaryExpression grammar in TypeScript
                    //  UnaryExpression (modified):
                    //      < type > UnaryExpression
                    return parseTypeAssertion();
                case 127 /* AwaitKeyword */:
                    if (isAwaitExpression()) {
                        return parseAwaitExpression();
                    }
                // falls through
                default:
                    return parseUpdateExpression();
            }
        }
        /**
         * Check if the current token can possibly be an ES7 increment expression.
         *
         * ES7 UpdateExpression:
         *      LeftHandSideExpression[?Yield]
         *      LeftHandSideExpression[?Yield][no LineTerminator here]++
         *      LeftHandSideExpression[?Yield][no LineTerminator here]--
         *      ++LeftHandSideExpression[?Yield]
         *      --LeftHandSideExpression[?Yield]
         */
        function isUpdateExpression() {
            // This function is called inside parseUnaryExpression to decide
            // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly
            switch (token()) {
                case 39 /* PlusToken */:
                case 40 /* MinusToken */:
                case 54 /* TildeToken */:
                case 53 /* ExclamationToken */:
                case 85 /* DeleteKeyword */:
                case 108 /* TypeOfKeyword */:
                case 110 /* VoidKeyword */:
                case 127 /* AwaitKeyword */:
                    return false;
                case 29 /* LessThanToken */:
                    // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
                    if (sourceFile.languageVariant !== 1 /* JSX */) {
                        return false;
                    }
                // We are in JSX context and the token is part of JSXElement.
                // falls through
                default:
                    return true;
            }
        }
        /**
         * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression.
         *
         * ES7 UpdateExpression[yield]:
         *      1) LeftHandSideExpression[?yield]
         *      2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
         *      3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
         *      4) ++LeftHandSideExpression[?yield]
         *      5) --LeftHandSideExpression[?yield]
         * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
         */
        function parseUpdateExpression() {
            if (token() === 45 /* PlusPlusToken */ || token() === 46 /* MinusMinusToken */) {
                var node = createNode(207 /* PrefixUnaryExpression */);
                node.operator = token();
                nextToken();
                node.operand = parseLeftHandSideExpressionOrHigher();
                return finishNode(node);
            }
            else if (sourceFile.languageVariant === 1 /* JSX */ && token() === 29 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) {
                // JSXElement is part of primaryExpression
                return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
            }
            var expression = parseLeftHandSideExpressionOrHigher();
            ts.Debug.assert(ts.isLeftHandSideExpression(expression));
            if ((token() === 45 /* PlusPlusToken */ || token() === 46 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
                var node = createNode(208 /* PostfixUnaryExpression */, expression.pos);
                node.operand = expression;
                node.operator = token();
                nextToken();
                return finishNode(node);
            }
            return expression;
        }
        function parseLeftHandSideExpressionOrHigher() {
            // Original Ecma:
            // LeftHandSideExpression: See 11.2
            //      NewExpression
            //      CallExpression
            //
            // Our simplification:
            //
            // LeftHandSideExpression: See 11.2
            //      MemberExpression
            //      CallExpression
            //
            // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
            // MemberExpression to make our lives easier.
            //
            // to best understand the below code, it's important to see how CallExpression expands
            // out into its own productions:
            //
            // CallExpression:
            //      MemberExpression Arguments
            //      CallExpression Arguments
            //      CallExpression[Expression]
            //      CallExpression.IdentifierName
            //      import (AssignmentExpression)
            //      super Arguments
            //      super.IdentifierName
            //
            // Because of the recursion in these calls, we need to bottom out first. There are three
            // bottom out states we can run into: 1) We see 'super' which must start either of
            // the last two CallExpression productions. 2) We see 'import' which must start import call.
            // 3)we have a MemberExpression which either completes the LeftHandSideExpression,
            // or starts the beginning of the first four CallExpression productions.
            var expression;
            if (token() === 96 /* ImportKeyword */) {
                if (lookAhead(nextTokenIsOpenParenOrLessThan)) {
                    // We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "("
                    // For example:
                    //      var foo3 = require("subfolder
                    //      import * as foo1 from "module-from-node
                    // We want this import to be a statement rather than import call expression
                    sourceFile.flags |= 1048576 /* PossiblyContainsDynamicImport */;
                    expression = parseTokenNode();
                }
                else if (lookAhead(nextTokenIsDot)) {
                    // This is an 'import.*' metaproperty (i.e. 'import.meta')
                    var fullStart = scanner.getStartPos();
                    nextToken(); // advance past the 'import'
                    nextToken(); // advance past the dot
                    var node = createNode(219 /* MetaProperty */, fullStart);
                    node.keywordToken = 96 /* ImportKeyword */;
                    node.name = parseIdentifierName();
                    expression = finishNode(node);
                    sourceFile.flags |= 2097152 /* PossiblyContainsImportMeta */;
                }
                else {
                    expression = parseMemberExpressionOrHigher();
                }
            }
            else {
                expression = token() === 102 /* SuperKeyword */ ? parseSuperExpression() : parseMemberExpressionOrHigher();
            }
            // Now, we *may* be complete.  However, we might have consumed the start of a
            // CallExpression or OptionalExpression.  As such, we need to consume the rest
            // of it here to be complete.
            return parseCallExpressionRest(expression);
        }
        function parseMemberExpressionOrHigher() {
            // Note: to make our lives simpler, we decompose the NewExpression productions and
            // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
            // like so:
            //
            //   PrimaryExpression : See 11.1
            //      this
            //      Identifier
            //      Literal
            //      ArrayLiteral
            //      ObjectLiteral
            //      (Expression)
            //      FunctionExpression
            //      new MemberExpression Arguments?
            //
            //   MemberExpression : See 11.2
            //      PrimaryExpression
            //      MemberExpression[Expression]
            //      MemberExpression.IdentifierName
            //
            //   CallExpression : See 11.2
            //      MemberExpression
            //      CallExpression Arguments
            //      CallExpression[Expression]
            //      CallExpression.IdentifierName
            //
            // Technically this is ambiguous.  i.e. CallExpression defines:
            //
            //   CallExpression:
            //      CallExpression Arguments
            //
            // If you see: "new Foo()"
            //
            // Then that could be treated as a single ObjectCreationExpression, or it could be
            // treated as the invocation of "new Foo".  We disambiguate that in code (to match
            // the original grammar) by making sure that if we see an ObjectCreationExpression
            // we always consume arguments if they are there. So we treat "new Foo()" as an
            // object creation only, and not at all as an invocation.  Another way to think
            // about this is that for every "new" that we see, we will consume an argument list if
            // it is there as part of the *associated* object creation node.  Any additional
            // argument lists we see, will become invocation expressions.
            //
            // Because there are no other places in the grammar now that refer to FunctionExpression
            // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
            // production.
            //
            // Because CallExpression and MemberExpression are left recursive, we need to bottom out
            // of the recursion immediately.  So we parse out a primary expression to start with.
            var expression = parsePrimaryExpression();
            return parseMemberExpressionRest(expression, /*allowOptionalChain*/ true);
        }
        function parseSuperExpression() {
            var expression = parseTokenNode();
            if (token() === 29 /* LessThanToken */) {
                var startPos = getNodePos();
                var typeArguments = tryParse(parseTypeArgumentsInExpression);
                if (typeArguments !== undefined) {
                    parseErrorAt(startPos, getNodePos(), ts.Diagnostics.super_may_not_use_type_arguments);
                }
            }
            if (token() === 20 /* OpenParenToken */ || token() === 24 /* DotToken */ || token() === 22 /* OpenBracketToken */) {
                return expression;
            }
            // If we have seen "super" it must be followed by '(' or '.'.
            // If it wasn't then just try to parse out a '.' and report an error.
            var node = createNode(194 /* PropertyAccessExpression */, expression.pos);
            node.expression = expression;
            parseExpectedToken(24 /* DotToken */, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
            // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic
            node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true);
            return finishNode(node);
        }
        function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext) {
            var opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext);
            var result;
            if (opening.kind === 268 /* JsxOpeningElement */) {
                var node = createNode(266 /* JsxElement */, opening.pos);
                node.openingElement = opening;
                node.children = parseJsxChildren(node.openingElement);
                node.closingElement = parseJsxClosingElement(inExpressionContext);
                if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
                    parseErrorAtRange(node.closingElement, ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, node.openingElement.tagName));
                }
                result = finishNode(node);
            }
            else if (opening.kind === 271 /* JsxOpeningFragment */) {
                var node = createNode(270 /* JsxFragment */, opening.pos);
                node.openingFragment = opening;
                node.children = parseJsxChildren(node.openingFragment);
                node.closingFragment = parseJsxClosingFragment(inExpressionContext);
                result = finishNode(node);
            }
            else {
                ts.Debug.assert(opening.kind === 267 /* JsxSelfClosingElement */);
                // Nothing else to do for self-closing elements
                result = opening;
            }
            // If the user writes the invalid code '<div></div><div></div>' in an expression context (i.e. not wrapped in
            // an enclosing tag), we'll naively try to parse   ^ this as a 'less than' operator and the remainder of the tag
            // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
            // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
            // does less damage and we can report a better error.
            // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
            // of one sort or another.
            if (inExpressionContext && token() === 29 /* LessThanToken */) {
                var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); });
                if (invalidElement) {
                    parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
                    var badNode = createNode(209 /* BinaryExpression */, result.pos);
                    badNode.end = invalidElement.end;
                    badNode.left = result;
                    badNode.right = invalidElement;
                    badNode.operatorToken = createMissingNode(27 /* CommaToken */, /*reportAtCurrentPosition*/ false);
                    badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
                    return badNode;
                }
            }
            return result;
        }
        function parseJsxText() {
            var node = createNode(11 /* JsxText */);
            node.text = scanner.getTokenValue();
            node.containsOnlyTriviaWhiteSpaces = currentToken === 12 /* JsxTextAllWhiteSpaces */;
            currentToken = scanner.scanJsxToken();
            return finishNode(node);
        }
        function parseJsxChild(openingTag, token) {
            switch (token) {
                case 1 /* EndOfFileToken */:
                    // If we hit EOF, issue the error at the tag that lacks the closing element
                    // rather than at the end of the file (which is useless)
                    if (ts.isJsxOpeningFragment(openingTag)) {
                        parseErrorAtRange(openingTag, ts.Diagnostics.JSX_fragment_has_no_corresponding_closing_tag);
                    }
                    else {
                        // We want the error span to cover only 'Foo.Bar' in < Foo.Bar >
                        // or to cover only 'Foo' in < Foo >
                        var tag = openingTag.tagName;
                        var start = ts.skipTrivia(sourceText, tag.pos);
                        parseErrorAt(start, tag.end, ts.Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, ts.getTextOfNodeFromSourceText(sourceText, openingTag.tagName));
                    }
                    return undefined;
                case 30 /* LessThanSlashToken */:
                case 7 /* ConflictMarkerTrivia */:
                    return undefined;
                case 11 /* JsxText */:
                case 12 /* JsxTextAllWhiteSpaces */:
                    return parseJsxText();
                case 18 /* OpenBraceToken */:
                    return parseJsxExpression(/*inExpressionContext*/ false);
                case 29 /* LessThanToken */:
                    return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false);
                default:
                    return ts.Debug.assertNever(token);
            }
        }
        function parseJsxChildren(openingTag) {
            var list = [];
            var listPos = getNodePos();
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << 14 /* JsxChildren */;
            while (true) {
                var child = parseJsxChild(openingTag, currentToken = scanner.reScanJsxToken());
                if (!child)
                    break;
                list.push(child);
            }
            parsingContext = saveParsingContext;
            return createNodeArray(list, listPos);
        }
        function parseJsxAttributes() {
            var jsxAttributes = createNode(274 /* JsxAttributes */);
            jsxAttributes.properties = parseList(13 /* JsxAttributes */, parseJsxAttribute);
            return finishNode(jsxAttributes);
        }
        function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext) {
            var fullStart = scanner.getStartPos();
            parseExpected(29 /* LessThanToken */);
            if (token() === 31 /* GreaterThanToken */) {
                // See below for explanation of scanJsxText
                var node_1 = createNode(271 /* JsxOpeningFragment */, fullStart);
                scanJsxText();
                return finishNode(node_1);
            }
            var tagName = parseJsxElementName();
            var typeArguments = tryParseTypeArguments();
            var attributes = parseJsxAttributes();
            var node;
            if (token() === 31 /* GreaterThanToken */) {
                // Closing tag, so scan the immediately-following text with the JSX scanning instead
                // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
                // scanning errors
                node = createNode(268 /* JsxOpeningElement */, fullStart);
                scanJsxText();
            }
            else {
                parseExpected(43 /* SlashToken */);
                if (inExpressionContext) {
                    parseExpected(31 /* GreaterThanToken */);
                }
                else {
                    parseExpected(31 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                    scanJsxText();
                }
                node = createNode(267 /* JsxSelfClosingElement */, fullStart);
            }
            node.tagName = tagName;
            node.typeArguments = typeArguments;
            node.attributes = attributes;
            return finishNode(node);
        }
        function parseJsxElementName() {
            scanJsxIdentifier();
            // JsxElement can have name in the form of
            //      propertyAccessExpression
            //      primaryExpression in the form of an identifier and "this" keyword
            // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
            // We only want to consider "this" as a primaryExpression
            var expression = token() === 104 /* ThisKeyword */ ?
                parseTokenNode() : parseIdentifierName();
            while (parseOptional(24 /* DotToken */)) {
                var propertyAccess = createNode(194 /* PropertyAccessExpression */, expression.pos);
                propertyAccess.expression = expression;
                propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false);
                expression = finishNode(propertyAccess);
            }
            return expression;
        }
        function parseJsxExpression(inExpressionContext) {
            var node = createNode(276 /* JsxExpression */);
            if (!parseExpected(18 /* OpenBraceToken */)) {
                return undefined;
            }
            if (token() !== 19 /* CloseBraceToken */) {
                node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
                // Only an AssignmentExpression is valid here per the JSX spec,
                // but we can unambiguously parse a comma sequence and provide
                // a better error message in grammar checking.
                node.expression = parseExpression();
            }
            if (inExpressionContext) {
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                if (parseExpected(19 /* CloseBraceToken */, /*message*/ undefined, /*shouldAdvance*/ false)) {
                    scanJsxText();
                }
            }
            return finishNode(node);
        }
        function parseJsxAttribute() {
            if (token() === 18 /* OpenBraceToken */) {
                return parseJsxSpreadAttribute();
            }
            scanJsxIdentifier();
            var node = createNode(273 /* JsxAttribute */);
            node.name = parseIdentifierName();
            if (token() === 62 /* EqualsToken */) {
                switch (scanJsxAttributeValue()) {
                    case 10 /* StringLiteral */:
                        node.initializer = parseLiteralNode();
                        break;
                    default:
                        node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
                        break;
                }
            }
            return finishNode(node);
        }
        function parseJsxSpreadAttribute() {
            var node = createNode(275 /* JsxSpreadAttribute */);
            parseExpected(18 /* OpenBraceToken */);
            parseExpected(25 /* DotDotDotToken */);
            node.expression = parseExpression();
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseJsxClosingElement(inExpressionContext) {
            var node = createNode(269 /* JsxClosingElement */);
            parseExpected(30 /* LessThanSlashToken */);
            node.tagName = parseJsxElementName();
            if (inExpressionContext) {
                parseExpected(31 /* GreaterThanToken */);
            }
            else {
                parseExpected(31 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseJsxClosingFragment(inExpressionContext) {
            var node = createNode(272 /* JsxClosingFragment */);
            parseExpected(30 /* LessThanSlashToken */);
            if (ts.tokenIsIdentifierOrKeyword(token())) {
                parseErrorAtRange(parseJsxElementName(), ts.Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment);
            }
            if (inExpressionContext) {
                parseExpected(31 /* GreaterThanToken */);
            }
            else {
                parseExpected(31 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseTypeAssertion() {
            var node = createNode(199 /* TypeAssertionExpression */);
            parseExpected(29 /* LessThanToken */);
            node.type = parseType();
            parseExpected(31 /* GreaterThanToken */);
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token())
                || token() === 22 /* OpenBracketToken */
                || isTemplateStartOfTaggedTemplate();
        }
        function isStartOfOptionalPropertyOrElementAccessChain() {
            return token() === 28 /* QuestionDotToken */
                && lookAhead(nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate);
        }
        function tryReparseOptionalChain(node) {
            if (node.flags & 32 /* OptionalChain */) {
                return true;
            }
            // check for an optional chain in a non-null expression
            if (ts.isNonNullExpression(node)) {
                var expr = node.expression;
                while (ts.isNonNullExpression(expr) && !(expr.flags & 32 /* OptionalChain */)) {
                    expr = expr.expression;
                }
                if (expr.flags & 32 /* OptionalChain */) {
                    // this is part of an optional chain. Walk down from `node` to `expression` and set the flag.
                    while (ts.isNonNullExpression(node)) {
                        node.flags |= 32 /* OptionalChain */;
                        node = node.expression;
                    }
                    return true;
                }
            }
            return false;
        }
        function parsePropertyAccessExpressionRest(expression, questionDotToken) {
            var propertyAccess = createNode(194 /* PropertyAccessExpression */, expression.pos);
            propertyAccess.expression = expression;
            propertyAccess.questionDotToken = questionDotToken;
            propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true);
            if (questionDotToken || tryReparseOptionalChain(expression)) {
                propertyAccess.flags |= 32 /* OptionalChain */;
                if (ts.isPrivateIdentifier(propertyAccess.name)) {
                    parseErrorAtRange(propertyAccess.name, ts.Diagnostics.An_optional_chain_cannot_contain_private_identifiers);
                }
            }
            return finishNode(propertyAccess);
        }
        function parseElementAccessExpressionRest(expression, questionDotToken) {
            var indexedAccess = createNode(195 /* ElementAccessExpression */, expression.pos);
            indexedAccess.expression = expression;
            indexedAccess.questionDotToken = questionDotToken;
            if (token() === 23 /* CloseBracketToken */) {
                indexedAccess.argumentExpression = createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.An_element_access_expression_should_take_an_argument);
            }
            else {
                var argument = allowInAnd(parseExpression);
                if (ts.isStringOrNumericLiteralLike(argument)) {
                    argument.text = internIdentifier(argument.text);
                }
                indexedAccess.argumentExpression = argument;
            }
            parseExpected(23 /* CloseBracketToken */);
            if (questionDotToken || tryReparseOptionalChain(expression)) {
                indexedAccess.flags |= 32 /* OptionalChain */;
            }
            return finishNode(indexedAccess);
        }
        function parseMemberExpressionRest(expression, allowOptionalChain) {
            while (true) {
                var questionDotToken = void 0;
                var isPropertyAccess = false;
                if (allowOptionalChain && isStartOfOptionalPropertyOrElementAccessChain()) {
                    questionDotToken = parseExpectedToken(28 /* QuestionDotToken */);
                    isPropertyAccess = ts.tokenIsIdentifierOrKeyword(token());
                }
                else {
                    isPropertyAccess = parseOptional(24 /* DotToken */);
                }
                if (isPropertyAccess) {
                    expression = parsePropertyAccessExpressionRest(expression, questionDotToken);
                    continue;
                }
                if (!questionDotToken && token() === 53 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                    nextToken();
                    var nonNullExpression = createNode(218 /* NonNullExpression */, expression.pos);
                    nonNullExpression.expression = expression;
                    expression = finishNode(nonNullExpression);
                    continue;
                }
                // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
                if ((questionDotToken || !inDecoratorContext()) && parseOptional(22 /* OpenBracketToken */)) {
                    expression = parseElementAccessExpressionRest(expression, questionDotToken);
                    continue;
                }
                if (isTemplateStartOfTaggedTemplate()) {
                    expression = parseTaggedTemplateRest(expression, questionDotToken, /*typeArguments*/ undefined);
                    continue;
                }
                return expression;
            }
        }
        function isTemplateStartOfTaggedTemplate() {
            return token() === 14 /* NoSubstitutionTemplateLiteral */ || token() === 15 /* TemplateHead */;
        }
        function parseTaggedTemplateRest(tag, questionDotToken, typeArguments) {
            var tagExpression = createNode(198 /* TaggedTemplateExpression */, tag.pos);
            tagExpression.tag = tag;
            tagExpression.questionDotToken = questionDotToken;
            tagExpression.typeArguments = typeArguments;
            tagExpression.template = token() === 14 /* NoSubstitutionTemplateLiteral */
                ? (reScanTemplateHeadOrNoSubstitutionTemplate(), parseLiteralNode())
                : parseTemplateExpression(/*isTaggedTemplate*/ true);
            if (questionDotToken || tag.flags & 32 /* OptionalChain */) {
                tagExpression.flags |= 32 /* OptionalChain */;
            }
            return finishNode(tagExpression);
        }
        function parseCallExpressionRest(expression) {
            while (true) {
                expression = parseMemberExpressionRest(expression, /*allowOptionalChain*/ true);
                var questionDotToken = parseOptionalToken(28 /* QuestionDotToken */);
                // handle 'foo<<T>()'
                if (token() === 29 /* LessThanToken */ || token() === 47 /* LessThanLessThanToken */) {
                    // See if this is the start of a generic invocation.  If so, consume it and
                    // keep checking for postfix expressions.  Otherwise, it's just a '<' that's
                    // part of an arithmetic expression.  Break out so we consume it higher in the
                    // stack.
                    var typeArguments = tryParse(parseTypeArgumentsInExpression);
                    if (typeArguments) {
                        if (isTemplateStartOfTaggedTemplate()) {
                            expression = parseTaggedTemplateRest(expression, questionDotToken, typeArguments);
                            continue;
                        }
                        var callExpr = createNode(196 /* CallExpression */, expression.pos);
                        callExpr.expression = expression;
                        callExpr.questionDotToken = questionDotToken;
                        callExpr.typeArguments = typeArguments;
                        callExpr.arguments = parseArgumentList();
                        if (questionDotToken || tryReparseOptionalChain(expression)) {
                            callExpr.flags |= 32 /* OptionalChain */;
                        }
                        expression = finishNode(callExpr);
                        continue;
                    }
                }
                else if (token() === 20 /* OpenParenToken */) {
                    var callExpr = createNode(196 /* CallExpression */, expression.pos);
                    callExpr.expression = expression;
                    callExpr.questionDotToken = questionDotToken;
                    callExpr.arguments = parseArgumentList();
                    if (questionDotToken || tryReparseOptionalChain(expression)) {
                        callExpr.flags |= 32 /* OptionalChain */;
                    }
                    expression = finishNode(callExpr);
                    continue;
                }
                if (questionDotToken) {
                    // We failed to parse anything, so report a missing identifier here.
                    var propertyAccess = createNode(194 /* PropertyAccessExpression */, expression.pos);
                    propertyAccess.expression = expression;
                    propertyAccess.questionDotToken = questionDotToken;
                    propertyAccess.name = createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.Identifier_expected);
                    propertyAccess.flags |= 32 /* OptionalChain */;
                    expression = finishNode(propertyAccess);
                }
                break;
            }
            return expression;
        }
        function parseArgumentList() {
            parseExpected(20 /* OpenParenToken */);
            var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
            parseExpected(21 /* CloseParenToken */);
            return result;
        }
        function parseTypeArgumentsInExpression() {
            if (reScanLessThanToken() !== 29 /* LessThanToken */) {
                return undefined;
            }
            nextToken();
            var typeArguments = parseDelimitedList(20 /* TypeArguments */, parseType);
            if (!parseExpected(31 /* GreaterThanToken */)) {
                // If it doesn't have the closing `>` then it's definitely not an type argument list.
                return undefined;
            }
            // If we have a '<', then only parse this as a argument list if the type arguments
            // are complete and we have an open paren.  if we don't, rewind and return nothing.
            return typeArguments && canFollowTypeArgumentsInExpression()
                ? typeArguments
                : undefined;
        }
        function canFollowTypeArgumentsInExpression() {
            switch (token()) {
                case 20 /* OpenParenToken */: // foo<x>(
                case 14 /* NoSubstitutionTemplateLiteral */: // foo<T> `...`
                case 15 /* TemplateHead */: // foo<T> `...${100}...`
                // these are the only tokens can legally follow a type argument
                // list. So we definitely want to treat them as type arg lists.
                // falls through
                case 24 /* DotToken */: // foo<x>.
                case 21 /* CloseParenToken */: // foo<x>)
                case 23 /* CloseBracketToken */: // foo<x>]
                case 58 /* ColonToken */: // foo<x>:
                case 26 /* SemicolonToken */: // foo<x>;
                case 57 /* QuestionToken */: // foo<x>?
                case 34 /* EqualsEqualsToken */: // foo<x> ==
                case 36 /* EqualsEqualsEqualsToken */: // foo<x> ===
                case 35 /* ExclamationEqualsToken */: // foo<x> !=
                case 37 /* ExclamationEqualsEqualsToken */: // foo<x> !==
                case 55 /* AmpersandAmpersandToken */: // foo<x> &&
                case 56 /* BarBarToken */: // foo<x> ||
                case 60 /* QuestionQuestionToken */: // foo<x> ??
                case 52 /* CaretToken */: // foo<x> ^
                case 50 /* AmpersandToken */: // foo<x> &
                case 51 /* BarToken */: // foo<x> |
                case 19 /* CloseBraceToken */: // foo<x> }
                case 1 /* EndOfFileToken */: // foo<x>
                    // these cases can't legally follow a type arg list.  However, they're not legal
                    // expressions either.  The user is probably in the middle of a generic type. So
                    // treat it as such.
                    return true;
                case 27 /* CommaToken */: // foo<x>,
                case 18 /* OpenBraceToken */: // foo<x> {
                // We don't want to treat these as type arguments.  Otherwise we'll parse this
                // as an invocation expression.  Instead, we want to parse out the expression
                // in isolation from the type arguments.
                // falls through
                default:
                    // Anything else treat as an expression.
                    return false;
            }
        }
        function parsePrimaryExpression() {
            switch (token()) {
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    return parseLiteralNode();
                case 104 /* ThisKeyword */:
                case 102 /* SuperKeyword */:
                case 100 /* NullKeyword */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                    return parseTokenNode();
                case 20 /* OpenParenToken */:
                    return parseParenthesizedExpression();
                case 22 /* OpenBracketToken */:
                    return parseArrayLiteralExpression();
                case 18 /* OpenBraceToken */:
                    return parseObjectLiteralExpression();
                case 126 /* AsyncKeyword */:
                    // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
                    // If we encounter `async [no LineTerminator here] function` then this is an async
                    // function; otherwise, its an identifier.
                    if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
                        break;
                    }
                    return parseFunctionExpression();
                case 80 /* ClassKeyword */:
                    return parseClassExpression();
                case 94 /* FunctionKeyword */:
                    return parseFunctionExpression();
                case 99 /* NewKeyword */:
                    return parseNewExpressionOrNewDotTarget();
                case 43 /* SlashToken */:
                case 67 /* SlashEqualsToken */:
                    if (reScanSlashToken() === 13 /* RegularExpressionLiteral */) {
                        return parseLiteralNode();
                    }
                    break;
                case 15 /* TemplateHead */:
                    return parseTemplateExpression(/* isTaggedTemplate */ false);
            }
            return parseIdentifier(ts.Diagnostics.Expression_expected);
        }
        function parseParenthesizedExpression() {
            var node = createNodeWithJSDoc(200 /* ParenthesizedExpression */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseSpreadElement() {
            var node = createNode(213 /* SpreadElement */);
            parseExpected(25 /* DotDotDotToken */);
            node.expression = parseAssignmentExpressionOrHigher();
            return finishNode(node);
        }
        function parseArgumentOrArrayLiteralElement() {
            return token() === 25 /* DotDotDotToken */ ? parseSpreadElement() :
                token() === 27 /* CommaToken */ ? createNode(215 /* OmittedExpression */) :
                    parseAssignmentExpressionOrHigher();
        }
        function parseArgumentExpression() {
            return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
        }
        function parseArrayLiteralExpression() {
            var node = createNode(192 /* ArrayLiteralExpression */);
            parseExpected(22 /* OpenBracketToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseObjectLiteralElement() {
            var node = createNodeWithJSDoc(0 /* Unknown */);
            if (parseOptionalToken(25 /* DotDotDotToken */)) {
                node.kind = 283 /* SpreadAssignment */;
                node.expression = parseAssignmentExpressionOrHigher();
                return finishNode(node);
            }
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            if (parseContextualModifier(131 /* GetKeyword */)) {
                return parseAccessorDeclaration(node, 163 /* GetAccessor */);
            }
            if (parseContextualModifier(142 /* SetKeyword */)) {
                return parseAccessorDeclaration(node, 164 /* SetAccessor */);
            }
            var asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
            var tokenIsIdentifier = isIdentifier();
            node.name = parsePropertyName();
            // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker.
            node.questionToken = parseOptionalToken(57 /* QuestionToken */);
            node.exclamationToken = parseOptionalToken(53 /* ExclamationToken */);
            if (asteriskToken || token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                return parseMethodDeclaration(node, asteriskToken);
            }
            // check if it is short-hand property assignment or normal property assignment
            // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
            // CoverInitializedName[Yield] :
            //     IdentifierReference[?Yield] Initializer[In, ?Yield]
            // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
            var isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== 58 /* ColonToken */);
            if (isShorthandPropertyAssignment) {
                node.kind = 282 /* ShorthandPropertyAssignment */;
                var equalsToken = parseOptionalToken(62 /* EqualsToken */);
                if (equalsToken) {
                    node.equalsToken = equalsToken;
                    node.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
                }
            }
            else {
                node.kind = 281 /* PropertyAssignment */;
                parseExpected(58 /* ColonToken */);
                node.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
            }
            return finishNode(node);
        }
        function parseObjectLiteralExpression() {
            var node = createNode(193 /* ObjectLiteralExpression */);
            var openBracePosition = scanner.getTokenPos();
            parseExpected(18 /* OpenBraceToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true);
            if (!parseExpected(19 /* CloseBraceToken */)) {
                var lastError = ts.lastOrUndefined(parseDiagnostics);
                if (lastError && lastError.code === ts.Diagnostics._0_expected.code) {
                    ts.addRelatedInfo(lastError, ts.createFileDiagnostic(sourceFile, openBracePosition, 1, ts.Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here));
                }
            }
            return finishNode(node);
        }
        function parseFunctionExpression() {
            // GeneratorExpression:
            //      function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
            //
            // FunctionExpression:
            //      function BindingIdentifier[opt](FormalParameters){ FunctionBody }
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var node = createNodeWithJSDoc(201 /* FunctionExpression */);
            node.modifiers = parseModifiers();
            parseExpected(94 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = hasModifierOfKind(node, 126 /* AsyncKeyword */) ? 2 /* Await */ : 0 /* None */;
            node.name =
                isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
                    isGenerator ? doInYieldContext(parseOptionalIdentifier) :
                        isAsync ? doInAwaitContext(parseOptionalIdentifier) :
                            parseOptionalIdentifier();
            fillSignature(58 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlock(isGenerator | isAsync);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return finishNode(node);
        }
        function parseOptionalIdentifier() {
            return isIdentifier() ? parseIdentifier() : undefined;
        }
        function parseNewExpressionOrNewDotTarget() {
            var fullStart = scanner.getStartPos();
            parseExpected(99 /* NewKeyword */);
            if (parseOptional(24 /* DotToken */)) {
                var node_2 = createNode(219 /* MetaProperty */, fullStart);
                node_2.keywordToken = 99 /* NewKeyword */;
                node_2.name = parseIdentifierName();
                return finishNode(node_2);
            }
            var expression = parsePrimaryExpression();
            var typeArguments;
            while (true) {
                expression = parseMemberExpressionRest(expression, /*allowOptionalChain*/ false);
                typeArguments = tryParse(parseTypeArgumentsInExpression);
                if (isTemplateStartOfTaggedTemplate()) {
                    ts.Debug.assert(!!typeArguments, "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'");
                    expression = parseTaggedTemplateRest(expression, /*optionalChain*/ undefined, typeArguments);
                    typeArguments = undefined;
                }
                break;
            }
            var node = createNode(197 /* NewExpression */, fullStart);
            node.expression = expression;
            node.typeArguments = typeArguments;
            if (token() === 20 /* OpenParenToken */) {
                node.arguments = parseArgumentList();
            }
            else if (node.typeArguments) {
                parseErrorAt(fullStart, scanner.getStartPos(), ts.Diagnostics.A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list);
            }
            return finishNode(node);
        }
        // STATEMENTS
        function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
            var node = createNode(223 /* Block */);
            var openBracePosition = scanner.getTokenPos();
            if (parseExpected(18 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
                if (scanner.hasPrecedingLineBreak()) {
                    node.multiLine = true;
                }
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                if (!parseExpected(19 /* CloseBraceToken */)) {
                    var lastError = ts.lastOrUndefined(parseDiagnostics);
                    if (lastError && lastError.code === ts.Diagnostics._0_expected.code) {
                        ts.addRelatedInfo(lastError, ts.createFileDiagnostic(sourceFile, openBracePosition, 1, ts.Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here));
                    }
                }
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseFunctionBlock(flags, diagnosticMessage) {
            var savedYieldContext = inYieldContext();
            setYieldContext(!!(flags & 1 /* Yield */));
            var savedAwaitContext = inAwaitContext();
            setAwaitContext(!!(flags & 2 /* Await */));
            // We may be in a [Decorator] context when parsing a function expression or
            // arrow function. The body of the function is not in [Decorator] context.
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var block = parseBlock(!!(flags & 16 /* IgnoreMissingOpenBrace */), diagnosticMessage);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            setYieldContext(savedYieldContext);
            setAwaitContext(savedAwaitContext);
            return block;
        }
        function parseEmptyStatement() {
            var node = createNode(224 /* EmptyStatement */);
            parseExpected(26 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseIfStatement() {
            var node = createNode(227 /* IfStatement */);
            parseExpected(95 /* IfKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.thenStatement = parseStatement();
            node.elseStatement = parseOptional(87 /* ElseKeyword */) ? parseStatement() : undefined;
            return finishNode(node);
        }
        function parseDoStatement() {
            var node = createNode(228 /* DoStatement */);
            parseExpected(86 /* DoKeyword */);
            node.statement = parseStatement();
            parseExpected(111 /* WhileKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
            // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
            // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
            //  do;while(0)x will have a semicolon inserted before x.
            parseOptional(26 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseWhileStatement() {
            var node = createNode(229 /* WhileStatement */);
            parseExpected(111 /* WhileKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.statement = parseStatement();
            return finishNode(node);
        }
        function parseForOrForInOrForOfStatement() {
            var pos = getNodePos();
            parseExpected(93 /* ForKeyword */);
            var awaitToken = parseOptionalToken(127 /* AwaitKeyword */);
            parseExpected(20 /* OpenParenToken */);
            var initializer;
            if (token() !== 26 /* SemicolonToken */) {
                if (token() === 109 /* VarKeyword */ || token() === 115 /* LetKeyword */ || token() === 81 /* ConstKeyword */) {
                    initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
                }
                else {
                    initializer = disallowInAnd(parseExpression);
                }
            }
            var forOrForInOrForOfStatement;
            if (awaitToken ? parseExpected(152 /* OfKeyword */) : parseOptional(152 /* OfKeyword */)) {
                var forOfStatement = createNode(232 /* ForOfStatement */, pos);
                forOfStatement.awaitModifier = awaitToken;
                forOfStatement.initializer = initializer;
                forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forOfStatement;
            }
            else if (parseOptional(97 /* InKeyword */)) {
                var forInStatement = createNode(231 /* ForInStatement */, pos);
                forInStatement.initializer = initializer;
                forInStatement.expression = allowInAnd(parseExpression);
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forInStatement;
            }
            else {
                var forStatement = createNode(230 /* ForStatement */, pos);
                forStatement.initializer = initializer;
                parseExpected(26 /* SemicolonToken */);
                if (token() !== 26 /* SemicolonToken */ && token() !== 21 /* CloseParenToken */) {
                    forStatement.condition = allowInAnd(parseExpression);
                }
                parseExpected(26 /* SemicolonToken */);
                if (token() !== 21 /* CloseParenToken */) {
                    forStatement.incrementor = allowInAnd(parseExpression);
                }
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forStatement;
            }
            forOrForInOrForOfStatement.statement = parseStatement();
            return finishNode(forOrForInOrForOfStatement);
        }
        function parseBreakOrContinueStatement(kind) {
            var node = createNode(kind);
            parseExpected(kind === 234 /* BreakStatement */ ? 77 /* BreakKeyword */ : 82 /* ContinueKeyword */);
            if (!canParseSemicolon()) {
                node.label = parseIdentifier();
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseReturnStatement() {
            var node = createNode(235 /* ReturnStatement */);
            parseExpected(101 /* ReturnKeyword */);
            if (!canParseSemicolon()) {
                node.expression = allowInAnd(parseExpression);
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseWithStatement() {
            var node = createNode(236 /* WithStatement */);
            parseExpected(112 /* WithKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.statement = doInsideOfContext(16777216 /* InWithStatement */, parseStatement);
            return finishNode(node);
        }
        function parseCaseClause() {
            var node = createNode(277 /* CaseClause */);
            parseExpected(78 /* CaseKeyword */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(58 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseDefaultClause() {
            var node = createNode(278 /* DefaultClause */);
            parseExpected(84 /* DefaultKeyword */);
            parseExpected(58 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseCaseOrDefaultClause() {
            return token() === 78 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
        }
        function parseSwitchStatement() {
            var node = createNode(237 /* SwitchStatement */);
            parseExpected(103 /* SwitchKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            var caseBlock = createNode(251 /* CaseBlock */);
            parseExpected(18 /* OpenBraceToken */);
            caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
            parseExpected(19 /* CloseBraceToken */);
            node.caseBlock = finishNode(caseBlock);
            return finishNode(node);
        }
        function parseThrowStatement() {
            // ThrowStatement[Yield] :
            //      throw [no LineTerminator here]Expression[In, ?Yield];
            // Because of automatic semicolon insertion, we need to report error if this
            // throw could be terminated with a semicolon.  Note: we can't call 'parseExpression'
            // directly as that might consume an expression on the following line.
            // We just return 'undefined' in that case.  The actual error will be reported in the
            // grammar walker.
            var node = createNode(239 /* ThrowStatement */);
            parseExpected(105 /* ThrowKeyword */);
            node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
            parseSemicolon();
            return finishNode(node);
        }
        // TODO: Review for error recovery
        function parseTryStatement() {
            var node = createNode(240 /* TryStatement */);
            parseExpected(107 /* TryKeyword */);
            node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            node.catchClause = token() === 79 /* CatchKeyword */ ? parseCatchClause() : undefined;
            // If we don't have a catch clause, then we must have a finally clause.  Try to parse
            // one out no matter what.
            if (!node.catchClause || token() === 92 /* FinallyKeyword */) {
                parseExpected(92 /* FinallyKeyword */);
                node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            }
            return finishNode(node);
        }
        function parseCatchClause() {
            var result = createNode(280 /* CatchClause */);
            parseExpected(79 /* CatchKeyword */);
            if (parseOptional(20 /* OpenParenToken */)) {
                result.variableDeclaration = parseVariableDeclaration();
                parseExpected(21 /* CloseParenToken */);
            }
            else {
                // Keep shape of node to avoid degrading performance.
                result.variableDeclaration = undefined;
            }
            result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
            return finishNode(result);
        }
        function parseDebuggerStatement() {
            var node = createNode(241 /* DebuggerStatement */);
            parseExpected(83 /* DebuggerKeyword */);
            parseSemicolon();
            return finishNode(node);
        }
        function parseExpressionOrLabeledStatement() {
            // Avoiding having to do the lookahead for a labeled statement by just trying to parse
            // out an expression, seeing if it is identifier and then seeing if it is followed by
            // a colon.
            var node = createNodeWithJSDoc(token() === 75 /* Identifier */ ? 0 /* Unknown */ : 226 /* ExpressionStatement */);
            var expression = allowInAnd(parseExpression);
            if (expression.kind === 75 /* Identifier */ && parseOptional(58 /* ColonToken */)) {
                node.kind = 238 /* LabeledStatement */;
                node.label = expression;
                node.statement = parseStatement();
            }
            else {
                node.kind = 226 /* ExpressionStatement */;
                node.expression = expression;
                parseSemicolon();
            }
            return finishNode(node);
        }
        function nextTokenIsIdentifierOrKeywordOnSameLine() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsClassKeywordOnSameLine() {
            nextToken();
            return token() === 80 /* ClassKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsFunctionKeywordOnSameLine() {
            nextToken();
            return token() === 94 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() {
            nextToken();
            return (ts.tokenIsIdentifierOrKeyword(token()) || token() === 8 /* NumericLiteral */ || token() === 9 /* BigIntLiteral */ || token() === 10 /* StringLiteral */) && !scanner.hasPrecedingLineBreak();
        }
        function isDeclaration() {
            while (true) {
                switch (token()) {
                    case 109 /* VarKeyword */:
                    case 115 /* LetKeyword */:
                    case 81 /* ConstKeyword */:
                    case 94 /* FunctionKeyword */:
                    case 80 /* ClassKeyword */:
                    case 88 /* EnumKeyword */:
                        return true;
                    // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
                    // however, an identifier cannot be followed by another identifier on the same line. This is what we
                    // count on to parse out the respective declarations. For instance, we exploit this to say that
                    //
                    //    namespace n
                    //
                    // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
                    //
                    //    namespace
                    //    n
                    //
                    // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
                    // We need to look one token ahead to see if it permissible to try parsing a declaration.
                    //
                    // *Note*: 'interface' is actually a strict mode reserved word. So while
                    //
                    //   "use strict"
                    //   interface
                    //   I {}
                    //
                    // could be legal, it would add complexity for very little gain.
                    case 114 /* InterfaceKeyword */:
                    case 145 /* TypeKeyword */:
                        return nextTokenIsIdentifierOnSameLine();
                    case 135 /* ModuleKeyword */:
                    case 136 /* NamespaceKeyword */:
                        return nextTokenIsIdentifierOrStringLiteralOnSameLine();
                    case 122 /* AbstractKeyword */:
                    case 126 /* AsyncKeyword */:
                    case 130 /* DeclareKeyword */:
                    case 117 /* PrivateKeyword */:
                    case 118 /* ProtectedKeyword */:
                    case 119 /* PublicKeyword */:
                    case 138 /* ReadonlyKeyword */:
                        nextToken();
                        // ASI takes effect for this modifier.
                        if (scanner.hasPrecedingLineBreak()) {
                            return false;
                        }
                        continue;
                    case 150 /* GlobalKeyword */:
                        nextToken();
                        return token() === 18 /* OpenBraceToken */ || token() === 75 /* Identifier */ || token() === 89 /* ExportKeyword */;
                    case 96 /* ImportKeyword */:
                        nextToken();
                        return token() === 10 /* StringLiteral */ || token() === 41 /* AsteriskToken */ ||
                            token() === 18 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token());
                    case 89 /* ExportKeyword */:
                        var currentToken_1 = nextToken();
                        if (currentToken_1 === 145 /* TypeKeyword */) {
                            currentToken_1 = lookAhead(nextToken);
                        }
                        if (currentToken_1 === 62 /* EqualsToken */ || currentToken_1 === 41 /* AsteriskToken */ ||
                            currentToken_1 === 18 /* OpenBraceToken */ || currentToken_1 === 84 /* DefaultKeyword */ ||
                            currentToken_1 === 123 /* AsKeyword */) {
                            return true;
                        }
                        continue;
                    case 120 /* StaticKeyword */:
                        nextToken();
                        continue;
                    default:
                        return false;
                }
            }
        }
        function isStartOfDeclaration() {
            return lookAhead(isDeclaration);
        }
        function isStartOfStatement() {
            switch (token()) {
                case 59 /* AtToken */:
                case 26 /* SemicolonToken */:
                case 18 /* OpenBraceToken */:
                case 109 /* VarKeyword */:
                case 115 /* LetKeyword */:
                case 94 /* FunctionKeyword */:
                case 80 /* ClassKeyword */:
                case 88 /* EnumKeyword */:
                case 95 /* IfKeyword */:
                case 86 /* DoKeyword */:
                case 111 /* WhileKeyword */:
                case 93 /* ForKeyword */:
                case 82 /* ContinueKeyword */:
                case 77 /* BreakKeyword */:
                case 101 /* ReturnKeyword */:
                case 112 /* WithKeyword */:
                case 103 /* SwitchKeyword */:
                case 105 /* ThrowKeyword */:
                case 107 /* TryKeyword */:
                case 83 /* DebuggerKeyword */:
                // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
                // however, we say they are here so that we may gracefully parse them and error later.
                // falls through
                case 79 /* CatchKeyword */:
                case 92 /* FinallyKeyword */:
                    return true;
                case 96 /* ImportKeyword */:
                    return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
                case 81 /* ConstKeyword */:
                case 89 /* ExportKeyword */:
                    return isStartOfDeclaration();
                case 126 /* AsyncKeyword */:
                case 130 /* DeclareKeyword */:
                case 114 /* InterfaceKeyword */:
                case 135 /* ModuleKeyword */:
                case 136 /* NamespaceKeyword */:
                case 145 /* TypeKeyword */:
                case 150 /* GlobalKeyword */:
                    // When these don't start a declaration, they're an identifier in an expression statement
                    return true;
                case 119 /* PublicKeyword */:
                case 117 /* PrivateKeyword */:
                case 118 /* ProtectedKeyword */:
                case 120 /* StaticKeyword */:
                case 138 /* ReadonlyKeyword */:
                    // When these don't start a declaration, they may be the start of a class member if an identifier
                    // immediately follows. Otherwise they're an identifier in an expression statement.
                    return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
                default:
                    return isStartOfExpression();
            }
        }
        function nextTokenIsIdentifierOrStartOfDestructuring() {
            nextToken();
            return isIdentifier() || token() === 18 /* OpenBraceToken */ || token() === 22 /* OpenBracketToken */;
        }
        function isLetDeclaration() {
            // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
            // or [.
            return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
        }
        function parseStatement() {
            switch (token()) {
                case 26 /* SemicolonToken */:
                    return parseEmptyStatement();
                case 18 /* OpenBraceToken */:
                    return parseBlock(/*ignoreMissingOpenBrace*/ false);
                case 109 /* VarKeyword */:
                    return parseVariableStatement(createNodeWithJSDoc(242 /* VariableDeclaration */));
                case 115 /* LetKeyword */:
                    if (isLetDeclaration()) {
                        return parseVariableStatement(createNodeWithJSDoc(242 /* VariableDeclaration */));
                    }
                    break;
                case 94 /* FunctionKeyword */:
                    return parseFunctionDeclaration(createNodeWithJSDoc(244 /* FunctionDeclaration */));
                case 80 /* ClassKeyword */:
                    return parseClassDeclaration(createNodeWithJSDoc(245 /* ClassDeclaration */));
                case 95 /* IfKeyword */:
                    return parseIfStatement();
                case 86 /* DoKeyword */:
                    return parseDoStatement();
                case 111 /* WhileKeyword */:
                    return parseWhileStatement();
                case 93 /* ForKeyword */:
                    return parseForOrForInOrForOfStatement();
                case 82 /* ContinueKeyword */:
                    return parseBreakOrContinueStatement(233 /* ContinueStatement */);
                case 77 /* BreakKeyword */:
                    return parseBreakOrContinueStatement(234 /* BreakStatement */);
                case 101 /* ReturnKeyword */:
                    return parseReturnStatement();
                case 112 /* WithKeyword */:
                    return parseWithStatement();
                case 103 /* SwitchKeyword */:
                    return parseSwitchStatement();
                case 105 /* ThrowKeyword */:
                    return parseThrowStatement();
                case 107 /* TryKeyword */:
                // Include 'catch' and 'finally' for error recovery.
                // falls through
                case 79 /* CatchKeyword */:
                case 92 /* FinallyKeyword */:
                    return parseTryStatement();
                case 83 /* DebuggerKeyword */:
                    return parseDebuggerStatement();
                case 59 /* AtToken */:
                    return parseDeclaration();
                case 126 /* AsyncKeyword */:
                case 114 /* InterfaceKeyword */:
                case 145 /* TypeKeyword */:
                case 135 /* ModuleKeyword */:
                case 136 /* NamespaceKeyword */:
                case 130 /* DeclareKeyword */:
                case 81 /* ConstKeyword */:
                case 88 /* EnumKeyword */:
                case 89 /* ExportKeyword */:
                case 96 /* ImportKeyword */:
                case 117 /* PrivateKeyword */:
                case 118 /* ProtectedKeyword */:
                case 119 /* PublicKeyword */:
                case 122 /* AbstractKeyword */:
                case 120 /* StaticKeyword */:
                case 138 /* ReadonlyKeyword */:
                case 150 /* GlobalKeyword */:
                    if (isStartOfDeclaration()) {
                        return parseDeclaration();
                    }
                    break;
            }
            return parseExpressionOrLabeledStatement();
        }
        function isDeclareModifier(modifier) {
            return modifier.kind === 130 /* DeclareKeyword */;
        }
        function parseDeclaration() {
            var modifiers = lookAhead(function () { return (parseDecorators(), parseModifiers()); });
            // `parseListElement` attempted to get the reused node at this position,
            // but the ambient context flag was not yet set, so the node appeared
            // not reusable in that context.
            var isAmbient = ts.some(modifiers, isDeclareModifier);
            if (isAmbient) {
                var node_3 = tryReuseAmbientDeclaration();
                if (node_3) {
                    return node_3;
                }
            }
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            if (isAmbient) {
                for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                    var m = _a[_i];
                    m.flags |= 8388608 /* Ambient */;
                }
                return doInsideOfContext(8388608 /* Ambient */, function () { return parseDeclarationWorker(node); });
            }
            else {
                return parseDeclarationWorker(node);
            }
        }
        function tryReuseAmbientDeclaration() {
            return doInsideOfContext(8388608 /* Ambient */, function () {
                var node = currentNode(parsingContext);
                if (node) {
                    return consumeNode(node);
                }
            });
        }
        function parseDeclarationWorker(node) {
            switch (token()) {
                case 109 /* VarKeyword */:
                case 115 /* LetKeyword */:
                case 81 /* ConstKeyword */:
                    return parseVariableStatement(node);
                case 94 /* FunctionKeyword */:
                    return parseFunctionDeclaration(node);
                case 80 /* ClassKeyword */:
                    return parseClassDeclaration(node);
                case 114 /* InterfaceKeyword */:
                    return parseInterfaceDeclaration(node);
                case 145 /* TypeKeyword */:
                    return parseTypeAliasDeclaration(node);
                case 88 /* EnumKeyword */:
                    return parseEnumDeclaration(node);
                case 150 /* GlobalKeyword */:
                case 135 /* ModuleKeyword */:
                case 136 /* NamespaceKeyword */:
                    return parseModuleDeclaration(node);
                case 96 /* ImportKeyword */:
                    return parseImportDeclarationOrImportEqualsDeclaration(node);
                case 89 /* ExportKeyword */:
                    nextToken();
                    switch (token()) {
                        case 84 /* DefaultKeyword */:
                        case 62 /* EqualsToken */:
                            return parseExportAssignment(node);
                        case 123 /* AsKeyword */:
                            return parseNamespaceExportDeclaration(node);
                        default:
                            return parseExportDeclaration(node);
                    }
                default:
                    if (node.decorators || node.modifiers) {
                        // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
                        // would follow. For recovery and error reporting purposes, return an incomplete declaration.
                        var missing = createMissingNode(264 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                        missing.pos = node.pos;
                        missing.decorators = node.decorators;
                        missing.modifiers = node.modifiers;
                        return finishNode(missing);
                    }
                    return undefined; // TODO: GH#18217
            }
        }
        function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === 10 /* StringLiteral */);
        }
        function parseFunctionBlockOrSemicolon(flags, diagnosticMessage) {
            if (token() !== 18 /* OpenBraceToken */ && canParseSemicolon()) {
                parseSemicolon();
                return;
            }
            return parseFunctionBlock(flags, diagnosticMessage);
        }
        // DECLARATIONS
        function parseArrayBindingElement() {
            if (token() === 27 /* CommaToken */) {
                return createNode(215 /* OmittedExpression */);
            }
            var node = createNode(191 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            node.name = parseIdentifierOrPattern();
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        function parseObjectBindingElement() {
            var node = createNode(191 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            var tokenIsIdentifier = isIdentifier();
            var propertyName = parsePropertyName();
            if (tokenIsIdentifier && token() !== 58 /* ColonToken */) {
                node.name = propertyName;
            }
            else {
                parseExpected(58 /* ColonToken */);
                node.propertyName = propertyName;
                node.name = parseIdentifierOrPattern();
            }
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        function parseObjectBindingPattern() {
            var node = createNode(189 /* ObjectBindingPattern */);
            parseExpected(18 /* OpenBraceToken */);
            node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseArrayBindingPattern() {
            var node = createNode(190 /* ArrayBindingPattern */);
            parseExpected(22 /* OpenBracketToken */);
            node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function isIdentifierOrPrivateIdentifierOrPattern() {
            return token() === 18 /* OpenBraceToken */
                || token() === 22 /* OpenBracketToken */
                || token() === 76 /* PrivateIdentifier */
                || isIdentifier();
        }
        function parseIdentifierOrPattern(privateIdentifierDiagnosticMessage) {
            if (token() === 22 /* OpenBracketToken */) {
                return parseArrayBindingPattern();
            }
            if (token() === 18 /* OpenBraceToken */) {
                return parseObjectBindingPattern();
            }
            return parseIdentifier(/*diagnosticMessage*/ undefined, privateIdentifierDiagnosticMessage);
        }
        function parseVariableDeclarationAllowExclamation() {
            return parseVariableDeclaration(/*allowExclamation*/ true);
        }
        function parseVariableDeclaration(allowExclamation) {
            var node = createNode(242 /* VariableDeclaration */);
            node.name = parseIdentifierOrPattern(ts.Diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations);
            if (allowExclamation && node.name.kind === 75 /* Identifier */ &&
                token() === 53 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                node.exclamationToken = parseTokenNode();
            }
            node.type = parseTypeAnnotation();
            if (!isInOrOfKeyword(token())) {
                node.initializer = parseInitializer();
            }
            return finishNode(node);
        }
        function parseVariableDeclarationList(inForStatementInitializer) {
            var node = createNode(243 /* VariableDeclarationList */);
            switch (token()) {
                case 109 /* VarKeyword */:
                    break;
                case 115 /* LetKeyword */:
                    node.flags |= 1 /* Let */;
                    break;
                case 81 /* ConstKeyword */:
                    node.flags |= 2 /* Const */;
                    break;
                default:
                    ts.Debug.fail();
            }
            nextToken();
            // The user may have written the following:
            //
            //    for (let of X) { }
            //
            // In this case, we want to parse an empty declaration list, and then parse 'of'
            // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
            // So we need to look ahead to determine if 'of' should be treated as a keyword in
            // this context.
            // The checker will then give an error that there is an empty declaration list.
            if (token() === 152 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
                node.declarations = createMissingList();
            }
            else {
                var savedDisallowIn = inDisallowInContext();
                setDisallowInContext(inForStatementInitializer);
                node.declarations = parseDelimitedList(8 /* VariableDeclarations */, inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation);
                setDisallowInContext(savedDisallowIn);
            }
            return finishNode(node);
        }
        function canFollowContextualOfKeyword() {
            return nextTokenIsIdentifier() && nextToken() === 21 /* CloseParenToken */;
        }
        function parseVariableStatement(node) {
            node.kind = 225 /* VariableStatement */;
            node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
            parseSemicolon();
            return finishNode(node);
        }
        function parseFunctionDeclaration(node) {
            node.kind = 244 /* FunctionDeclaration */;
            parseExpected(94 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
            node.name = hasModifierOfKind(node, 84 /* DefaultKeyword */) ? parseOptionalIdentifier() : parseIdentifier();
            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = hasModifierOfKind(node, 126 /* AsyncKeyword */) ? 2 /* Await */ : 0 /* None */;
            fillSignature(58 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, ts.Diagnostics.or_expected);
            return finishNode(node);
        }
        function parseConstructorName() {
            if (token() === 129 /* ConstructorKeyword */) {
                return parseExpected(129 /* ConstructorKeyword */);
            }
            if (token() === 10 /* StringLiteral */ && lookAhead(nextToken) === 20 /* OpenParenToken */) {
                return tryParse(function () {
                    var literalNode = parseLiteralNode();
                    return literalNode.text === "constructor" ? literalNode : undefined;
                });
            }
        }
        function tryParseConstructorDeclaration(node) {
            return tryParse(function () {
                if (parseConstructorName()) {
                    node.kind = 162 /* Constructor */;
                    fillSignature(58 /* ColonToken */, 0 /* None */, node);
                    node.body = parseFunctionBlockOrSemicolon(0 /* None */, ts.Diagnostics.or_expected);
                    return finishNode(node);
                }
            });
        }
        function parseMethodDeclaration(node, asteriskToken, diagnosticMessage) {
            node.kind = 161 /* MethodDeclaration */;
            node.asteriskToken = asteriskToken;
            var isGenerator = asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = hasModifierOfKind(node, 126 /* AsyncKeyword */) ? 2 /* Await */ : 0 /* None */;
            fillSignature(58 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage);
            return finishNode(node);
        }
        function parsePropertyDeclaration(node) {
            node.kind = 159 /* PropertyDeclaration */;
            if (!node.questionToken && token() === 53 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                node.exclamationToken = parseTokenNode();
            }
            node.type = parseTypeAnnotation();
            node.initializer = doOutsideOfContext(8192 /* YieldContext */ | 32768 /* AwaitContext */ | 4096 /* DisallowInContext */, parseInitializer);
            parseSemicolon();
            return finishNode(node);
        }
        function parsePropertyOrMethodDeclaration(node) {
            var asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
            node.name = parsePropertyName();
            // Note: this is not legal as per the grammar.  But we allow it in the parser and
            // report an error in the grammar checker.
            node.questionToken = parseOptionalToken(57 /* QuestionToken */);
            if (asteriskToken || token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                return parseMethodDeclaration(node, asteriskToken, ts.Diagnostics.or_expected);
            }
            return parsePropertyDeclaration(node);
        }
        function parseAccessorDeclaration(node, kind) {
            node.kind = kind;
            node.name = parsePropertyName();
            fillSignature(58 /* ColonToken */, 0 /* None */, node);
            node.body = parseFunctionBlockOrSemicolon(0 /* None */);
            return finishNode(node);
        }
        function isClassMemberStart() {
            var idToken;
            if (token() === 59 /* AtToken */) {
                return true;
            }
            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
            while (ts.isModifierKind(token())) {
                idToken = token();
                // If the idToken is a class modifier (protected, private, public, and static), it is
                // certain that we are starting to parse class member. This allows better error recovery
                // Example:
                //      public foo() ...     // true
                //      public @dec blah ... // true; we will then report an error later
                //      export public ...    // true; we will then report an error later
                if (ts.isClassMemberModifier(idToken)) {
                    return true;
                }
                nextToken();
            }
            if (token() === 41 /* AsteriskToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers.
            // This can either be an identifier or the 'get' or 'set' keywords.
            if (isLiteralPropertyName()) {
                idToken = token();
                nextToken();
            }
            // Index signatures and computed properties are class members; we can parse.
            if (token() === 22 /* OpenBracketToken */) {
                return true;
            }
            // If we were able to get any potential identifier...
            if (idToken !== undefined) {
                // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
                if (!ts.isKeyword(idToken) || idToken === 142 /* SetKeyword */ || idToken === 131 /* GetKeyword */) {
                    return true;
                }
                // If it *is* a keyword, but not an accessor, check a little farther along
                // to see if it should actually be parsed as a class member.
                switch (token()) {
                    case 20 /* OpenParenToken */: // Method declaration
                    case 29 /* LessThanToken */: // Generic Method declaration
                    case 53 /* ExclamationToken */: // Non-null assertion on property name
                    case 58 /* ColonToken */: // Type Annotation for declaration
                    case 62 /* EqualsToken */: // Initializer for declaration
                    case 57 /* QuestionToken */: // Not valid, but permitted so that it gets caught later on.
                        return true;
                    default:
                        // Covers
                        //  - Semicolons     (declaration termination)
                        //  - Closing braces (end-of-class, must be declaration)
                        //  - End-of-files   (not valid, but permitted so that it gets caught later on)
                        //  - Line-breaks    (enabling *automatic semicolon insertion*)
                        return canParseSemicolon();
                }
            }
            return false;
        }
        function parseDecorators() {
            var list;
            var listPos = getNodePos();
            while (true) {
                var decoratorStart = getNodePos();
                if (!parseOptional(59 /* AtToken */)) {
                    break;
                }
                var decorator = createNode(157 /* Decorator */, decoratorStart);
                decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
                finishNode(decorator);
                (list || (list = [])).push(decorator);
            }
            return list && createNodeArray(list, listPos);
        }
        /*
         * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member.
         * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect
         * and turns it into a standalone declaration), then it is better to parse it and report an error later.
         *
         * In such situations, 'permitInvalidConstAsModifier' should be set to true.
         */
        function parseModifiers(permitInvalidConstAsModifier) {
            var list;
            var listPos = getNodePos();
            while (true) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token();
                if (token() === 81 /* ConstKeyword */ && permitInvalidConstAsModifier) {
                    // We need to ensure that any subsequent modifiers appear on the same line
                    // so that when 'const' is a standalone declaration, we don't issue an error.
                    if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) {
                        break;
                    }
                }
                else {
                    if (!parseAnyContextualModifier()) {
                        break;
                    }
                }
                var modifier = finishNode(createNode(modifierKind, modifierStart));
                (list || (list = [])).push(modifier);
            }
            return list && createNodeArray(list, listPos);
        }
        function parseModifiersForArrowFunction() {
            var modifiers;
            if (token() === 126 /* AsyncKeyword */) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token();
                nextToken();
                var modifier = finishNode(createNode(modifierKind, modifierStart));
                modifiers = createNodeArray([modifier], modifierStart);
            }
            return modifiers;
        }
        function parseClassElement() {
            if (token() === 26 /* SemicolonToken */) {
                var result = createNode(222 /* SemicolonClassElement */);
                nextToken();
                return finishNode(result);
            }
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true);
            if (parseContextualModifier(131 /* GetKeyword */)) {
                return parseAccessorDeclaration(node, 163 /* GetAccessor */);
            }
            if (parseContextualModifier(142 /* SetKeyword */)) {
                return parseAccessorDeclaration(node, 164 /* SetAccessor */);
            }
            if (token() === 129 /* ConstructorKeyword */ || token() === 10 /* StringLiteral */) {
                var constructorDeclaration = tryParseConstructorDeclaration(node);
                if (constructorDeclaration) {
                    return constructorDeclaration;
                }
            }
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(node);
            }
            // It is very important that we check this *after* checking indexers because
            // the [ token can start an index signature or a computed property name
            if (ts.tokenIsIdentifierOrKeyword(token()) ||
                token() === 10 /* StringLiteral */ ||
                token() === 8 /* NumericLiteral */ ||
                token() === 41 /* AsteriskToken */ ||
                token() === 22 /* OpenBracketToken */) {
                var isAmbient = node.modifiers && ts.some(node.modifiers, isDeclareModifier);
                if (isAmbient) {
                    for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                        var m = _a[_i];
                        m.flags |= 8388608 /* Ambient */;
                    }
                    return doInsideOfContext(8388608 /* Ambient */, function () { return parsePropertyOrMethodDeclaration(node); });
                }
                else {
                    return parsePropertyOrMethodDeclaration(node);
                }
            }
            if (node.decorators || node.modifiers) {
                // treat this as a property declaration with a missing name.
                node.name = createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                return parsePropertyDeclaration(node);
            }
            // 'isClassMemberStart' should have hinted not to attempt parsing.
            return ts.Debug.fail("Should not have attempted to parse class member declaration.");
        }
        function parseClassExpression() {
            return parseClassDeclarationOrExpression(createNodeWithJSDoc(0 /* Unknown */), 214 /* ClassExpression */);
        }
        function parseClassDeclaration(node) {
            return parseClassDeclarationOrExpression(node, 245 /* ClassDeclaration */);
        }
        function parseClassDeclarationOrExpression(node, kind) {
            node.kind = kind;
            parseExpected(80 /* ClassKeyword */);
            node.name = parseNameOfClassDeclarationOrExpression();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses();
            if (parseExpected(18 /* OpenBraceToken */)) {
                // ClassTail[Yield,Await] : (Modified) See 14.5
                //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
                node.members = parseClassMembers();
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return finishNode(node);
        }
        function parseNameOfClassDeclarationOrExpression() {
            // implements is a future reserved word so
            // 'class implements' might mean either
            // - class expression with omitted name, 'implements' starts heritage clause
            // - class with name 'implements'
            // 'isImplementsClause' helps to disambiguate between these two cases
            return isIdentifier() && !isImplementsClause()
                ? parseIdentifier()
                : undefined;
        }
        function isImplementsClause() {
            return token() === 113 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
        }
        function parseHeritageClauses() {
            // ClassTail[Yield,Await] : (Modified) See 14.5
            //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
            if (isHeritageClause()) {
                return parseList(22 /* HeritageClauses */, parseHeritageClause);
            }
            return undefined;
        }
        function parseHeritageClause() {
            var tok = token();
            ts.Debug.assert(tok === 90 /* ExtendsKeyword */ || tok === 113 /* ImplementsKeyword */); // isListElement() should ensure this.
            var node = createNode(279 /* HeritageClause */);
            node.token = tok;
            nextToken();
            node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
            return finishNode(node);
        }
        function parseExpressionWithTypeArguments() {
            var node = createNode(216 /* ExpressionWithTypeArguments */);
            node.expression = parseLeftHandSideExpressionOrHigher();
            node.typeArguments = tryParseTypeArguments();
            return finishNode(node);
        }
        function tryParseTypeArguments() {
            return token() === 29 /* LessThanToken */ ?
                parseBracketedList(20 /* TypeArguments */, parseType, 29 /* LessThanToken */, 31 /* GreaterThanToken */) : undefined;
        }
        function isHeritageClause() {
            return token() === 90 /* ExtendsKeyword */ || token() === 113 /* ImplementsKeyword */;
        }
        function parseClassMembers() {
            return parseList(5 /* ClassMembers */, parseClassElement);
        }
        function parseInterfaceDeclaration(node) {
            node.kind = 246 /* InterfaceDeclaration */;
            parseExpected(114 /* InterfaceKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses();
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseTypeAliasDeclaration(node) {
            node.kind = 247 /* TypeAliasDeclaration */;
            parseExpected(145 /* TypeKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            parseExpected(62 /* EqualsToken */);
            node.type = parseType();
            parseSemicolon();
            return finishNode(node);
        }
        // In an ambient declaration, the grammar only allows integer literals as initializers.
        // In a non-ambient declaration, the grammar allows uninitialized members only in a
        // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
        // or any time an integer literal initializer is encountered.
        function parseEnumMember() {
            var node = createNodeWithJSDoc(284 /* EnumMember */);
            node.name = parsePropertyName();
            node.initializer = allowInAnd(parseInitializer);
            return finishNode(node);
        }
        function parseEnumDeclaration(node) {
            node.kind = 248 /* EnumDeclaration */;
            parseExpected(88 /* EnumKeyword */);
            node.name = parseIdentifier();
            if (parseExpected(18 /* OpenBraceToken */)) {
                node.members = doOutsideOfYieldAndAwaitContext(function () { return parseDelimitedList(6 /* EnumMembers */, parseEnumMember); });
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleBlock() {
            var node = createNode(250 /* ModuleBlock */);
            if (parseExpected(18 /* OpenBraceToken */)) {
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleOrNamespaceDeclaration(node, flags) {
            node.kind = 249 /* ModuleDeclaration */;
            // If we are parsing a dotted namespace name, we want to
            // propagate the 'Namespace' flag across the names if set.
            var namespaceFlag = flags & 16 /* Namespace */;
            node.flags |= flags;
            node.name = parseIdentifier();
            node.body = parseOptional(24 /* DotToken */)
                ? parseModuleOrNamespaceDeclaration(createNode(0 /* Unknown */), 4 /* NestedNamespace */ | namespaceFlag)
                : parseModuleBlock();
            return finishNode(node);
        }
        function parseAmbientExternalModuleDeclaration(node) {
            node.kind = 249 /* ModuleDeclaration */;
            if (token() === 150 /* GlobalKeyword */) {
                // parse 'global' as name of global scope augmentation
                node.name = parseIdentifier();
                node.flags |= 1024 /* GlobalAugmentation */;
            }
            else {
                node.name = parseLiteralNode();
                node.name.text = internIdentifier(node.name.text);
            }
            if (token() === 18 /* OpenBraceToken */) {
                node.body = parseModuleBlock();
            }
            else {
                parseSemicolon();
            }
            return finishNode(node);
        }
        function parseModuleDeclaration(node) {
            var flags = 0;
            if (token() === 150 /* GlobalKeyword */) {
                // global augmentation
                return parseAmbientExternalModuleDeclaration(node);
            }
            else if (parseOptional(136 /* NamespaceKeyword */)) {
                flags |= 16 /* Namespace */;
            }
            else {
                parseExpected(135 /* ModuleKeyword */);
                if (token() === 10 /* StringLiteral */) {
                    return parseAmbientExternalModuleDeclaration(node);
                }
            }
            return parseModuleOrNamespaceDeclaration(node, flags);
        }
        function isExternalModuleReference() {
            return token() === 139 /* RequireKeyword */ &&
                lookAhead(nextTokenIsOpenParen);
        }
        function nextTokenIsOpenParen() {
            return nextToken() === 20 /* OpenParenToken */;
        }
        function nextTokenIsSlash() {
            return nextToken() === 43 /* SlashToken */;
        }
        function parseNamespaceExportDeclaration(node) {
            node.kind = 252 /* NamespaceExportDeclaration */;
            parseExpected(123 /* AsKeyword */);
            parseExpected(136 /* NamespaceKeyword */);
            node.name = parseIdentifier();
            parseSemicolon();
            return finishNode(node);
        }
        function parseImportDeclarationOrImportEqualsDeclaration(node) {
            parseExpected(96 /* ImportKeyword */);
            var afterImportPos = scanner.getStartPos();
            var identifier;
            if (isIdentifier()) {
                identifier = parseIdentifier();
            }
            var isTypeOnly = false;
            if (token() !== 149 /* FromKeyword */ &&
                (identifier === null || identifier === void 0 ? void 0 : identifier.escapedText) === "type" &&
                (isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration())) {
                isTypeOnly = true;
                identifier = isIdentifier() ? parseIdentifier() : undefined;
            }
            if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration()) {
                return parseImportEqualsDeclaration(node, identifier, isTypeOnly);
            }
            // Import statement
            node.kind = 254 /* ImportDeclaration */;
            // ImportDeclaration:
            //  import ImportClause from ModuleSpecifier ;
            //  import ModuleSpecifier;
            if (identifier || // import id
                token() === 41 /* AsteriskToken */ || // import *
                token() === 18 /* OpenBraceToken */ // import {
            ) {
                node.importClause = parseImportClause(identifier, afterImportPos, isTypeOnly);
                parseExpected(149 /* FromKeyword */);
            }
            node.moduleSpecifier = parseModuleSpecifier();
            parseSemicolon();
            return finishNode(node);
        }
        function tokenAfterImportDefinitelyProducesImportDeclaration() {
            return token() === 41 /* AsteriskToken */ || token() === 18 /* OpenBraceToken */;
        }
        function tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() {
            // In `import id ___`, the current token decides whether to produce
            // an ImportDeclaration or ImportEqualsDeclaration.
            return token() === 27 /* CommaToken */ || token() === 149 /* FromKeyword */;
        }
        function parseImportEqualsDeclaration(node, identifier, isTypeOnly) {
            node.kind = 253 /* ImportEqualsDeclaration */;
            node.name = identifier;
            parseExpected(62 /* EqualsToken */);
            node.moduleReference = parseModuleReference();
            parseSemicolon();
            var finished = finishNode(node);
            if (isTypeOnly) {
                parseErrorAtRange(finished, ts.Diagnostics.Only_ECMAScript_imports_may_use_import_type);
            }
            return finished;
        }
        function parseImportClause(identifier, fullStart, isTypeOnly) {
            // ImportClause:
            //  ImportedDefaultBinding
            //  NameSpaceImport
            //  NamedImports
            //  ImportedDefaultBinding, NameSpaceImport
            //  ImportedDefaultBinding, NamedImports
            var importClause = createNode(255 /* ImportClause */, fullStart);
            importClause.isTypeOnly = isTypeOnly;
            if (identifier) {
                // ImportedDefaultBinding:
                //  ImportedBinding
                importClause.name = identifier;
            }
            // If there was no default import or if there is comma token after default import
            // parse namespace or named imports
            if (!importClause.name ||
                parseOptional(27 /* CommaToken */)) {
                importClause.namedBindings = token() === 41 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(257 /* NamedImports */);
            }
            return finishNode(importClause);
        }
        function parseModuleReference() {
            return isExternalModuleReference()
                ? parseExternalModuleReference()
                : parseEntityName(/*allowReservedWords*/ false);
        }
        function parseExternalModuleReference() {
            var node = createNode(265 /* ExternalModuleReference */);
            parseExpected(139 /* RequireKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = parseModuleSpecifier();
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseModuleSpecifier() {
            if (token() === 10 /* StringLiteral */) {
                var result = parseLiteralNode();
                result.text = internIdentifier(result.text);
                return result;
            }
            else {
                // We allow arbitrary expressions here, even though the grammar only allows string
                // literals.  We check to ensure that it is only a string literal later in the grammar
                // check pass.
                return parseExpression();
            }
        }
        function parseNamespaceImport() {
            // NameSpaceImport:
            //  * as ImportedBinding
            var namespaceImport = createNode(256 /* NamespaceImport */);
            parseExpected(41 /* AsteriskToken */);
            parseExpected(123 /* AsKeyword */);
            namespaceImport.name = parseIdentifier();
            return finishNode(namespaceImport);
        }
        function parseNamedImportsOrExports(kind) {
            var node = createNode(kind);
            // NamedImports:
            //  { }
            //  { ImportsList }
            //  { ImportsList, }
            // ImportsList:
            //  ImportSpecifier
            //  ImportsList, ImportSpecifier
            node.elements = parseBracketedList(23 /* ImportOrExportSpecifiers */, kind === 257 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 18 /* OpenBraceToken */, 19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseExportSpecifier() {
            return parseImportOrExportSpecifier(263 /* ExportSpecifier */);
        }
        function parseImportSpecifier() {
            return parseImportOrExportSpecifier(258 /* ImportSpecifier */);
        }
        function parseImportOrExportSpecifier(kind) {
            var node = createNode(kind);
            // ImportSpecifier:
            //   BindingIdentifier
            //   IdentifierName as BindingIdentifier
            // ExportSpecifier:
            //   IdentifierName
            //   IdentifierName as IdentifierName
            var checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
            var checkIdentifierStart = scanner.getTokenPos();
            var checkIdentifierEnd = scanner.getTextPos();
            var identifierName = parseIdentifierName();
            if (token() === 123 /* AsKeyword */) {
                node.propertyName = identifierName;
                parseExpected(123 /* AsKeyword */);
                checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
                checkIdentifierStart = scanner.getTokenPos();
                checkIdentifierEnd = scanner.getTextPos();
                node.name = parseIdentifierName();
            }
            else {
                node.name = identifierName;
            }
            if (kind === 258 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
                parseErrorAt(checkIdentifierStart, checkIdentifierEnd, ts.Diagnostics.Identifier_expected);
            }
            return finishNode(node);
        }
        function parseNamespaceExport(pos) {
            var node = createNode(262 /* NamespaceExport */, pos);
            node.name = parseIdentifier();
            return finishNode(node);
        }
        function parseExportDeclaration(node) {
            node.kind = 260 /* ExportDeclaration */;
            node.isTypeOnly = parseOptional(145 /* TypeKeyword */);
            var namespaceExportPos = scanner.getStartPos();
            if (parseOptional(41 /* AsteriskToken */)) {
                if (parseOptional(123 /* AsKeyword */)) {
                    node.exportClause = parseNamespaceExport(namespaceExportPos);
                }
                parseExpected(149 /* FromKeyword */);
                node.moduleSpecifier = parseModuleSpecifier();
            }
            else {
                node.exportClause = parseNamedImportsOrExports(261 /* NamedExports */);
                // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
                // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
                // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
                if (token() === 149 /* FromKeyword */ || (token() === 10 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
                    parseExpected(149 /* FromKeyword */);
                    node.moduleSpecifier = parseModuleSpecifier();
                }
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseExportAssignment(node) {
            node.kind = 259 /* ExportAssignment */;
            if (parseOptional(62 /* EqualsToken */)) {
                node.isExportEquals = true;
            }
            else {
                parseExpected(84 /* DefaultKeyword */);
            }
            node.expression = parseAssignmentExpressionOrHigher();
            parseSemicolon();
            return finishNode(node);
        }
        function setExternalModuleIndicator(sourceFile) {
            // Try to use the first top-level import/export when available, then
            // fall back to looking for an 'import.meta' somewhere in the tree if necessary.
            sourceFile.externalModuleIndicator =
                ts.forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) ||
                    getImportMetaIfNecessary(sourceFile);
        }
        function isAnExternalModuleIndicatorNode(node) {
            return hasModifierOfKind(node, 89 /* ExportKeyword */)
                || node.kind === 253 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 265 /* ExternalModuleReference */
                || node.kind === 254 /* ImportDeclaration */
                || node.kind === 259 /* ExportAssignment */
                || node.kind === 260 /* ExportDeclaration */ ? node : undefined;
        }
        function getImportMetaIfNecessary(sourceFile) {
            return sourceFile.flags & 2097152 /* PossiblyContainsImportMeta */ ?
                walkTreeForExternalModuleIndicators(sourceFile) :
                undefined;
        }
        function walkTreeForExternalModuleIndicators(node) {
            return isImportMeta(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
        }
        /** Do not use hasModifier inside the parser; it relies on parent pointers. Use this instead. */
        function hasModifierOfKind(node, kind) {
            return ts.some(node.modifiers, function (m) { return m.kind === kind; });
        }
        function isImportMeta(node) {
            return ts.isMetaProperty(node) && node.keywordToken === 96 /* ImportKeyword */ && node.name.escapedText === "meta";
        }
        var ParsingContext;
        (function (ParsingContext) {
            ParsingContext[ParsingContext["SourceElements"] = 0] = "SourceElements";
            ParsingContext[ParsingContext["BlockStatements"] = 1] = "BlockStatements";
            ParsingContext[ParsingContext["SwitchClauses"] = 2] = "SwitchClauses";
            ParsingContext[ParsingContext["SwitchClauseStatements"] = 3] = "SwitchClauseStatements";
            ParsingContext[ParsingContext["TypeMembers"] = 4] = "TypeMembers";
            ParsingContext[ParsingContext["ClassMembers"] = 5] = "ClassMembers";
            ParsingContext[ParsingContext["EnumMembers"] = 6] = "EnumMembers";
            ParsingContext[ParsingContext["HeritageClauseElement"] = 7] = "HeritageClauseElement";
            ParsingContext[ParsingContext["VariableDeclarations"] = 8] = "VariableDeclarations";
            ParsingContext[ParsingContext["ObjectBindingElements"] = 9] = "ObjectBindingElements";
            ParsingContext[ParsingContext["ArrayBindingElements"] = 10] = "ArrayBindingElements";
            ParsingContext[ParsingContext["ArgumentExpressions"] = 11] = "ArgumentExpressions";
            ParsingContext[ParsingContext["ObjectLiteralMembers"] = 12] = "ObjectLiteralMembers";
            ParsingContext[ParsingContext["JsxAttributes"] = 13] = "JsxAttributes";
            ParsingContext[ParsingContext["JsxChildren"] = 14] = "JsxChildren";
            ParsingContext[ParsingContext["ArrayLiteralMembers"] = 15] = "ArrayLiteralMembers";
            ParsingContext[ParsingContext["Parameters"] = 16] = "Parameters";
            ParsingContext[ParsingContext["JSDocParameters"] = 17] = "JSDocParameters";
            ParsingContext[ParsingContext["RestProperties"] = 18] = "RestProperties";
            ParsingContext[ParsingContext["TypeParameters"] = 19] = "TypeParameters";
            ParsingContext[ParsingContext["TypeArguments"] = 20] = "TypeArguments";
            ParsingContext[ParsingContext["TupleElementTypes"] = 21] = "TupleElementTypes";
            ParsingContext[ParsingContext["HeritageClauses"] = 22] = "HeritageClauses";
            ParsingContext[ParsingContext["ImportOrExportSpecifiers"] = 23] = "ImportOrExportSpecifiers";
            ParsingContext[ParsingContext["Count"] = 24] = "Count"; // Number of parsing contexts
        })(ParsingContext || (ParsingContext = {}));
        var Tristate;
        (function (Tristate) {
            Tristate[Tristate["False"] = 0] = "False";
            Tristate[Tristate["True"] = 1] = "True";
            Tristate[Tristate["Unknown"] = 2] = "Unknown";
        })(Tristate || (Tristate = {}));
        var JSDocParser;
        (function (JSDocParser) {
            function parseJSDocTypeExpressionForTests(content, start, length) {
                initializeState(content, 99 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = createSourceFile("file.js", 99 /* Latest */, 1 /* JS */, /*isDeclarationFile*/ false);
                scanner.setText(content, start, length);
                currentToken = scanner.scan();
                var jsDocTypeExpression = parseJSDocTypeExpression();
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
            // Parses out a JSDoc type expression.
            function parseJSDocTypeExpression(mayOmitBraces) {
                var result = createNode(294 /* JSDocTypeExpression */);
                var hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(18 /* OpenBraceToken */);
                result.type = doInsideOfContext(4194304 /* JSDoc */, parseJSDocType);
                if (!mayOmitBraces || hasBrace) {
                    parseExpectedJSDoc(19 /* CloseBraceToken */);
                }
                fixupParentReferences(result);
                return finishNode(result);
            }
            JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression;
            function parseIsolatedJSDocComment(content, start, length) {
                initializeState(content, 99 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = { languageVariant: 0 /* Standard */, text: content };
                var jsDoc = doInsideOfContext(4194304 /* JSDoc */, function () { return parseJSDocCommentWorker(start, length); });
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDoc ? { jsDoc: jsDoc, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
            function parseJSDocComment(parent, start, length) {
                var _a;
                var saveToken = currentToken;
                var saveParseDiagnosticsLength = parseDiagnostics.length;
                var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
                var comment = doInsideOfContext(4194304 /* JSDoc */, function () { return parseJSDocCommentWorker(start, length); });
                if (comment) {
                    comment.parent = parent;
                }
                if (contextFlags & 131072 /* JavaScriptFile */) {
                    if (!sourceFile.jsDocDiagnostics) {
                        sourceFile.jsDocDiagnostics = [];
                    }
                    (_a = sourceFile.jsDocDiagnostics).push.apply(_a, parseDiagnostics);
                }
                currentToken = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
                return comment;
            }
            JSDocParser.parseJSDocComment = parseJSDocComment;
            var JSDocState;
            (function (JSDocState) {
                JSDocState[JSDocState["BeginningOfLine"] = 0] = "BeginningOfLine";
                JSDocState[JSDocState["SawAsterisk"] = 1] = "SawAsterisk";
                JSDocState[JSDocState["SavingComments"] = 2] = "SavingComments";
                JSDocState[JSDocState["SavingBackticks"] = 3] = "SavingBackticks";
            })(JSDocState || (JSDocState = {}));
            var PropertyLikeParse;
            (function (PropertyLikeParse) {
                PropertyLikeParse[PropertyLikeParse["Property"] = 1] = "Property";
                PropertyLikeParse[PropertyLikeParse["Parameter"] = 2] = "Parameter";
                PropertyLikeParse[PropertyLikeParse["CallbackParameter"] = 4] = "CallbackParameter";
            })(PropertyLikeParse || (PropertyLikeParse = {}));
            function parseJSDocCommentWorker(start, length) {
                if (start === void 0) { start = 0; }
                var content = sourceText;
                var end = length === undefined ? content.length : start + length;
                length = end - start;
                ts.Debug.assert(start >= 0);
                ts.Debug.assert(start <= end);
                ts.Debug.assert(end <= content.length);
                // Check for /** (JSDoc opening part)
                if (!isJSDocLikeText(content, start)) {
                    return undefined;
                }
                var tags;
                var tagsPos;
                var tagsEnd;
                var comments = [];
                // + 3 for leading /**, - 5 in total for /** */
                return scanner.scanRange(start + 3, length - 5, function () {
                    // Initially we can parse out a tag.  We also have seen a starting asterisk.
                    // This is so that /** * @type */ doesn't parse.
                    var state = 1 /* SawAsterisk */;
                    var margin;
                    // + 4 for leading '/** '
                    var indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4;
                    function pushComment(text) {
                        if (!margin) {
                            margin = indent;
                        }
                        comments.push(text);
                        indent += text.length;
                    }
                    nextTokenJSDoc();
                    while (parseOptionalJsdoc(5 /* WhitespaceTrivia */))
                        ;
                    if (parseOptionalJsdoc(4 /* NewLineTrivia */)) {
                        state = 0 /* BeginningOfLine */;
                        indent = 0;
                    }
                    loop: while (true) {
                        switch (token()) {
                            case 59 /* AtToken */:
                                if (state === 0 /* BeginningOfLine */ || state === 1 /* SawAsterisk */) {
                                    removeTrailingWhitespace(comments);
                                    addTag(parseTag(indent));
                                    // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag.
                                    // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning
                                    // for malformed examples like `/** @param {string} x @returns {number} the length */`
                                    state = 0 /* BeginningOfLine */;
                                    margin = undefined;
                                }
                                else {
                                    pushComment(scanner.getTokenText());
                                }
                                break;
                            case 4 /* NewLineTrivia */:
                                comments.push(scanner.getTokenText());
                                state = 0 /* BeginningOfLine */;
                                indent = 0;
                                break;
                            case 41 /* AsteriskToken */:
                                var asterisk = scanner.getTokenText();
                                if (state === 1 /* SawAsterisk */ || state === 2 /* SavingComments */) {
                                    // If we've already seen an asterisk, then we can no longer parse a tag on this line
                                    state = 2 /* SavingComments */;
                                    pushComment(asterisk);
                                }
                                else {
                                    // Ignore the first asterisk on a line
                                    state = 1 /* SawAsterisk */;
                                    indent += asterisk.length;
                                }
                                break;
                            case 5 /* WhitespaceTrivia */:
                                // only collect whitespace if we're already saving comments or have just crossed the comment indent margin
                                var whitespace = scanner.getTokenText();
                                if (state === 2 /* SavingComments */) {
                                    comments.push(whitespace);
                                }
                                else if (margin !== undefined && indent + whitespace.length > margin) {
                                    comments.push(whitespace.slice(margin - indent - 1));
                                }
                                indent += whitespace.length;
                                break;
                            case 1 /* EndOfFileToken */:
                                break loop;
                            default:
                                // Anything else is doc comment text. We just save it. Because it
                                // wasn't a tag, we can no longer parse a tag on this line until we hit the next
                                // line break.
                                state = 2 /* SavingComments */;
                                pushComment(scanner.getTokenText());
                                break;
                        }
                        nextTokenJSDoc();
                    }
                    removeLeadingNewlines(comments);
                    removeTrailingWhitespace(comments);
                    return createJSDocComment();
                });
                function removeLeadingNewlines(comments) {
                    while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) {
                        comments.shift();
                    }
                }
                function removeTrailingWhitespace(comments) {
                    while (comments.length && comments[comments.length - 1].trim() === "") {
                        comments.pop();
                    }
                }
                function createJSDocComment() {
                    var result = createNode(303 /* JSDocComment */, start);
                    result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd);
                    result.comment = comments.length ? comments.join("") : undefined;
                    return finishNode(result, end);
                }
                function isNextNonwhitespaceTokenEndOfFile() {
                    // We must use infinite lookahead, as there could be any number of newlines :(
                    while (true) {
                        nextTokenJSDoc();
                        if (token() === 1 /* EndOfFileToken */) {
                            return true;
                        }
                        if (!(token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */)) {
                            return false;
                        }
                    }
                }
                function skipWhitespace() {
                    if (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
                            return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
                        }
                    }
                    while (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        nextTokenJSDoc();
                    }
                }
                function skipWhitespaceOrAsterisk() {
                    if (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
                            return ""; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
                        }
                    }
                    var precedingLineBreak = scanner.hasPrecedingLineBreak();
                    var seenLineBreak = false;
                    var indentText = "";
                    while ((precedingLineBreak && token() === 41 /* AsteriskToken */) || token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        indentText += scanner.getTokenText();
                        if (token() === 4 /* NewLineTrivia */) {
                            precedingLineBreak = true;
                            seenLineBreak = true;
                            indentText = "";
                        }
                        else if (token() === 41 /* AsteriskToken */) {
                            precedingLineBreak = false;
                        }
                        nextTokenJSDoc();
                    }
                    return seenLineBreak ? indentText : "";
                }
                function parseTag(margin) {
                    ts.Debug.assert(token() === 59 /* AtToken */);
                    var start = scanner.getTokenPos();
                    nextTokenJSDoc();
                    var tagName = parseJSDocIdentifierName(/*message*/ undefined);
                    var indentText = skipWhitespaceOrAsterisk();
                    var tag;
                    switch (tagName.escapedText) {
                        case "author":
                            tag = parseAuthorTag(start, tagName, margin);
                            break;
                        case "implements":
                            tag = parseImplementsTag(start, tagName);
                            break;
                        case "augments":
                        case "extends":
                            tag = parseAugmentsTag(start, tagName);
                            break;
                        case "class":
                        case "constructor":
                            tag = parseSimpleTag(start, 310 /* JSDocClassTag */, tagName);
                            break;
                        case "public":
                            tag = parseSimpleTag(start, 311 /* JSDocPublicTag */, tagName);
                            break;
                        case "private":
                            tag = parseSimpleTag(start, 312 /* JSDocPrivateTag */, tagName);
                            break;
                        case "protected":
                            tag = parseSimpleTag(start, 313 /* JSDocProtectedTag */, tagName);
                            break;
                        case "readonly":
                            tag = parseSimpleTag(start, 314 /* JSDocReadonlyTag */, tagName);
                            break;
                        case "this":
                            tag = parseThisTag(start, tagName);
                            break;
                        case "enum":
                            tag = parseEnumTag(start, tagName);
                            break;
                        case "arg":
                        case "argument":
                        case "param":
                            return parseParameterOrPropertyTag(start, tagName, 2 /* Parameter */, margin);
                        case "return":
                        case "returns":
                            tag = parseReturnTag(start, tagName);
                            break;
                        case "template":
                            tag = parseTemplateTag(start, tagName);
                            break;
                        case "type":
                            tag = parseTypeTag(start, tagName);
                            break;
                        case "typedef":
                            tag = parseTypedefTag(start, tagName, margin);
                            break;
                        case "callback":
                            tag = parseCallbackTag(start, tagName, margin);
                            break;
                        default:
                            tag = parseUnknownTag(start, tagName);
                            break;
                    }
                    if (!tag.comment) {
                        // some tags, like typedef and callback, have already parsed their comments earlier
                        if (!indentText) {
                            margin += tag.end - tag.pos;
                        }
                        tag.comment = parseTagComments(margin, indentText.slice(margin));
                    }
                    return tag;
                }
                function parseTagComments(indent, initialMargin) {
                    var comments = [];
                    var state = 0 /* BeginningOfLine */;
                    var margin;
                    function pushComment(text) {
                        if (!margin) {
                            margin = indent;
                        }
                        comments.push(text);
                        indent += text.length;
                    }
                    if (initialMargin !== undefined) {
                        // jump straight to saving comments if there is some initial indentation
                        if (initialMargin !== "") {
                            pushComment(initialMargin);
                        }
                        state = 1 /* SawAsterisk */;
                    }
                    var tok = token();
                    loop: while (true) {
                        switch (tok) {
                            case 4 /* NewLineTrivia */:
                                if (state >= 1 /* SawAsterisk */) {
                                    state = 0 /* BeginningOfLine */;
                                    // don't use pushComment here because we want to keep the margin unchanged
                                    comments.push(scanner.getTokenText());
                                }
                                indent = 0;
                                break;
                            case 59 /* AtToken */:
                                if (state === 3 /* SavingBackticks */) {
                                    comments.push(scanner.getTokenText());
                                    break;
                                }
                                scanner.setTextPos(scanner.getTextPos() - 1);
                            // falls through
                            case 1 /* EndOfFileToken */:
                                // Done
                                break loop;
                            case 5 /* WhitespaceTrivia */:
                                if (state === 2 /* SavingComments */ || state === 3 /* SavingBackticks */) {
                                    pushComment(scanner.getTokenText());
                                }
                                else {
                                    var whitespace = scanner.getTokenText();
                                    // if the whitespace crosses the margin, take only the whitespace that passes the margin
                                    if (margin !== undefined && indent + whitespace.length > margin) {
                                        comments.push(whitespace.slice(margin - indent));
                                    }
                                    indent += whitespace.length;
                                }
                                break;
                            case 18 /* OpenBraceToken */:
                                state = 2 /* SavingComments */;
                                if (lookAhead(function () { return nextTokenJSDoc() === 59 /* AtToken */ && ts.tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && scanner.getTokenText() === "link"; })) {
                                    pushComment(scanner.getTokenText());
                                    nextTokenJSDoc();
                                    pushComment(scanner.getTokenText());
                                    nextTokenJSDoc();
                                }
                                pushComment(scanner.getTokenText());
                                break;
                            case 61 /* BacktickToken */:
                                if (state === 3 /* SavingBackticks */) {
                                    state = 2 /* SavingComments */;
                                }
                                else {
                                    state = 3 /* SavingBackticks */;
                                }
                                pushComment(scanner.getTokenText());
                                break;
                            case 41 /* AsteriskToken */:
                                if (state === 0 /* BeginningOfLine */) {
                                    // leading asterisks start recording on the *next* (non-whitespace) token
                                    state = 1 /* SawAsterisk */;
                                    indent += 1;
                                    break;
                                }
                            // record the * as a comment
                            // falls through
                            default:
                                if (state !== 3 /* SavingBackticks */) {
                                    state = 2 /* SavingComments */; // leading identifiers start recording as well
                                }
                                pushComment(scanner.getTokenText());
                                break;
                        }
                        tok = nextTokenJSDoc();
                    }
                    removeLeadingNewlines(comments);
                    removeTrailingWhitespace(comments);
                    return comments.length === 0 ? undefined : comments.join("");
                }
                function parseUnknownTag(start, tagName) {
                    var result = createNode(306 /* JSDocTag */, start);
                    result.tagName = tagName;
                    return finishNode(result);
                }
                function addTag(tag) {
                    if (!tag) {
                        return;
                    }
                    if (!tags) {
                        tags = [tag];
                        tagsPos = tag.pos;
                    }
                    else {
                        tags.push(tag);
                    }
                    tagsEnd = tag.end;
                }
                function tryParseTypeExpression() {
                    skipWhitespaceOrAsterisk();
                    return token() === 18 /* OpenBraceToken */ ? parseJSDocTypeExpression() : undefined;
                }
                function parseBracketNameInPropertyAndParamTag() {
                    // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar'
                    var isBracketed = parseOptionalJsdoc(22 /* OpenBracketToken */);
                    if (isBracketed) {
                        skipWhitespace();
                    }
                    // a markdown-quoted name: `arg` is not legal jsdoc, but occurs in the wild
                    var isBackquoted = parseOptionalJsdoc(61 /* BacktickToken */);
                    var name = parseJSDocEntityName();
                    if (isBackquoted) {
                        parseExpectedTokenJSDoc(61 /* BacktickToken */);
                    }
                    if (isBracketed) {
                        skipWhitespace();
                        // May have an optional default, e.g. '[foo = 42]'
                        if (parseOptionalToken(62 /* EqualsToken */)) {
                            parseExpression();
                        }
                        parseExpected(23 /* CloseBracketToken */);
                    }
                    return { name: name, isBracketed: isBracketed };
                }
                function isObjectOrObjectArrayTypeReference(node) {
                    switch (node.kind) {
                        case 141 /* ObjectKeyword */:
                            return true;
                        case 174 /* ArrayType */:
                            return isObjectOrObjectArrayTypeReference(node.elementType);
                        default:
                            return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object" && !node.typeArguments;
                    }
                }
                function parseParameterOrPropertyTag(start, tagName, target, indent) {
                    var typeExpression = tryParseTypeExpression();
                    var isNameFirst = !typeExpression;
                    skipWhitespaceOrAsterisk();
                    var _a = parseBracketNameInPropertyAndParamTag(), name = _a.name, isBracketed = _a.isBracketed;
                    skipWhitespace();
                    if (isNameFirst) {
                        typeExpression = tryParseTypeExpression();
                    }
                    var result = target === 1 /* Property */ ?
                        createNode(323 /* JSDocPropertyTag */, start) :
                        createNode(317 /* JSDocParameterTag */, start);
                    var comment = parseTagComments(indent + scanner.getStartPos() - start);
                    var nestedTypeLiteral = target !== 4 /* CallbackParameter */ && parseNestedTypeLiteral(typeExpression, name, target, indent);
                    if (nestedTypeLiteral) {
                        typeExpression = nestedTypeLiteral;
                        isNameFirst = true;
                    }
                    result.tagName = tagName;
                    result.typeExpression = typeExpression;
                    result.name = name;
                    result.isNameFirst = isNameFirst;
                    result.isBracketed = isBracketed;
                    result.comment = comment;
                    return finishNode(result);
                }
                function parseNestedTypeLiteral(typeExpression, name, target, indent) {
                    if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
                        var typeLiteralExpression = createNode(294 /* JSDocTypeExpression */, scanner.getTokenPos());
                        var child = void 0;
                        var jsdocTypeLiteral = void 0;
                        var start_3 = scanner.getStartPos();
                        var children = void 0;
                        while (child = tryParse(function () { return parseChildParameterOrPropertyTag(target, indent, name); })) {
                            if (child.kind === 317 /* JSDocParameterTag */ || child.kind === 323 /* JSDocPropertyTag */) {
                                children = ts.append(children, child);
                            }
                        }
                        if (children) {
                            jsdocTypeLiteral = createNode(304 /* JSDocTypeLiteral */, start_3);
                            jsdocTypeLiteral.jsDocPropertyTags = children;
                            if (typeExpression.type.kind === 174 /* ArrayType */) {
                                jsdocTypeLiteral.isArrayType = true;
                            }
                            typeLiteralExpression.type = finishNode(jsdocTypeLiteral);
                            return finishNode(typeLiteralExpression);
                        }
                    }
                }
                function parseReturnTag(start, tagName) {
                    if (ts.some(tags, ts.isJSDocReturnTag)) {
                        parseErrorAt(tagName.pos, scanner.getTokenPos(), ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    var result = createNode(318 /* JSDocReturnTag */, start);
                    result.tagName = tagName;
                    result.typeExpression = tryParseTypeExpression();
                    return finishNode(result);
                }
                function parseTypeTag(start, tagName) {
                    if (ts.some(tags, ts.isJSDocTypeTag)) {
                        parseErrorAt(tagName.pos, scanner.getTokenPos(), ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    var result = createNode(320 /* JSDocTypeTag */, start);
                    result.tagName = tagName;
                    result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    return finishNode(result);
                }
                function parseAuthorTag(start, tagName, indent) {
                    var result = createNode(309 /* JSDocAuthorTag */, start);
                    result.tagName = tagName;
                    var authorInfoWithEmail = tryParse(function () { return tryParseAuthorNameAndEmail(); });
                    if (!authorInfoWithEmail) {
                        return finishNode(result);
                    }
                    result.comment = authorInfoWithEmail;
                    if (lookAhead(function () { return nextToken() !== 4 /* NewLineTrivia */; })) {
                        var comment = parseTagComments(indent);
                        if (comment) {
                            result.comment += comment;
                        }
                    }
                    return finishNode(result);
                }
                function tryParseAuthorNameAndEmail() {
                    var comments = [];
                    var seenLessThan = false;
                    var seenGreaterThan = false;
                    var token = scanner.getToken();
                    loop: while (true) {
                        switch (token) {
                            case 75 /* Identifier */:
                            case 5 /* WhitespaceTrivia */:
                            case 24 /* DotToken */:
                            case 59 /* AtToken */:
                                comments.push(scanner.getTokenText());
                                break;
                            case 29 /* LessThanToken */:
                                if (seenLessThan || seenGreaterThan) {
                                    return;
                                }
                                seenLessThan = true;
                                comments.push(scanner.getTokenText());
                                break;
                            case 31 /* GreaterThanToken */:
                                if (!seenLessThan || seenGreaterThan) {
                                    return;
                                }
                                seenGreaterThan = true;
                                comments.push(scanner.getTokenText());
                                scanner.setTextPos(scanner.getTokenPos() + 1);
                                break loop;
                            case 4 /* NewLineTrivia */:
                            case 1 /* EndOfFileToken */:
                                break loop;
                        }
                        token = nextTokenJSDoc();
                    }
                    if (seenLessThan && seenGreaterThan) {
                        return comments.length === 0 ? undefined : comments.join("");
                    }
                }
                function parseImplementsTag(start, tagName) {
                    var result = createNode(308 /* JSDocImplementsTag */, start);
                    result.tagName = tagName;
                    result.class = parseExpressionWithTypeArgumentsForAugments();
                    return finishNode(result);
                }
                function parseAugmentsTag(start, tagName) {
                    var result = createNode(307 /* JSDocAugmentsTag */, start);
                    result.tagName = tagName;
                    result.class = parseExpressionWithTypeArgumentsForAugments();
                    return finishNode(result);
                }
                function parseExpressionWithTypeArgumentsForAugments() {
                    var usedBrace = parseOptional(18 /* OpenBraceToken */);
                    var node = createNode(216 /* ExpressionWithTypeArguments */);
                    node.expression = parsePropertyAccessEntityNameExpression();
                    node.typeArguments = tryParseTypeArguments();
                    var res = finishNode(node);
                    if (usedBrace) {
                        parseExpected(19 /* CloseBraceToken */);
                    }
                    return res;
                }
                function parsePropertyAccessEntityNameExpression() {
                    var node = parseJSDocIdentifierName();
                    while (parseOptional(24 /* DotToken */)) {
                        var prop = createNode(194 /* PropertyAccessExpression */, node.pos);
                        prop.expression = node;
                        prop.name = parseJSDocIdentifierName();
                        node = finishNode(prop);
                    }
                    return node;
                }
                function parseSimpleTag(start, kind, tagName) {
                    var tag = createNode(kind, start);
                    tag.tagName = tagName;
                    return finishNode(tag);
                }
                function parseThisTag(start, tagName) {
                    var tag = createNode(319 /* JSDocThisTag */, start);
                    tag.tagName = tagName;
                    tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    skipWhitespace();
                    return finishNode(tag);
                }
                function parseEnumTag(start, tagName) {
                    var tag = createNode(316 /* JSDocEnumTag */, start);
                    tag.tagName = tagName;
                    tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    skipWhitespace();
                    return finishNode(tag);
                }
                function parseTypedefTag(start, tagName, indent) {
                    var typeExpression = tryParseTypeExpression();
                    skipWhitespaceOrAsterisk();
                    var typedefTag = createNode(322 /* JSDocTypedefTag */, start);
                    typedefTag.tagName = tagName;
                    typedefTag.fullName = parseJSDocTypeNameWithNamespace();
                    typedefTag.name = getJSDocTypeAliasName(typedefTag.fullName);
                    skipWhitespace();
                    typedefTag.comment = parseTagComments(indent);
                    typedefTag.typeExpression = typeExpression;
                    var end;
                    if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
                        var child = void 0;
                        var jsdocTypeLiteral = void 0;
                        var childTypeTag = void 0;
                        while (child = tryParse(function () { return parseChildPropertyTag(indent); })) {
                            if (!jsdocTypeLiteral) {
                                jsdocTypeLiteral = createNode(304 /* JSDocTypeLiteral */, start);
                            }
                            if (child.kind === 320 /* JSDocTypeTag */) {
                                if (childTypeTag) {
                                    break;
                                }
                                else {
                                    childTypeTag = child;
                                }
                            }
                            else {
                                jsdocTypeLiteral.jsDocPropertyTags = ts.append(jsdocTypeLiteral.jsDocPropertyTags, child);
                            }
                        }
                        if (jsdocTypeLiteral) {
                            if (typeExpression && typeExpression.type.kind === 174 /* ArrayType */) {
                                jsdocTypeLiteral.isArrayType = true;
                            }
                            typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
                                childTypeTag.typeExpression :
                                finishNode(jsdocTypeLiteral);
                            end = typedefTag.typeExpression.end;
                        }
                    }
                    // Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace
                    return finishNode(typedefTag, end || typedefTag.comment !== undefined ? scanner.getStartPos() : (typedefTag.fullName || typedefTag.typeExpression || typedefTag.tagName).end);
                }
                function parseJSDocTypeNameWithNamespace(nested) {
                    var pos = scanner.getTokenPos();
                    if (!ts.tokenIsIdentifierOrKeyword(token())) {
                        return undefined;
                    }
                    var typeNameOrNamespaceName = parseJSDocIdentifierName();
                    if (parseOptional(24 /* DotToken */)) {
                        var jsDocNamespaceNode = createNode(249 /* ModuleDeclaration */, pos);
                        if (nested) {
                            jsDocNamespaceNode.flags |= 4 /* NestedNamespace */;
                        }
                        jsDocNamespaceNode.name = typeNameOrNamespaceName;
                        jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(/*nested*/ true);
                        return finishNode(jsDocNamespaceNode);
                    }
                    if (nested) {
                        typeNameOrNamespaceName.isInJSDocNamespace = true;
                    }
                    return typeNameOrNamespaceName;
                }
                function parseCallbackTag(start, tagName, indent) {
                    var callbackTag = createNode(315 /* JSDocCallbackTag */, start);
                    callbackTag.tagName = tagName;
                    callbackTag.fullName = parseJSDocTypeNameWithNamespace();
                    callbackTag.name = getJSDocTypeAliasName(callbackTag.fullName);
                    skipWhitespace();
                    callbackTag.comment = parseTagComments(indent);
                    var child;
                    var jsdocSignature = createNode(305 /* JSDocSignature */, start);
                    jsdocSignature.parameters = [];
                    while (child = tryParse(function () { return parseChildParameterOrPropertyTag(4 /* CallbackParameter */, indent); })) {
                        jsdocSignature.parameters = ts.append(jsdocSignature.parameters, child);
                    }
                    var returnTag = tryParse(function () {
                        if (parseOptionalJsdoc(59 /* AtToken */)) {
                            var tag = parseTag(indent);
                            if (tag && tag.kind === 318 /* JSDocReturnTag */) {
                                return tag;
                            }
                        }
                    });
                    if (returnTag) {
                        jsdocSignature.type = returnTag;
                    }
                    callbackTag.typeExpression = finishNode(jsdocSignature);
                    return finishNode(callbackTag);
                }
                function getJSDocTypeAliasName(fullName) {
                    if (fullName) {
                        var rightNode = fullName;
                        while (true) {
                            if (ts.isIdentifier(rightNode) || !rightNode.body) {
                                return ts.isIdentifier(rightNode) ? rightNode : rightNode.name;
                            }
                            rightNode = rightNode.body;
                        }
                    }
                }
                function escapedTextsEqual(a, b) {
                    while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) {
                        if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) {
                            a = a.left;
                            b = b.left;
                        }
                        else {
                            return false;
                        }
                    }
                    return a.escapedText === b.escapedText;
                }
                function parseChildPropertyTag(indent) {
                    return parseChildParameterOrPropertyTag(1 /* Property */, indent);
                }
                function parseChildParameterOrPropertyTag(target, indent, name) {
                    var canParseTag = true;
                    var seenAsterisk = false;
                    while (true) {
                        switch (nextTokenJSDoc()) {
                            case 59 /* AtToken */:
                                if (canParseTag) {
                                    var child = tryParseChildTag(target, indent);
                                    if (child && (child.kind === 317 /* JSDocParameterTag */ || child.kind === 323 /* JSDocPropertyTag */) &&
                                        target !== 4 /* CallbackParameter */ &&
                                        name && (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
                                        return false;
                                    }
                                    return child;
                                }
                                seenAsterisk = false;
                                break;
                            case 4 /* NewLineTrivia */:
                                canParseTag = true;
                                seenAsterisk = false;
                                break;
                            case 41 /* AsteriskToken */:
                                if (seenAsterisk) {
                                    canParseTag = false;
                                }
                                seenAsterisk = true;
                                break;
                            case 75 /* Identifier */:
                                canParseTag = false;
                                break;
                            case 1 /* EndOfFileToken */:
                                return false;
                        }
                    }
                }
                function tryParseChildTag(target, indent) {
                    ts.Debug.assert(token() === 59 /* AtToken */);
                    var start = scanner.getStartPos();
                    nextTokenJSDoc();
                    var tagName = parseJSDocIdentifierName();
                    skipWhitespace();
                    var t;
                    switch (tagName.escapedText) {
                        case "type":
                            return target === 1 /* Property */ && parseTypeTag(start, tagName);
                        case "prop":
                        case "property":
                            t = 1 /* Property */;
                            break;
                        case "arg":
                        case "argument":
                        case "param":
                            t = 2 /* Parameter */ | 4 /* CallbackParameter */;
                            break;
                        default:
                            return false;
                    }
                    if (!(target & t)) {
                        return false;
                    }
                    return parseParameterOrPropertyTag(start, tagName, target, indent);
                }
                function parseTemplateTag(start, tagName) {
                    // the template tag looks like '@template {Constraint} T,U,V'
                    var constraint;
                    if (token() === 18 /* OpenBraceToken */) {
                        constraint = parseJSDocTypeExpression();
                    }
                    var typeParameters = [];
                    var typeParametersPos = getNodePos();
                    do {
                        skipWhitespace();
                        var typeParameter = createNode(155 /* TypeParameter */);
                        typeParameter.name = parseJSDocIdentifierName(ts.Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces);
                        finishNode(typeParameter);
                        skipWhitespaceOrAsterisk();
                        typeParameters.push(typeParameter);
                    } while (parseOptionalJsdoc(27 /* CommaToken */));
                    var result = createNode(321 /* JSDocTemplateTag */, start);
                    result.tagName = tagName;
                    result.constraint = constraint;
                    result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
                    finishNode(result);
                    return result;
                }
                function parseOptionalJsdoc(t) {
                    if (token() === t) {
                        nextTokenJSDoc();
                        return true;
                    }
                    return false;
                }
                function parseJSDocEntityName() {
                    var entity = parseJSDocIdentifierName();
                    if (parseOptional(22 /* OpenBracketToken */)) {
                        parseExpected(23 /* CloseBracketToken */);
                        // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking.
                        // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}>
                        // but it's not worth it to enforce that restriction.
                    }
                    while (parseOptional(24 /* DotToken */)) {
                        var name = parseJSDocIdentifierName();
                        if (parseOptional(22 /* OpenBracketToken */)) {
                            parseExpected(23 /* CloseBracketToken */);
                        }
                        entity = createQualifiedName(entity, name);
                    }
                    return entity;
                }
                function parseJSDocIdentifierName(message) {
                    if (!ts.tokenIsIdentifierOrKeyword(token())) {
                        return createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ !message, message || ts.Diagnostics.Identifier_expected);
                    }
                    identifierCount++;
                    var pos = scanner.getTokenPos();
                    var end = scanner.getTextPos();
                    var result = createNode(75 /* Identifier */, pos);
                    if (token() !== 75 /* Identifier */) {
                        result.originalKeywordKind = token();
                    }
                    result.escapedText = ts.escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
                    finishNode(result, end);
                    nextTokenJSDoc();
                    return result;
                }
            }
        })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
    })(Parser || (Parser = {}));
    var IncrementalParser;
    (function (IncrementalParser) {
        function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
            aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
            checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
            if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
                // if the text didn't change, then we can just return our current source file as-is.
                return sourceFile;
            }
            if (sourceFile.statements.length === 0) {
                // If we don't have any statements in the current source file, then there's no real
                // way to incrementally parse.  So just do a full parse instead.
                return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind);
            }
            // Make sure we're not trying to incrementally update a source file more than once.  Once
            // we do an update the original source file is considered unusable from that point onwards.
            //
            // This is because we do incremental parsing in-place.  i.e. we take nodes from the old
            // tree and give them new positions and parents.  From that point on, trusting the old
            // tree at all is not possible as far too much of it may violate invariants.
            var incrementalSourceFile = sourceFile;
            ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
            incrementalSourceFile.hasBeenIncrementallyParsed = true;
            var oldText = sourceFile.text;
            var syntaxCursor = createSyntaxCursor(sourceFile);
            // Make the actual change larger so that we know to reparse anything whose lookahead
            // might have intersected the change.
            var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
            checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
            // Ensure that extending the affected range only moved the start of the change range
            // earlier in the file.
            ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
            ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
            ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
            // The is the amount the nodes after the edit range need to be adjusted.  It can be
            // positive (if the edit added characters), negative (if the edit deleted characters)
            // or zero (if this was a pure overwrite with nothing added/removed).
            var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
            // If we added or removed characters during the edit, then we need to go and adjust all
            // the nodes after the edit.  Those nodes may move forward (if we inserted chars) or they
            // may move backward (if we deleted chars).
            //
            // Doing this helps us out in two ways.  First, it means that any nodes/tokens we want
            // to reuse are already at the appropriate position in the new text.  That way when we
            // reuse them, we don't have to figure out if they need to be adjusted.  Second, it makes
            // it very easy to determine if we can reuse a node.  If the node's position is at where
            // we are in the text, then we can reuse it.  Otherwise we can't.  If the node's position
            // is ahead of us, then we'll need to rescan tokens.  If the node's position is behind
            // us, then we'll need to skip it or crumble it as appropriate
            //
            // We will also adjust the positions of nodes that intersect the change range as well.
            // By doing this, we ensure that all the positions in the old tree are consistent, not
            // just the positions of nodes entirely before/after the change range.  By being
            // consistent, we can then easily map from positions to nodes in the old tree easily.
            //
            // Also, mark any syntax elements that intersect the changed span.  We know, up front,
            // that we cannot reuse these elements.
            updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
            // Now that we've set up our internal incremental state just proceed and parse the
            // source file in the normal fashion.  When possible the parser will retrieve and
            // reuse nodes from the old tree.
            //
            // Note: passing in 'true' for setNodeParents is very important.  When incrementally
            // parsing, we will be reusing nodes from the old tree, and placing it into new
            // parents.  If we don't set the parents now, we'll end up with an observably
            // inconsistent tree.  Setting the parents on the new tree should be very fast.  We
            // will immediately bail out of walking any subtrees when we can see that their parents
            // are already correct.
            var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind);
            result.commentDirectives = getNewCommentDirectives(sourceFile.commentDirectives, result.commentDirectives, changeRange.span.start, ts.textSpanEnd(changeRange.span), delta, oldText, newText, aggressiveChecks);
            return result;
        }
        IncrementalParser.updateSourceFile = updateSourceFile;
        function getNewCommentDirectives(oldDirectives, newDirectives, changeStart, changeRangeOldEnd, delta, oldText, newText, aggressiveChecks) {
            if (!oldDirectives)
                return newDirectives;
            var commentDirectives;
            var addedNewlyScannedDirectives = false;
            for (var _i = 0, oldDirectives_1 = oldDirectives; _i < oldDirectives_1.length; _i++) {
                var directive = oldDirectives_1[_i];
                var range = directive.range, type = directive.type;
                // Range before the change
                if (range.end < changeStart) {
                    commentDirectives = ts.append(commentDirectives, directive);
                }
                else if (range.pos > changeRangeOldEnd) {
                    addNewlyScannedDirectives();
                    // Node is entirely past the change range.  We need to move both its pos and
                    // end, forward or backward appropriately.
                    var updatedDirective = {
                        range: { pos: range.pos + delta, end: range.end + delta },
                        type: type
                    };
                    commentDirectives = ts.append(commentDirectives, updatedDirective);
                    if (aggressiveChecks) {
                        ts.Debug.assert(oldText.substring(range.pos, range.end) === newText.substring(updatedDirective.range.pos, updatedDirective.range.end));
                    }
                }
                // Ignore ranges that fall in change range
            }
            addNewlyScannedDirectives();
            return commentDirectives;
            function addNewlyScannedDirectives() {
                if (addedNewlyScannedDirectives)
                    return;
                addedNewlyScannedDirectives = true;
                if (!commentDirectives) {
                    commentDirectives = newDirectives;
                }
                else if (newDirectives) {
                    commentDirectives.push.apply(commentDirectives, newDirectives);
                }
            }
        }
        function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
            if (isArray) {
                visitArray(element);
            }
            else {
                visitNode(element);
            }
            return;
            function visitNode(node) {
                var text = "";
                if (aggressiveChecks && shouldCheckNode(node)) {
                    text = oldText.substring(node.pos, node.end);
                }
                // Ditch any existing LS children we may have created.  This way we can avoid
                // moving them forward.
                if (node._children) {
                    node._children = undefined;
                }
                node.pos += delta;
                node.end += delta;
                if (aggressiveChecks && shouldCheckNode(node)) {
                    ts.Debug.assert(text === newText.substring(node.pos, node.end));
                }
                forEachChild(node, visitNode, visitArray);
                if (ts.hasJSDocNodes(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsDocComment = _a[_i];
                        visitNode(jsDocComment);
                    }
                }
                checkNodePositions(node, aggressiveChecks);
            }
            function visitArray(array) {
                array._children = undefined;
                array.pos += delta;
                array.end += delta;
                for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
                    var node = array_8[_i];
                    visitNode(node);
                }
            }
        }
        function shouldCheckNode(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 75 /* Identifier */:
                    return true;
            }
            return false;
        }
        function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
            ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
            ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
            ts.Debug.assert(element.pos <= element.end);
            // We have an element that intersects the change range in some way.  It may have its
            // start, or its end (or both) in the changed range.  We want to adjust any part
            // that intersects such that the final tree is in a consistent state.  i.e. all
            // children have spans within the span of their parent, and all siblings are ordered
            // properly.
            // We may need to update both the 'pos' and the 'end' of the element.
            // If the 'pos' is before the start of the change, then we don't need to touch it.
            // If it isn't, then the 'pos' must be inside the change.  How we update it will
            // depend if delta is positive or negative. If delta is positive then we have
            // something like:
            //
            //  -------------------AAA-----------------
            //  -------------------BBBCCCCCCC-----------------
            //
            // In this case, we consider any node that started in the change range to still be
            // starting at the same position.
            //
            // however, if the delta is negative, then we instead have something like this:
            //
            //  -------------------XXXYYYYYYY-----------------
            //  -------------------ZZZ-----------------
            //
            // In this case, any element that started in the 'X' range will keep its position.
            // However any element that started after that will have their pos adjusted to be
            // at the end of the new range.  i.e. any node that started in the 'Y' range will
            // be adjusted to have their start at the end of the 'Z' range.
            //
            // The element will keep its position if possible.  Or Move backward to the new-end
            // if it's in the 'Y' range.
            element.pos = Math.min(element.pos, changeRangeNewEnd);
            // If the 'end' is after the change range, then we always adjust it by the delta
            // amount.  However, if the end is in the change range, then how we adjust it
            // will depend on if delta is positive or negative.  If delta is positive then we
            // have something like:
            //
            //  -------------------AAA-----------------
            //  -------------------BBBCCCCCCC-----------------
            //
            // In this case, we consider any node that ended inside the change range to keep its
            // end position.
            //
            // however, if the delta is negative, then we instead have something like this:
            //
            //  -------------------XXXYYYYYYY-----------------
            //  -------------------ZZZ-----------------
            //
            // In this case, any element that ended in the 'X' range will keep its position.
            // However any element that ended after that will have their pos adjusted to be
            // at the end of the new range.  i.e. any node that ended in the 'Y' range will
            // be adjusted to have their end at the end of the 'Z' range.
            if (element.end >= changeRangeOldEnd) {
                // Element ends after the change range.  Always adjust the end pos.
                element.end += delta;
            }
            else {
                // Element ends in the change range.  The element will keep its position if
                // possible. Or Move backward to the new-end if it's in the 'Y' range.
                element.end = Math.min(element.end, changeRangeNewEnd);
            }
            ts.Debug.assert(element.pos <= element.end);
            if (element.parent) {
                ts.Debug.assert(element.pos >= element.parent.pos);
                ts.Debug.assert(element.end <= element.parent.end);
            }
        }
        function checkNodePositions(node, aggressiveChecks) {
            if (aggressiveChecks) {
                var pos_2 = node.pos;
                var visitNode_1 = function (child) {
                    ts.Debug.assert(child.pos >= pos_2);
                    pos_2 = child.end;
                };
                if (ts.hasJSDocNodes(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsDocComment = _a[_i];
                        visitNode_1(jsDocComment);
                    }
                }
                forEachChild(node, visitNode_1);
                ts.Debug.assert(pos_2 <= node.end);
            }
        }
        function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
            visitNode(sourceFile);
            return;
            function visitNode(child) {
                ts.Debug.assert(child.pos <= child.end);
                if (child.pos > changeRangeOldEnd) {
                    // Node is entirely past the change range.  We need to move both its pos and
                    // end, forward or backward appropriately.
                    moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
                    return;
                }
                // Check if the element intersects the change range.  If it does, then it is not
                // reusable.  Also, we'll need to recurse to see what constituent portions we may
                // be able to use.
                var fullEnd = child.end;
                if (fullEnd >= changeStart) {
                    child.intersectsChange = true;
                    child._children = undefined;
                    // Adjust the pos or end (or both) of the intersecting element accordingly.
                    adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
                    forEachChild(child, visitNode, visitArray);
                    if (ts.hasJSDocNodes(child)) {
                        for (var _i = 0, _a = child.jsDoc; _i < _a.length; _i++) {
                            var jsDocComment = _a[_i];
                            visitNode(jsDocComment);
                        }
                    }
                    checkNodePositions(child, aggressiveChecks);
                    return;
                }
                // Otherwise, the node is entirely before the change range.  No need to do anything with it.
                ts.Debug.assert(fullEnd < changeStart);
            }
            function visitArray(array) {
                ts.Debug.assert(array.pos <= array.end);
                if (array.pos > changeRangeOldEnd) {
                    // Array is entirely after the change range.  We need to move it, and move any of
                    // its children.
                    moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
                    return;
                }
                // Check if the element intersects the change range.  If it does, then it is not
                // reusable.  Also, we'll need to recurse to see what constituent portions we may
                // be able to use.
                var fullEnd = array.end;
                if (fullEnd >= changeStart) {
                    array.intersectsChange = true;
                    array._children = undefined;
                    // Adjust the pos or end (or both) of the intersecting array accordingly.
                    adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
                    for (var _i = 0, array_9 = array; _i < array_9.length; _i++) {
                        var node = array_9[_i];
                        visitNode(node);
                    }
                    return;
                }
                // Otherwise, the array is entirely before the change range.  No need to do anything with it.
                ts.Debug.assert(fullEnd < changeStart);
            }
        }
        function extendToAffectedRange(sourceFile, changeRange) {
            // Consider the following code:
            //      void foo() { /; }
            //
            // If the text changes with an insertion of / just before the semicolon then we end up with:
            //      void foo() { //; }
            //
            // If we were to just use the changeRange a is, then we would not rescan the { token
            // (as it does not intersect the actual original change range).  Because an edit may
            // change the token touching it, we actually need to look back *at least* one token so
            // that the prior token sees that change.
            var maxLookahead = 1;
            var start = changeRange.span.start;
            // the first iteration aligns us with the change start. subsequent iteration move us to
            // the left by maxLookahead tokens.  We only need to do this as long as we're not at the
            // start of the tree.
            for (var i = 0; start > 0 && i <= maxLookahead; i++) {
                var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
                ts.Debug.assert(nearestNode.pos <= start);
                var position = nearestNode.pos;
                start = Math.max(0, position - 1);
            }
            var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
            var finalLength = changeRange.newLength + (changeRange.span.start - start);
            return ts.createTextChangeRange(finalSpan, finalLength);
        }
        function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
            var bestResult = sourceFile;
            var lastNodeEntirelyBeforePosition;
            forEachChild(sourceFile, visit);
            if (lastNodeEntirelyBeforePosition) {
                var lastChildOfLastEntireNodeBeforePosition = getLastDescendant(lastNodeEntirelyBeforePosition);
                if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
                    bestResult = lastChildOfLastEntireNodeBeforePosition;
                }
            }
            return bestResult;
            function getLastDescendant(node) {
                while (true) {
                    var lastChild = ts.getLastChild(node);
                    if (lastChild) {
                        node = lastChild;
                    }
                    else {
                        return node;
                    }
                }
            }
            function visit(child) {
                if (ts.nodeIsMissing(child)) {
                    // Missing nodes are effectively invisible to us.  We never even consider them
                    // When trying to find the nearest node before us.
                    return;
                }
                // If the child intersects this position, then this node is currently the nearest
                // node that starts before the position.
                if (child.pos <= position) {
                    if (child.pos >= bestResult.pos) {
                        // This node starts before the position, and is closer to the position than
                        // the previous best node we found.  It is now the new best node.
                        bestResult = child;
                    }
                    // Now, the node may overlap the position, or it may end entirely before the
                    // position.  If it overlaps with the position, then either it, or one of its
                    // children must be the nearest node before the position.  So we can just
                    // recurse into this child to see if we can find something better.
                    if (position < child.end) {
                        // The nearest node is either this child, or one of the children inside
                        // of it.  We've already marked this child as the best so far.  Recurse
                        // in case one of the children is better.
                        forEachChild(child, visit);
                        // Once we look at the children of this node, then there's no need to
                        // continue any further.
                        return true;
                    }
                    else {
                        ts.Debug.assert(child.end <= position);
                        // The child ends entirely before this position.  Say you have the following
                        // (where $ is the position)
                        //
                        //      <complex expr 1> ? <complex expr 2> $ : <...> <...>
                        //
                        // We would want to find the nearest preceding node in "complex expr 2".
                        // To support that, we keep track of this node, and once we're done searching
                        // for a best node, we recurse down this node to see if we can find a good
                        // result in it.
                        //
                        // This approach allows us to quickly skip over nodes that are entirely
                        // before the position, while still allowing us to find any nodes in the
                        // last one that might be what we want.
                        lastNodeEntirelyBeforePosition = child;
                    }
                }
                else {
                    ts.Debug.assert(child.pos > position);
                    // We're now at a node that is entirely past the position we're searching for.
                    // This node (and all following nodes) could never contribute to the result,
                    // so just skip them by returning 'true' here.
                    return true;
                }
            }
        }
        function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
            var oldText = sourceFile.text;
            if (textChangeRange) {
                ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
                if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
                    var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
                    var newTextPrefix = newText.substr(0, textChangeRange.span.start);
                    ts.Debug.assert(oldTextPrefix === newTextPrefix);
                    var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
                    var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
                    ts.Debug.assert(oldTextSuffix === newTextSuffix);
                }
            }
        }
        function createSyntaxCursor(sourceFile) {
            var currentArray = sourceFile.statements;
            var currentArrayIndex = 0;
            ts.Debug.assert(currentArrayIndex < currentArray.length);
            var current = currentArray[currentArrayIndex];
            var lastQueriedPosition = -1 /* Value */;
            return {
                currentNode: function (position) {
                    // Only compute the current node if the position is different than the last time
                    // we were asked.  The parser commonly asks for the node at the same position
                    // twice.  Once to know if can read an appropriate list element at a certain point,
                    // and then to actually read and consume the node.
                    if (position !== lastQueriedPosition) {
                        // Much of the time the parser will need the very next node in the array that
                        // we just returned a node from.So just simply check for that case and move
                        // forward in the array instead of searching for the node again.
                        if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
                            currentArrayIndex++;
                            current = currentArray[currentArrayIndex];
                        }
                        // If we don't have a node, or the node we have isn't in the right position,
                        // then try to find a viable node at the position requested.
                        if (!current || current.pos !== position) {
                            findHighestListElementThatStartsAtPosition(position);
                        }
                    }
                    // Cache this query so that we don't do any extra work if the parser calls back
                    // into us.  Note: this is very common as the parser will make pairs of calls like
                    // 'isListElement -> parseListElement'.  If we were unable to find a node when
                    // called with 'isListElement', we don't want to redo the work when parseListElement
                    // is called immediately after.
                    lastQueriedPosition = position;
                    // Either we don'd have a node, or we have a node at the position being asked for.
                    ts.Debug.assert(!current || current.pos === position);
                    return current;
                }
            };
            // Finds the highest element in the tree we can find that starts at the provided position.
            // The element must be a direct child of some node list in the tree.  This way after we
            // return it, we can easily return its next sibling in the list.
            function findHighestListElementThatStartsAtPosition(position) {
                // Clear out any cached state about the last node we found.
                currentArray = undefined;
                currentArrayIndex = -1 /* Value */;
                current = undefined;
                // Recurse into the source file to find the highest node at this position.
                forEachChild(sourceFile, visitNode, visitArray);
                return;
                function visitNode(node) {
                    if (position >= node.pos && position < node.end) {
                        // Position was within this node.  Keep searching deeper to find the node.
                        forEachChild(node, visitNode, visitArray);
                        // don't proceed any further in the search.
                        return true;
                    }
                    // position wasn't in this node, have to keep searching.
                    return false;
                }
                function visitArray(array) {
                    if (position >= array.pos && position < array.end) {
                        // position was in this array.  Search through this array to see if we find a
                        // viable element.
                        for (var i = 0; i < array.length; i++) {
                            var child = array[i];
                            if (child) {
                                if (child.pos === position) {
                                    // Found the right node.  We're done.
                                    currentArray = array;
                                    currentArrayIndex = i;
                                    current = child;
                                    return true;
                                }
                                else {
                                    if (child.pos < position && position < child.end) {
                                        // Position in somewhere within this child.  Search in it and
                                        // stop searching in this array.
                                        forEachChild(child, visitNode, visitArray);
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                    // position wasn't in this array, have to keep searching.
                    return false;
                }
            }
        }
        var InvalidPosition;
        (function (InvalidPosition) {
            InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
        })(InvalidPosition || (InvalidPosition = {}));
    })(IncrementalParser || (IncrementalParser = {}));
    /** @internal */
    function isDeclarationFileName(fileName) {
        return ts.fileExtensionIs(fileName, ".d.ts" /* Dts */);
    }
    ts.isDeclarationFileName = isDeclarationFileName;
    /*@internal*/
    function processCommentPragmas(context, sourceText) {
        var pragmas = [];
        for (var _i = 0, _a = ts.getLeadingCommentRanges(sourceText, 0) || ts.emptyArray; _i < _a.length; _i++) {
            var range = _a[_i];
            var comment = sourceText.substring(range.pos, range.end);
            extractPragmas(pragmas, range, comment);
        }
        context.pragmas = ts.createMap();
        for (var _b = 0, pragmas_1 = pragmas; _b < pragmas_1.length; _b++) {
            var pragma = pragmas_1[_b];
            if (context.pragmas.has(pragma.name)) {
                var currentValue = context.pragmas.get(pragma.name);
                if (currentValue instanceof Array) {
                    currentValue.push(pragma.args);
                }
                else {
                    context.pragmas.set(pragma.name, [currentValue, pragma.args]);
                }
                continue;
            }
            context.pragmas.set(pragma.name, pragma.args);
        }
    }
    ts.processCommentPragmas = processCommentPragmas;
    /*@internal*/
    function processPragmasIntoFields(context, reportDiagnostic) {
        context.checkJsDirective = undefined;
        context.referencedFiles = [];
        context.typeReferenceDirectives = [];
        context.libReferenceDirectives = [];
        context.amdDependencies = [];
        context.hasNoDefaultLib = false;
        context.pragmas.forEach(function (entryOrList, key) {
            // TODO: The below should be strongly type-guarded and not need casts/explicit annotations, since entryOrList is related to
            // key and key is constrained to a union; but it's not (see GH#21483 for at least partial fix) :(
            switch (key) {
                case "reference": {
                    var referencedFiles_1 = context.referencedFiles;
                    var typeReferenceDirectives_1 = context.typeReferenceDirectives;
                    var libReferenceDirectives_1 = context.libReferenceDirectives;
                    ts.forEach(ts.toArray(entryOrList), function (arg) {
                        var _a = arg.arguments, types = _a.types, lib = _a.lib, path = _a.path;
                        if (arg.arguments["no-default-lib"]) {
                            context.hasNoDefaultLib = true;
                        }
                        else if (types) {
                            typeReferenceDirectives_1.push({ pos: types.pos, end: types.end, fileName: types.value });
                        }
                        else if (lib) {
                            libReferenceDirectives_1.push({ pos: lib.pos, end: lib.end, fileName: lib.value });
                        }
                        else if (path) {
                            referencedFiles_1.push({ pos: path.pos, end: path.end, fileName: path.value });
                        }
                        else {
                            reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, ts.Diagnostics.Invalid_reference_directive_syntax);
                        }
                    });
                    break;
                }
                case "amd-dependency": {
                    context.amdDependencies = ts.map(ts.toArray(entryOrList), function (x) { return ({ name: x.arguments.name, path: x.arguments.path }); });
                    break;
                }
                case "amd-module": {
                    if (entryOrList instanceof Array) {
                        for (var _i = 0, entryOrList_1 = entryOrList; _i < entryOrList_1.length; _i++) {
                            var entry = entryOrList_1[_i];
                            if (context.moduleName) {
                                // TODO: It's probably fine to issue this diagnostic on all instances of the pragma
                                reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments);
                            }
                            context.moduleName = entry.arguments.name;
                        }
                    }
                    else {
                        context.moduleName = entryOrList.arguments.name;
                    }
                    break;
                }
                case "ts-nocheck":
                case "ts-check": {
                    // _last_ of either nocheck or check in a file is the "winner"
                    ts.forEach(ts.toArray(entryOrList), function (entry) {
                        if (!context.checkJsDirective || entry.range.pos > context.checkJsDirective.pos) {
                            context.checkJsDirective = {
                                enabled: key === "ts-check",
                                end: entry.range.end,
                                pos: entry.range.pos
                            };
                        }
                    });
                    break;
                }
                case "jsx": return; // Accessed directly
                default: ts.Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future?
            }
        });
    }
    ts.processPragmasIntoFields = processPragmasIntoFields;
    var namedArgRegExCache = ts.createMap();
    function getNamedArgRegEx(name) {
        if (namedArgRegExCache.has(name)) {
            return namedArgRegExCache.get(name);
        }
        var result = new RegExp("(\\s" + name + "\\s*=\\s*)('|\")(.+?)\\2", "im");
        namedArgRegExCache.set(name, result);
        return result;
    }
    var tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/im;
    var singleLinePragmaRegEx = /^\/\/\/?\s*@(\S+)\s*(.*)\s*$/im;
    function extractPragmas(pragmas, range, text) {
        var tripleSlash = range.kind === 2 /* SingleLineCommentTrivia */ && tripleSlashXMLCommentStartRegEx.exec(text);
        if (tripleSlash) {
            var name = tripleSlash[1].toLowerCase(); // Technically unsafe cast, but we do it so the below check to make it safe typechecks
            var pragma = ts.commentPragmas[name];
            if (!pragma || !(pragma.kind & 1 /* TripleSlashXML */)) {
                return;
            }
            if (pragma.args) {
                var argument = {};
                for (var _i = 0, _a = pragma.args; _i < _a.length; _i++) {
                    var arg = _a[_i];
                    var matcher = getNamedArgRegEx(arg.name);
                    var matchResult = matcher.exec(text);
                    if (!matchResult && !arg.optional) {
                        return; // Missing required argument, don't parse
                    }
                    else if (matchResult) {
                        if (arg.captureSpan) {
                            var startPos = range.pos + matchResult.index + matchResult[1].length + matchResult[2].length;
                            argument[arg.name] = {
                                value: matchResult[3],
                                pos: startPos,
                                end: startPos + matchResult[3].length
                            };
                        }
                        else {
                            argument[arg.name] = matchResult[3];
                        }
                    }
                }
                pragmas.push({ name: name, args: { arguments: argument, range: range } });
            }
            else {
                pragmas.push({ name: name, args: { arguments: {}, range: range } });
            }
            return;
        }
        var singleLine = range.kind === 2 /* SingleLineCommentTrivia */ && singleLinePragmaRegEx.exec(text);
        if (singleLine) {
            return addPragmaForMatch(pragmas, range, 2 /* SingleLine */, singleLine);
        }
        if (range.kind === 3 /* MultiLineCommentTrivia */) {
            var multiLinePragmaRegEx = /\s*@(\S+)\s*(.*)\s*$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
            var multiLineMatch = void 0;
            while (multiLineMatch = multiLinePragmaRegEx.exec(text)) {
                addPragmaForMatch(pragmas, range, 4 /* MultiLine */, multiLineMatch);
            }
        }
    }
    function addPragmaForMatch(pragmas, range, kind, match) {
        if (!match)
            return;
        var name = match[1].toLowerCase(); // Technically unsafe cast, but we do it so they below check to make it safe typechecks
        var pragma = ts.commentPragmas[name];
        if (!pragma || !(pragma.kind & kind)) {
            return;
        }
        var args = match[2]; // Split on spaces and match up positionally with definition
        var argument = getNamedPragmaArguments(pragma, args);
        if (argument === "fail")
            return; // Missing required argument, fail to parse it
        pragmas.push({ name: name, args: { arguments: argument, range: range } });
        return;
    }
    function getNamedPragmaArguments(pragma, text) {
        if (!text)
            return {};
        if (!pragma.args)
            return {};
        var args = text.split(/\s+/);
        var argMap = {};
        for (var i = 0; i < pragma.args.length; i++) {
            var argument = pragma.args[i];
            if (!args[i] && !argument.optional) {
                return "fail";
            }
            if (argument.captureSpan) {
                return ts.Debug.fail("Capture spans not yet implemented for non-xml pragmas");
            }
            argMap[argument.name] = args[i];
        }
        return argMap;
    }
    /** @internal */
    function tagNamesAreEquivalent(lhs, rhs) {
        if (lhs.kind !== rhs.kind) {
            return false;
        }
        if (lhs.kind === 75 /* Identifier */) {
            return lhs.escapedText === rhs.escapedText;
        }
        if (lhs.kind === 104 /* ThisKeyword */) {
            return true;
        }
        // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
        // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
        // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
        return lhs.name.escapedText === rhs.name.escapedText &&
            tagNamesAreEquivalent(lhs.expression, rhs.expression);
    }
    ts.tagNamesAreEquivalent = tagNamesAreEquivalent;
})(ts || (ts = {}));
var ts;
(function (ts) {
    /* @internal */
    ts.compileOnSaveCommandLineOption = { name: "compileOnSave", type: "boolean" };
    // NOTE: The order here is important to default lib ordering as entries will have the same
    //       order in the generated program (see `getDefaultLibPriority` in program.ts). This
    //       order also affects overload resolution when a type declared in one lib is
    //       augmented in another lib.
    var libEntries = [
        // JavaScript only
        ["es5", "lib.es5.d.ts"],
        ["es6", "lib.es2015.d.ts"],
        ["es2015", "lib.es2015.d.ts"],
        ["es7", "lib.es2016.d.ts"],
        ["es2016", "lib.es2016.d.ts"],
        ["es2017", "lib.es2017.d.ts"],
        ["es2018", "lib.es2018.d.ts"],
        ["es2019", "lib.es2019.d.ts"],
        ["es2020", "lib.es2020.d.ts"],
        ["esnext", "lib.esnext.d.ts"],
        // Host only
        ["dom", "lib.dom.d.ts"],
        ["dom.iterable", "lib.dom.iterable.d.ts"],
        ["webworker", "lib.webworker.d.ts"],
        ["webworker.importscripts", "lib.webworker.importscripts.d.ts"],
        ["scripthost", "lib.scripthost.d.ts"],
        // ES2015 Or ESNext By-feature options
        ["es2015.core", "lib.es2015.core.d.ts"],
        ["es2015.collection", "lib.es2015.collection.d.ts"],
        ["es2015.generator", "lib.es2015.generator.d.ts"],
        ["es2015.iterable", "lib.es2015.iterable.d.ts"],
        ["es2015.promise", "lib.es2015.promise.d.ts"],
        ["es2015.proxy", "lib.es2015.proxy.d.ts"],
        ["es2015.reflect", "lib.es2015.reflect.d.ts"],
        ["es2015.symbol", "lib.es2015.symbol.d.ts"],
        ["es2015.symbol.wellknown", "lib.es2015.symbol.wellknown.d.ts"],
        ["es2016.array.include", "lib.es2016.array.include.d.ts"],
        ["es2017.object", "lib.es2017.object.d.ts"],
        ["es2017.sharedmemory", "lib.es2017.sharedmemory.d.ts"],
        ["es2017.string", "lib.es2017.string.d.ts"],
        ["es2017.intl", "lib.es2017.intl.d.ts"],
        ["es2017.typedarrays", "lib.es2017.typedarrays.d.ts"],
        ["es2018.asyncgenerator", "lib.es2018.asyncgenerator.d.ts"],
        ["es2018.asynciterable", "lib.es2018.asynciterable.d.ts"],
        ["es2018.intl", "lib.es2018.intl.d.ts"],
        ["es2018.promise", "lib.es2018.promise.d.ts"],
        ["es2018.regexp", "lib.es2018.regexp.d.ts"],
        ["es2019.array", "lib.es2019.array.d.ts"],
        ["es2019.object", "lib.es2019.object.d.ts"],
        ["es2019.string", "lib.es2019.string.d.ts"],
        ["es2019.symbol", "lib.es2019.symbol.d.ts"],
        ["es2020.bigint", "lib.es2020.bigint.d.ts"],
        ["es2020.promise", "lib.es2020.promise.d.ts"],
        ["es2020.string", "lib.es2020.string.d.ts"],
        ["es2020.symbol.wellknown", "lib.es2020.symbol.wellknown.d.ts"],
        ["esnext.array", "lib.es2019.array.d.ts"],
        ["esnext.symbol", "lib.es2019.symbol.d.ts"],
        ["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
        ["esnext.intl", "lib.esnext.intl.d.ts"],
        ["esnext.bigint", "lib.es2020.bigint.d.ts"],
        ["esnext.string", "lib.esnext.string.d.ts"],
        ["esnext.promise", "lib.esnext.promise.d.ts"]
    ];
    /**
     * An array of supported "lib" reference file names used to determine the order for inclusion
     * when referenced, as well as for spelling suggestions. This ensures the correct ordering for
     * overload resolution when a type declared in one lib is extended by another.
     */
    /* @internal */
    ts.libs = libEntries.map(function (entry) { return entry[0]; });
    /**
     * A map of lib names to lib files. This map is used both for parsing the "lib" command line
     * option as well as for resolving lib reference directives.
     */
    /* @internal */
    ts.libMap = ts.createMapFromEntries(libEntries);
    // Watch related options
    /* @internal */
    ts.optionsForWatch = [
        {
            name: "watchFile",
            type: ts.createMapFromTemplate({
                fixedpollinginterval: ts.WatchFileKind.FixedPollingInterval,
                prioritypollinginterval: ts.WatchFileKind.PriorityPollingInterval,
                dynamicprioritypolling: ts.WatchFileKind.DynamicPriorityPolling,
                usefsevents: ts.WatchFileKind.UseFsEvents,
                usefseventsonparentdirectory: ts.WatchFileKind.UseFsEventsOnParentDirectory,
            }),
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_DynamicPriorityPolling_UseFsEvents_UseFsEventsOnParentDirectory,
        },
        {
            name: "watchDirectory",
            type: ts.createMapFromTemplate({
                usefsevents: ts.WatchDirectoryKind.UseFsEvents,
                fixedpollinginterval: ts.WatchDirectoryKind.FixedPollingInterval,
                dynamicprioritypolling: ts.WatchDirectoryKind.DynamicPriorityPolling,
            }),
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively_Colon_UseFsEvents_default_FixedPollingInterval_DynamicPriorityPolling,
        },
        {
            name: "fallbackPolling",
            type: ts.createMapFromTemplate({
                fixedinterval: ts.PollingWatchKind.FixedInterval,
                priorityinterval: ts.PollingWatchKind.PriorityInterval,
                dynamicpriority: ts.PollingWatchKind.DynamicPriority,
            }),
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_FixedInterval_default_PriorityInterval_DynamicPriority,
        },
        {
            name: "synchronousWatchDirectory",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively,
        },
    ];
    /* @internal */
    ts.commonOptionsWithBuild = [
        {
            name: "help",
            shortName: "h",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Print_this_message,
        },
        {
            name: "help",
            shortName: "?",
            type: "boolean"
        },
        {
            name: "watch",
            shortName: "w",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Watch_input_files,
        },
        {
            name: "preserveWatchOutput",
            type: "boolean",
            showInSimplifiedHelpView: false,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen,
        },
        {
            name: "listFiles",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Print_names_of_files_part_of_the_compilation
        },
        {
            name: "listEmittedFiles",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Print_names_of_generated_files_part_of_the_compilation
        },
        {
            name: "pretty",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
        },
        {
            name: "traceResolution",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Enable_tracing_of_the_name_resolution_process
        },
        {
            name: "diagnostics",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Show_diagnostic_information
        },
        {
            name: "extendedDiagnostics",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Show_verbose_diagnostic_information
        },
        {
            name: "generateCpuProfile",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.FILE_OR_DIRECTORY,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Generates_a_CPU_profile
        },
        {
            name: "incremental",
            shortName: "i",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Enable_incremental_compilation,
            transpileOptionValue: undefined
        },
        {
            name: "assumeChangesOnlyAffectDirectDependencies",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it
        },
        {
            name: "locale",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us
        },
    ];
    /* @internal */
    ts.optionDeclarations = __spreadArrays(ts.commonOptionsWithBuild, [
        {
            name: "all",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Show_all_compiler_options,
        },
        {
            name: "version",
            shortName: "v",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Print_the_compiler_s_version,
        },
        {
            name: "init",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file,
        },
        {
            name: "project",
            shortName: "p",
            type: "string",
            isFilePath: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            paramType: ts.Diagnostics.FILE_OR_DIRECTORY,
            description: ts.Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json,
        },
        {
            name: "build",
            type: "boolean",
            shortName: "b",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date
        },
        {
            name: "showConfig",
            type: "boolean",
            category: ts.Diagnostics.Command_line_Options,
            isCommandLineOnly: true,
            description: ts.Diagnostics.Print_the_final_configuration_instead_of_building
        },
        {
            name: "listFilesOnly",
            type: "boolean",
            category: ts.Diagnostics.Command_line_Options,
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            isCommandLineOnly: true,
            description: ts.Diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing
        },
        // Basic
        {
            name: "target",
            shortName: "t",
            type: ts.createMapFromTemplate({
                es3: 0 /* ES3 */,
                es5: 1 /* ES5 */,
                es6: 2 /* ES2015 */,
                es2015: 2 /* ES2015 */,
                es2016: 3 /* ES2016 */,
                es2017: 4 /* ES2017 */,
                es2018: 5 /* ES2018 */,
                es2019: 6 /* ES2019 */,
                es2020: 7 /* ES2020 */,
                esnext: 99 /* ESNext */,
            }),
            affectsSourceFile: true,
            affectsModuleResolution: true,
            affectsEmit: true,
            paramType: ts.Diagnostics.VERSION,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_ES2020_or_ESNEXT,
        },
        {
            name: "module",
            shortName: "m",
            type: ts.createMapFromTemplate({
                none: ts.ModuleKind.None,
                commonjs: ts.ModuleKind.CommonJS,
                amd: ts.ModuleKind.AMD,
                system: ts.ModuleKind.System,
                umd: ts.ModuleKind.UMD,
                es6: ts.ModuleKind.ES2015,
                es2015: ts.ModuleKind.ES2015,
                es2020: ts.ModuleKind.ES2020,
                esnext: ts.ModuleKind.ESNext
            }),
            affectsModuleResolution: true,
            affectsEmit: true,
            paramType: ts.Diagnostics.KIND,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_es2020_or_ESNext,
        },
        {
            name: "lib",
            type: "list",
            element: {
                name: "lib",
                type: ts.libMap
            },
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_library_files_to_be_included_in_the_compilation,
            transpileOptionValue: undefined
        },
        {
            name: "allowJs",
            type: "boolean",
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Allow_javascript_files_to_be_compiled
        },
        {
            name: "checkJs",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Report_errors_in_js_files
        },
        {
            name: "jsx",
            type: ts.createMapFromTemplate({
                "preserve": 1 /* Preserve */,
                "react-native": 3 /* ReactNative */,
                "react": 2 /* React */
            }),
            affectsSourceFile: true,
            paramType: ts.Diagnostics.KIND,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react,
        },
        {
            name: "declaration",
            shortName: "d",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_corresponding_d_ts_file,
            transpileOptionValue: undefined
        },
        {
            name: "declarationMap",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_a_sourcemap_for_each_corresponding_d_ts_file,
            transpileOptionValue: undefined
        },
        {
            name: "emitDeclarationOnly",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Only_emit_d_ts_declaration_files,
            transpileOptionValue: undefined
        },
        {
            name: "sourceMap",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_corresponding_map_file,
        },
        {
            name: "outFile",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.FILE,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Concatenate_and_emit_output_to_single_file,
            transpileOptionValue: undefined
        },
        {
            name: "outDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Redirect_output_structure_to_the_directory,
        },
        {
            name: "rootDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
        },
        {
            name: "composite",
            type: "boolean",
            affectsEmit: true,
            isTSConfigOnly: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Enable_project_compilation,
            transpileOptionValue: undefined
        },
        {
            name: "tsBuildInfoFile",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.FILE,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_file_to_store_incremental_compilation_information,
            transpileOptionValue: undefined
        },
        {
            name: "removeComments",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Do_not_emit_comments_to_output,
        },
        {
            name: "noEmit",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Do_not_emit_outputs,
            transpileOptionValue: undefined
        },
        {
            name: "importHelpers",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Import_emit_helpers_from_tslib
        },
        {
            name: "importsNotUsedAsValues",
            type: ts.createMapFromTemplate({
                remove: 0 /* Remove */,
                preserve: 1 /* Preserve */,
                error: 2 /* Error */
            }),
            affectsEmit: true,
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types
        },
        {
            name: "downlevelIteration",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3
        },
        {
            name: "isolatedModules",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule,
            transpileOptionValue: true
        },
        // Strict Type Checks
        {
            name: "strict",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_all_strict_type_checking_options
        },
        {
            name: "noImplicitAny",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type
        },
        {
            name: "strictNullChecks",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_null_checks
        },
        {
            name: "strictFunctionTypes",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_checking_of_function_types
        },
        {
            name: "strictBindCallApply",
            type: "boolean",
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_bind_call_and_apply_methods_on_functions
        },
        {
            name: "strictPropertyInitialization",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_checking_of_property_initialization_in_classes
        },
        {
            name: "noImplicitThis",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type,
        },
        {
            name: "alwaysStrict",
            type: "boolean",
            affectsSourceFile: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
        },
        // Additional Checks
        {
            name: "noUnusedLocals",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_on_unused_locals,
        },
        {
            name: "noUnusedParameters",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_on_unused_parameters,
        },
        {
            name: "noImplicitReturns",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value
        },
        {
            name: "noFallthroughCasesInSwitch",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement
        },
        // Module Resolution
        {
            name: "moduleResolution",
            type: ts.createMapFromTemplate({
                node: ts.ModuleResolutionKind.NodeJs,
                classic: ts.ModuleResolutionKind.Classic,
            }),
            affectsModuleResolution: true,
            paramType: ts.Diagnostics.STRATEGY,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
        },
        {
            name: "baseUrl",
            type: "string",
            affectsModuleResolution: true,
            isFilePath: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Base_directory_to_resolve_non_absolute_module_names
        },
        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "paths",
            type: "object",
            affectsModuleResolution: true,
            isTSConfigOnly: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl,
            transpileOptionValue: undefined
        },
        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "rootDirs",
            type: "list",
            isTSConfigOnly: true,
            element: {
                name: "rootDirs",
                type: "string",
                isFilePath: true
            },
            affectsModuleResolution: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime,
            transpileOptionValue: undefined
        },
        {
            name: "typeRoots",
            type: "list",
            element: {
                name: "typeRoots",
                type: "string",
                isFilePath: true
            },
            affectsModuleResolution: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.List_of_folders_to_include_type_definitions_from
        },
        {
            name: "types",
            type: "list",
            element: {
                name: "types",
                type: "string"
            },
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Type_declaration_files_to_be_included_in_compilation,
            transpileOptionValue: undefined
        },
        {
            name: "allowSyntheticDefaultImports",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
        },
        {
            name: "esModuleInterop",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports
        },
        {
            name: "preserveSymlinks",
            type: "boolean",
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks,
        },
        {
            name: "allowUmdGlobalAccess",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Allow_accessing_UMD_globals_from_modules,
        },
        // Source Maps
        {
            name: "sourceRoot",
            type: "string",
            affectsEmit: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
        },
        {
            name: "mapRoot",
            type: "string",
            affectsEmit: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
        },
        {
            name: "inlineSourceMap",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file
        },
        {
            name: "inlineSources",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set
        },
        // Experimental
        {
            name: "experimentalDecorators",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Experimental_Options,
            description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators
        },
        {
            name: "emitDecoratorMetadata",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            category: ts.Diagnostics.Experimental_Options,
            description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
        },
        // Advanced
        {
            name: "jsxFactory",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h
        },
        {
            name: "resolveJsonModule",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Include_modules_imported_with_json_extension
        },
        {
            name: "out",
            type: "string",
            affectsEmit: true,
            isFilePath: false,
            // for correct behaviour, please use outFile
            category: ts.Diagnostics.Advanced_Options,
            paramType: ts.Diagnostics.FILE,
            description: ts.Diagnostics.Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file,
            transpileOptionValue: undefined
        },
        {
            name: "reactNamespace",
            type: "string",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit
        },
        {
            name: "skipDefaultLibCheck",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files
        },
        {
            name: "charset",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_character_set_of_the_input_files
        },
        {
            name: "emitBOM",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files
        },
        {
            name: "newLine",
            type: ts.createMapFromTemplate({
                crlf: 0 /* CarriageReturnLineFeed */,
                lf: 1 /* LineFeed */
            }),
            affectsEmit: true,
            paramType: ts.Diagnostics.NEWLINE,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
        },
        {
            name: "noErrorTruncation",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_truncate_error_messages
        },
        {
            name: "noLib",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_include_the_default_library_file_lib_d_ts,
            // We are not returning a sourceFile for lib file when asked by the program,
            // so pass --noLib to avoid reporting a file not found error.
            transpileOptionValue: true
        },
        {
            name: "noResolve",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files,
            // We are not doing a full typecheck, we are not resolving the whole context,
            // so pass --noResolve to avoid reporting missing file errors.
            transpileOptionValue: true
        },
        {
            name: "stripInternal",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation,
        },
        {
            name: "disableSizeLimit",
            type: "boolean",
            affectsSourceFile: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_size_limitations_on_JavaScript_projects
        },
        {
            name: "disableSourceOfProjectReferenceRedirect",
            type: "boolean",
            isTSConfigOnly: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_use_of_source_files_instead_of_declaration_files_from_referenced_projects
        },
        {
            name: "disableSolutionSearching",
            type: "boolean",
            isTSConfigOnly: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_solution_searching_for_this_project
        },
        {
            name: "noImplicitUseStrict",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_use_strict_directives_in_module_output
        },
        {
            name: "noEmitHelpers",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output
        },
        {
            name: "noEmitOnError",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported,
            transpileOptionValue: undefined
        },
        {
            name: "preserveConstEnums",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code
        },
        {
            name: "declarationDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Output_directory_for_generated_declaration_files,
            transpileOptionValue: undefined
        },
        {
            name: "skipLibCheck",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Skip_type_checking_of_declaration_files,
        },
        {
            name: "allowUnusedLabels",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_report_errors_on_unused_labels
        },
        {
            name: "allowUnreachableCode",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_report_errors_on_unreachable_code
        },
        {
            name: "suppressExcessPropertyErrors",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals,
        },
        {
            name: "suppressImplicitAnyIndexErrors",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures,
        },
        {
            name: "forceConsistentCasingInFileNames",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
        },
        {
            name: "maxNodeModuleJsDepth",
            type: "number",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
        },
        {
            name: "noStrictGenericChecks",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
        },
        {
            name: "useDefineForClassFields",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Emit_class_fields_with_Define_instead_of_Set,
        },
        {
            name: "keyofStringsOnly",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols,
        },
        {
            // A list of plugins to load in the language service
            name: "plugins",
            type: "list",
            isTSConfigOnly: true,
            element: {
                name: "plugin",
                type: "object"
            },
            description: ts.Diagnostics.List_of_language_service_plugins
        },
    ]);
    /* @internal */
    ts.semanticDiagnosticsOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsSemanticDiagnostics; });
    /* @internal */
    ts.affectsEmitOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsEmit; });
    /* @internal */
    ts.moduleResolutionOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsModuleResolution; });
    /* @internal */
    ts.sourceFileAffectingCompilerOptions = ts.optionDeclarations.filter(function (option) {
        return !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics;
    });
    /* @internal */
    ts.transpileOptionValueCompilerOptions = ts.optionDeclarations.filter(function (option) {
        return ts.hasProperty(option, "transpileOptionValue");
    });
    /* @internal */
    ts.buildOpts = __spreadArrays(ts.commonOptionsWithBuild, [
        {
            name: "verbose",
            shortName: "v",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Enable_verbose_logging,
            type: "boolean"
        },
        {
            name: "dry",
            shortName: "d",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean,
            type: "boolean"
        },
        {
            name: "force",
            shortName: "f",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date,
            type: "boolean"
        },
        {
            name: "clean",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Delete_the_outputs_of_all_projects,
            type: "boolean"
        }
    ]);
    /* @internal */
    ts.typeAcquisitionDeclarations = [
        {
            /* @deprecated typingOptions.enableAutoDiscovery
             * Use typeAcquisition.enable instead.
             */
            name: "enableAutoDiscovery",
            type: "boolean",
        },
        {
            name: "enable",
            type: "boolean",
        },
        {
            name: "include",
            type: "list",
            element: {
                name: "include",
                type: "string"
            }
        },
        {
            name: "exclude",
            type: "list",
            element: {
                name: "exclude",
                type: "string"
            }
        }
    ];
    /*@internal*/
    function createOptionNameMap(optionDeclarations) {
        var optionsNameMap = ts.createMap();
        var shortOptionNames = ts.createMap();
        ts.forEach(optionDeclarations, function (option) {
            optionsNameMap.set(option.name.toLowerCase(), option);
            if (option.shortName) {
                shortOptionNames.set(option.shortName, option.name);
            }
        });
        return { optionsNameMap: optionsNameMap, shortOptionNames: shortOptionNames };
    }
    ts.createOptionNameMap = createOptionNameMap;
    var optionsNameMapCache;
    /* @internal */
    function getOptionsNameMap() {
        return optionsNameMapCache || (optionsNameMapCache = createOptionNameMap(ts.optionDeclarations));
    }
    ts.getOptionsNameMap = getOptionsNameMap;
    /* @internal */
    ts.defaultInitCompilerOptions = {
        module: ts.ModuleKind.CommonJS,
        target: 1 /* ES5 */,
        strict: true,
        esModuleInterop: true,
        forceConsistentCasingInFileNames: true,
        skipLibCheck: true
    };
    /* @internal */
    function convertEnableAutoDiscoveryToEnable(typeAcquisition) {
        // Convert deprecated typingOptions.enableAutoDiscovery to typeAcquisition.enable
        if (typeAcquisition && typeAcquisition.enableAutoDiscovery !== undefined && typeAcquisition.enable === undefined) {
            return {
                enable: typeAcquisition.enableAutoDiscovery,
                include: typeAcquisition.include || [],
                exclude: typeAcquisition.exclude || []
            };
        }
        return typeAcquisition;
    }
    ts.convertEnableAutoDiscoveryToEnable = convertEnableAutoDiscoveryToEnable;
    /* @internal */
    function createCompilerDiagnosticForInvalidCustomType(opt) {
        return createDiagnosticForInvalidCustomType(opt, ts.createCompilerDiagnostic);
    }
    ts.createCompilerDiagnosticForInvalidCustomType = createCompilerDiagnosticForInvalidCustomType;
    function createDiagnosticForInvalidCustomType(opt, createDiagnostic) {
        var namesOfType = ts.arrayFrom(opt.type.keys()).map(function (key) { return "'" + key + "'"; }).join(", ");
        return createDiagnostic(ts.Diagnostics.Argument_for_0_option_must_be_Colon_1, "--" + opt.name, namesOfType);
    }
    /* @internal */
    function parseCustomTypeOption(opt, value, errors) {
        return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
    }
    ts.parseCustomTypeOption = parseCustomTypeOption;
    /* @internal */
    function parseListTypeOption(opt, value, errors) {
        if (value === void 0) { value = ""; }
        value = trimString(value);
        if (ts.startsWith(value, "-")) {
            return undefined;
        }
        if (value === "") {
            return [];
        }
        var values = value.split(",");
        switch (opt.element.type) {
            case "number":
                return ts.map(values, parseInt);
            case "string":
                return ts.map(values, function (v) { return v || ""; });
            default:
                return ts.mapDefined(values, function (v) { return parseCustomTypeOption(opt.element, v, errors); });
        }
    }
    ts.parseListTypeOption = parseListTypeOption;
    function getOptionName(option) {
        return option.name;
    }
    function createUnknownOptionError(unknownOption, diagnostics, createDiagnostics, unknownOptionErrorText) {
        var possibleOption = ts.getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName);
        return possibleOption ?
            createDiagnostics(diagnostics.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) :
            createDiagnostics(diagnostics.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption);
    }
    /*@internal*/
    function parseCommandLineWorker(diagnostics, commandLine, readFile) {
        var options = {};
        var watchOptions;
        var fileNames = [];
        var errors = [];
        parseStrings(commandLine);
        return {
            options: options,
            watchOptions: watchOptions,
            fileNames: fileNames,
            errors: errors
        };
        function parseStrings(args) {
            var i = 0;
            while (i < args.length) {
                var s = args[i];
                i++;
                if (s.charCodeAt(0) === 64 /* at */) {
                    parseResponseFile(s.slice(1));
                }
                else if (s.charCodeAt(0) === 45 /* minus */) {
                    var inputOptionName = s.slice(s.charCodeAt(1) === 45 /* minus */ ? 2 : 1);
                    var opt = getOptionDeclarationFromName(diagnostics.getOptionsNameMap, inputOptionName, /*allowShort*/ true);
                    if (opt) {
                        i = parseOptionValue(args, i, diagnostics, opt, options, errors);
                    }
                    else {
                        var watchOpt = getOptionDeclarationFromName(watchOptionsDidYouMeanDiagnostics.getOptionsNameMap, inputOptionName, /*allowShort*/ true);
                        if (watchOpt) {
                            i = parseOptionValue(args, i, watchOptionsDidYouMeanDiagnostics, watchOpt, watchOptions || (watchOptions = {}), errors);
                        }
                        else {
                            errors.push(createUnknownOptionError(inputOptionName, diagnostics, ts.createCompilerDiagnostic, s));
                        }
                    }
                }
                else {
                    fileNames.push(s);
                }
            }
        }
        function parseResponseFile(fileName) {
            var text = tryReadFile(fileName, readFile || (function (fileName) { return ts.sys.readFile(fileName); }));
            if (!ts.isString(text)) {
                errors.push(text);
                return;
            }
            var args = [];
            var pos = 0;
            while (true) {
                while (pos < text.length && text.charCodeAt(pos) <= 32 /* space */)
                    pos++;
                if (pos >= text.length)
                    break;
                var start = pos;
                if (text.charCodeAt(start) === 34 /* doubleQuote */) {
                    pos++;
                    while (pos < text.length && text.charCodeAt(pos) !== 34 /* doubleQuote */)
                        pos++;
                    if (pos < text.length) {
                        args.push(text.substring(start + 1, pos));
                        pos++;
                    }
                    else {
                        errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unterminated_quoted_string_in_response_file_0, fileName));
                    }
                }
                else {
                    while (text.charCodeAt(pos) > 32 /* space */)
                        pos++;
                    args.push(text.substring(start, pos));
                }
            }
            parseStrings(args);
        }
    }
    ts.parseCommandLineWorker = parseCommandLineWorker;
    function parseOptionValue(args, i, diagnostics, opt, options, errors) {
        if (opt.isTSConfigOnly) {
            var optValue = args[i];
            if (optValue === "null") {
                options[opt.name] = undefined;
                i++;
            }
            else if (opt.type === "boolean") {
                if (optValue === "false") {
                    options[opt.name] = false;
                    i++;
                }
                else {
                    if (optValue === "true")
                        i++;
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line, opt.name));
                }
            }
            else {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line, opt.name));
                if (optValue && !ts.startsWith(optValue, "-"))
                    i++;
            }
        }
        else {
            // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
            if (!args[i] && opt.type !== "boolean") {
                errors.push(ts.createCompilerDiagnostic(diagnostics.optionTypeMismatchDiagnostic, opt.name, getCompilerOptionValueTypeString(opt)));
            }
            if (args[i] !== "null") {
                switch (opt.type) {
                    case "number":
                        options[opt.name] = parseInt(args[i]);
                        i++;
                        break;
                    case "boolean":
                        // boolean flag has optional value true, false, others
                        var optValue = args[i];
                        options[opt.name] = optValue !== "false";
                        // consume next argument as boolean flag value
                        if (optValue === "false" || optValue === "true") {
                            i++;
                        }
                        break;
                    case "string":
                        options[opt.name] = args[i] || "";
                        i++;
                        break;
                    case "list":
                        var result = parseListTypeOption(opt, args[i], errors);
                        options[opt.name] = result || [];
                        if (result) {
                            i++;
                        }
                        break;
                    // If not a primitive, the possible types are specified in what is effectively a map of options.
                    default:
                        options[opt.name] = parseCustomTypeOption(opt, args[i], errors);
                        i++;
                        break;
                }
            }
            else {
                options[opt.name] = undefined;
                i++;
            }
        }
        return i;
    }
    /*@internal*/
    ts.compilerOptionsDidYouMeanDiagnostics = {
        getOptionsNameMap: getOptionsNameMap,
        optionDeclarations: ts.optionDeclarations,
        unknownOptionDiagnostic: ts.Diagnostics.Unknown_compiler_option_0,
        unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_compiler_option_0_Did_you_mean_1,
        optionTypeMismatchDiagnostic: ts.Diagnostics.Compiler_option_0_expects_an_argument
    };
    function parseCommandLine(commandLine, readFile) {
        return parseCommandLineWorker(ts.compilerOptionsDidYouMeanDiagnostics, commandLine, readFile);
    }
    ts.parseCommandLine = parseCommandLine;
    /** @internal */
    function getOptionFromName(optionName, allowShort) {
        return getOptionDeclarationFromName(getOptionsNameMap, optionName, allowShort);
    }
    ts.getOptionFromName = getOptionFromName;
    function getOptionDeclarationFromName(getOptionNameMap, optionName, allowShort) {
        if (allowShort === void 0) { allowShort = false; }
        optionName = optionName.toLowerCase();
        var _a = getOptionNameMap(), optionsNameMap = _a.optionsNameMap, shortOptionNames = _a.shortOptionNames;
        // Try to translate short option names to their full equivalents.
        if (allowShort) {
            var short = shortOptionNames.get(optionName);
            if (short !== undefined) {
                optionName = short;
            }
        }
        return optionsNameMap.get(optionName);
    }
    var buildOptionsNameMapCache;
    function getBuildOptionsNameMap() {
        return buildOptionsNameMapCache || (buildOptionsNameMapCache = createOptionNameMap(ts.buildOpts));
    }
    var buildOptionsDidYouMeanDiagnostics = {
        getOptionsNameMap: getBuildOptionsNameMap,
        optionDeclarations: ts.buildOpts,
        unknownOptionDiagnostic: ts.Diagnostics.Unknown_build_option_0,
        unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_build_option_0_Did_you_mean_1,
        optionTypeMismatchDiagnostic: ts.Diagnostics.Build_option_0_requires_a_value_of_type_1
    };
    /*@internal*/
    function parseBuildCommand(args) {
        var _a = parseCommandLineWorker(buildOptionsDidYouMeanDiagnostics, args), options = _a.options, watchOptions = _a.watchOptions, projects = _a.fileNames, errors = _a.errors;
        var buildOptions = options;
        if (projects.length === 0) {
            // tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ."
            projects.push(".");
        }
        // Nonsensical combinations
        if (buildOptions.clean && buildOptions.force) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"));
        }
        if (buildOptions.clean && buildOptions.verbose) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"));
        }
        if (buildOptions.clean && buildOptions.watch) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"));
        }
        if (buildOptions.watch && buildOptions.dry) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"));
        }
        return { buildOptions: buildOptions, watchOptions: watchOptions, projects: projects, errors: errors };
    }
    ts.parseBuildCommand = parseBuildCommand;
    /* @internal */
    function getDiagnosticText(_message) {
        var _args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            _args[_i - 1] = arguments[_i];
        }
        var diagnostic = ts.createCompilerDiagnostic.apply(undefined, arguments);
        return diagnostic.messageText;
    }
    ts.getDiagnosticText = getDiagnosticText;
    /**
     * Reads the config file, reports errors if any and exits if the config file cannot be found
     */
    function getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host, extendedConfigCache, watchOptionsToExtend, extraFileExtensions) {
        var configFileText = tryReadFile(configFileName, function (fileName) { return host.readFile(fileName); });
        if (!ts.isString(configFileText)) {
            host.onUnRecoverableConfigFileDiagnostic(configFileText);
            return undefined;
        }
        var result = ts.parseJsonText(configFileName, configFileText);
        var cwd = host.getCurrentDirectory();
        result.path = ts.toPath(configFileName, cwd, ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames));
        result.resolvedPath = result.path;
        result.originalFileName = result.fileName;
        return parseJsonSourceFileConfigFileContent(result, host, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), cwd), optionsToExtend, ts.getNormalizedAbsolutePath(configFileName, cwd), 
        /*resolutionStack*/ undefined, extraFileExtensions, extendedConfigCache, watchOptionsToExtend);
    }
    ts.getParsedCommandLineOfConfigFile = getParsedCommandLineOfConfigFile;
    /**
     * Read tsconfig.json file
     * @param fileName The path to the config file
     */
    function readConfigFile(fileName, readFile) {
        var textOrDiagnostic = tryReadFile(fileName, readFile);
        return ts.isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
    }
    ts.readConfigFile = readConfigFile;
    /**
     * Parse the text of the tsconfig.json file
     * @param fileName The path to the config file
     * @param jsonText The text of the config file
     */
    function parseConfigFileTextToJson(fileName, jsonText) {
        var jsonSourceFile = ts.parseJsonText(fileName, jsonText);
        return {
            config: convertToObject(jsonSourceFile, jsonSourceFile.parseDiagnostics),
            error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
        };
    }
    ts.parseConfigFileTextToJson = parseConfigFileTextToJson;
    /**
     * Read tsconfig.json file
     * @param fileName The path to the config file
     */
    function readJsonConfigFile(fileName, readFile) {
        var textOrDiagnostic = tryReadFile(fileName, readFile);
        return ts.isString(textOrDiagnostic) ? ts.parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] };
    }
    ts.readJsonConfigFile = readJsonConfigFile;
    /*@internal*/
    function tryReadFile(fileName, readFile) {
        var text;
        try {
            text = readFile(fileName);
        }
        catch (e) {
            return ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message);
        }
        return text === undefined ? ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0, fileName) : text;
    }
    ts.tryReadFile = tryReadFile;
    function commandLineOptionsToMap(options) {
        return ts.arrayToMap(options, getOptionName);
    }
    var typeAcquisitionDidYouMeanDiagnostics = {
        optionDeclarations: ts.typeAcquisitionDeclarations,
        unknownOptionDiagnostic: ts.Diagnostics.Unknown_type_acquisition_option_0,
        unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1,
    };
    var watchOptionsNameMapCache;
    function getWatchOptionsNameMap() {
        return watchOptionsNameMapCache || (watchOptionsNameMapCache = createOptionNameMap(ts.optionsForWatch));
    }
    var watchOptionsDidYouMeanDiagnostics = {
        getOptionsNameMap: getWatchOptionsNameMap,
        optionDeclarations: ts.optionsForWatch,
        unknownOptionDiagnostic: ts.Diagnostics.Unknown_watch_option_0,
        unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_watch_option_0_Did_you_mean_1,
        optionTypeMismatchDiagnostic: ts.Diagnostics.Watch_option_0_requires_a_value_of_type_1
    };
    var commandLineCompilerOptionsMapCache;
    function getCommandLineCompilerOptionsMap() {
        return commandLineCompilerOptionsMapCache || (commandLineCompilerOptionsMapCache = commandLineOptionsToMap(ts.optionDeclarations));
    }
    var commandLineWatchOptionsMapCache;
    function getCommandLineWatchOptionsMap() {
        return commandLineWatchOptionsMapCache || (commandLineWatchOptionsMapCache = commandLineOptionsToMap(ts.optionsForWatch));
    }
    var commandLineTypeAcquisitionMapCache;
    function getCommandLineTypeAcquisitionMap() {
        return commandLineTypeAcquisitionMapCache || (commandLineTypeAcquisitionMapCache = commandLineOptionsToMap(ts.typeAcquisitionDeclarations));
    }
    var _tsconfigRootOptions;
    function getTsconfigRootOptionsMap() {
        if (_tsconfigRootOptions === undefined) {
            _tsconfigRootOptions = {
                name: undefined,
                type: "object",
                elementOptions: commandLineOptionsToMap([
                    {
                        name: "compilerOptions",
                        type: "object",
                        elementOptions: getCommandLineCompilerOptionsMap(),
                        extraKeyDiagnostics: ts.compilerOptionsDidYouMeanDiagnostics,
                    },
                    {
                        name: "watchOptions",
                        type: "object",
                        elementOptions: getCommandLineWatchOptionsMap(),
                        extraKeyDiagnostics: watchOptionsDidYouMeanDiagnostics,
                    },
                    {
                        name: "typingOptions",
                        type: "object",
                        elementOptions: getCommandLineTypeAcquisitionMap(),
                        extraKeyDiagnostics: typeAcquisitionDidYouMeanDiagnostics,
                    },
                    {
                        name: "typeAcquisition",
                        type: "object",
                        elementOptions: getCommandLineTypeAcquisitionMap(),
                        extraKeyDiagnostics: typeAcquisitionDidYouMeanDiagnostics
                    },
                    {
                        name: "extends",
                        type: "string"
                    },
                    {
                        name: "references",
                        type: "list",
                        element: {
                            name: "references",
                            type: "object"
                        }
                    },
                    {
                        name: "files",
                        type: "list",
                        element: {
                            name: "files",
                            type: "string"
                        }
                    },
                    {
                        name: "include",
                        type: "list",
                        element: {
                            name: "include",
                            type: "string"
                        }
                    },
                    {
                        name: "exclude",
                        type: "list",
                        element: {
                            name: "exclude",
                            type: "string"
                        }
                    },
                    ts.compileOnSaveCommandLineOption
                ])
            };
        }
        return _tsconfigRootOptions;
    }
    /**
     * Convert the json syntax tree into the json value
     */
    function convertToObject(sourceFile, errors) {
        return convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
    }
    ts.convertToObject = convertToObject;
    /**
     * Convert the json syntax tree into the json value and report errors
     * This returns the json value (apart from checking errors) only if returnValue provided is true.
     * Otherwise it just checks the errors and returns undefined
     */
    /*@internal*/
    function convertToObjectWorker(sourceFile, errors, returnValue, knownRootOptions, jsonConversionNotifier) {
        if (!sourceFile.statements.length) {
            return returnValue ? {} : undefined;
        }
        return convertPropertyValueToJson(sourceFile.statements[0].expression, knownRootOptions);
        function isRootOptionMap(knownOptions) {
            return knownRootOptions && knownRootOptions.elementOptions === knownOptions;
        }
        function convertObjectLiteralExpressionToJson(node, knownOptions, extraKeyDiagnostics, parentOption) {
            var result = returnValue ? {} : undefined;
            var _loop_3 = function (element) {
                if (element.kind !== 281 /* PropertyAssignment */) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element, ts.Diagnostics.Property_assignment_expected));
                    return "continue";
                }
                if (element.questionToken) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.questionToken, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?"));
                }
                if (!isDoubleQuotedString(element.name)) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, ts.Diagnostics.String_literal_with_double_quotes_expected));
                }
                var textOfKey = ts.isComputedNonLiteralName(element.name) ? undefined : ts.getTextOfPropertyName(element.name);
                var keyText = textOfKey && ts.unescapeLeadingUnderscores(textOfKey);
                var option = keyText && knownOptions ? knownOptions.get(keyText) : undefined;
                if (keyText && extraKeyDiagnostics && !option) {
                    if (knownOptions) {
                        errors.push(createUnknownOptionError(keyText, extraKeyDiagnostics, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, message, arg0, arg1); }));
                    }
                    else {
                        errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnostics.unknownOptionDiagnostic, keyText));
                    }
                }
                var value = convertPropertyValueToJson(element.initializer, option);
                if (typeof keyText !== "undefined") {
                    if (returnValue) {
                        result[keyText] = value;
                    }
                    // Notify key value set, if user asked for it
                    if (jsonConversionNotifier &&
                        // Current callbacks are only on known parent option or if we are setting values in the root
                        (parentOption || isRootOptionMap(knownOptions))) {
                        var isValidOptionValue = isCompilerOptionsValue(option, value);
                        if (parentOption) {
                            if (isValidOptionValue) {
                                // Notify option set in the parent if its a valid option value
                                jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option, value);
                            }
                        }
                        else if (isRootOptionMap(knownOptions)) {
                            if (isValidOptionValue) {
                                // Notify about the valid root key value being set
                                jsonConversionNotifier.onSetValidOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
                            }
                            else if (!option) {
                                // Notify about the unknown root key value being set
                                jsonConversionNotifier.onSetUnknownOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
                            }
                        }
                    }
                }
            };
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var element = _a[_i];
                _loop_3(element);
            }
            return result;
        }
        function convertArrayLiteralExpressionToJson(elements, elementOption) {
            if (!returnValue) {
                return elements.forEach(function (element) { return convertPropertyValueToJson(element, elementOption); });
            }
            // Filter out invalid values
            return ts.filter(elements.map(function (element) { return convertPropertyValueToJson(element, elementOption); }), function (v) { return v !== undefined; });
        }
        function convertPropertyValueToJson(valueExpression, option) {
            switch (valueExpression.kind) {
                case 106 /* TrueKeyword */:
                    reportInvalidOptionValue(option && option.type !== "boolean");
                    return true;
                case 91 /* FalseKeyword */:
                    reportInvalidOptionValue(option && option.type !== "boolean");
                    return false;
                case 100 /* NullKeyword */:
                    reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for
                    return null; // eslint-disable-line no-null/no-null
                case 10 /* StringLiteral */:
                    if (!isDoubleQuotedString(valueExpression)) {
                        errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.String_literal_with_double_quotes_expected));
                    }
                    reportInvalidOptionValue(option && (ts.isString(option.type) && option.type !== "string"));
                    var text = valueExpression.text;
                    if (option && !ts.isString(option.type)) {
                        var customOption = option;
                        // Validate custom option type
                        if (!customOption.type.has(text.toLowerCase())) {
                            errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); }));
                        }
                    }
                    return text;
                case 8 /* NumericLiteral */:
                    reportInvalidOptionValue(option && option.type !== "number");
                    return Number(valueExpression.text);
                case 207 /* PrefixUnaryExpression */:
                    if (valueExpression.operator !== 40 /* MinusToken */ || valueExpression.operand.kind !== 8 /* NumericLiteral */) {
                        break; // not valid JSON syntax
                    }
                    reportInvalidOptionValue(option && option.type !== "number");
                    return -Number(valueExpression.operand.text);
                case 193 /* ObjectLiteralExpression */:
                    reportInvalidOptionValue(option && option.type !== "object");
                    var objectLiteralExpression = valueExpression;
                    // Currently having element option declaration in the tsconfig with type "object"
                    // determines if it needs onSetValidOptionKeyValueInParent callback or not
                    // At moment there are only "compilerOptions", "typeAcquisition" and "typingOptions"
                    // that satifies it and need it to modify options set in them (for normalizing file paths)
                    // vs what we set in the json
                    // If need arises, we can modify this interface and callbacks as needed
                    if (option) {
                        var _a = option, elementOptions = _a.elementOptions, extraKeyDiagnostics = _a.extraKeyDiagnostics, optionName = _a.name;
                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, elementOptions, extraKeyDiagnostics, optionName);
                    }
                    else {
                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, /* knownOptions*/ undefined, 
                        /*extraKeyDiagnosticMessage */ undefined, /*parentOption*/ undefined);
                    }
                case 192 /* ArrayLiteralExpression */:
                    reportInvalidOptionValue(option && option.type !== "list");
                    return convertArrayLiteralExpressionToJson(valueExpression.elements, option && option.element);
            }
            // Not in expected format
            if (option) {
                reportInvalidOptionValue(/*isError*/ true);
            }
            else {
                errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal));
            }
            return undefined;
            function reportInvalidOptionValue(isError) {
                if (isError) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option.name, getCompilerOptionValueTypeString(option)));
                }
            }
        }
        function isDoubleQuotedString(node) {
            return ts.isStringLiteral(node) && ts.isStringDoubleQuoted(node, sourceFile);
        }
    }
    ts.convertToObjectWorker = convertToObjectWorker;
    function getCompilerOptionValueTypeString(option) {
        return option.type === "list" ?
            "Array" :
            ts.isString(option.type) ? option.type : "string";
    }
    function isCompilerOptionsValue(option, value) {
        if (option) {
            if (isNullOrUndefined(value))
                return true; // All options are undefinable/nullable
            if (option.type === "list") {
                return ts.isArray(value);
            }
            var expectedType = ts.isString(option.type) ? option.type : "string";
            return typeof value === expectedType;
        }
        return false;
    }
    /**
     * Generate an uncommented, complete tsconfig for use with "--showConfig"
     * @param configParseResult options to be generated into tsconfig.json
     * @param configFileName name of the parsed config file - output paths will be generated relative to this
     * @param host provides current directory and case sensitivity services
     */
    /** @internal */
    function convertToTSConfig(configParseResult, configFileName, host) {
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        var files = ts.map(ts.filter(configParseResult.fileNames, (!configParseResult.configFileSpecs || !configParseResult.configFileSpecs.validatedIncludeSpecs) ? function (_) { return true; } : matchesSpecs(configFileName, configParseResult.configFileSpecs.validatedIncludeSpecs, configParseResult.configFileSpecs.validatedExcludeSpecs, host)), function (f) { return ts.getRelativePathFromFile(ts.getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), ts.getNormalizedAbsolutePath(f, host.getCurrentDirectory()), getCanonicalFileName); });
        var optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: ts.getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames });
        var watchOptionMap = configParseResult.watchOptions && serializeWatchOptions(configParseResult.watchOptions);
        var config = __assign(__assign({ compilerOptions: __assign(__assign({}, optionMapToObject(optionMap)), { showConfig: undefined, configFile: undefined, configFilePath: undefined, help: undefined, init: undefined, listFiles: undefined, listEmittedFiles: undefined, project: undefined, build: undefined, version: undefined }), watchOptions: watchOptionMap && optionMapToObject(watchOptionMap), references: ts.map(configParseResult.projectReferences, function (r) { return (__assign(__assign({}, r), { path: r.originalPath ? r.originalPath : "", originalPath: undefined })); }), files: ts.length(files) ? files : undefined }, (configParseResult.configFileSpecs ? {
            include: filterSameAsDefaultInclude(configParseResult.configFileSpecs.validatedIncludeSpecs),
            exclude: configParseResult.configFileSpecs.validatedExcludeSpecs
        } : {})), { compileOnSave: !!configParseResult.compileOnSave ? true : undefined });
        return config;
    }
    ts.convertToTSConfig = convertToTSConfig;
    function optionMapToObject(optionMap) {
        return __assign({}, ts.arrayFrom(optionMap.entries()).reduce(function (prev, cur) {
            var _a;
            return (__assign(__assign({}, prev), (_a = {}, _a[cur[0]] = cur[1], _a)));
        }, {}));
    }
    function filterSameAsDefaultInclude(specs) {
        if (!ts.length(specs))
            return undefined;
        if (ts.length(specs) !== 1)
            return specs;
        if (specs[0] === "**/*")
            return undefined;
        return specs;
    }
    function matchesSpecs(path, includeSpecs, excludeSpecs, host) {
        if (!includeSpecs)
            return function (_) { return true; };
        var patterns = ts.getFileMatcherPatterns(path, excludeSpecs, includeSpecs, host.useCaseSensitiveFileNames, host.getCurrentDirectory());
        var excludeRe = patterns.excludePattern && ts.getRegexFromPattern(patterns.excludePattern, host.useCaseSensitiveFileNames);
        var includeRe = patterns.includeFilePattern && ts.getRegexFromPattern(patterns.includeFilePattern, host.useCaseSensitiveFileNames);
        if (includeRe) {
            if (excludeRe) {
                return function (path) { return !(includeRe.test(path) && !excludeRe.test(path)); };
            }
            return function (path) { return !includeRe.test(path); };
        }
        if (excludeRe) {
            return function (path) { return excludeRe.test(path); };
        }
        return function (_) { return true; };
    }
    function getCustomTypeMapOfCommandLineOption(optionDefinition) {
        if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean" || optionDefinition.type === "object") {
            // this is of a type CommandLineOptionOfPrimitiveType
            return undefined;
        }
        else if (optionDefinition.type === "list") {
            return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
        }
        else {
            return optionDefinition.type;
        }
    }
    function getNameOfCompilerOptionValue(value, customTypeMap) {
        // There is a typeMap associated with this command-line option so use it to map value back to its name
        return ts.forEachEntry(customTypeMap, function (mapValue, key) {
            if (mapValue === value) {
                return key;
            }
        });
    }
    function serializeCompilerOptions(options, pathOptions) {
        return serializeOptionBaseObject(options, getOptionsNameMap(), pathOptions);
    }
    function serializeWatchOptions(options) {
        return serializeOptionBaseObject(options, getWatchOptionsNameMap());
    }
    function serializeOptionBaseObject(options, _a, pathOptions) {
        var optionsNameMap = _a.optionsNameMap;
        var result = ts.createMap();
        var getCanonicalFileName = pathOptions && ts.createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames);
        var _loop_4 = function (name) {
            if (ts.hasProperty(options, name)) {
                // tsconfig only options cannot be specified via command line,
                // so we can assume that only types that can appear here string | number | boolean
                if (optionsNameMap.has(name) && optionsNameMap.get(name).category === ts.Diagnostics.Command_line_Options) {
                    return "continue";
                }
                var value = options[name];
                var optionDefinition = optionsNameMap.get(name.toLowerCase());
                if (optionDefinition) {
                    var customTypeMap_1 = getCustomTypeMapOfCommandLineOption(optionDefinition);
                    if (!customTypeMap_1) {
                        // There is no map associated with this compiler option then use the value as-is
                        // This is the case if the value is expect to be string, number, boolean or list of string
                        if (pathOptions && optionDefinition.isFilePath) {
                            result.set(name, ts.getRelativePathFromFile(pathOptions.configFilePath, ts.getNormalizedAbsolutePath(value, ts.getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName));
                        }
                        else {
                            result.set(name, value);
                        }
                    }
                    else {
                        if (optionDefinition.type === "list") {
                            result.set(name, value.map(function (element) { return getNameOfCompilerOptionValue(element, customTypeMap_1); })); // TODO: GH#18217
                        }
                        else {
                            // There is a typeMap associated with this command-line option so use it to map value back to its name
                            result.set(name, getNameOfCompilerOptionValue(value, customTypeMap_1));
                        }
                    }
                }
            }
        };
        for (var name in options) {
            _loop_4(name);
        }
        return result;
    }
    /**
     * Generate tsconfig configuration when running command line "--init"
     * @param options commandlineOptions to be generated into tsconfig.json
     * @param fileNames array of filenames to be generated into tsconfig.json
     */
    /* @internal */
    function generateTSConfig(options, fileNames, newLine) {
        var compilerOptions = ts.extend(options, ts.defaultInitCompilerOptions);
        var compilerOptionsMap = serializeCompilerOptions(compilerOptions);
        return writeConfigurations();
        function getDefaultValueForOption(option) {
            switch (option.type) {
                case "number":
                    return 1;
                case "boolean":
                    return true;
                case "string":
                    return option.isFilePath ? "./" : "";
                case "list":
                    return [];
                case "object":
                    return {};
                default:
                    var iterResult = option.type.keys().next();
                    if (!iterResult.done)
                        return iterResult.value;
                    return ts.Debug.fail("Expected 'option.type' to have entries.");
            }
        }
        function makePadding(paddingLength) {
            return Array(paddingLength + 1).join(" ");
        }
        function isAllowedOption(_a) {
            var category = _a.category, name = _a.name;
            // Skip options which do not have a category or have category `Command_line_Options`
            // Exclude all possible `Advanced_Options` in tsconfig.json which were NOT defined in command line
            return category !== undefined
                && category !== ts.Diagnostics.Command_line_Options
                && (category !== ts.Diagnostics.Advanced_Options || compilerOptionsMap.has(name));
        }
        function writeConfigurations() {
            // Filter applicable options to place in the file
            var categorizedOptions = ts.createMultiMap();
            for (var _i = 0, optionDeclarations_1 = ts.optionDeclarations; _i < optionDeclarations_1.length; _i++) {
                var option = optionDeclarations_1[_i];
                var category = option.category;
                if (isAllowedOption(option)) {
                    categorizedOptions.add(ts.getLocaleSpecificMessage(category), option);
                }
            }
            // Serialize all options and their descriptions
            var marginLength = 0;
            var seenKnownKeys = 0;
            var entries = [];
            categorizedOptions.forEach(function (options, category) {
                if (entries.length !== 0) {
                    entries.push({ value: "" });
                }
                entries.push({ value: "/* " + category + " */" });
                for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
                    var option = options_1[_i];
                    var optionName = void 0;
                    if (compilerOptionsMap.has(option.name)) {
                        optionName = "\"" + option.name + "\": " + JSON.stringify(compilerOptionsMap.get(option.name)) + ((seenKnownKeys += 1) === compilerOptionsMap.size ? "" : ",");
                    }
                    else {
                        optionName = "// \"" + option.name + "\": " + JSON.stringify(getDefaultValueForOption(option)) + ",";
                    }
                    entries.push({
                        value: optionName,
                        description: "/* " + (option.description && ts.getLocaleSpecificMessage(option.description) || option.name) + " */"
                    });
                    marginLength = Math.max(optionName.length, marginLength);
                }
            });
            // Write the output
            var tab = makePadding(2);
            var result = [];
            result.push("{");
            result.push(tab + "\"compilerOptions\": {");
            result.push("" + tab + tab + "/* " + ts.getLocaleSpecificMessage(ts.Diagnostics.Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_json_to_read_more_about_this_file) + " */");
            result.push("");
            // Print out each row, aligning all the descriptions on the same column.
            for (var _a = 0, entries_3 = entries; _a < entries_3.length; _a++) {
                var entry = entries_3[_a];
                var value = entry.value, _b = entry.description, description = _b === void 0 ? "" : _b;
                result.push(value && "" + tab + tab + value + (description && (makePadding(marginLength - value.length + 2) + description)));
            }
            if (fileNames.length) {
                result.push(tab + "},");
                result.push(tab + "\"files\": [");
                for (var i = 0; i < fileNames.length; i++) {
                    result.push("" + tab + tab + JSON.stringify(fileNames[i]) + (i === fileNames.length - 1 ? "" : ","));
                }
                result.push(tab + "]");
            }
            else {
                result.push(tab + "}");
            }
            result.push("}");
            return result.join(newLine) + newLine;
        }
    }
    ts.generateTSConfig = generateTSConfig;
    /* @internal */
    function convertToOptionsWithAbsolutePaths(options, toAbsolutePath) {
        var result = {};
        var optionsNameMap = getOptionsNameMap().optionsNameMap;
        for (var name in options) {
            if (ts.hasProperty(options, name)) {
                result[name] = convertToOptionValueWithAbsolutePaths(optionsNameMap.get(name.toLowerCase()), options[name], toAbsolutePath);
            }
        }
        if (result.configFilePath) {
            result.configFilePath = toAbsolutePath(result.configFilePath);
        }
        return result;
    }
    ts.convertToOptionsWithAbsolutePaths = convertToOptionsWithAbsolutePaths;
    function convertToOptionValueWithAbsolutePaths(option, value, toAbsolutePath) {
        if (option && !isNullOrUndefined(value)) {
            if (option.type === "list") {
                var values = value;
                if (option.element.isFilePath && values.length) {
                    return values.map(toAbsolutePath);
                }
            }
            else if (option.isFilePath) {
                return toAbsolutePath(value);
            }
        }
        return value;
    }
    /**
     * Parse the contents of a config file (tsconfig.json).
     * @param json The contents of the config file to parse
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     */
    function parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache, existingWatchOptions) {
        return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache);
    }
    ts.parseJsonConfigFileContent = parseJsonConfigFileContent;
    /**
     * Parse the contents of a config file (tsconfig.json).
     * @param jsonNode The contents of the config file to parse
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     */
    function parseJsonSourceFileConfigFileContent(sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache, existingWatchOptions) {
        return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache);
    }
    ts.parseJsonSourceFileConfigFileContent = parseJsonSourceFileConfigFileContent;
    /*@internal*/
    function setConfigFileInOptions(options, configFile) {
        if (configFile) {
            Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile });
        }
    }
    ts.setConfigFileInOptions = setConfigFileInOptions;
    function isNullOrUndefined(x) {
        return x === undefined || x === null; // eslint-disable-line no-null/no-null
    }
    function directoryOfCombinedPath(fileName, basePath) {
        // Use the `getNormalizedAbsolutePath` function to avoid canonicalizing the path, as it must remain noncanonical
        // until consistent casing errors are reported
        return ts.getDirectoryPath(ts.getNormalizedAbsolutePath(fileName, basePath));
    }
    /**
     * Parse the contents of a config file from json or json source file (tsconfig.json).
     * @param json The contents of the config file to parse
     * @param sourceFile sourceFile corresponding to the Json
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     * @param resolutionStack Only present for backwards-compatibility. Should be empty.
     */
    function parseJsonConfigFileContentWorker(json, sourceFile, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache) {
        if (existingOptions === void 0) { existingOptions = {}; }
        if (resolutionStack === void 0) { resolutionStack = []; }
        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
        ts.Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
        var errors = [];
        var parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache);
        var raw = parsedConfig.raw;
        var options = ts.extend(existingOptions, parsedConfig.options || {});
        var watchOptions = existingWatchOptions && parsedConfig.watchOptions ?
            ts.extend(existingWatchOptions, parsedConfig.watchOptions) :
            parsedConfig.watchOptions || existingWatchOptions;
        options.configFilePath = configFileName && ts.normalizeSlashes(configFileName);
        setConfigFileInOptions(options, sourceFile);
        var projectReferences;
        var _a = getFileNames(), fileNames = _a.fileNames, wildcardDirectories = _a.wildcardDirectories, spec = _a.spec;
        return {
            options: options,
            watchOptions: watchOptions,
            fileNames: fileNames,
            projectReferences: projectReferences,
            typeAcquisition: parsedConfig.typeAcquisition || getDefaultTypeAcquisition(),
            raw: raw,
            errors: errors,
            wildcardDirectories: wildcardDirectories,
            compileOnSave: !!raw.compileOnSave,
            configFileSpecs: spec
        };
        function getFileNames() {
            var filesSpecs;
            if (ts.hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) {
                if (ts.isArray(raw.files)) {
                    filesSpecs = raw.files;
                    var hasReferences = ts.hasProperty(raw, "references") && !isNullOrUndefined(raw.references);
                    var hasZeroOrNoReferences = !hasReferences || raw.references.length === 0;
                    var hasExtends = ts.hasProperty(raw, "extends");
                    if (filesSpecs.length === 0 && hasZeroOrNoReferences && !hasExtends) {
                        if (sourceFile) {
                            var fileName = configFileName || "tsconfig.json";
                            var diagnosticMessage = ts.Diagnostics.The_files_list_in_config_file_0_is_empty;
                            var nodeValue = ts.firstDefined(ts.getTsConfigPropArray(sourceFile, "files"), function (property) { return property.initializer; });
                            var error = nodeValue
                                ? ts.createDiagnosticForNodeInSourceFile(sourceFile, nodeValue, diagnosticMessage, fileName)
                                : ts.createCompilerDiagnostic(diagnosticMessage, fileName);
                            errors.push(error);
                        }
                        else {
                            createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
                        }
                    }
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array");
                }
            }
            var includeSpecs;
            if (ts.hasProperty(raw, "include") && !isNullOrUndefined(raw.include)) {
                if (ts.isArray(raw.include)) {
                    includeSpecs = raw.include;
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array");
                }
            }
            var excludeSpecs;
            if (ts.hasProperty(raw, "exclude") && !isNullOrUndefined(raw.exclude)) {
                if (ts.isArray(raw.exclude)) {
                    excludeSpecs = raw.exclude;
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array");
                }
            }
            else if (raw.compilerOptions) {
                var outDir = raw.compilerOptions.outDir;
                var declarationDir = raw.compilerOptions.declarationDir;
                if (outDir || declarationDir) {
                    excludeSpecs = [outDir, declarationDir].filter(function (d) { return !!d; });
                }
            }
            if (filesSpecs === undefined && includeSpecs === undefined) {
                includeSpecs = ["**/*"];
            }
            var result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
            if (shouldReportNoInputFiles(result, canJsonReportNoInutFiles(raw), resolutionStack)) {
                errors.push(getErrorForNoInputFiles(result.spec, configFileName));
            }
            if (ts.hasProperty(raw, "references") && !isNullOrUndefined(raw.references)) {
                if (ts.isArray(raw.references)) {
                    for (var _i = 0, _a = raw.references; _i < _a.length; _i++) {
                        var ref = _a[_i];
                        if (typeof ref.path !== "string") {
                            createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "reference.path", "string");
                        }
                        else {
                            (projectReferences || (projectReferences = [])).push({
                                path: ts.getNormalizedAbsolutePath(ref.path, basePath),
                                originalPath: ref.path,
                                prepend: ref.prepend,
                                circular: ref.circular
                            });
                        }
                    }
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "references", "Array");
                }
            }
            return result;
        }
        function createCompilerDiagnosticOnlyIfJson(message, arg0, arg1) {
            if (!sourceFile) {
                errors.push(ts.createCompilerDiagnostic(message, arg0, arg1));
            }
        }
    }
    function isErrorNoInputFiles(error) {
        return error.code === ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code;
    }
    function getErrorForNoInputFiles(_a, configFileName) {
        var includeSpecs = _a.includeSpecs, excludeSpecs = _a.excludeSpecs;
        return ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName || "tsconfig.json", JSON.stringify(includeSpecs || []), JSON.stringify(excludeSpecs || []));
    }
    function shouldReportNoInputFiles(result, canJsonReportNoInutFiles, resolutionStack) {
        return result.fileNames.length === 0 && canJsonReportNoInutFiles && (!resolutionStack || resolutionStack.length === 0);
    }
    /*@internal*/
    function canJsonReportNoInutFiles(raw) {
        return !ts.hasProperty(raw, "files") && !ts.hasProperty(raw, "references");
    }
    ts.canJsonReportNoInutFiles = canJsonReportNoInutFiles;
    /*@internal*/
    function updateErrorForNoInputFiles(result, configFileName, configFileSpecs, configParseDiagnostics, canJsonReportNoInutFiles) {
        var existingErrors = configParseDiagnostics.length;
        if (shouldReportNoInputFiles(result, canJsonReportNoInutFiles)) {
            configParseDiagnostics.push(getErrorForNoInputFiles(configFileSpecs, configFileName));
        }
        else {
            ts.filterMutate(configParseDiagnostics, function (error) { return !isErrorNoInputFiles(error); });
        }
        return existingErrors !== configParseDiagnostics.length;
    }
    ts.updateErrorForNoInputFiles = updateErrorForNoInputFiles;
    function isSuccessfulParsedTsconfig(value) {
        return !!value.options;
    }
    /**
     * This *just* extracts options/include/exclude/files out of a config file.
     * It does *not* resolve the included files.
     */
    function parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache) {
        basePath = ts.normalizeSlashes(basePath);
        var resolvedPath = ts.getNormalizedAbsolutePath(configFileName || "", basePath);
        if (resolutionStack.indexOf(resolvedPath) >= 0) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, __spreadArrays(resolutionStack, [resolvedPath]).join(" -> ")));
            return { raw: json || convertToObject(sourceFile, errors) };
        }
        var ownConfig = json ?
            parseOwnConfigOfJson(json, host, basePath, configFileName, errors) :
            parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, configFileName, errors);
        if (ownConfig.extendedConfigPath) {
            // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
            resolutionStack = resolutionStack.concat([resolvedPath]);
            var extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors, extendedConfigCache);
            if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
                var baseRaw_1 = extendedConfig.raw;
                var raw_1 = ownConfig.raw;
                var setPropertyInRawIfNotUndefined = function (propertyName) {
                    var value = raw_1[propertyName] || baseRaw_1[propertyName];
                    if (value) {
                        raw_1[propertyName] = value;
                    }
                };
                setPropertyInRawIfNotUndefined("include");
                setPropertyInRawIfNotUndefined("exclude");
                setPropertyInRawIfNotUndefined("files");
                if (raw_1.compileOnSave === undefined) {
                    raw_1.compileOnSave = baseRaw_1.compileOnSave;
                }
                ownConfig.options = ts.assign({}, extendedConfig.options, ownConfig.options);
                ownConfig.watchOptions = ownConfig.watchOptions && extendedConfig.watchOptions ?
                    ts.assign({}, extendedConfig.watchOptions, ownConfig.watchOptions) :
                    ownConfig.watchOptions || extendedConfig.watchOptions;
                // TODO extend type typeAcquisition
            }
        }
        return ownConfig;
    }
    function parseOwnConfigOfJson(json, host, basePath, configFileName, errors) {
        if (ts.hasProperty(json, "excludes")) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
        }
        var options = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName);
        // typingOptions has been deprecated and is only supported for backward compatibility purposes.
        // It should be removed in future releases - use typeAcquisition instead.
        var typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName);
        var watchOptions = convertWatchOptionsFromJsonWorker(json.watchOptions, basePath, errors);
        json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
        var extendedConfigPath;
        if (json.extends) {
            if (!ts.isString(json.extends)) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
            }
            else {
                var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
                extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, errors, ts.createCompilerDiagnostic);
            }
        }
        return { raw: json, options: options, watchOptions: watchOptions, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
    }
    function parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, configFileName, errors) {
        var options = getDefaultCompilerOptions(configFileName);
        var typeAcquisition, typingOptionstypeAcquisition;
        var watchOptions;
        var extendedConfigPath;
        var optionsIterator = {
            onSetValidOptionKeyValueInParent: function (parentOption, option, value) {
                var currentOption;
                switch (parentOption) {
                    case "compilerOptions":
                        currentOption = options;
                        break;
                    case "watchOptions":
                        currentOption = (watchOptions || (watchOptions = {}));
                        break;
                    case "typeAcquisition":
                        currentOption = (typeAcquisition || (typeAcquisition = getDefaultTypeAcquisition(configFileName)));
                        break;
                    case "typingOptions":
                        currentOption = (typingOptionstypeAcquisition || (typingOptionstypeAcquisition = getDefaultTypeAcquisition(configFileName)));
                        break;
                    default:
                        ts.Debug.fail("Unknown option");
                }
                currentOption[option.name] = normalizeOptionValue(option, basePath, value);
            },
            onSetValidOptionKeyValueInRoot: function (key, _keyNode, value, valueNode) {
                switch (key) {
                    case "extends":
                        var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
                        extendedConfigPath = getExtendsConfigPath(value, host, newBase, errors, function (message, arg0) {
                            return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0);
                        });
                        return;
                }
            },
            onSetUnknownOptionKeyValueInRoot: function (key, keyNode, _value, _valueNode) {
                if (key === "excludes") {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, keyNode, ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
                }
            }
        };
        var json = convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, getTsconfigRootOptionsMap(), optionsIterator);
        if (!typeAcquisition) {
            if (typingOptionstypeAcquisition) {
                typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ?
                    {
                        enable: typingOptionstypeAcquisition.enableAutoDiscovery,
                        include: typingOptionstypeAcquisition.include,
                        exclude: typingOptionstypeAcquisition.exclude
                    } :
                    typingOptionstypeAcquisition;
            }
            else {
                typeAcquisition = getDefaultTypeAcquisition(configFileName);
            }
        }
        return { raw: json, options: options, watchOptions: watchOptions, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
    }
    function getExtendsConfigPath(extendedConfig, host, basePath, errors, createDiagnostic) {
        extendedConfig = ts.normalizeSlashes(extendedConfig);
        if (ts.isRootedDiskPath(extendedConfig) || ts.startsWith(extendedConfig, "./") || ts.startsWith(extendedConfig, "../")) {
            var extendedConfigPath = ts.getNormalizedAbsolutePath(extendedConfig, basePath);
            if (!host.fileExists(extendedConfigPath) && !ts.endsWith(extendedConfigPath, ".json" /* Json */)) {
                extendedConfigPath = extendedConfigPath + ".json";
                if (!host.fileExists(extendedConfigPath)) {
                    errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig));
                    return undefined;
                }
            }
            return extendedConfigPath;
        }
        // If the path isn't a rooted or relative path, resolve like a module
        var resolved = ts.nodeModuleNameResolver(extendedConfig, ts.combinePaths(basePath, "tsconfig.json"), { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true);
        if (resolved.resolvedModule) {
            return resolved.resolvedModule.resolvedFileName;
        }
        errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig));
        return undefined;
    }
    function getExtendedConfig(sourceFile, extendedConfigPath, host, basePath, resolutionStack, errors, extendedConfigCache) {
        var _a;
        var path = host.useCaseSensitiveFileNames ? extendedConfigPath : ts.toFileNameLowerCase(extendedConfigPath);
        var value;
        var extendedResult;
        var extendedConfig;
        if (extendedConfigCache && (value = extendedConfigCache.get(path))) {
            (extendedResult = value.extendedResult, extendedConfig = value.extendedConfig);
        }
        else {
            extendedResult = readJsonConfigFile(extendedConfigPath, function (path) { return host.readFile(path); });
            if (!extendedResult.parseDiagnostics.length) {
                var extendedDirname = ts.getDirectoryPath(extendedConfigPath);
                extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname, ts.getBaseFileName(extendedConfigPath), resolutionStack, errors, extendedConfigCache);
                if (isSuccessfulParsedTsconfig(extendedConfig)) {
                    // Update the paths to reflect base path
                    var relativeDifference_1 = ts.convertToRelativePath(extendedDirname, basePath, ts.identity);
                    var updatePath_1 = function (path) { return ts.isRootedDiskPath(path) ? path : ts.combinePaths(relativeDifference_1, path); };
                    var mapPropertiesInRawIfNotUndefined = function (propertyName) {
                        if (raw_2[propertyName]) {
                            raw_2[propertyName] = ts.map(raw_2[propertyName], updatePath_1);
                        }
                    };
                    var raw_2 = extendedConfig.raw;
                    mapPropertiesInRawIfNotUndefined("include");
                    mapPropertiesInRawIfNotUndefined("exclude");
                    mapPropertiesInRawIfNotUndefined("files");
                }
            }
            if (extendedConfigCache) {
                extendedConfigCache.set(path, { extendedResult: extendedResult, extendedConfig: extendedConfig });
            }
        }
        if (sourceFile) {
            sourceFile.extendedSourceFiles = [extendedResult.fileName];
            if (extendedResult.extendedSourceFiles) {
                (_a = sourceFile.extendedSourceFiles).push.apply(_a, extendedResult.extendedSourceFiles);
            }
        }
        if (extendedResult.parseDiagnostics.length) {
            errors.push.apply(errors, extendedResult.parseDiagnostics);
            return undefined;
        }
        return extendedConfig;
    }
    function convertCompileOnSaveOptionFromJson(jsonOption, basePath, errors) {
        if (!ts.hasProperty(jsonOption, ts.compileOnSaveCommandLineOption.name)) {
            return false;
        }
        var result = convertJsonOption(ts.compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors);
        return typeof result === "boolean" && result;
    }
    function convertCompilerOptionsFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertCompilerOptionsFromJson = convertCompilerOptionsFromJson;
    function convertTypeAcquisitionFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertTypeAcquisitionFromJson = convertTypeAcquisitionFromJson;
    function getDefaultCompilerOptions(configFileName) {
        var options = configFileName && ts.getBaseFileName(configFileName) === "jsconfig.json"
            ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, noEmit: true }
            : {};
        return options;
    }
    function convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = getDefaultCompilerOptions(configFileName);
        convertOptionsFromJson(getCommandLineCompilerOptionsMap(), jsonOptions, basePath, options, ts.compilerOptionsDidYouMeanDiagnostics, errors);
        if (configFileName) {
            options.configFilePath = ts.normalizeSlashes(configFileName);
        }
        return options;
    }
    function getDefaultTypeAcquisition(configFileName) {
        return { enable: !!configFileName && ts.getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
    }
    function convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = getDefaultTypeAcquisition(configFileName);
        var typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions);
        convertOptionsFromJson(getCommandLineTypeAcquisitionMap(), typeAcquisition, basePath, options, typeAcquisitionDidYouMeanDiagnostics, errors);
        return options;
    }
    function convertWatchOptionsFromJsonWorker(jsonOptions, basePath, errors) {
        return convertOptionsFromJson(getCommandLineWatchOptionsMap(), jsonOptions, basePath, /*defaultOptions*/ undefined, watchOptionsDidYouMeanDiagnostics, errors);
    }
    function convertOptionsFromJson(optionsNameMap, jsonOptions, basePath, defaultOptions, diagnostics, errors) {
        if (!jsonOptions) {
            return;
        }
        for (var id in jsonOptions) {
            var opt = optionsNameMap.get(id);
            if (opt) {
                (defaultOptions || (defaultOptions = {}))[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
            }
            else {
                errors.push(createUnknownOptionError(id, diagnostics, ts.createCompilerDiagnostic));
            }
        }
        return defaultOptions;
    }
    function convertJsonOption(opt, value, basePath, errors) {
        if (isCompilerOptionsValue(opt, value)) {
            var optType = opt.type;
            if (optType === "list" && ts.isArray(value)) {
                return convertJsonOptionOfListType(opt, value, basePath, errors);
            }
            else if (!ts.isString(optType)) {
                return convertJsonOptionOfCustomType(opt, value, errors);
            }
            return normalizeNonListOptionValue(opt, basePath, value);
        }
        else {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, getCompilerOptionValueTypeString(opt)));
        }
    }
    function normalizeOptionValue(option, basePath, value) {
        if (isNullOrUndefined(value))
            return undefined;
        if (option.type === "list") {
            var listOption_1 = option;
            if (listOption_1.element.isFilePath || !ts.isString(listOption_1.element.type)) {
                return ts.filter(ts.map(value, function (v) { return normalizeOptionValue(listOption_1.element, basePath, v); }), function (v) { return !!v; });
            }
            return value;
        }
        else if (!ts.isString(option.type)) {
            return option.type.get(ts.isString(value) ? value.toLowerCase() : value);
        }
        return normalizeNonListOptionValue(option, basePath, value);
    }
    function normalizeNonListOptionValue(option, basePath, value) {
        if (option.isFilePath) {
            value = ts.getNormalizedAbsolutePath(value, basePath);
            if (value === "") {
                value = ".";
            }
        }
        return value;
    }
    function convertJsonOptionOfCustomType(opt, value, errors) {
        if (isNullOrUndefined(value))
            return undefined;
        var key = value.toLowerCase();
        var val = opt.type.get(key);
        if (val !== undefined) {
            return val;
        }
        else {
            errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
        }
    }
    function convertJsonOptionOfListType(option, values, basePath, errors) {
        return ts.filter(ts.map(values, function (v) { return convertJsonOption(option.element, v, basePath, errors); }), function (v) { return !!v; });
    }
    function trimString(s) {
        return typeof s.trim === "function" ? s.trim() : s.replace(/^[\s]+|[\s]+$/g, "");
    }
    /**
     * Tests for a path that ends in a recursive directory wildcard.
     * Matches **, \**, **\, and \**\, but not a**b.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*        # matches the recursive directory wildcard "**".
     *  \/?$        # matches an optional trailing directory separator at the end of the string.
     */
    var invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
    /**
     * Tests for a path where .. appears after a recursive directory wildcard.
     * Matches **\..\*, **\a\..\*, and **\.., but not ..\**\*
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*\/      # matches a recursive directory wildcard "**" followed by a directory separator.
     *  (.*\/)?     # optionally matches any number of characters followed by a directory separator.
     *  \.\.        # matches a parent directory path component ".."
     *  ($|\/)      # matches either the end of the string or a directory separator.
     */
    var invalidDotDotAfterRecursiveWildcardPattern = /(^|\/)\*\*\/(.*\/)?\.\.($|\/)/;
    /**
     * Tests for a path containing a wildcard character in a directory component of the path.
     * Matches \*\, \?\, and \a*b\, but not \a\ or \a\*.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  \/          # matches a directory separator.
     *  [^/]*?      # matches any number of characters excluding directory separators (non-greedy).
     *  [*?]        # matches either a wildcard character (* or ?)
     *  [^/]*       # matches any number of characters excluding directory separators (greedy).
     *  \/          # matches a directory separator.
     */
    var watchRecursivePattern = /\/[^/]*?[*?][^/]*\//;
    /**
     * Matches the portion of a wildcard path that does not contain wildcards.
     * Matches \a of \a\*, or \a\b\c of \a\b\c\?\d.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  ^                   # matches the beginning of the string
     *  [^*?]*              # matches any number of non-wildcard characters
     *  (?=\/[^/]*[*?])     # lookahead that matches a directory separator followed by
     *                      # a path component that contains at least one wildcard character (* or ?).
     */
    var wildcardDirectoryPattern = /^[^*?]*(?=\/[^/]*[*?])/;
    /**
     * Expands an array of file specifications.
     *
     * @param filesSpecs The literal file names to include.
     * @param includeSpecs The wildcard file specifications to include.
     * @param excludeSpecs The wildcard file specifications to exclude.
     * @param basePath The base path for any relative file specifications.
     * @param options Compiler options.
     * @param host The host used to resolve files and directories.
     * @param errors An array for diagnostic reporting.
     */
    function matchFileNames(filesSpecs, includeSpecs, excludeSpecs, basePath, options, host, errors, extraFileExtensions, jsonSourceFile) {
        basePath = ts.normalizePath(basePath);
        var validatedIncludeSpecs, validatedExcludeSpecs;
        // The exclude spec list is converted into a regular expression, which allows us to quickly
        // test whether a file or directory should be excluded before recursively traversing the
        // file system.
        if (includeSpecs) {
            validatedIncludeSpecs = validateSpecs(includeSpecs, errors, /*allowTrailingRecursion*/ false, jsonSourceFile, "include");
        }
        if (excludeSpecs) {
            validatedExcludeSpecs = validateSpecs(excludeSpecs, errors, /*allowTrailingRecursion*/ true, jsonSourceFile, "exclude");
        }
        // Wildcard directories (provided as part of a wildcard path) are stored in a
        // file map that marks whether it was a regular wildcard match (with a `*` or `?` token),
        // or a recursive directory. This information is used by filesystem watchers to monitor for
        // new entries in these paths.
        var wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames);
        var spec = { filesSpecs: filesSpecs, includeSpecs: includeSpecs, excludeSpecs: excludeSpecs, validatedIncludeSpecs: validatedIncludeSpecs, validatedExcludeSpecs: validatedExcludeSpecs, wildcardDirectories: wildcardDirectories };
        return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions);
    }
    /**
     * Gets the file names from the provided config file specs that contain, files, include, exclude and
     * other properties needed to resolve the file names
     * @param spec The config file specs extracted with file names to include, wildcards to include/exclude and other details
     * @param basePath The base path for any relative file specifications.
     * @param options Compiler options.
     * @param host The host used to resolve files and directories.
     * @param extraFileExtensions optionaly file extra file extension information from host
     */
    /* @internal */
    function getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions) {
        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
        basePath = ts.normalizePath(basePath);
        var keyMapper = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        // Literal file names (provided via the "files" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map later when when including
        // wildcard paths.
        var literalFileMap = ts.createMap();
        // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map to store paths matched
        // via wildcard, and to handle extension priority.
        var wildcardFileMap = ts.createMap();
        // Wildcard paths of json files (provided via the "includes" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map to store paths matched
        // via wildcard of *.json kind
        var wildCardJsonFileMap = ts.createMap();
        var filesSpecs = spec.filesSpecs, validatedIncludeSpecs = spec.validatedIncludeSpecs, validatedExcludeSpecs = spec.validatedExcludeSpecs, wildcardDirectories = spec.wildcardDirectories;
        // Rather than requery this for each file and filespec, we query the supported extensions
        // once and store it on the expansion context.
        var supportedExtensions = ts.getSupportedExtensions(options, extraFileExtensions);
        var supportedExtensionsWithJsonIfResolveJsonModule = ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
        // Literal files are always included verbatim. An "include" or "exclude" specification cannot
        // remove a literal file.
        if (filesSpecs) {
            for (var _i = 0, filesSpecs_1 = filesSpecs; _i < filesSpecs_1.length; _i++) {
                var fileName = filesSpecs_1[_i];
                var file = ts.getNormalizedAbsolutePath(fileName, basePath);
                literalFileMap.set(keyMapper(file), file);
            }
        }
        var jsonOnlyIncludeRegexes;
        if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) {
            var _loop_5 = function (file) {
                if (ts.fileExtensionIs(file, ".json" /* Json */)) {
                    // Valid only if *.json specified
                    if (!jsonOnlyIncludeRegexes) {
                        var includes = validatedIncludeSpecs.filter(function (s) { return ts.endsWith(s, ".json" /* Json */); });
                        var includeFilePatterns = ts.map(ts.getRegularExpressionsForWildcards(includes, basePath, "files"), function (pattern) { return "^" + pattern + "$"; });
                        jsonOnlyIncludeRegexes = includeFilePatterns ? includeFilePatterns.map(function (pattern) { return ts.getRegexFromPattern(pattern, host.useCaseSensitiveFileNames); }) : ts.emptyArray;
                    }
                    var includeIndex = ts.findIndex(jsonOnlyIncludeRegexes, function (re) { return re.test(file); });
                    if (includeIndex !== -1) {
                        var key_1 = keyMapper(file);
                        if (!literalFileMap.has(key_1) && !wildCardJsonFileMap.has(key_1)) {
                            wildCardJsonFileMap.set(key_1, file);
                        }
                    }
                    return "continue";
                }
                // If we have already included a literal or wildcard path with a
                // higher priority extension, we should skip this file.
                //
                // This handles cases where we may encounter both <file>.ts and
                // <file>.d.ts (or <file>.js if "allowJs" is enabled) in the same
                // directory when they are compilation outputs.
                if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) {
                    return "continue";
                }
                // We may have included a wildcard path with a lower priority
                // extension due to the user-defined order of entries in the
                // "include" array. If there is a lower priority extension in the
                // same directory, we should remove it.
                removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper);
                var key = keyMapper(file);
                if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) {
                    wildcardFileMap.set(key, file);
                }
            };
            for (var _a = 0, _b = host.readDirectory(basePath, supportedExtensionsWithJsonIfResolveJsonModule, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined); _a < _b.length; _a++) {
                var file = _b[_a];
                _loop_5(file);
            }
        }
        var literalFiles = ts.arrayFrom(literalFileMap.values());
        var wildcardFiles = ts.arrayFrom(wildcardFileMap.values());
        return {
            fileNames: literalFiles.concat(wildcardFiles, ts.arrayFrom(wildCardJsonFileMap.values())),
            wildcardDirectories: wildcardDirectories,
            spec: spec
        };
    }
    ts.getFileNamesFromConfigSpecs = getFileNamesFromConfigSpecs;
    function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) {
        return specs.filter(function (spec) {
            var diag = specToDiagnostic(spec, allowTrailingRecursion);
            if (diag !== undefined) {
                errors.push(createDiagnostic(diag, spec));
            }
            return diag === undefined;
        });
        function createDiagnostic(message, spec) {
            var element = ts.getTsConfigPropArrayElementValue(jsonSourceFile, specKey, spec);
            return element ?
                ts.createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec) :
                ts.createCompilerDiagnostic(message, spec);
        }
    }
    function specToDiagnostic(spec, allowTrailingRecursion) {
        if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
        }
        else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
        }
    }
    /**
     * Gets directories in a set of include patterns that should be watched for changes.
     */
    function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) {
        // We watch a directory recursively if it contains a wildcard anywhere in a directory segment
        // of the pattern:
        //
        //  /a/b/**/d   - Watch /a/b recursively to catch changes to any d in any subfolder recursively
        //  /a/b/*/d    - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added
        //  /a/b        - Watch /a/b recursively to catch changes to anything in any recursive subfoler
        //
        // We watch a directory without recursion if it contains a wildcard in the file segment of
        // the pattern:
        //
        //  /a/b/*      - Watch /a/b directly to catch any new file
        //  /a/b/a?z    - Watch /a/b directly to catch any new file matching a?z
        var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude");
        var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i");
        var wildcardDirectories = {};
        if (include !== undefined) {
            var recursiveKeys = [];
            for (var _i = 0, include_1 = include; _i < include_1.length; _i++) {
                var file = include_1[_i];
                var spec = ts.normalizePath(ts.combinePaths(path, file));
                if (excludeRegex && excludeRegex.test(spec)) {
                    continue;
                }
                var match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames);
                if (match) {
                    var key = match.key, flags = match.flags;
                    var existingFlags = wildcardDirectories[key];
                    if (existingFlags === undefined || existingFlags < flags) {
                        wildcardDirectories[key] = flags;
                        if (flags === 1 /* Recursive */) {
                            recursiveKeys.push(key);
                        }
                    }
                }
            }
            // Remove any subpaths under an existing recursively watched directory.
            for (var key in wildcardDirectories) {
                if (ts.hasProperty(wildcardDirectories, key)) {
                    for (var _a = 0, recursiveKeys_1 = recursiveKeys; _a < recursiveKeys_1.length; _a++) {
                        var recursiveKey = recursiveKeys_1[_a];
                        if (key !== recursiveKey && ts.containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) {
                            delete wildcardDirectories[key];
                        }
                    }
                }
            }
        }
        return wildcardDirectories;
    }
    function getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames) {
        var match = wildcardDirectoryPattern.exec(spec);
        if (match) {
            return {
                key: useCaseSensitiveFileNames ? match[0] : ts.toFileNameLowerCase(match[0]),
                flags: watchRecursivePattern.test(spec) ? 1 /* Recursive */ : 0 /* None */
            };
        }
        if (ts.isImplicitGlob(spec)) {
            return { key: spec, flags: 1 /* Recursive */ };
        }
        return undefined;
    }
    /**
     * Determines whether a literal or wildcard file has already been included that has a higher
     * extension priority.
     *
     * @param file The path to the file.
     * @param extensionPriority The priority of the extension.
     * @param context The expansion context.
     */
    function hasFileWithHigherPriorityExtension(file, literalFiles, wildcardFiles, extensions, keyMapper) {
        var extensionPriority = ts.getExtensionPriority(file, extensions);
        var adjustedExtensionPriority = ts.adjustExtensionPriority(extensionPriority, extensions);
        for (var i = 0 /* Highest */; i < adjustedExtensionPriority; i++) {
            var higherPriorityExtension = extensions[i];
            var higherPriorityPath = keyMapper(ts.changeExtension(file, higherPriorityExtension));
            if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) {
                return true;
            }
        }
        return false;
    }
    /**
     * Removes files included via wildcard expansion with a lower extension priority that have
     * already been included.
     *
     * @param file The path to the file.
     * @param extensionPriority The priority of the extension.
     * @param context The expansion context.
     */
    function removeWildcardFilesWithLowerPriorityExtension(file, wildcardFiles, extensions, keyMapper) {
        var extensionPriority = ts.getExtensionPriority(file, extensions);
        var nextExtensionPriority = ts.getNextLowestExtensionPriority(extensionPriority, extensions);
        for (var i = nextExtensionPriority; i < extensions.length; i++) {
            var lowerPriorityExtension = extensions[i];
            var lowerPriorityPath = keyMapper(ts.changeExtension(file, lowerPriorityExtension));
            wildcardFiles.delete(lowerPriorityPath);
        }
    }
    /**
     * Produces a cleaned version of compiler options with personally identifying info (aka, paths) removed.
     * Also converts enum values back to strings.
     */
    /* @internal */
    function convertCompilerOptionsForTelemetry(opts) {
        var out = {};
        for (var key in opts) {
            if (opts.hasOwnProperty(key)) {
                var type = getOptionFromName(key);
                if (type !== undefined) { // Ignore unknown options
                    out[key] = getOptionValueWithEmptyStrings(opts[key], type);
                }
            }
        }
        return out;
    }
    ts.convertCompilerOptionsForTelemetry = convertCompilerOptionsForTelemetry;
    function getOptionValueWithEmptyStrings(value, option) {
        switch (option.type) {
            case "object": // "paths". Can't get any useful information from the value since we blank out strings, so just return "".
                return "";
            case "string": // Could be any arbitrary string -- use empty string instead.
                return "";
            case "number": // Allow numbers, but be sure to check it's actually a number.
                return typeof value === "number" ? value : "";
            case "boolean":
                return typeof value === "boolean" ? value : "";
            case "list":
                var elementType_1 = option.element;
                return ts.isArray(value) ? value.map(function (v) { return getOptionValueWithEmptyStrings(v, elementType_1); }) : "";
            default:
                return ts.forEachEntry(option.type, function (optionEnumValue, optionStringValue) {
                    if (optionEnumValue === value) {
                        return optionStringValue;
                    }
                }); // TODO: GH#18217
        }
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    function trace(host) {
        host.trace(ts.formatMessage.apply(undefined, arguments));
    }
    ts.trace = trace;
    /* @internal */
    function isTraceEnabled(compilerOptions, host) {
        return !!compilerOptions.traceResolution && host.trace !== undefined;
    }
    ts.isTraceEnabled = isTraceEnabled;
    function withPackageId(packageInfo, r) {
        var packageId;
        if (r && packageInfo) {
            var packageJsonContent = packageInfo.packageJsonContent;
            if (typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string") {
                packageId = {
                    name: packageJsonContent.name,
                    subModuleName: r.path.slice(packageInfo.packageDirectory.length + ts.directorySeparator.length),
                    version: packageJsonContent.version
                };
            }
        }
        return r && { path: r.path, extension: r.ext, packageId: packageId };
    }
    function noPackageId(r) {
        return withPackageId(/*packageInfo*/ undefined, r);
    }
    function removeIgnoredPackageId(r) {
        if (r) {
            ts.Debug.assert(r.packageId === undefined);
            return { path: r.path, ext: r.extension };
        }
    }
    /**
     * Kinds of file that we are currently looking for.
     * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript.
     */
    var Extensions;
    (function (Extensions) {
        Extensions[Extensions["TypeScript"] = 0] = "TypeScript";
        Extensions[Extensions["JavaScript"] = 1] = "JavaScript";
        Extensions[Extensions["Json"] = 2] = "Json";
        Extensions[Extensions["TSConfig"] = 3] = "TSConfig";
        Extensions[Extensions["DtsOnly"] = 4] = "DtsOnly"; /** Only '.d.ts' */
    })(Extensions || (Extensions = {}));
    /** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
    function resolvedTypeScriptOnly(resolved) {
        if (!resolved) {
            return undefined;
        }
        ts.Debug.assert(ts.extensionIsTS(resolved.extension));
        return { fileName: resolved.path, packageId: resolved.packageId };
    }
    function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations, resultFromCache) {
        var _a;
        if (resultFromCache) {
            (_a = resultFromCache.failedLookupLocations).push.apply(_a, failedLookupLocations);
            return resultFromCache;
        }
        return {
            resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId },
            failedLookupLocations: failedLookupLocations
        };
    }
    function readPackageJsonField(jsonContent, fieldName, typeOfTag, state) {
        if (!ts.hasProperty(jsonContent, fieldName)) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_does_not_have_a_0_field, fieldName);
            }
            return;
        }
        var value = jsonContent[fieldName];
        if (typeof value !== typeOfTag || value === null) { // eslint-disable-line no-null/no-null
            if (state.traceEnabled) {
                // eslint-disable-next-line no-null/no-null
                trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value);
            }
            return;
        }
        return value;
    }
    function readPackageJsonPathField(jsonContent, fieldName, baseDirectory, state) {
        var fileName = readPackageJsonField(jsonContent, fieldName, "string", state);
        if (fileName === undefined) {
            return;
        }
        if (!fileName) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_had_a_falsy_0_field, fieldName);
            }
            return;
        }
        var path = ts.normalizePath(ts.combinePaths(baseDirectory, fileName));
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
        }
        return path;
    }
    function readPackageJsonTypesFields(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "typings", baseDirectory, state)
            || readPackageJsonPathField(jsonContent, "types", baseDirectory, state);
    }
    function readPackageJsonTSConfigField(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "tsconfig", baseDirectory, state);
    }
    function readPackageJsonMainField(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "main", baseDirectory, state);
    }
    function readPackageJsonTypesVersionsField(jsonContent, state) {
        var typesVersions = readPackageJsonField(jsonContent, "typesVersions", "object", state);
        if (typesVersions === undefined)
            return;
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_field_with_version_specific_path_mappings);
        }
        return typesVersions;
    }
    function readPackageJsonTypesVersionPaths(jsonContent, state) {
        var typesVersions = readPackageJsonTypesVersionsField(jsonContent, state);
        if (typesVersions === undefined)
            return;
        if (state.traceEnabled) {
            for (var key in typesVersions) {
                if (ts.hasProperty(typesVersions, key) && !ts.VersionRange.tryParse(key)) {
                    trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range, key);
                }
            }
        }
        var result = getPackageJsonTypesVersionsPaths(typesVersions);
        if (!result) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, ts.versionMajorMinor);
            }
            return;
        }
        var bestVersionKey = result.version, bestVersionPaths = result.paths;
        if (typeof bestVersionPaths !== "object") {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, "typesVersions['" + bestVersionKey + "']", "object", typeof bestVersionPaths);
            }
            return;
        }
        return result;
    }
    var typeScriptVersion;
    /* @internal */
    function getPackageJsonTypesVersionsPaths(typesVersions) {
        if (!typeScriptVersion)
            typeScriptVersion = new ts.Version(ts.version);
        for (var key in typesVersions) {
            if (!ts.hasProperty(typesVersions, key))
                continue;
            var keyRange = ts.VersionRange.tryParse(key);
            if (keyRange === undefined) {
                continue;
            }
            // return the first entry whose range matches the current compiler version.
            if (keyRange.test(typeScriptVersion)) {
                return { version: key, paths: typesVersions[key] };
            }
        }
    }
    ts.getPackageJsonTypesVersionsPaths = getPackageJsonTypesVersionsPaths;
    function getEffectiveTypeRoots(options, host) {
        if (options.typeRoots) {
            return options.typeRoots;
        }
        var currentDirectory;
        if (options.configFilePath) {
            currentDirectory = ts.getDirectoryPath(options.configFilePath);
        }
        else if (host.getCurrentDirectory) {
            currentDirectory = host.getCurrentDirectory();
        }
        if (currentDirectory !== undefined) {
            return getDefaultTypeRoots(currentDirectory, host);
        }
    }
    ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
    /**
     * Returns the path to every node_modules/@types directory from some ancestor directory.
     * Returns undefined if there are none.
     */
    function getDefaultTypeRoots(currentDirectory, host) {
        if (!host.directoryExists) {
            return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
            // And if it doesn't exist, tough.
        }
        var typeRoots;
        ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
            var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
            if (host.directoryExists(atTypes)) {
                (typeRoots || (typeRoots = [])).push(atTypes);
            }
            return undefined;
        });
        return typeRoots;
    }
    var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
    /**
     * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
     * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
     * is assumed to be the same as root directory of the project.
     */
    function resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference) {
        var traceEnabled = isTraceEnabled(options, host);
        if (redirectedReference) {
            options = redirectedReference.commandLine.options;
        }
        var failedLookupLocations = [];
        var moduleResolutionState = { compilerOptions: options, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var typeRoots = getEffectiveTypeRoots(options, host);
        if (traceEnabled) {
            if (containingFile === undefined) {
                if (typeRoots === undefined) {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName);
                }
                else {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, typeRoots);
                }
            }
            else {
                if (typeRoots === undefined) {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile);
                }
                else {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots);
                }
            }
            if (redirectedReference) {
                trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
            }
        }
        var resolved = primaryLookup();
        var primary = true;
        if (!resolved) {
            resolved = secondaryLookup();
            primary = false;
        }
        var resolvedTypeReferenceDirective;
        if (resolved) {
            var fileName = resolved.fileName, packageId = resolved.packageId;
            var resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
            if (traceEnabled) {
                if (packageId) {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, resolvedFileName, ts.packageIdToString(packageId), primary);
                }
                else {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
                }
            }
            resolvedTypeReferenceDirective = { primary: primary, resolvedFileName: resolvedFileName, packageId: packageId, isExternalLibraryImport: pathContainsNodeModules(fileName) };
        }
        return { resolvedTypeReferenceDirective: resolvedTypeReferenceDirective, failedLookupLocations: failedLookupLocations };
        function primaryLookup() {
            // Check primary library paths
            if (typeRoots && typeRoots.length) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
                }
                return ts.firstDefined(typeRoots, function (typeRoot) {
                    var candidate = ts.combinePaths(typeRoot, typeReferenceDirectiveName);
                    var candidateDirectory = ts.getDirectoryPath(candidate);
                    var directoryExists = ts.directoryProbablyExists(candidateDirectory, host);
                    if (!directoryExists && traceEnabled) {
                        trace(host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory);
                    }
                    return resolvedTypeScriptOnly(loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, !directoryExists, moduleResolutionState));
                });
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths);
                }
            }
        }
        function secondaryLookup() {
            var initialLocationForSecondaryLookup = containingFile && ts.getDirectoryPath(containingFile);
            if (initialLocationForSecondaryLookup !== undefined) {
                // check secondary locations
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
                }
                var result = void 0;
                if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
                    var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
                    result = searchResult && searchResult.value;
                }
                else {
                    var candidate = ts.normalizePathAndParts(ts.combinePaths(initialLocationForSecondaryLookup, typeReferenceDirectiveName)).path;
                    result = nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true);
                }
                var resolvedFile = resolvedTypeScriptOnly(result);
                if (!resolvedFile && traceEnabled) {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
                }
                return resolvedFile;
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder);
                }
            }
        }
    }
    ts.resolveTypeReferenceDirective = resolveTypeReferenceDirective;
    /**
     * Given a set of options, returns the set of type directive names
     *   that should be included for this program automatically.
     * This list could either come from the config file,
     *   or from enumerating the types root + initial secondary types lookup location.
     * More type directives might appear in the program later as a result of loading actual source files;
     *   this list is only the set of defaults that are implicitly included.
     */
    function getAutomaticTypeDirectiveNames(options, host) {
        // Use explicit type list from tsconfig.json
        if (options.types) {
            return options.types;
        }
        // Walk the primary type lookup locations
        var result = [];
        if (host.directoryExists && host.getDirectories) {
            var typeRoots = getEffectiveTypeRoots(options, host);
            if (typeRoots) {
                for (var _i = 0, typeRoots_1 = typeRoots; _i < typeRoots_1.length; _i++) {
                    var root = typeRoots_1[_i];
                    if (host.directoryExists(root)) {
                        for (var _a = 0, _b = host.getDirectories(root); _a < _b.length; _a++) {
                            var typeDirectivePath = _b[_a];
                            var normalized = ts.normalizePath(typeDirectivePath);
                            var packageJsonPath = ts.combinePaths(root, normalized, "package.json");
                            // `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
                            // See `createNotNeededPackageJSON` in the types-publisher` repo.
                            // eslint-disable-next-line no-null/no-null
                            var isNotNeededPackage = host.fileExists(packageJsonPath) && ts.readJson(packageJsonPath, host).typings === null;
                            if (!isNotNeededPackage) {
                                var baseFileName = ts.getBaseFileName(normalized);
                                // At this stage, skip results with leading dot.
                                if (baseFileName.charCodeAt(0) !== 46 /* dot */) {
                                    // Return just the type directive names
                                    result.push(baseFileName);
                                }
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
    ts.getAutomaticTypeDirectiveNames = getAutomaticTypeDirectiveNames;
    function createModuleResolutionCache(currentDirectory, getCanonicalFileName, options) {
        return createModuleResolutionCacheWithMaps(createCacheWithRedirects(options), createCacheWithRedirects(options), currentDirectory, getCanonicalFileName);
    }
    ts.createModuleResolutionCache = createModuleResolutionCache;
    /*@internal*/
    function createCacheWithRedirects(options) {
        var ownMap = ts.createMap();
        var redirectsMap = ts.createMap();
        return {
            ownMap: ownMap,
            redirectsMap: redirectsMap,
            getOrCreateMapOfCacheRedirects: getOrCreateMapOfCacheRedirects,
            clear: clear,
            setOwnOptions: setOwnOptions,
            setOwnMap: setOwnMap
        };
        function setOwnOptions(newOptions) {
            options = newOptions;
        }
        function setOwnMap(newOwnMap) {
            ownMap = newOwnMap;
        }
        function getOrCreateMapOfCacheRedirects(redirectedReference) {
            if (!redirectedReference) {
                return ownMap;
            }
            var path = redirectedReference.sourceFile.path;
            var redirects = redirectsMap.get(path);
            if (!redirects) {
                // Reuse map if redirected reference map uses same resolution
                redirects = !options || ts.optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? ts.createMap() : ownMap;
                redirectsMap.set(path, redirects);
            }
            return redirects;
        }
        function clear() {
            ownMap.clear();
            redirectsMap.clear();
        }
    }
    ts.createCacheWithRedirects = createCacheWithRedirects;
    /*@internal*/
    function createModuleResolutionCacheWithMaps(directoryToModuleNameMap, moduleNameToDirectoryMap, currentDirectory, getCanonicalFileName) {
        return { getOrCreateCacheForDirectory: getOrCreateCacheForDirectory, getOrCreateCacheForModuleName: getOrCreateCacheForModuleName, directoryToModuleNameMap: directoryToModuleNameMap, moduleNameToDirectoryMap: moduleNameToDirectoryMap };
        function getOrCreateCacheForDirectory(directoryName, redirectedReference) {
            var path = ts.toPath(directoryName, currentDirectory, getCanonicalFileName);
            return getOrCreateCache(directoryToModuleNameMap, redirectedReference, path, ts.createMap);
        }
        function getOrCreateCacheForModuleName(nonRelativeModuleName, redirectedReference) {
            ts.Debug.assert(!ts.isExternalModuleNameRelative(nonRelativeModuleName));
            return getOrCreateCache(moduleNameToDirectoryMap, redirectedReference, nonRelativeModuleName, createPerModuleNameCache);
        }
        function getOrCreateCache(cacheWithRedirects, redirectedReference, key, create) {
            var cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
            var result = cache.get(key);
            if (!result) {
                result = create();
                cache.set(key, result);
            }
            return result;
        }
        function createPerModuleNameCache() {
            var directoryPathMap = ts.createMap();
            return { get: get, set: set };
            function get(directory) {
                return directoryPathMap.get(ts.toPath(directory, currentDirectory, getCanonicalFileName));
            }
            /**
             * At first this function add entry directory -> module resolution result to the table.
             * Then it computes the set of parent folders for 'directory' that should have the same module resolution result
             * and for every parent folder in set it adds entry: parent -> module resolution. .
             * Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts.
             * Set of parent folders that should have the same result will be:
             * [
             *     /a/b/c/d, /a/b/c, /a/b
             * ]
             * this means that request for module resolution from file in any of these folder will be immediately found in cache.
             */
            function set(directory, result) {
                var path = ts.toPath(directory, currentDirectory, getCanonicalFileName);
                // if entry is already in cache do nothing
                if (directoryPathMap.has(path)) {
                    return;
                }
                directoryPathMap.set(path, result);
                var resolvedFileName = result.resolvedModule &&
                    (result.resolvedModule.originalPath || result.resolvedModule.resolvedFileName);
                // find common prefix between directory and resolved file name
                // this common prefix should be the shortest path that has the same resolution
                // directory: /a/b/c/d/e
                // resolvedFileName: /a/b/foo.d.ts
                // commonPrefix: /a/b
                // for failed lookups cache the result for every directory up to root
                var commonPrefix = resolvedFileName && getCommonPrefix(path, resolvedFileName);
                var current = path;
                while (current !== commonPrefix) {
                    var parent = ts.getDirectoryPath(current);
                    if (parent === current || directoryPathMap.has(parent)) {
                        break;
                    }
                    directoryPathMap.set(parent, result);
                    current = parent;
                }
            }
            function getCommonPrefix(directory, resolution) {
                var resolutionDirectory = ts.toPath(ts.getDirectoryPath(resolution), currentDirectory, getCanonicalFileName);
                // find first position where directory and resolution differs
                var i = 0;
                var limit = Math.min(directory.length, resolutionDirectory.length);
                while (i < limit && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) {
                    i++;
                }
                if (i === directory.length && (resolutionDirectory.length === i || resolutionDirectory[i] === ts.directorySeparator)) {
                    return directory;
                }
                var rootLength = ts.getRootLength(directory);
                if (i < rootLength) {
                    return undefined;
                }
                var sep = directory.lastIndexOf(ts.directorySeparator, i - 1);
                if (sep === -1) {
                    return undefined;
                }
                return directory.substr(0, Math.max(sep, rootLength));
            }
        }
    }
    ts.createModuleResolutionCacheWithMaps = createModuleResolutionCacheWithMaps;
    function resolveModuleNameFromCache(moduleName, containingFile, cache) {
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
        return perFolderCache && perFolderCache.get(moduleName);
    }
    ts.resolveModuleNameFromCache = resolveModuleNameFromCache;
    function resolveModuleName(moduleName, containingFile, compilerOptions, host, cache, redirectedReference) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (redirectedReference) {
            compilerOptions = redirectedReference.commandLine.options;
        }
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
            if (redirectedReference) {
                trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
            }
        }
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference);
        var result = perFolderCache && perFolderCache.get(moduleName);
        if (result) {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
            }
        }
        else {
            var moduleResolution = compilerOptions.moduleResolution;
            if (moduleResolution === undefined) {
                moduleResolution = ts.getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Module_resolution_kind_is_not_specified_using_0, ts.ModuleResolutionKind[moduleResolution]);
                }
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ts.ModuleResolutionKind[moduleResolution]);
                }
            }
            ts.perfLogger.logStartResolveModule(moduleName /* , containingFile, ModuleResolutionKind[moduleResolution]*/);
            switch (moduleResolution) {
                case ts.ModuleResolutionKind.NodeJs:
                    result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
                    break;
                case ts.ModuleResolutionKind.Classic:
                    result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
                    break;
                default:
                    return ts.Debug.fail("Unexpected moduleResolution: " + moduleResolution);
            }
            if (result && result.resolvedModule)
                ts.perfLogger.logInfoEvent("Module \"" + moduleName + "\" resolved to \"" + result.resolvedModule.resolvedFileName + "\"");
            ts.perfLogger.logStopResolveModule((result && result.resolvedModule) ? "" + result.resolvedModule.resolvedFileName : "null");
            if (perFolderCache) {
                perFolderCache.set(moduleName, result);
                if (!ts.isExternalModuleNameRelative(moduleName)) {
                    // put result in per-module name cache
                    cache.getOrCreateCacheForModuleName(moduleName, redirectedReference).set(containingDirectory, result);
                }
            }
        }
        if (traceEnabled) {
            if (result.resolvedModule) {
                if (result.resolvedModule.packageId) {
                    trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2, moduleName, result.resolvedModule.resolvedFileName, ts.packageIdToString(result.resolvedModule.packageId));
                }
                else {
                    trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
                }
            }
            else {
                trace(host, ts.Diagnostics.Module_name_0_was_not_resolved, moduleName);
            }
        }
        return result;
    }
    ts.resolveModuleName = resolveModuleName;
    /**
     * Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
     * mitigate differences between design time structure of the project and its runtime counterpart so the same import name
     * can be resolved successfully by TypeScript compiler and runtime module loader.
     * If these settings are set then loading procedure will try to use them to resolve module name and it can of failure it will
     * fallback to standard resolution routine.
     *
     * - baseUrl - this setting controls how non-relative module names are resolved. If this setting is specified then non-relative
     * names will be resolved relative to baseUrl: i.e. if baseUrl is '/a/b' then candidate location to resolve module name 'c/d' will
     * be '/a/b/c/d'
     * - paths - this setting can only be used when baseUrl is specified. allows to tune how non-relative module names
     * will be resolved based on the content of the module name.
     * Structure of 'paths' compiler options
     * 'paths': {
     *    pattern-1: [...substitutions],
     *    pattern-2: [...substitutions],
     *    ...
     *    pattern-n: [...substitutions]
     * }
     * Pattern here is a string that can contain zero or one '*' character. During module resolution module name will be matched against
     * all patterns in the list. Matching for patterns that don't contain '*' means that module name must be equal to pattern respecting the case.
     * If pattern contains '*' then to match pattern "<prefix>*<suffix>" module name must start with the <prefix> and end with <suffix>.
     * <MatchedStar> denotes part of the module name between <prefix> and <suffix>.
     * If module name can be matches with multiple patterns then pattern with the longest prefix will be picked.
     * After selecting pattern we'll use list of substitutions to get candidate locations of the module and the try to load module
     * from the candidate location.
     * Substitution is a string that can contain zero or one '*'. To get candidate location from substitution we'll pick every
     * substitution in the list and replace '*' with <MatchedStar> string. If candidate location is not rooted it
     * will be converted to absolute using baseUrl.
     * For example:
     * baseUrl: /a/b/c
     * "paths": {
     *     // match all module names
     *     "*": [
     *         "*",        // use matched name as is,
     *                     // <matched name> will be looked as /a/b/c/<matched name>
     *
     *         "folder1/*" // substitution will convert matched name to 'folder1/<matched name>',
     *                     // since it is not rooted then final candidate location will be /a/b/c/folder1/<matched name>
     *     ],
     *     // match module names that start with 'components/'
     *     "components/*": [ "/root/components/*" ] // substitution will convert /components/folder1/<matched name> to '/root/components/folder1/<matched name>',
     *                                              // it is rooted so it will be final candidate location
     * }
     *
     * 'rootDirs' allows the project to be spreaded across multiple locations and resolve modules with relative names as if
     * they were in the same location. For example lets say there are two files
     * '/local/src/content/file1.ts'
     * '/shared/components/contracts/src/content/protocols/file2.ts'
     * After bundling content of '/shared/components/contracts/src' will be merged with '/local/src' so
     * if file1 has the following import 'import {x} from "./protocols/file2"' it will be resolved successfully in runtime.
     * 'rootDirs' provides the way to tell compiler that in order to get the whole project it should behave as if content of all
     * root dirs were merged together.
     * I.e. for the example above 'rootDirs' will have two entries: [ '/local/src', '/shared/components/contracts/src' ].
     * Compiler will first convert './protocols/file2' into absolute path relative to the location of containing file:
     * '/local/src/content/protocols/file2' and try to load it - failure.
     * Then it will search 'rootDirs' looking for a longest matching prefix of this absolute path and if such prefix is found - absolute path will
     * be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining
     * entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
     */
    function tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state) {
        var resolved = tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state);
        if (resolved)
            return resolved.value;
        if (!ts.isExternalModuleNameRelative(moduleName)) {
            return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state);
        }
        else {
            return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, state);
        }
    }
    function tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state) {
        var _a = state.compilerOptions, baseUrl = _a.baseUrl, paths = _a.paths;
        if (baseUrl && paths && !ts.pathIsRelative(moduleName)) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
                trace(state.host, ts.Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
            }
            return tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
        }
    }
    function tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, state) {
        if (!state.compilerOptions.rootDirs) {
            return undefined;
        }
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, moduleName);
        }
        var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
        var matchedRootDir;
        var matchedNormalizedPrefix;
        for (var _i = 0, _a = state.compilerOptions.rootDirs; _i < _a.length; _i++) {
            var rootDir = _a[_i];
            // rootDirs are expected to be absolute
            // in case of tsconfig.json this will happen automatically - compiler will expand relative names
            // using location of tsconfig.json as base location
            var normalizedRoot = ts.normalizePath(rootDir);
            if (!ts.endsWith(normalizedRoot, ts.directorySeparator)) {
                normalizedRoot += ts.directorySeparator;
            }
            var isLongestMatchingPrefix = ts.startsWith(candidate, normalizedRoot) &&
                (matchedNormalizedPrefix === undefined || matchedNormalizedPrefix.length < normalizedRoot.length);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2, normalizedRoot, candidate, isLongestMatchingPrefix);
            }
            if (isLongestMatchingPrefix) {
                matchedNormalizedPrefix = normalizedRoot;
                matchedRootDir = rootDir;
            }
        }
        if (matchedNormalizedPrefix) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedNormalizedPrefix);
            }
            var suffix = candidate.substr(matchedNormalizedPrefix.length);
            // first - try to load from a initial location
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
            }
            var resolvedFileName = loader(extensions, candidate, !ts.directoryProbablyExists(containingDirectory, state.host), state);
            if (resolvedFileName) {
                return resolvedFileName;
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Trying_other_entries_in_rootDirs);
            }
            // then try to resolve using remaining entries in rootDirs
            for (var _b = 0, _c = state.compilerOptions.rootDirs; _b < _c.length; _b++) {
                var rootDir = _c[_b];
                if (rootDir === matchedRootDir) {
                    // skip the initially matched entry
                    continue;
                }
                var candidate_1 = ts.combinePaths(ts.normalizePath(rootDir), suffix);
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate_1);
                }
                var baseDirectory = ts.getDirectoryPath(candidate_1);
                var resolvedFileName_1 = loader(extensions, candidate_1, !ts.directoryProbablyExists(baseDirectory, state.host), state);
                if (resolvedFileName_1) {
                    return resolvedFileName_1;
                }
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_resolution_using_rootDirs_has_failed);
            }
        }
        return undefined;
    }
    function tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state) {
        var baseUrl = state.compilerOptions.baseUrl;
        if (!baseUrl) {
            return undefined;
        }
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
        }
        var candidate = ts.normalizePath(ts.combinePaths(baseUrl, moduleName));
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate);
        }
        return loader(extensions, candidate, !ts.directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
    }
    /**
     * Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations.
     * No way to do this with `require()`: https://github.com/nodejs/node/issues/5963
     * Throws an error if the module can't be resolved.
     */
    /* @internal */
    function resolveJSModule(moduleName, initialDir, host) {
        var _a = tryResolveJSModuleWorker(moduleName, initialDir, host), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations;
        if (!resolvedModule) {
            throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", "));
        }
        return resolvedModule.resolvedFileName;
    }
    ts.resolveJSModule = resolveJSModule;
    /* @internal */
    function tryResolveJSModule(moduleName, initialDir, host) {
        var resolvedModule = tryResolveJSModuleWorker(moduleName, initialDir, host).resolvedModule;
        return resolvedModule && resolvedModule.resolvedFileName;
    }
    ts.tryResolveJSModule = tryResolveJSModule;
    var jsOnlyExtensions = [Extensions.JavaScript];
    var tsExtensions = [Extensions.TypeScript, Extensions.JavaScript];
    var tsPlusJsonExtensions = __spreadArrays(tsExtensions, [Extensions.Json]);
    var tsconfigExtensions = [Extensions.TSConfig];
    function tryResolveJSModuleWorker(moduleName, initialDir, host) {
        return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined);
    }
    function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, lookupConfig) {
        return nodeModuleNameResolverWorker(moduleName, ts.getDirectoryPath(containingFile), compilerOptions, host, cache, lookupConfig ? tsconfigExtensions : (compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions), redirectedReference);
    }
    ts.nodeModuleNameResolver = nodeModuleNameResolver;
    function nodeModuleNameResolverWorker(moduleName, containingDirectory, compilerOptions, host, cache, extensions, redirectedReference) {
        var _a, _b;
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var result = ts.forEach(extensions, function (ext) { return tryResolve(ext); });
        return createResolvedModuleWithFailedLookupLocations((_a = result === null || result === void 0 ? void 0 : result.value) === null || _a === void 0 ? void 0 : _a.resolved, (_b = result === null || result === void 0 ? void 0 : result.value) === null || _b === void 0 ? void 0 : _b.isExternalLibraryImport, failedLookupLocations, state.resultFromCache);
        function tryResolve(extensions) {
            var loader = function (extensions, candidate, onlyRecordFailures, state) { return nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true); };
            var resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state);
            if (resolved) {
                return toSearchResult({ resolved: resolved, isExternalLibraryImport: pathContainsNodeModules(resolved.path) });
            }
            if (!ts.isExternalModuleNameRelative(moduleName)) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
                }
                var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
                if (!resolved_1)
                    return undefined;
                var resolvedValue = resolved_1.value;
                if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
                    var path = realPath(resolvedValue.path, host, traceEnabled);
                    var originalPath = path === resolvedValue.path ? undefined : resolvedValue.path;
                    resolvedValue = __assign(__assign({}, resolvedValue), { path: path, originalPath: originalPath });
                }
                // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
                return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
            }
            else {
                var _a = ts.normalizePathAndParts(ts.combinePaths(containingDirectory, moduleName)), candidate = _a.path, parts = _a.parts;
                var resolved_2 = nodeLoadModuleByRelativeName(extensions, candidate, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
                // Treat explicit "node_modules" import as an external library import.
                return resolved_2 && toSearchResult({ resolved: resolved_2, isExternalLibraryImport: ts.contains(parts, "node_modules") });
            }
        }
    }
    function realPath(path, host, traceEnabled) {
        if (!host.realpath) {
            return path;
        }
        var real = ts.normalizePath(host.realpath(path));
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_real_path_for_0_result_1, path, real);
        }
        ts.Debug.assert(host.fileExists(real), path + " linked to nonexistent file " + real);
        return real;
    }
    function nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, considerPackageJson) {
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]);
        }
        if (!ts.hasTrailingDirectorySeparator(candidate)) {
            if (!onlyRecordFailures) {
                var parentOfCandidate = ts.getDirectoryPath(candidate);
                if (!ts.directoryProbablyExists(parentOfCandidate, state.host)) {
                    if (state.traceEnabled) {
                        trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parentOfCandidate);
                    }
                    onlyRecordFailures = true;
                }
            }
            var resolvedFromFile = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state);
            if (resolvedFromFile) {
                var packageDirectory = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined;
                var packageInfo = packageDirectory ? getPackageJsonInfo(packageDirectory, /*onlyRecordFailures*/ false, state) : undefined;
                return withPackageId(packageInfo, resolvedFromFile);
            }
        }
        if (!onlyRecordFailures) {
            var candidateExists = ts.directoryProbablyExists(candidate, state.host);
            if (!candidateExists) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate);
                }
                onlyRecordFailures = true;
            }
        }
        return loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson);
    }
    /*@internal*/
    ts.nodeModulesPathPart = "/node_modules/";
    /*@internal*/
    function pathContainsNodeModules(path) {
        return ts.stringContains(path, ts.nodeModulesPathPart);
    }
    ts.pathContainsNodeModules = pathContainsNodeModules;
    /**
     * This will be called on the successfully resolved path from `loadModuleFromFile`.
     * (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.)
     *
     * packageDirectory is the directory of the package itself.
     *   For `blah/node_modules/foo/index.d.ts` this is packageDirectory: "foo"
     *   For `/node_modules/foo/bar.d.ts` this is packageDirectory: "foo"
     *   For `/node_modules/@types/foo/bar/index.d.ts` this is packageDirectory: "@types/foo"
     *   For `/node_modules/foo/bar/index.d.ts` this is packageDirectory: "foo"
     */
    function parseNodeModuleFromPath(resolved) {
        var path = ts.normalizePath(resolved.path);
        var idx = path.lastIndexOf(ts.nodeModulesPathPart);
        if (idx === -1) {
            return undefined;
        }
        var indexAfterNodeModules = idx + ts.nodeModulesPathPart.length;
        var indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules);
        if (path.charCodeAt(indexAfterNodeModules) === 64 /* at */) {
            indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName);
        }
        return path.slice(0, indexAfterPackageName);
    }
    function moveToNextDirectorySeparatorIfAvailable(path, prevSeparatorIndex) {
        var nextSeparatorIndex = path.indexOf(ts.directorySeparator, prevSeparatorIndex + 1);
        return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex;
    }
    function loadModuleFromFileNoPackageId(extensions, candidate, onlyRecordFailures, state) {
        return noPackageId(loadModuleFromFile(extensions, candidate, onlyRecordFailures, state));
    }
    /**
     * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
     * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
     */
    function loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) {
        if (extensions === Extensions.Json || extensions === Extensions.TSConfig) {
            var extensionLess = ts.tryRemoveExtension(candidate, ".json" /* Json */);
            return (extensionLess === undefined && extensions === Extensions.Json) ? undefined : tryAddingExtensions(extensionLess || candidate, extensions, onlyRecordFailures, state);
        }
        // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
        var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, onlyRecordFailures, state);
        if (resolvedByAddingExtension) {
            return resolvedByAddingExtension;
        }
        // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
        // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
        if (ts.hasJSFileExtension(candidate)) {
            var extensionless = ts.removeFileExtension(candidate);
            if (state.traceEnabled) {
                var extension = candidate.substring(extensionless.length);
                trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
            }
            return tryAddingExtensions(extensionless, extensions, onlyRecordFailures, state);
        }
    }
    /** Try to return an existing file that adds one of the `extensions` to `candidate`. */
    function tryAddingExtensions(candidate, extensions, onlyRecordFailures, state) {
        if (!onlyRecordFailures) {
            // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
            var directory = ts.getDirectoryPath(candidate);
            if (directory) {
                onlyRecordFailures = !ts.directoryProbablyExists(directory, state.host);
            }
        }
        switch (extensions) {
            case Extensions.DtsOnly:
                return tryExtension(".d.ts" /* Dts */);
            case Extensions.TypeScript:
                return tryExtension(".ts" /* Ts */) || tryExtension(".tsx" /* Tsx */) || tryExtension(".d.ts" /* Dts */);
            case Extensions.JavaScript:
                return tryExtension(".js" /* Js */) || tryExtension(".jsx" /* Jsx */);
            case Extensions.TSConfig:
            case Extensions.Json:
                return tryExtension(".json" /* Json */);
        }
        function tryExtension(ext) {
            var path = tryFile(candidate + ext, onlyRecordFailures, state);
            return path === undefined ? undefined : { path: path, ext: ext };
        }
    }
    /** Return the file if it exists. */
    function tryFile(fileName, onlyRecordFailures, state) {
        if (!onlyRecordFailures) {
            if (state.host.fileExists(fileName)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName);
                }
                return fileName;
            }
            else {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName);
                }
            }
        }
        state.failedLookupLocations.push(fileName);
        return undefined;
    }
    function loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson) {
        if (considerPackageJson === void 0) { considerPackageJson = true; }
        var packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, onlyRecordFailures, state) : undefined;
        var packageJsonContent = packageInfo && packageInfo.packageJsonContent;
        var versionPaths = packageInfo && packageInfo.versionPaths;
        return withPackageId(packageInfo, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
    }
    function getPackageJsonInfo(packageDirectory, onlyRecordFailures, state) {
        var host = state.host, traceEnabled = state.traceEnabled;
        var directoryExists = !onlyRecordFailures && ts.directoryProbablyExists(packageDirectory, host);
        var packageJsonPath = ts.combinePaths(packageDirectory, "package.json");
        if (directoryExists && host.fileExists(packageJsonPath)) {
            var packageJsonContent = ts.readJson(packageJsonPath, host);
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath);
            }
            var versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
            return { packageDirectory: packageDirectory, packageJsonContent: packageJsonContent, versionPaths: versionPaths };
        }
        else {
            if (directoryExists && traceEnabled) {
                trace(host, ts.Diagnostics.File_0_does_not_exist, packageJsonPath);
            }
            // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
            state.failedLookupLocations.push(packageJsonPath);
        }
    }
    function loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, jsonContent, versionPaths) {
        var packageFile;
        if (jsonContent) {
            switch (extensions) {
                case Extensions.JavaScript:
                case Extensions.Json:
                    packageFile = readPackageJsonMainField(jsonContent, candidate, state);
                    break;
                case Extensions.TypeScript:
                    // When resolving typescript modules, try resolving using main field as well
                    packageFile = readPackageJsonTypesFields(jsonContent, candidate, state) || readPackageJsonMainField(jsonContent, candidate, state);
                    break;
                case Extensions.DtsOnly:
                    packageFile = readPackageJsonTypesFields(jsonContent, candidate, state);
                    break;
                case Extensions.TSConfig:
                    packageFile = readPackageJsonTSConfigField(jsonContent, candidate, state);
                    break;
                default:
                    return ts.Debug.assertNever(extensions);
            }
        }
        var loader = function (extensions, candidate, onlyRecordFailures, state) {
            var fromFile = tryFile(candidate, onlyRecordFailures, state);
            if (fromFile) {
                var resolved = resolvedIfExtensionMatches(extensions, fromFile);
                if (resolved) {
                    return noPackageId(resolved);
                }
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
                }
            }
            // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
            var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions;
            // Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
            return nodeLoadModuleByRelativeName(nextExtensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ false);
        };
        var onlyRecordFailuresForPackageFile = packageFile ? !ts.directoryProbablyExists(ts.getDirectoryPath(packageFile), state.host) : undefined;
        var onlyRecordFailuresForIndex = onlyRecordFailures || !ts.directoryProbablyExists(candidate, state.host);
        var indexPath = ts.combinePaths(candidate, extensions === Extensions.TSConfig ? "tsconfig" : "index");
        if (versionPaths && (!packageFile || ts.containsPath(candidate, packageFile))) {
            var moduleName = ts.getRelativePathFromDirectory(candidate, packageFile || indexPath, /*ignoreCase*/ false);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, ts.version, moduleName);
            }
            var result = tryLoadModuleUsingPaths(extensions, moduleName, candidate, versionPaths.paths, loader, onlyRecordFailuresForPackageFile || onlyRecordFailuresForIndex, state);
            if (result) {
                return removeIgnoredPackageId(result.value);
            }
        }
        // It won't have a `packageId` set, because we disabled `considerPackageJson`.
        var packageFileResult = packageFile && removeIgnoredPackageId(loader(extensions, packageFile, onlyRecordFailuresForPackageFile, state));
        if (packageFileResult)
            return packageFileResult;
        return loadModuleFromFile(extensions, indexPath, onlyRecordFailuresForIndex, state);
    }
    /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
    function resolvedIfExtensionMatches(extensions, path) {
        var ext = ts.tryGetExtensionFromPath(path);
        return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined;
    }
    /** True if `extension` is one of the supported `extensions`. */
    function extensionIsOk(extensions, extension) {
        switch (extensions) {
            case Extensions.JavaScript:
                return extension === ".js" /* Js */ || extension === ".jsx" /* Jsx */;
            case Extensions.TSConfig:
            case Extensions.Json:
                return extension === ".json" /* Json */;
            case Extensions.TypeScript:
                return extension === ".ts" /* Ts */ || extension === ".tsx" /* Tsx */ || extension === ".d.ts" /* Dts */;
            case Extensions.DtsOnly:
                return extension === ".d.ts" /* Dts */;
        }
    }
    /* @internal */
    function parsePackageName(moduleName) {
        var idx = moduleName.indexOf(ts.directorySeparator);
        if (moduleName[0] === "@") {
            idx = moduleName.indexOf(ts.directorySeparator, idx + 1);
        }
        return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
    }
    ts.parsePackageName = parsePackageName;
    function loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, directory, state, cache, redirectedReference) {
        return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache, redirectedReference);
    }
    function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, directory, state) {
        // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
        return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined, /*redirectedReference*/ undefined);
    }
    function loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, typesScopeOnly, cache, redirectedReference) {
        var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
        return ts.forEachAncestorDirectory(ts.normalizeSlashes(directory), function (ancestorDirectory) {
            if (ts.getBaseFileName(ancestorDirectory) !== "node_modules") {
                var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state);
                if (resolutionFromCache) {
                    return resolutionFromCache;
                }
                return toSearchResult(loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, ancestorDirectory, state, typesScopeOnly));
            }
        });
    }
    function loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, directory, state, typesScopeOnly) {
        var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
        var nodeModulesFolderExists = ts.directoryProbablyExists(nodeModulesFolder, state.host);
        if (!nodeModulesFolderExists && state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder);
        }
        var packageResult = typesScopeOnly ? undefined : loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, state);
        if (packageResult) {
            return packageResult;
        }
        if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
            var nodeModulesAtTypes_1 = ts.combinePaths(nodeModulesFolder, "@types");
            var nodeModulesAtTypesExists = nodeModulesFolderExists;
            if (nodeModulesFolderExists && !ts.directoryProbablyExists(nodeModulesAtTypes_1, state.host)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesAtTypes_1);
                }
                nodeModulesAtTypesExists = false;
            }
            return loadModuleFromSpecificNodeModulesDirectory(Extensions.DtsOnly, mangleScopedPackageNameWithTrace(moduleName, state), nodeModulesAtTypes_1, nodeModulesAtTypesExists, state);
        }
    }
    function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
        var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
        // First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
        var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
        if (packageInfo) {
            var fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
            if (fromFile) {
                return noPackageId(fromFile);
            }
            var fromDirectory = loadNodeModuleFromDirectoryWorker(extensions, candidate, !nodeModulesDirectoryExists, state, packageInfo.packageJsonContent, packageInfo.versionPaths);
            return withPackageId(packageInfo, fromDirectory);
        }
        var loader = function (extensions, candidate, onlyRecordFailures, state) {
            var pathAndExtension = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
                loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
            return withPackageId(packageInfo, pathAndExtension);
        };
        var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
        if (rest !== "") { // If "rest" is empty, we just did this search above.
            var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
            // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
            packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
            if (packageInfo && packageInfo.versionPaths) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.versionPaths.version, ts.version, rest);
                }
                var packageDirectoryExists = nodeModulesDirectoryExists && ts.directoryProbablyExists(packageDirectory, state.host);
                var fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, packageInfo.versionPaths.paths, loader, !packageDirectoryExists, state);
                if (fromPaths) {
                    return fromPaths.value;
                }
            }
        }
        return loader(extensions, candidate, !nodeModulesDirectoryExists, state);
    }
    function tryLoadModuleUsingPaths(extensions, moduleName, baseDirectory, paths, loader, onlyRecordFailures, state) {
        var matchedPattern = ts.matchPatternOrExact(ts.getOwnKeys(paths), moduleName);
        if (matchedPattern) {
            var matchedStar_1 = ts.isString(matchedPattern) ? undefined : ts.matchedText(matchedPattern, moduleName);
            var matchedPatternText = ts.isString(matchedPattern) ? matchedPattern : ts.patternText(matchedPattern);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
            }
            var resolved = ts.forEach(paths[matchedPatternText], function (subst) {
                var path = matchedStar_1 ? subst.replace("*", matchedStar_1) : subst;
                var candidate = ts.normalizePath(ts.combinePaths(baseDirectory, path));
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
                }
                // A path mapping may have an extension, in contrast to an import, which should omit it.
                var extension = ts.tryGetExtensionFromPath(candidate);
                if (extension !== undefined) {
                    var path_1 = tryFile(candidate, onlyRecordFailures, state);
                    if (path_1 !== undefined) {
                        return noPackageId({ path: path_1, ext: extension });
                    }
                }
                return loader(extensions, candidate, onlyRecordFailures || !ts.directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
            });
            return { value: resolved };
        }
    }
    /** Double underscores are used in DefinitelyTyped to delimit scoped packages. */
    var mangledScopedPackageSeparator = "__";
    /** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
    function mangleScopedPackageNameWithTrace(packageName, state) {
        var mangled = mangleScopedPackageName(packageName);
        if (state.traceEnabled && mangled !== packageName) {
            trace(state.host, ts.Diagnostics.Scoped_package_detected_looking_in_0, mangled);
        }
        return mangled;
    }
    /* @internal */
    function getTypesPackageName(packageName) {
        return "@types/" + mangleScopedPackageName(packageName);
    }
    ts.getTypesPackageName = getTypesPackageName;
    /* @internal */
    function mangleScopedPackageName(packageName) {
        if (ts.startsWith(packageName, "@")) {
            var replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
            if (replaceSlash !== packageName) {
                return replaceSlash.slice(1); // Take off the "@"
            }
        }
        return packageName;
    }
    ts.mangleScopedPackageName = mangleScopedPackageName;
    /* @internal */
    function getPackageNameFromTypesPackageName(mangledName) {
        var withoutAtTypePrefix = ts.removePrefix(mangledName, "@types/");
        if (withoutAtTypePrefix !== mangledName) {
            return unmangleScopedPackageName(withoutAtTypePrefix);
        }
        return mangledName;
    }
    ts.getPackageNameFromTypesPackageName = getPackageNameFromTypesPackageName;
    /* @internal */
    function unmangleScopedPackageName(typesPackageName) {
        return ts.stringContains(typesPackageName, mangledScopedPackageSeparator) ?
            "@" + typesPackageName.replace(mangledScopedPackageSeparator, ts.directorySeparator) :
            typesPackageName;
    }
    ts.unmangleScopedPackageName = unmangleScopedPackageName;
    function tryFindNonRelativeModuleNameInCache(cache, moduleName, containingDirectory, state) {
        var result = cache && cache.get(containingDirectory);
        if (result) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
            }
            state.resultFromCache = result;
            return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, originalPath: result.resolvedModule.originalPath || true, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
        }
    }
    function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
        // No originalPath because classic resolution doesn't resolve realPath
        return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations, state.resultFromCache);
        function tryResolve(extensions) {
            var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, state);
            if (resolvedUsingSettings) {
                return { value: resolvedUsingSettings };
            }
            if (!ts.isExternalModuleNameRelative(moduleName)) {
                var perModuleNameCache_1 = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
                // Climb up parent directories looking for a module.
                var resolved_3 = ts.forEachAncestorDirectory(containingDirectory, function (directory) {
                    var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache_1, moduleName, directory, state);
                    if (resolutionFromCache) {
                        return resolutionFromCache;
                    }
                    var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName));
                    return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, /*onlyRecordFailures*/ false, state));
                });
                if (resolved_3) {
                    return resolved_3;
                }
                if (extensions === Extensions.TypeScript) {
                    // If we didn't find the file normally, look it up in @types.
                    return loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, containingDirectory, state);
                }
            }
            else {
                var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
                return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, /*onlyRecordFailures*/ false, state));
            }
        }
    }
    ts.classicNameResolver = classicNameResolver;
    /**
     * A host may load a module from a global cache of typings.
     * This is the minumum code needed to expose that functionality; the rest is in the host.
     */
    /* @internal */
    function loadModuleFromGlobalCache(moduleName, projectName, compilerOptions, host, globalCache) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
        }
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false);
        return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations, state.resultFromCache);
    }
    ts.loadModuleFromGlobalCache = loadModuleFromGlobalCache;
    /**
     * Wraps value to SearchResult.
     * @returns undefined if value is undefined or { value } otherwise
     */
    function toSearchResult(value) {
        return value !== undefined ? { value: value } : undefined;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var ModuleInstanceState;
    (function (ModuleInstanceState) {
        ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
        ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
        ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
    })(ModuleInstanceState = ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
    function getModuleInstanceState(node, visited) {
        if (node.body && !node.body.parent) {
            // getModuleInstanceStateForAliasTarget needs to walk up the parent chain, so parent pointers must be set on this tree already
            setParentPointers(node, node.body);
        }
        return node.body ? getModuleInstanceStateCached(node.body, visited) : 1 /* Instantiated */;
    }
    ts.getModuleInstanceState = getModuleInstanceState;
    function getModuleInstanceStateCached(node, visited) {
        if (visited === void 0) { visited = ts.createMap(); }
        var nodeId = "" + ts.getNodeId(node);
        if (visited.has(nodeId)) {
            return visited.get(nodeId) || 0 /* NonInstantiated */;
        }
        visited.set(nodeId, undefined);
        var result = getModuleInstanceStateWorker(node, visited);
        visited.set(nodeId, result);
        return result;
    }
    function getModuleInstanceStateWorker(node, visited) {
        // A module is uninstantiated if it contains only
        switch (node.kind) {
            // 1. interface declarations, type alias declarations
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
                return 0 /* NonInstantiated */;
            // 2. const enum declarations
            case 248 /* EnumDeclaration */:
                if (ts.isEnumConst(node)) {
                    return 2 /* ConstEnumOnly */;
                }
                break;
            // 3. non-exported import declarations
            case 254 /* ImportDeclaration */:
            case 253 /* ImportEqualsDeclaration */:
                if (!(ts.hasModifier(node, 1 /* Export */))) {
                    return 0 /* NonInstantiated */;
                }
                break;
            // 4. Export alias declarations pointing at only uninstantiated modules or things uninstantiated modules contain
            case 260 /* ExportDeclaration */:
                var exportDeclaration = node;
                if (!exportDeclaration.moduleSpecifier && exportDeclaration.exportClause && exportDeclaration.exportClause.kind === 261 /* NamedExports */) {
                    var state = 0 /* NonInstantiated */;
                    for (var _i = 0, _a = exportDeclaration.exportClause.elements; _i < _a.length; _i++) {
                        var specifier = _a[_i];
                        var specifierState = getModuleInstanceStateForAliasTarget(specifier, visited);
                        if (specifierState > state) {
                            state = specifierState;
                        }
                        if (state === 1 /* Instantiated */) {
                            return state;
                        }
                    }
                    return state;
                }
                break;
            // 5. other uninstantiated module declarations.
            case 250 /* ModuleBlock */: {
                var state_1 = 0 /* NonInstantiated */;
                ts.forEachChild(node, function (n) {
                    var childState = getModuleInstanceStateCached(n, visited);
                    switch (childState) {
                        case 0 /* NonInstantiated */:
                            // child is non-instantiated - continue searching
                            return;
                        case 2 /* ConstEnumOnly */:
                            // child is const enum only - record state and continue searching
                            state_1 = 2 /* ConstEnumOnly */;
                            return;
                        case 1 /* Instantiated */:
                            // child is instantiated - record state and stop
                            state_1 = 1 /* Instantiated */;
                            return true;
                        default:
                            ts.Debug.assertNever(childState);
                    }
                });
                return state_1;
            }
            case 249 /* ModuleDeclaration */:
                return getModuleInstanceState(node, visited);
            case 75 /* Identifier */:
                // Only jsdoc typedef definition can exist in jsdoc namespace, and it should
                // be considered the same as type alias
                if (node.isInJSDocNamespace) {
                    return 0 /* NonInstantiated */;
                }
        }
        return 1 /* Instantiated */;
    }
    function getModuleInstanceStateForAliasTarget(specifier, visited) {
        var name = specifier.propertyName || specifier.name;
        var p = specifier.parent;
        while (p) {
            if (ts.isBlock(p) || ts.isModuleBlock(p) || ts.isSourceFile(p)) {
                var statements = p.statements;
                var found = void 0;
                for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
                    var statement = statements_1[_i];
                    if (ts.nodeHasName(statement, name)) {
                        if (!statement.parent) {
                            setParentPointers(p, statement);
                        }
                        var state = getModuleInstanceStateCached(statement, visited);
                        if (found === undefined || state > found) {
                            found = state;
                        }
                        if (found === 1 /* Instantiated */) {
                            return found;
                        }
                    }
                }
                if (found !== undefined) {
                    return found;
                }
            }
            p = p.parent;
        }
        return 1 /* Instantiated */; // Couldn't locate, assume could refer to a value
    }
    var ContainerFlags;
    (function (ContainerFlags) {
        // The current node is not a container, and no container manipulation should happen before
        // recursing into it.
        ContainerFlags[ContainerFlags["None"] = 0] = "None";
        // The current node is a container.  It should be set as the current container (and block-
        // container) before recursing into it.  The current node does not have locals.  Examples:
        //
        //      Classes, ObjectLiterals, TypeLiterals, Interfaces...
        ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
        // The current node is a block-scoped-container.  It should be set as the current block-
        // container before recursing into it.  Examples:
        //
        //      Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
        ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
        // The current node is the container of a control flow path. The current control flow should
        // be saved and restored, and a new control flow initialized within the container.
        ContainerFlags[ContainerFlags["IsControlFlowContainer"] = 4] = "IsControlFlowContainer";
        ContainerFlags[ContainerFlags["IsFunctionLike"] = 8] = "IsFunctionLike";
        ContainerFlags[ContainerFlags["IsFunctionExpression"] = 16] = "IsFunctionExpression";
        ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals";
        ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface";
        ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod";
    })(ContainerFlags || (ContainerFlags = {}));
    function initFlowNode(node) {
        ts.Debug.attachFlowNodeDebugInfo(node);
        return node;
    }
    var binder = createBinder();
    function bindSourceFile(file, options) {
        ts.performance.mark("beforeBind");
        ts.perfLogger.logStartBindFile("" + file.fileName);
        binder(file, options);
        ts.perfLogger.logStopBindFile();
        ts.performance.mark("afterBind");
        ts.performance.measure("Bind", "beforeBind", "afterBind");
    }
    ts.bindSourceFile = bindSourceFile;
    function createBinder() {
        var file;
        var options;
        var languageVersion;
        var parent;
        var container;
        var thisParentContainer; // Container one level up
        var blockScopeContainer;
        var lastContainer;
        var delayedTypeAliases;
        var seenThisKeyword;
        // state used by control flow analysis
        var currentFlow;
        var currentBreakTarget;
        var currentContinueTarget;
        var currentReturnTarget;
        var currentTrueTarget;
        var currentFalseTarget;
        var currentExceptionTarget;
        var preSwitchCaseFlow;
        var activeLabelList;
        var hasExplicitReturn;
        // state used for emit helpers
        var emitFlags;
        // If this file is an external module, then it is automatically in strict-mode according to
        // ES6.  If it is not an external module, then we'll determine if it is in strict mode or
        // not depending on if we see "use strict" in certain places or if we hit a class/namespace
        // or if compiler options contain alwaysStrict.
        var inStrictMode;
        var symbolCount = 0;
        var Symbol;
        var classifiableNames;
        var unreachableFlow = { flags: 1 /* Unreachable */ };
        var reportedUnreachableFlow = { flags: 1 /* Unreachable */ };
        // state used to aggregate transform flags during bind.
        var subtreeTransformFlags = 0 /* None */;
        var skipTransformFlagAggregation;
        /**
         * Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file)
         * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node)
         * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations.
         */
        function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
            return ts.createDiagnosticForNodeInSourceFile(ts.getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2);
        }
        function bindSourceFile(f, opts) {
            file = f;
            options = opts;
            languageVersion = ts.getEmitScriptTarget(options);
            inStrictMode = bindInStrictMode(file, opts);
            classifiableNames = ts.createUnderscoreEscapedMap();
            symbolCount = 0;
            skipTransformFlagAggregation = file.isDeclarationFile;
            Symbol = ts.objectAllocator.getSymbolConstructor();
            // Attach debugging information if necessary
            ts.Debug.attachFlowNodeDebugInfo(unreachableFlow);
            ts.Debug.attachFlowNodeDebugInfo(reportedUnreachableFlow);
            if (!file.locals) {
                bind(file);
                file.symbolCount = symbolCount;
                file.classifiableNames = classifiableNames;
                delayedBindJSDocTypedefTag();
            }
            file = undefined;
            options = undefined;
            languageVersion = undefined;
            parent = undefined;
            container = undefined;
            thisParentContainer = undefined;
            blockScopeContainer = undefined;
            lastContainer = undefined;
            delayedTypeAliases = undefined;
            seenThisKeyword = false;
            currentFlow = undefined;
            currentBreakTarget = undefined;
            currentContinueTarget = undefined;
            currentReturnTarget = undefined;
            currentTrueTarget = undefined;
            currentFalseTarget = undefined;
            currentExceptionTarget = undefined;
            activeLabelList = undefined;
            hasExplicitReturn = false;
            emitFlags = 0 /* None */;
            subtreeTransformFlags = 0 /* None */;
        }
        return bindSourceFile;
        function bindInStrictMode(file, opts) {
            if (ts.getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) {
                // bind in strict mode source files with alwaysStrict option
                return true;
            }
            else {
                return !!file.externalModuleIndicator;
            }
        }
        function createSymbol(flags, name) {
            symbolCount++;
            return new Symbol(flags, name);
        }
        function addDeclarationToSymbol(symbol, node, symbolFlags) {
            symbol.flags |= symbolFlags;
            node.symbol = symbol;
            symbol.declarations = ts.appendIfUnique(symbol.declarations, node);
            if (symbolFlags & (32 /* Class */ | 384 /* Enum */ | 1536 /* Module */ | 3 /* Variable */) && !symbol.exports) {
                symbol.exports = ts.createSymbolTable();
            }
            if (symbolFlags & (32 /* Class */ | 64 /* Interface */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && !symbol.members) {
                symbol.members = ts.createSymbolTable();
            }
            // On merge of const enum module with class or function, reset const enum only flag (namespaces will already recalculate)
            if (symbol.constEnumOnlyModule && (symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */))) {
                symbol.constEnumOnlyModule = false;
            }
            if (symbolFlags & 111551 /* Value */) {
                ts.setValueDeclaration(symbol, node);
            }
        }
        // Should not be called on a declaration with a computed property name,
        // unless it is a well known Symbol.
        function getDeclarationName(node) {
            if (node.kind === 259 /* ExportAssignment */) {
                return node.isExportEquals ? "export=" /* ExportEquals */ : "default" /* Default */;
            }
            var name = ts.getNameOfDeclaration(node);
            if (name) {
                if (ts.isAmbientModule(node)) {
                    var moduleName = ts.getTextOfIdentifierOrLiteral(name);
                    return (ts.isGlobalScopeAugmentation(node) ? "__global" : "\"" + moduleName + "\"");
                }
                if (name.kind === 154 /* ComputedPropertyName */) {
                    var nameExpression = name.expression;
                    // treat computed property names where expression is string/numeric literal as just string/numeric literal
                    if (ts.isStringOrNumericLiteralLike(nameExpression)) {
                        return ts.escapeLeadingUnderscores(nameExpression.text);
                    }
                    if (ts.isSignedNumericLiteral(nameExpression)) {
                        return ts.tokenToString(nameExpression.operator) + nameExpression.operand.text;
                    }
                    ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
                    return ts.getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
                }
                if (ts.isWellKnownSymbolSyntactically(name)) {
                    return ts.getPropertyNameForKnownSymbolName(ts.idText(name.name));
                }
                if (ts.isPrivateIdentifier(name)) {
                    // containingClass exists because private names only allowed inside classes
                    var containingClass = ts.getContainingClass(node);
                    if (!containingClass) {
                        // we can get here in cases where there is already a parse error.
                        return undefined;
                    }
                    var containingClassSymbol = containingClass.symbol;
                    return ts.getSymbolNameForPrivateIdentifier(containingClassSymbol, name.escapedText);
                }
                return ts.isPropertyNameLiteral(name) ? ts.getEscapedTextOfIdentifierOrLiteral(name) : undefined;
            }
            switch (node.kind) {
                case 162 /* Constructor */:
                    return "__constructor" /* Constructor */;
                case 170 /* FunctionType */:
                case 165 /* CallSignature */:
                case 305 /* JSDocSignature */:
                    return "__call" /* Call */;
                case 171 /* ConstructorType */:
                case 166 /* ConstructSignature */:
                    return "__new" /* New */;
                case 167 /* IndexSignature */:
                    return "__index" /* Index */;
                case 260 /* ExportDeclaration */:
                    return "__export" /* ExportStar */;
                case 290 /* SourceFile */:
                    // json file should behave as
                    // module.exports = ...
                    return "export=" /* ExportEquals */;
                case 209 /* BinaryExpression */:
                    if (ts.getAssignmentDeclarationKind(node) === 2 /* ModuleExports */) {
                        // module.exports = ...
                        return "export=" /* ExportEquals */;
                    }
                    ts.Debug.fail("Unknown binary declaration kind");
                    break;
                case 300 /* JSDocFunctionType */:
                    return (ts.isJSDocConstructSignature(node) ? "__new" /* New */ : "__call" /* Call */);
                case 156 /* Parameter */:
                    // Parameters with names are handled at the top of this function.  Parameters
                    // without names can only come from JSDocFunctionTypes.
                    ts.Debug.assert(node.parent.kind === 300 /* JSDocFunctionType */, "Impossible parameter parent kind", function () { return "parent is: " + (ts.SyntaxKind ? ts.SyntaxKind[node.parent.kind] : node.parent.kind) + ", expected JSDocFunctionType"; });
                    var functionType = node.parent;
                    var index = functionType.parameters.indexOf(node);
                    return "arg" + index;
            }
        }
        function getDisplayName(node) {
            return ts.isNamedDeclaration(node) ? ts.declarationNameToString(node.name) : ts.unescapeLeadingUnderscores(ts.Debug.checkDefined(getDeclarationName(node)));
        }
        /**
         * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names.
         * @param symbolTable - The symbol table which node will be added to.
         * @param parent - node's parent declaration.
         * @param node - The declaration to be added to the symbol table
         * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
         * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
         */
        function declareSymbol(symbolTable, parent, node, includes, excludes, isReplaceableByMethod) {
            ts.Debug.assert(!ts.hasDynamicName(node));
            var isDefaultExport = ts.hasModifier(node, 512 /* Default */) || ts.isExportSpecifier(node) && node.name.escapedText === "default";
            // The exported symbol for an export default function/class node is always named "default"
            var name = isDefaultExport && parent ? "default" /* Default */ : getDeclarationName(node);
            var symbol;
            if (name === undefined) {
                symbol = createSymbol(0 /* None */, "__missing" /* Missing */);
            }
            else {
                // Check and see if the symbol table already has a symbol with this name.  If not,
                // create a new symbol with this name and add it to the table.  Note that we don't
                // give the new symbol any flags *yet*.  This ensures that it will not conflict
                // with the 'excludes' flags we pass in.
                //
                // If we do get an existing symbol, see if it conflicts with the new symbol we're
                // creating.  For example, a 'var' symbol and a 'class' symbol will conflict within
                // the same symbol table.  If we have a conflict, report the issue on each
                // declaration we have for this symbol, and then create a new symbol for this
                // declaration.
                //
                // Note that when properties declared in Javascript constructors
                // (marked by isReplaceableByMethod) conflict with another symbol, the property loses.
                // Always. This allows the common Javascript pattern of overwriting a prototype method
                // with an bound instance method of the same type: `this.method = this.method.bind(this)`
                //
                // If we created a new symbol, either because we didn't have a symbol with this name
                // in the symbol table, or we conflicted with an existing symbol, then just add this
                // node as the sole declaration of the new symbol.
                //
                // Otherwise, we'll be merging into a compatible existing symbol (for example when
                // you have multiple 'vars' with the same name in the same container).  In this case
                // just add this node into the declarations list of the symbol.
                symbol = symbolTable.get(name);
                if (includes & 2885600 /* Classifiable */) {
                    classifiableNames.set(name, true);
                }
                if (!symbol) {
                    symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
                    if (isReplaceableByMethod)
                        symbol.isReplaceableByMethod = true;
                }
                else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) {
                    // A symbol already exists, so don't add this as a declaration.
                    return symbol;
                }
                else if (symbol.flags & excludes) {
                    if (symbol.isReplaceableByMethod) {
                        // Javascript constructor-declared symbols can be discarded in favor of
                        // prototype symbols like methods.
                        symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
                    }
                    else if (!(includes & 3 /* Variable */ && symbol.flags & 67108864 /* Assignment */)) {
                        // Assignment declarations are allowed to merge with variables, no matter what other flags they have.
                        if (ts.isNamedDeclaration(node)) {
                            node.name.parent = node;
                        }
                        // Report errors every position with duplicate declaration
                        // Report errors on previous encountered declarations
                        var message_1 = symbol.flags & 2 /* BlockScopedVariable */
                            ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
                            : ts.Diagnostics.Duplicate_identifier_0;
                        var messageNeedsName_1 = true;
                        if (symbol.flags & 384 /* Enum */ || includes & 384 /* Enum */) {
                            message_1 = ts.Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations;
                            messageNeedsName_1 = false;
                        }
                        var multipleDefaultExports_1 = false;
                        if (ts.length(symbol.declarations)) {
                            // If the current node is a default export of some sort, then check if
                            // there are any other default exports that we need to error on.
                            // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
                            if (isDefaultExport) {
                                message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                                messageNeedsName_1 = false;
                                multipleDefaultExports_1 = true;
                            }
                            else {
                                // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
                                // Error on multiple export default in the following case:
                                // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
                                // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
                                if (symbol.declarations && symbol.declarations.length &&
                                    (node.kind === 259 /* ExportAssignment */ && !node.isExportEquals)) {
                                    message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                                    messageNeedsName_1 = false;
                                    multipleDefaultExports_1 = true;
                                }
                            }
                        }
                        var relatedInformation_1 = [];
                        if (ts.isTypeAliasDeclaration(node) && ts.nodeIsMissing(node.type) && ts.hasModifier(node, 1 /* Export */) && symbol.flags & (2097152 /* Alias */ | 788968 /* Type */ | 1920 /* Namespace */)) {
                            // export type T; - may have meant export type { T }?
                            relatedInformation_1.push(createDiagnosticForNode(node, ts.Diagnostics.Did_you_mean_0, "export type { " + ts.unescapeLeadingUnderscores(node.name.escapedText) + " }"));
                        }
                        var declarationName_1 = ts.getNameOfDeclaration(node) || node;
                        ts.forEach(symbol.declarations, function (declaration, index) {
                            var decl = ts.getNameOfDeclaration(declaration) || declaration;
                            var diag = createDiagnosticForNode(decl, message_1, messageNeedsName_1 ? getDisplayName(declaration) : undefined);
                            file.bindDiagnostics.push(multipleDefaultExports_1 ? ts.addRelatedInfo(diag, createDiagnosticForNode(declarationName_1, index === 0 ? ts.Diagnostics.Another_export_default_is_here : ts.Diagnostics.and_here)) : diag);
                            if (multipleDefaultExports_1) {
                                relatedInformation_1.push(createDiagnosticForNode(decl, ts.Diagnostics.The_first_export_default_is_here));
                            }
                        });
                        var diag = createDiagnosticForNode(declarationName_1, message_1, messageNeedsName_1 ? getDisplayName(node) : undefined);
                        file.bindDiagnostics.push(ts.addRelatedInfo.apply(void 0, __spreadArrays([diag], relatedInformation_1)));
                        symbol = createSymbol(0 /* None */, name);
                    }
                }
            }
            addDeclarationToSymbol(symbol, node, includes);
            if (symbol.parent) {
                ts.Debug.assert(symbol.parent === parent, "Existing symbol parent should match new one");
            }
            else {
                symbol.parent = parent;
            }
            return symbol;
        }
        function declareModuleMember(node, symbolFlags, symbolExcludes) {
            var hasExportModifier = ts.getCombinedModifierFlags(node) & 1 /* Export */;
            if (symbolFlags & 2097152 /* Alias */) {
                if (node.kind === 263 /* ExportSpecifier */ || (node.kind === 253 /* ImportEqualsDeclaration */ && hasExportModifier)) {
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                }
                else {
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
                }
            }
            else {
                // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue flag,
                // and an associated export symbol with all the correct flags set on it. There are 2 main reasons:
                //
                //   1. We treat locals and exports of the same name as mutually exclusive within a container.
                //      That means the binder will issue a Duplicate Identifier error if you mix locals and exports
                //      with the same name in the same container.
                //      TODO: Make this a more specific error and decouple it from the exclusion logic.
                //   2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
                //      but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
                //      when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
                // NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge
                //       during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
                //       and this case is specially handled. Module augmentations should only be merged with original module definition
                //       and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
                if (ts.isJSDocTypeAlias(node))
                    ts.Debug.assert(ts.isInJSFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
                if ((!ts.isAmbientModule(node) && (hasExportModifier || container.flags & 64 /* ExportContext */)) || ts.isJSDocTypeAlias(node)) {
                    if (!container.locals || (ts.hasModifier(node, 512 /* Default */) && !getDeclarationName(node))) {
                        return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default!
                    }
                    var exportKind = symbolFlags & 111551 /* Value */ ? 1048576 /* ExportValue */ : 0;
                    var local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
                    local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                    node.localSymbol = local;
                    return local;
                }
                else {
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
                }
            }
        }
        // All container nodes are kept on a linked list in declaration order. This list is used by
        // the getLocalNameOfContainer function in the type checker to validate that the local name
        // used for a container is unique.
        function bindContainer(node, containerFlags) {
            // Before we recurse into a node's children, we first save the existing parent, container
            // and block-container.  Then after we pop out of processing the children, we restore
            // these saved values.
            var saveContainer = container;
            var saveThisParentContainer = thisParentContainer;
            var savedBlockScopeContainer = blockScopeContainer;
            // Depending on what kind of node this is, we may have to adjust the current container
            // and block-container.   If the current node is a container, then it is automatically
            // considered the current block-container as well.  Also, for containers that we know
            // may contain locals, we eagerly initialize the .locals field. We do this because
            // it's highly likely that the .locals will be needed to place some child in (for example,
            // a parameter, or variable declaration).
            //
            // However, we do not proactively create the .locals for block-containers because it's
            // totally normal and common for block-containers to never actually have a block-scoped
            // variable in them.  We don't want to end up allocating an object for every 'block' we
            // run into when most of them won't be necessary.
            //
            // Finally, if this is a block-container, then we clear out any existing .locals object
            // it may contain within it.  This happens in incremental scenarios.  Because we can be
            // reusing a node from a previous compilation, that node may have had 'locals' created
            // for it.  We must clear this so we don't accidentally move any stale data forward from
            // a previous compilation.
            if (containerFlags & 1 /* IsContainer */) {
                if (node.kind !== 202 /* ArrowFunction */) {
                    thisParentContainer = container;
                }
                container = blockScopeContainer = node;
                if (containerFlags & 32 /* HasLocals */) {
                    container.locals = ts.createSymbolTable();
                }
                addToContainerChain(container);
            }
            else if (containerFlags & 2 /* IsBlockScopedContainer */) {
                blockScopeContainer = node;
                blockScopeContainer.locals = undefined;
            }
            if (containerFlags & 4 /* IsControlFlowContainer */) {
                var saveCurrentFlow = currentFlow;
                var saveBreakTarget = currentBreakTarget;
                var saveContinueTarget = currentContinueTarget;
                var saveReturnTarget = currentReturnTarget;
                var saveExceptionTarget = currentExceptionTarget;
                var saveActiveLabelList = activeLabelList;
                var saveHasExplicitReturn = hasExplicitReturn;
                var isIIFE = containerFlags & 16 /* IsFunctionExpression */ && !ts.hasModifier(node, 256 /* Async */) &&
                    !node.asteriskToken && !!ts.getImmediatelyInvokedFunctionExpression(node);
                // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave
                // similarly to break statements that exit to a label just past the statement body.
                if (!isIIFE) {
                    currentFlow = initFlowNode({ flags: 2 /* Start */ });
                    if (containerFlags & (16 /* IsFunctionExpression */ | 128 /* IsObjectLiteralOrClassExpressionMethod */)) {
                        currentFlow.node = node;
                    }
                }
                // We create a return control flow graph for IIFEs and constructors. For constructors
                // we use the return control flow graph in strict property initialization checks.
                currentReturnTarget = isIIFE || node.kind === 162 /* Constructor */ ? createBranchLabel() : undefined;
                currentExceptionTarget = undefined;
                currentBreakTarget = undefined;
                currentContinueTarget = undefined;
                activeLabelList = undefined;
                hasExplicitReturn = false;
                bindChildren(node);
                // Reset all reachability check related flags on node (for incremental scenarios)
                node.flags &= ~2816 /* ReachabilityAndEmitFlags */;
                if (!(currentFlow.flags & 1 /* Unreachable */) && containerFlags & 8 /* IsFunctionLike */ && ts.nodeIsPresent(node.body)) {
                    node.flags |= 256 /* HasImplicitReturn */;
                    if (hasExplicitReturn)
                        node.flags |= 512 /* HasExplicitReturn */;
                    node.endFlowNode = currentFlow;
                }
                if (node.kind === 290 /* SourceFile */) {
                    node.flags |= emitFlags;
                }
                if (currentReturnTarget) {
                    addAntecedent(currentReturnTarget, currentFlow);
                    currentFlow = finishFlowLabel(currentReturnTarget);
                    if (node.kind === 162 /* Constructor */) {
                        node.returnFlowNode = currentFlow;
                    }
                }
                if (!isIIFE) {
                    currentFlow = saveCurrentFlow;
                }
                currentBreakTarget = saveBreakTarget;
                currentContinueTarget = saveContinueTarget;
                currentReturnTarget = saveReturnTarget;
                currentExceptionTarget = saveExceptionTarget;
                activeLabelList = saveActiveLabelList;
                hasExplicitReturn = saveHasExplicitReturn;
            }
            else if (containerFlags & 64 /* IsInterface */) {
                seenThisKeyword = false;
                bindChildren(node);
                node.flags = seenThisKeyword ? node.flags | 128 /* ContainsThis */ : node.flags & ~128 /* ContainsThis */;
            }
            else {
                bindChildren(node);
            }
            container = saveContainer;
            thisParentContainer = saveThisParentContainer;
            blockScopeContainer = savedBlockScopeContainer;
        }
        function bindChildren(node) {
            if (skipTransformFlagAggregation) {
                bindChildrenWorker(node);
            }
            else if (node.transformFlags & 536870912 /* HasComputedFlags */) {
                skipTransformFlagAggregation = true;
                bindChildrenWorker(node);
                skipTransformFlagAggregation = false;
                subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
            }
            else {
                var savedSubtreeTransformFlags = subtreeTransformFlags;
                subtreeTransformFlags = 0;
                bindChildrenWorker(node);
                subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags);
            }
        }
        function bindEachFunctionsFirst(nodes) {
            bindEach(nodes, function (n) { return n.kind === 244 /* FunctionDeclaration */ ? bind(n) : undefined; });
            bindEach(nodes, function (n) { return n.kind !== 244 /* FunctionDeclaration */ ? bind(n) : undefined; });
        }
        function bindEach(nodes, bindFunction) {
            if (bindFunction === void 0) { bindFunction = bind; }
            if (nodes === undefined) {
                return;
            }
            if (skipTransformFlagAggregation) {
                ts.forEach(nodes, bindFunction);
            }
            else {
                var savedSubtreeTransformFlags = subtreeTransformFlags;
                subtreeTransformFlags = 0 /* None */;
                var nodeArrayFlags = 0 /* None */;
                for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                    var node = nodes_2[_i];
                    bindFunction(node);
                    nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
                }
                nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
                subtreeTransformFlags |= savedSubtreeTransformFlags;
            }
        }
        function bindEachChild(node) {
            ts.forEachChild(node, bind, bindEach);
        }
        function bindChildrenWorker(node) {
            if (checkUnreachable(node)) {
                bindEachChild(node);
                bindJSDoc(node);
                return;
            }
            if (node.kind >= 225 /* FirstStatement */ && node.kind <= 241 /* LastStatement */ && !options.allowUnreachableCode) {
                node.flowNode = currentFlow;
            }
            switch (node.kind) {
                case 229 /* WhileStatement */:
                    bindWhileStatement(node);
                    break;
                case 228 /* DoStatement */:
                    bindDoStatement(node);
                    break;
                case 230 /* ForStatement */:
                    bindForStatement(node);
                    break;
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                    bindForInOrForOfStatement(node);
                    break;
                case 227 /* IfStatement */:
                    bindIfStatement(node);
                    break;
                case 235 /* ReturnStatement */:
                case 239 /* ThrowStatement */:
                    bindReturnOrThrow(node);
                    break;
                case 234 /* BreakStatement */:
                case 233 /* ContinueStatement */:
                    bindBreakOrContinueStatement(node);
                    break;
                case 240 /* TryStatement */:
                    bindTryStatement(node);
                    break;
                case 237 /* SwitchStatement */:
                    bindSwitchStatement(node);
                    break;
                case 251 /* CaseBlock */:
                    bindCaseBlock(node);
                    break;
                case 277 /* CaseClause */:
                    bindCaseClause(node);
                    break;
                case 226 /* ExpressionStatement */:
                    bindExpressionStatement(node);
                    break;
                case 238 /* LabeledStatement */:
                    bindLabeledStatement(node);
                    break;
                case 207 /* PrefixUnaryExpression */:
                    bindPrefixUnaryExpressionFlow(node);
                    break;
                case 208 /* PostfixUnaryExpression */:
                    bindPostfixUnaryExpressionFlow(node);
                    break;
                case 209 /* BinaryExpression */:
                    bindBinaryExpressionFlow(node);
                    break;
                case 203 /* DeleteExpression */:
                    bindDeleteExpressionFlow(node);
                    break;
                case 210 /* ConditionalExpression */:
                    bindConditionalExpressionFlow(node);
                    break;
                case 242 /* VariableDeclaration */:
                    bindVariableDeclarationFlow(node);
                    break;
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    bindAccessExpressionFlow(node);
                    break;
                case 196 /* CallExpression */:
                    bindCallExpressionFlow(node);
                    break;
                case 218 /* NonNullExpression */:
                    bindNonNullExpressionFlow(node);
                    break;
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 316 /* JSDocEnumTag */:
                    bindJSDocTypeAlias(node);
                    break;
                // In source files and blocks, bind functions first to match hoisting that occurs at runtime
                case 290 /* SourceFile */: {
                    bindEachFunctionsFirst(node.statements);
                    bind(node.endOfFileToken);
                    break;
                }
                case 223 /* Block */:
                case 250 /* ModuleBlock */:
                    bindEachFunctionsFirst(node.statements);
                    break;
                default:
                    bindEachChild(node);
                    break;
            }
            bindJSDoc(node);
        }
        function isNarrowingExpression(expr) {
            switch (expr.kind) {
                case 75 /* Identifier */:
                case 104 /* ThisKeyword */:
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    return containsNarrowableReference(expr);
                case 196 /* CallExpression */:
                    return hasNarrowableArgument(expr);
                case 200 /* ParenthesizedExpression */:
                    return isNarrowingExpression(expr.expression);
                case 209 /* BinaryExpression */:
                    return isNarrowingBinaryExpression(expr);
                case 207 /* PrefixUnaryExpression */:
                    return expr.operator === 53 /* ExclamationToken */ && isNarrowingExpression(expr.operand);
                case 204 /* TypeOfExpression */:
                    return isNarrowingExpression(expr.expression);
            }
            return false;
        }
        function isNarrowableReference(expr) {
            return expr.kind === 75 /* Identifier */ || expr.kind === 104 /* ThisKeyword */ || expr.kind === 102 /* SuperKeyword */ ||
                (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) ||
                ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression);
        }
        function containsNarrowableReference(expr) {
            return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression);
        }
        function hasNarrowableArgument(expr) {
            if (expr.arguments) {
                for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) {
                    var argument = _a[_i];
                    if (containsNarrowableReference(argument)) {
                        return true;
                    }
                }
            }
            if (expr.expression.kind === 194 /* PropertyAccessExpression */ &&
                containsNarrowableReference(expr.expression.expression)) {
                return true;
            }
            return false;
        }
        function isNarrowingTypeofOperands(expr1, expr2) {
            return ts.isTypeOfExpression(expr1) && isNarrowableOperand(expr1.expression) && ts.isStringLiteralLike(expr2);
        }
        function isNarrowableInOperands(left, right) {
            return ts.isStringLiteralLike(left) && isNarrowingExpression(right);
        }
        function isNarrowingBinaryExpression(expr) {
            switch (expr.operatorToken.kind) {
                case 62 /* EqualsToken */:
                    return containsNarrowableReference(expr.left);
                case 34 /* EqualsEqualsToken */:
                case 35 /* ExclamationEqualsToken */:
                case 36 /* EqualsEqualsEqualsToken */:
                case 37 /* ExclamationEqualsEqualsToken */:
                    return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) ||
                        isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
                case 98 /* InstanceOfKeyword */:
                    return isNarrowableOperand(expr.left);
                case 97 /* InKeyword */:
                    return isNarrowableInOperands(expr.left, expr.right);
                case 27 /* CommaToken */:
                    return isNarrowingExpression(expr.right);
            }
            return false;
        }
        function isNarrowableOperand(expr) {
            switch (expr.kind) {
                case 200 /* ParenthesizedExpression */:
                    return isNarrowableOperand(expr.expression);
                case 209 /* BinaryExpression */:
                    switch (expr.operatorToken.kind) {
                        case 62 /* EqualsToken */:
                            return isNarrowableOperand(expr.left);
                        case 27 /* CommaToken */:
                            return isNarrowableOperand(expr.right);
                    }
            }
            return containsNarrowableReference(expr);
        }
        function createBranchLabel() {
            return initFlowNode({ flags: 4 /* BranchLabel */, antecedents: undefined });
        }
        function createLoopLabel() {
            return initFlowNode({ flags: 8 /* LoopLabel */, antecedents: undefined });
        }
        function createReduceLabel(target, antecedents, antecedent) {
            return initFlowNode({ flags: 1024 /* ReduceLabel */, target: target, antecedents: antecedents, antecedent: antecedent });
        }
        function setFlowNodeReferenced(flow) {
            // On first reference we set the Referenced flag, thereafter we set the Shared flag
            flow.flags |= flow.flags & 2048 /* Referenced */ ? 4096 /* Shared */ : 2048 /* Referenced */;
        }
        function addAntecedent(label, antecedent) {
            if (!(antecedent.flags & 1 /* Unreachable */) && !ts.contains(label.antecedents, antecedent)) {
                (label.antecedents || (label.antecedents = [])).push(antecedent);
                setFlowNodeReferenced(antecedent);
            }
        }
        function createFlowCondition(flags, antecedent, expression) {
            if (antecedent.flags & 1 /* Unreachable */) {
                return antecedent;
            }
            if (!expression) {
                return flags & 32 /* TrueCondition */ ? antecedent : unreachableFlow;
            }
            if ((expression.kind === 106 /* TrueKeyword */ && flags & 64 /* FalseCondition */ ||
                expression.kind === 91 /* FalseKeyword */ && flags & 32 /* TrueCondition */) &&
                !ts.isExpressionOfOptionalChainRoot(expression) && !ts.isNullishCoalesce(expression.parent)) {
                return unreachableFlow;
            }
            if (!isNarrowingExpression(expression)) {
                return antecedent;
            }
            setFlowNodeReferenced(antecedent);
            return initFlowNode({ flags: flags, antecedent: antecedent, node: expression });
        }
        function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) {
            setFlowNodeReferenced(antecedent);
            return initFlowNode({ flags: 128 /* SwitchClause */, antecedent: antecedent, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd });
        }
        function createFlowMutation(flags, antecedent, node) {
            setFlowNodeReferenced(antecedent);
            var result = initFlowNode({ flags: flags, antecedent: antecedent, node: node });
            if (currentExceptionTarget) {
                addAntecedent(currentExceptionTarget, result);
            }
            return result;
        }
        function createFlowCall(antecedent, node) {
            setFlowNodeReferenced(antecedent);
            return initFlowNode({ flags: 512 /* Call */, antecedent: antecedent, node: node });
        }
        function finishFlowLabel(flow) {
            var antecedents = flow.antecedents;
            if (!antecedents) {
                return unreachableFlow;
            }
            if (antecedents.length === 1) {
                return antecedents[0];
            }
            return flow;
        }
        function isStatementCondition(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 227 /* IfStatement */:
                case 229 /* WhileStatement */:
                case 228 /* DoStatement */:
                    return parent.expression === node;
                case 230 /* ForStatement */:
                case 210 /* ConditionalExpression */:
                    return parent.condition === node;
            }
            return false;
        }
        function isLogicalExpression(node) {
            while (true) {
                if (node.kind === 200 /* ParenthesizedExpression */) {
                    node = node.expression;
                }
                else if (node.kind === 207 /* PrefixUnaryExpression */ && node.operator === 53 /* ExclamationToken */) {
                    node = node.operand;
                }
                else {
                    return node.kind === 209 /* BinaryExpression */ && (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */ ||
                        node.operatorToken.kind === 56 /* BarBarToken */ ||
                        node.operatorToken.kind === 60 /* QuestionQuestionToken */);
                }
            }
        }
        function isTopLevelLogicalExpression(node) {
            while (ts.isParenthesizedExpression(node.parent) ||
                ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === 53 /* ExclamationToken */) {
                node = node.parent;
            }
            return !isStatementCondition(node) &&
                !isLogicalExpression(node.parent) &&
                !(ts.isOptionalChain(node.parent) && node.parent.expression === node);
        }
        function doWithConditionalBranches(action, value, trueTarget, falseTarget) {
            var savedTrueTarget = currentTrueTarget;
            var savedFalseTarget = currentFalseTarget;
            currentTrueTarget = trueTarget;
            currentFalseTarget = falseTarget;
            action(value);
            currentTrueTarget = savedTrueTarget;
            currentFalseTarget = savedFalseTarget;
        }
        function bindCondition(node, trueTarget, falseTarget) {
            doWithConditionalBranches(bind, node, trueTarget, falseTarget);
            if (!node || !isLogicalExpression(node) && !(ts.isOptionalChain(node) && ts.isOutermostOptionalChain(node))) {
                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
            }
        }
        function bindIterativeStatement(node, breakTarget, continueTarget) {
            var saveBreakTarget = currentBreakTarget;
            var saveContinueTarget = currentContinueTarget;
            currentBreakTarget = breakTarget;
            currentContinueTarget = continueTarget;
            bind(node);
            currentBreakTarget = saveBreakTarget;
            currentContinueTarget = saveContinueTarget;
        }
        function setContinueTarget(node, target) {
            var label = activeLabelList;
            while (label && node.parent.kind === 238 /* LabeledStatement */) {
                label.continueTarget = target;
                label = label.next;
                node = node.parent;
            }
            return target;
        }
        function bindWhileStatement(node) {
            var preWhileLabel = setContinueTarget(node, createLoopLabel());
            var preBodyLabel = createBranchLabel();
            var postWhileLabel = createBranchLabel();
            addAntecedent(preWhileLabel, currentFlow);
            currentFlow = preWhileLabel;
            bindCondition(node.expression, preBodyLabel, postWhileLabel);
            currentFlow = finishFlowLabel(preBodyLabel);
            bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel);
            addAntecedent(preWhileLabel, currentFlow);
            currentFlow = finishFlowLabel(postWhileLabel);
        }
        function bindDoStatement(node) {
            var preDoLabel = createLoopLabel();
            var preConditionLabel = setContinueTarget(node, createBranchLabel());
            var postDoLabel = createBranchLabel();
            addAntecedent(preDoLabel, currentFlow);
            currentFlow = preDoLabel;
            bindIterativeStatement(node.statement, postDoLabel, preConditionLabel);
            addAntecedent(preConditionLabel, currentFlow);
            currentFlow = finishFlowLabel(preConditionLabel);
            bindCondition(node.expression, preDoLabel, postDoLabel);
            currentFlow = finishFlowLabel(postDoLabel);
        }
        function bindForStatement(node) {
            var preLoopLabel = setContinueTarget(node, createLoopLabel());
            var preBodyLabel = createBranchLabel();
            var postLoopLabel = createBranchLabel();
            bind(node.initializer);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = preLoopLabel;
            bindCondition(node.condition, preBodyLabel, postLoopLabel);
            currentFlow = finishFlowLabel(preBodyLabel);
            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
            bind(node.incrementor);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = finishFlowLabel(postLoopLabel);
        }
        function bindForInOrForOfStatement(node) {
            var preLoopLabel = setContinueTarget(node, createLoopLabel());
            var postLoopLabel = createBranchLabel();
            bind(node.expression);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = preLoopLabel;
            if (node.kind === 232 /* ForOfStatement */) {
                bind(node.awaitModifier);
            }
            addAntecedent(postLoopLabel, currentFlow);
            bind(node.initializer);
            if (node.initializer.kind !== 243 /* VariableDeclarationList */) {
                bindAssignmentTargetFlow(node.initializer);
            }
            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = finishFlowLabel(postLoopLabel);
        }
        function bindIfStatement(node) {
            var thenLabel = createBranchLabel();
            var elseLabel = createBranchLabel();
            var postIfLabel = createBranchLabel();
            bindCondition(node.expression, thenLabel, elseLabel);
            currentFlow = finishFlowLabel(thenLabel);
            bind(node.thenStatement);
            addAntecedent(postIfLabel, currentFlow);
            currentFlow = finishFlowLabel(elseLabel);
            bind(node.elseStatement);
            addAntecedent(postIfLabel, currentFlow);
            currentFlow = finishFlowLabel(postIfLabel);
        }
        function bindReturnOrThrow(node) {
            bind(node.expression);
            if (node.kind === 235 /* ReturnStatement */) {
                hasExplicitReturn = true;
                if (currentReturnTarget) {
                    addAntecedent(currentReturnTarget, currentFlow);
                }
            }
            currentFlow = unreachableFlow;
        }
        function findActiveLabel(name) {
            for (var label = activeLabelList; label; label = label.next) {
                if (label.name === name) {
                    return label;
                }
            }
            return undefined;
        }
        function bindBreakOrContinueFlow(node, breakTarget, continueTarget) {
            var flowLabel = node.kind === 234 /* BreakStatement */ ? breakTarget : continueTarget;
            if (flowLabel) {
                addAntecedent(flowLabel, currentFlow);
                currentFlow = unreachableFlow;
            }
        }
        function bindBreakOrContinueStatement(node) {
            bind(node.label);
            if (node.label) {
                var activeLabel = findActiveLabel(node.label.escapedText);
                if (activeLabel) {
                    activeLabel.referenced = true;
                    bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
                }
            }
            else {
                bindBreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
            }
        }
        function bindTryStatement(node) {
            // We conservatively assume that *any* code in the try block can cause an exception, but we only need
            // to track code that causes mutations (because only mutations widen the possible control flow type of
            // a variable). The exceptionLabel is the target label for control flows that result from exceptions.
            // We add all mutation flow nodes as antecedents of this label such that we can analyze them as possible
            // antecedents of the start of catch or finally blocks. Furthermore, we add the current control flow to
            // represent exceptions that occur before any mutations.
            var saveReturnTarget = currentReturnTarget;
            var saveExceptionTarget = currentExceptionTarget;
            var normalExitLabel = createBranchLabel();
            var returnLabel = createBranchLabel();
            var exceptionLabel = createBranchLabel();
            if (node.finallyBlock) {
                currentReturnTarget = returnLabel;
            }
            addAntecedent(exceptionLabel, currentFlow);
            currentExceptionTarget = exceptionLabel;
            bind(node.tryBlock);
            addAntecedent(normalExitLabel, currentFlow);
            if (node.catchClause) {
                // Start of catch clause is the target of exceptions from try block.
                currentFlow = finishFlowLabel(exceptionLabel);
                // The currentExceptionTarget now represents control flows from exceptions in the catch clause.
                // Effectively, in a try-catch-finally, if an exception occurs in the try block, the catch block
                // acts like a second try block.
                exceptionLabel = createBranchLabel();
                addAntecedent(exceptionLabel, currentFlow);
                currentExceptionTarget = exceptionLabel;
                bind(node.catchClause);
                addAntecedent(normalExitLabel, currentFlow);
            }
            currentReturnTarget = saveReturnTarget;
            currentExceptionTarget = saveExceptionTarget;
            if (node.finallyBlock) {
                // Possible ways control can reach the finally block:
                // 1) Normal completion of try block of a try-finally or try-catch-finally
                // 2) Normal completion of catch block (following exception in try block) of a try-catch-finally
                // 3) Return in try or catch block of a try-finally or try-catch-finally
                // 4) Exception in try block of a try-finally
                // 5) Exception in catch block of a try-catch-finally
                // When analyzing a control flow graph that starts inside a finally block we want to consider all
                // five possibilities above. However, when analyzing a control flow graph that starts outside (past)
                // the finally block, we only want to consider the first two (if we're past a finally block then it
                // must have completed normally). Likewise, when analyzing a control flow graph from return statements
                // in try or catch blocks in an IIFE, we only want to consider the third. To make this possible, we
                // inject a ReduceLabel node into the control flow graph. This node contains an alternate reduced
                // set of antecedents for the pre-finally label. As control flow analysis passes by a ReduceLabel
                // node, the pre-finally label is temporarily switched to the reduced antecedent set.
                var finallyLabel = createBranchLabel();
                finallyLabel.antecedents = ts.concatenate(ts.concatenate(normalExitLabel.antecedents, exceptionLabel.antecedents), returnLabel.antecedents);
                currentFlow = finallyLabel;
                bind(node.finallyBlock);
                if (currentFlow.flags & 1 /* Unreachable */) {
                    // If the end of the finally block is unreachable, the end of the entire try statement is unreachable.
                    currentFlow = unreachableFlow;
                }
                else {
                    // If we have an IIFE return target and return statements in the try or catch blocks, add a control
                    // flow that goes back through the finally block and back through only the return statements.
                    if (currentReturnTarget && returnLabel.antecedents) {
                        addAntecedent(currentReturnTarget, createReduceLabel(finallyLabel, returnLabel.antecedents, currentFlow));
                    }
                    // If the end of the finally block is reachable, but the end of the try and catch blocks are not,
                    // convert the current flow to unreachable. For example, 'try { return 1; } finally { ... }' should
                    // result in an unreachable current control flow.
                    currentFlow = normalExitLabel.antecedents ? createReduceLabel(finallyLabel, normalExitLabel.antecedents, currentFlow) : unreachableFlow;
                }
            }
            else {
                currentFlow = finishFlowLabel(normalExitLabel);
            }
        }
        function bindSwitchStatement(node) {
            var postSwitchLabel = createBranchLabel();
            bind(node.expression);
            var saveBreakTarget = currentBreakTarget;
            var savePreSwitchCaseFlow = preSwitchCaseFlow;
            currentBreakTarget = postSwitchLabel;
            preSwitchCaseFlow = currentFlow;
            bind(node.caseBlock);
            addAntecedent(postSwitchLabel, currentFlow);
            var hasDefault = ts.forEach(node.caseBlock.clauses, function (c) { return c.kind === 278 /* DefaultClause */; });
            // We mark a switch statement as possibly exhaustive if it has no default clause and if all
            // case clauses have unreachable end points (e.g. they all return). Note, we no longer need
            // this property in control flow analysis, it's there only for backwards compatibility.
            node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents;
            if (!hasDefault) {
                addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0));
            }
            currentBreakTarget = saveBreakTarget;
            preSwitchCaseFlow = savePreSwitchCaseFlow;
            currentFlow = finishFlowLabel(postSwitchLabel);
        }
        function bindCaseBlock(node) {
            var savedSubtreeTransformFlags = subtreeTransformFlags;
            subtreeTransformFlags = 0;
            var clauses = node.clauses;
            var isNarrowingSwitch = isNarrowingExpression(node.parent.expression);
            var fallthroughFlow = unreachableFlow;
            for (var i = 0; i < clauses.length; i++) {
                var clauseStart = i;
                while (!clauses[i].statements.length && i + 1 < clauses.length) {
                    bind(clauses[i]);
                    i++;
                }
                var preCaseLabel = createBranchLabel();
                addAntecedent(preCaseLabel, isNarrowingSwitch ? createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1) : preSwitchCaseFlow);
                addAntecedent(preCaseLabel, fallthroughFlow);
                currentFlow = finishFlowLabel(preCaseLabel);
                var clause = clauses[i];
                bind(clause);
                fallthroughFlow = currentFlow;
                if (!(currentFlow.flags & 1 /* Unreachable */) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) {
                    clause.fallthroughFlowNode = currentFlow;
                }
            }
            clauses.transformFlags = subtreeTransformFlags | 536870912 /* HasComputedFlags */;
            subtreeTransformFlags |= savedSubtreeTransformFlags;
        }
        function bindCaseClause(node) {
            var saveCurrentFlow = currentFlow;
            currentFlow = preSwitchCaseFlow;
            bind(node.expression);
            currentFlow = saveCurrentFlow;
            bindEach(node.statements);
        }
        function bindExpressionStatement(node) {
            bind(node.expression);
            // A top level call expression with a dotted function name and at least one argument
            // is potentially an assertion and is therefore included in the control flow.
            if (node.expression.kind === 196 /* CallExpression */) {
                var call = node.expression;
                if (ts.isDottedName(call.expression)) {
                    currentFlow = createFlowCall(currentFlow, call);
                }
            }
        }
        function bindLabeledStatement(node) {
            var postStatementLabel = createBranchLabel();
            activeLabelList = {
                next: activeLabelList,
                name: node.label.escapedText,
                breakTarget: postStatementLabel,
                continueTarget: undefined,
                referenced: false
            };
            bind(node.label);
            bind(node.statement);
            if (!activeLabelList.referenced && !options.allowUnusedLabels) {
                errorOrSuggestionOnNode(ts.unusedLabelIsError(options), node.label, ts.Diagnostics.Unused_label);
            }
            activeLabelList = activeLabelList.next;
            addAntecedent(postStatementLabel, currentFlow);
            currentFlow = finishFlowLabel(postStatementLabel);
        }
        function bindDestructuringTargetFlow(node) {
            if (node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 62 /* EqualsToken */) {
                bindAssignmentTargetFlow(node.left);
            }
            else {
                bindAssignmentTargetFlow(node);
            }
        }
        function bindAssignmentTargetFlow(node) {
            if (isNarrowableReference(node)) {
                currentFlow = createFlowMutation(16 /* Assignment */, currentFlow, node);
            }
            else if (node.kind === 192 /* ArrayLiteralExpression */) {
                for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                    var e = _a[_i];
                    if (e.kind === 213 /* SpreadElement */) {
                        bindAssignmentTargetFlow(e.expression);
                    }
                    else {
                        bindDestructuringTargetFlow(e);
                    }
                }
            }
            else if (node.kind === 193 /* ObjectLiteralExpression */) {
                for (var _b = 0, _c = node.properties; _b < _c.length; _b++) {
                    var p = _c[_b];
                    if (p.kind === 281 /* PropertyAssignment */) {
                        bindDestructuringTargetFlow(p.initializer);
                    }
                    else if (p.kind === 282 /* ShorthandPropertyAssignment */) {
                        bindAssignmentTargetFlow(p.name);
                    }
                    else if (p.kind === 283 /* SpreadAssignment */) {
                        bindAssignmentTargetFlow(p.expression);
                    }
                }
            }
        }
        function bindLogicalExpression(node, trueTarget, falseTarget) {
            var preRightLabel = createBranchLabel();
            if (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */) {
                bindCondition(node.left, preRightLabel, falseTarget);
            }
            else {
                bindCondition(node.left, trueTarget, preRightLabel);
            }
            currentFlow = finishFlowLabel(preRightLabel);
            bind(node.operatorToken);
            bindCondition(node.right, trueTarget, falseTarget);
        }
        function bindPrefixUnaryExpressionFlow(node) {
            if (node.operator === 53 /* ExclamationToken */) {
                var saveTrueTarget = currentTrueTarget;
                currentTrueTarget = currentFalseTarget;
                currentFalseTarget = saveTrueTarget;
                bindEachChild(node);
                currentFalseTarget = currentTrueTarget;
                currentTrueTarget = saveTrueTarget;
            }
            else {
                bindEachChild(node);
                if (node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */) {
                    bindAssignmentTargetFlow(node.operand);
                }
            }
        }
        function bindPostfixUnaryExpressionFlow(node) {
            bindEachChild(node);
            if (node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */) {
                bindAssignmentTargetFlow(node.operand);
            }
        }
        var BindBinaryExpressionFlowState;
        (function (BindBinaryExpressionFlowState) {
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["BindThenBindChildren"] = 0] = "BindThenBindChildren";
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["MaybeBindLeft"] = 1] = "MaybeBindLeft";
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["BindToken"] = 2] = "BindToken";
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["BindRight"] = 3] = "BindRight";
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["FinishBind"] = 4] = "FinishBind";
        })(BindBinaryExpressionFlowState || (BindBinaryExpressionFlowState = {}));
        function bindBinaryExpressionFlow(node) {
            var workStacks = {
                expr: [node],
                state: [1 /* MaybeBindLeft */],
                inStrictMode: [undefined],
                parent: [undefined],
                subtreeFlags: [undefined]
            };
            var stackIndex = 0;
            while (stackIndex >= 0) {
                node = workStacks.expr[stackIndex];
                switch (workStacks.state[stackIndex]) {
                    case 0 /* BindThenBindChildren */: {
                        // This state is used only when recuring, to emulate the work that `bind` does before
                        // reaching `bindChildren`. A normal call to `bindBinaryExpressionFlow` will already have done this work.
                        node.parent = parent;
                        var saveInStrictMode = inStrictMode;
                        bindWorker(node);
                        var saveParent = parent;
                        parent = node;
                        var subtreeFlagsState = void 0;
                        // While this next part does the work of `bindChildren` before it descends into `bindChildrenWorker`
                        // and uses `subtreeFlagsState` to queue up the work that needs to be done once the node is bound.
                        if (skipTransformFlagAggregation) {
                            // do nothing extra
                        }
                        else if (node.transformFlags & 536870912 /* HasComputedFlags */) {
                            skipTransformFlagAggregation = true;
                            subtreeFlagsState = -1;
                        }
                        else {
                            var savedSubtreeTransformFlags = subtreeTransformFlags;
                            subtreeTransformFlags = 0;
                            subtreeFlagsState = savedSubtreeTransformFlags;
                        }
                        advanceState(1 /* MaybeBindLeft */, saveInStrictMode, saveParent, subtreeFlagsState);
                        break;
                    }
                    case 1 /* MaybeBindLeft */: {
                        var operator = node.operatorToken.kind;
                        // TODO: bindLogicalExpression is recursive - if we want to handle deeply nested `&&` expressions
                        // we'll need to handle the `bindLogicalExpression` scenarios in this state machine, too
                        // For now, though, since the common cases are chained `+`, leaving it recursive is fine
                        if (operator === 55 /* AmpersandAmpersandToken */ || operator === 56 /* BarBarToken */ || operator === 60 /* QuestionQuestionToken */) {
                            if (isTopLevelLogicalExpression(node)) {
                                var postExpressionLabel = createBranchLabel();
                                bindLogicalExpression(node, postExpressionLabel, postExpressionLabel);
                                currentFlow = finishFlowLabel(postExpressionLabel);
                            }
                            else {
                                bindLogicalExpression(node, currentTrueTarget, currentFalseTarget);
                            }
                            completeNode();
                        }
                        else {
                            advanceState(2 /* BindToken */);
                            maybeBind(node.left);
                        }
                        break;
                    }
                    case 2 /* BindToken */: {
                        advanceState(3 /* BindRight */);
                        maybeBind(node.operatorToken);
                        break;
                    }
                    case 3 /* BindRight */: {
                        advanceState(4 /* FinishBind */);
                        maybeBind(node.right);
                        break;
                    }
                    case 4 /* FinishBind */: {
                        var operator = node.operatorToken.kind;
                        if (ts.isAssignmentOperator(operator) && !ts.isAssignmentTarget(node)) {
                            bindAssignmentTargetFlow(node.left);
                            if (operator === 62 /* EqualsToken */ && node.left.kind === 195 /* ElementAccessExpression */) {
                                var elementAccess = node.left;
                                if (isNarrowableOperand(elementAccess.expression)) {
                                    currentFlow = createFlowMutation(256 /* ArrayMutation */, currentFlow, node);
                                }
                            }
                        }
                        completeNode();
                        break;
                    }
                    default: return ts.Debug.fail("Invalid state " + workStacks.state[stackIndex] + " for bindBinaryExpressionFlow");
                }
            }
            /**
             * Note that `advanceState` sets the _current_ head state, and that `maybeBind` potentially pushes on a new
             * head state; so `advanceState` must be called before any `maybeBind` during a state's execution.
             */
            function advanceState(state, isInStrictMode, parent, subtreeFlags) {
                workStacks.state[stackIndex] = state;
                if (isInStrictMode !== undefined) {
                    workStacks.inStrictMode[stackIndex] = isInStrictMode;
                }
                if (parent !== undefined) {
                    workStacks.parent[stackIndex] = parent;
                }
                if (subtreeFlags !== undefined) {
                    workStacks.subtreeFlags[stackIndex] = subtreeFlags;
                }
            }
            function completeNode() {
                if (workStacks.inStrictMode[stackIndex] !== undefined) {
                    if (workStacks.subtreeFlags[stackIndex] === -1) {
                        skipTransformFlagAggregation = false;
                        subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
                    }
                    else if (workStacks.subtreeFlags[stackIndex] !== undefined) {
                        subtreeTransformFlags = workStacks.subtreeFlags[stackIndex] | computeTransformFlagsForNode(node, subtreeTransformFlags);
                    }
                    inStrictMode = workStacks.inStrictMode[stackIndex];
                    parent = workStacks.parent[stackIndex];
                }
                stackIndex--;
            }
            /**
             * If `node` is a BinaryExpression, adds it to the local work stack, otherwise recursively binds it
             */
            function maybeBind(node) {
                if (node && ts.isBinaryExpression(node)) {
                    stackIndex++;
                    workStacks.expr[stackIndex] = node;
                    workStacks.state[stackIndex] = 0 /* BindThenBindChildren */;
                    workStacks.inStrictMode[stackIndex] = undefined;
                    workStacks.parent[stackIndex] = undefined;
                    workStacks.subtreeFlags[stackIndex] = undefined;
                }
                else {
                    bind(node);
                }
            }
        }
        function bindDeleteExpressionFlow(node) {
            bindEachChild(node);
            if (node.expression.kind === 194 /* PropertyAccessExpression */) {
                bindAssignmentTargetFlow(node.expression);
            }
        }
        function bindConditionalExpressionFlow(node) {
            var trueLabel = createBranchLabel();
            var falseLabel = createBranchLabel();
            var postExpressionLabel = createBranchLabel();
            bindCondition(node.condition, trueLabel, falseLabel);
            currentFlow = finishFlowLabel(trueLabel);
            bind(node.questionToken);
            bind(node.whenTrue);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(falseLabel);
            bind(node.colonToken);
            bind(node.whenFalse);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(postExpressionLabel);
        }
        function bindInitializedVariableFlow(node) {
            var name = !ts.isOmittedExpression(node) ? node.name : undefined;
            if (ts.isBindingPattern(name)) {
                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                    var child = _a[_i];
                    bindInitializedVariableFlow(child);
                }
            }
            else {
                currentFlow = createFlowMutation(16 /* Assignment */, currentFlow, node);
            }
        }
        function bindVariableDeclarationFlow(node) {
            bindEachChild(node);
            if (node.initializer || ts.isForInOrOfStatement(node.parent.parent)) {
                bindInitializedVariableFlow(node);
            }
        }
        function bindJSDocTypeAlias(node) {
            node.tagName.parent = node;
            if (node.kind !== 316 /* JSDocEnumTag */ && node.fullName) {
                setParentPointers(node, node.fullName);
            }
        }
        function bindJSDocClassTag(node) {
            bindEachChild(node);
            var host = ts.getHostSignatureFromJSDoc(node);
            if (host && host.kind !== 161 /* MethodDeclaration */) {
                addDeclarationToSymbol(host.symbol, host, 32 /* Class */);
            }
        }
        function bindOptionalExpression(node, trueTarget, falseTarget) {
            doWithConditionalBranches(bind, node, trueTarget, falseTarget);
            if (!ts.isOptionalChain(node) || ts.isOutermostOptionalChain(node)) {
                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
            }
        }
        function bindOptionalChainRest(node) {
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                    bind(node.questionDotToken);
                    bind(node.name);
                    break;
                case 195 /* ElementAccessExpression */:
                    bind(node.questionDotToken);
                    bind(node.argumentExpression);
                    break;
                case 196 /* CallExpression */:
                    bind(node.questionDotToken);
                    bindEach(node.typeArguments);
                    bindEach(node.arguments);
                    break;
            }
        }
        function bindOptionalChain(node, trueTarget, falseTarget) {
            // For an optional chain, we emulate the behavior of a logical expression:
            //
            // a?.b         -> a && a.b
            // a?.b.c       -> a && a.b.c
            // a?.b?.c      -> a && a.b && a.b.c
            // a?.[x = 1]   -> a && a[x = 1]
            //
            // To do this we descend through the chain until we reach the root of a chain (the expression with a `?.`)
            // and build it's CFA graph as if it were the first condition (`a && ...`). Then we bind the rest
            // of the node as part of the "true" branch, and continue to do so as we ascend back up to the outermost
            // chain node. We then treat the entire node as the right side of the expression.
            var preChainLabel = ts.isOptionalChainRoot(node) ? createBranchLabel() : undefined;
            bindOptionalExpression(node.expression, preChainLabel || trueTarget, falseTarget);
            if (preChainLabel) {
                currentFlow = finishFlowLabel(preChainLabel);
            }
            doWithConditionalBranches(bindOptionalChainRest, node, trueTarget, falseTarget);
            if (ts.isOutermostOptionalChain(node)) {
                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
            }
        }
        function bindOptionalChainFlow(node) {
            if (isTopLevelLogicalExpression(node)) {
                var postExpressionLabel = createBranchLabel();
                bindOptionalChain(node, postExpressionLabel, postExpressionLabel);
                currentFlow = finishFlowLabel(postExpressionLabel);
            }
            else {
                bindOptionalChain(node, currentTrueTarget, currentFalseTarget);
            }
        }
        function bindNonNullExpressionFlow(node) {
            if (ts.isOptionalChain(node)) {
                bindOptionalChainFlow(node);
            }
            else {
                bindEachChild(node);
            }
        }
        function bindAccessExpressionFlow(node) {
            if (ts.isOptionalChain(node)) {
                bindOptionalChainFlow(node);
            }
            else {
                bindEachChild(node);
            }
        }
        function bindCallExpressionFlow(node) {
            if (ts.isOptionalChain(node)) {
                bindOptionalChainFlow(node);
            }
            else {
                // If the target of the call expression is a function expression or arrow function we have
                // an immediately invoked function expression (IIFE). Initialize the flowNode property to
                // the current control flow (which includes evaluation of the IIFE arguments).
                var expr = ts.skipParentheses(node.expression);
                if (expr.kind === 201 /* FunctionExpression */ || expr.kind === 202 /* ArrowFunction */) {
                    bindEach(node.typeArguments);
                    bindEach(node.arguments);
                    bind(node.expression);
                }
                else {
                    bindEachChild(node);
                }
            }
            if (node.expression.kind === 194 /* PropertyAccessExpression */) {
                var propertyAccess = node.expression;
                if (ts.isIdentifier(propertyAccess.name) && isNarrowableOperand(propertyAccess.expression) && ts.isPushOrUnshiftIdentifier(propertyAccess.name)) {
                    currentFlow = createFlowMutation(256 /* ArrayMutation */, currentFlow, node);
                }
            }
        }
        function getContainerFlags(node) {
            switch (node.kind) {
                case 214 /* ClassExpression */:
                case 245 /* ClassDeclaration */:
                case 248 /* EnumDeclaration */:
                case 193 /* ObjectLiteralExpression */:
                case 173 /* TypeLiteral */:
                case 304 /* JSDocTypeLiteral */:
                case 274 /* JsxAttributes */:
                    return 1 /* IsContainer */;
                case 246 /* InterfaceDeclaration */:
                    return 1 /* IsContainer */ | 64 /* IsInterface */;
                case 249 /* ModuleDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 186 /* MappedType */:
                    return 1 /* IsContainer */ | 32 /* HasLocals */;
                case 290 /* SourceFile */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */;
                case 161 /* MethodDeclaration */:
                    if (ts.isObjectLiteralOrClassExpressionMethod(node)) {
                        return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 128 /* IsObjectLiteralOrClassExpressionMethod */;
                    }
                // falls through
                case 162 /* Constructor */:
                case 244 /* FunctionDeclaration */:
                case 160 /* MethodSignature */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 165 /* CallSignature */:
                case 305 /* JSDocSignature */:
                case 300 /* JSDocFunctionType */:
                case 170 /* FunctionType */:
                case 166 /* ConstructSignature */:
                case 167 /* IndexSignature */:
                case 171 /* ConstructorType */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */;
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 16 /* IsFunctionExpression */;
                case 250 /* ModuleBlock */:
                    return 4 /* IsControlFlowContainer */;
                case 159 /* PropertyDeclaration */:
                    return node.initializer ? 4 /* IsControlFlowContainer */ : 0;
                case 280 /* CatchClause */:
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                case 251 /* CaseBlock */:
                    return 2 /* IsBlockScopedContainer */;
                case 223 /* Block */:
                    // do not treat blocks directly inside a function as a block-scoped-container.
                    // Locals that reside in this block should go to the function locals. Otherwise 'x'
                    // would not appear to be a redeclaration of a block scoped local in the following
                    // example:
                    //
                    //      function foo() {
                    //          var x;
                    //          let x;
                    //      }
                    //
                    // If we placed 'var x' into the function locals and 'let x' into the locals of
                    // the block, then there would be no collision.
                    //
                    // By not creating a new block-scoped-container here, we ensure that both 'var x'
                    // and 'let x' go into the Function-container's locals, and we do get a collision
                    // conflict.
                    return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
            }
            return 0 /* None */;
        }
        function addToContainerChain(next) {
            if (lastContainer) {
                lastContainer.nextContainer = next;
            }
            lastContainer = next;
        }
        function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
            switch (container.kind) {
                // Modules, source files, and classes need specialized handling for how their
                // members are declared (for example, a member of a class will go into a specific
                // symbol table depending on if it is static or not). We defer to specialized
                // handlers to take care of declaring these child members.
                case 249 /* ModuleDeclaration */:
                    return declareModuleMember(node, symbolFlags, symbolExcludes);
                case 290 /* SourceFile */:
                    return declareSourceFileMember(node, symbolFlags, symbolExcludes);
                case 214 /* ClassExpression */:
                case 245 /* ClassDeclaration */:
                    return declareClassMember(node, symbolFlags, symbolExcludes);
                case 248 /* EnumDeclaration */:
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                case 173 /* TypeLiteral */:
                case 304 /* JSDocTypeLiteral */:
                case 193 /* ObjectLiteralExpression */:
                case 246 /* InterfaceDeclaration */:
                case 274 /* JsxAttributes */:
                    // Interface/Object-types always have their children added to the 'members' of
                    // their container. They are only accessible through an instance of their
                    // container, and are never in scope otherwise (even inside the body of the
                    // object / type / interface declaring them). An exception is type parameters,
                    // which are in scope without qualification (similar to 'locals').
                    return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 305 /* JSDocSignature */:
                case 167 /* IndexSignature */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 162 /* Constructor */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 300 /* JSDocFunctionType */:
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 247 /* TypeAliasDeclaration */:
                case 186 /* MappedType */:
                    // All the children of these container types are never visible through another
                    // symbol (i.e. through another symbol's 'exports' or 'members').  Instead,
                    // they're only accessed 'lexically' (i.e. from code that exists underneath
                    // their container in the tree). To accomplish this, we simply add their declared
                    // symbol to the 'locals' of the container.  These symbols can then be found as
                    // the type checker walks up the containers, checking them for matching names.
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
            }
        }
        function declareClassMember(node, symbolFlags, symbolExcludes) {
            return ts.hasModifier(node, 32 /* Static */)
                ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
                : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
        }
        function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
            return ts.isExternalModule(file)
                ? declareModuleMember(node, symbolFlags, symbolExcludes)
                : declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
        }
        function hasExportDeclarations(node) {
            var body = ts.isSourceFile(node) ? node : ts.tryCast(node.body, ts.isModuleBlock);
            return !!body && body.statements.some(function (s) { return ts.isExportDeclaration(s) || ts.isExportAssignment(s); });
        }
        function setExportContextFlag(node) {
            // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
            // declarations with export modifiers) is an export context in which declarations are implicitly exported.
            if (node.flags & 8388608 /* Ambient */ && !hasExportDeclarations(node)) {
                node.flags |= 64 /* ExportContext */;
            }
            else {
                node.flags &= ~64 /* ExportContext */;
            }
        }
        function bindModuleDeclaration(node) {
            setExportContextFlag(node);
            if (ts.isAmbientModule(node)) {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    errorOnFirstToken(node, ts.Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible);
                }
                if (ts.isModuleAugmentationExternal(node)) {
                    declareModuleSymbol(node);
                }
                else {
                    var pattern = void 0;
                    if (node.name.kind === 10 /* StringLiteral */) {
                        var text = node.name.text;
                        if (ts.hasZeroOrOneAsteriskCharacter(text)) {
                            pattern = ts.tryParsePattern(text);
                        }
                        else {
                            errorOnFirstToken(node.name, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text);
                        }
                    }
                    var symbol = declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 110735 /* ValueModuleExcludes */);
                    file.patternAmbientModules = ts.append(file.patternAmbientModules, pattern && { pattern: pattern, symbol: symbol });
                }
            }
            else {
                var state = declareModuleSymbol(node);
                if (state !== 0 /* NonInstantiated */) {
                    var symbol = node.symbol;
                    // if module was already merged with some function, class or non-const enum, treat it as non-const-enum-only
                    symbol.constEnumOnlyModule = (!(symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)))
                        // Current must be `const enum` only
                        && state === 2 /* ConstEnumOnly */
                        // Can't have been set to 'false' in a previous merged symbol. ('undefined' OK)
                        && symbol.constEnumOnlyModule !== false;
                }
            }
        }
        function declareModuleSymbol(node) {
            var state = getModuleInstanceState(node);
            var instantiated = state !== 0 /* NonInstantiated */;
            declareSymbolAndAddToSymbolTable(node, instantiated ? 512 /* ValueModule */ : 1024 /* NamespaceModule */, instantiated ? 110735 /* ValueModuleExcludes */ : 0 /* NamespaceModuleExcludes */);
            return state;
        }
        function bindFunctionOrConstructorType(node) {
            // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
            // to the one we would get for: { <...>(...): T }
            //
            // We do that by making an anonymous type literal symbol, and then setting the function
            // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
            // from an actual type literal symbol you would have gotten had you used the long form.
            var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node)); // TODO: GH#18217
            addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
            var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
            addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
            typeLiteralSymbol.members = ts.createSymbolTable();
            typeLiteralSymbol.members.set(symbol.escapedName, symbol);
        }
        function bindObjectLiteralExpression(node) {
            var ElementKind;
            (function (ElementKind) {
                ElementKind[ElementKind["Property"] = 1] = "Property";
                ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
            })(ElementKind || (ElementKind = {}));
            if (inStrictMode && !ts.isAssignmentTarget(node)) {
                var seen = ts.createUnderscoreEscapedMap();
                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (prop.kind === 283 /* SpreadAssignment */ || prop.name.kind !== 75 /* Identifier */) {
                        continue;
                    }
                    var identifier = prop.name;
                    // ECMA-262 11.1.5 Object Initializer
                    // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
                    // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
                    // IsDataDescriptor(propId.descriptor) is true.
                    //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
                    //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
                    //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
                    // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
                    var currentKind = prop.kind === 281 /* PropertyAssignment */ || prop.kind === 282 /* ShorthandPropertyAssignment */ || prop.kind === 161 /* MethodDeclaration */
                        ? 1 /* Property */
                        : 2 /* Accessor */;
                    var existingKind = seen.get(identifier.escapedText);
                    if (!existingKind) {
                        seen.set(identifier.escapedText, currentKind);
                        continue;
                    }
                    if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
                        var span = ts.getErrorSpanForNode(file, identifier);
                        file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
                    }
                }
            }
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object" /* Object */);
        }
        function bindJsxAttributes(node) {
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__jsxAttributes" /* JSXAttributes */);
        }
        function bindJsxAttribute(node, symbolFlags, symbolExcludes) {
            return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        function bindAnonymousDeclaration(node, symbolFlags, name) {
            var symbol = createSymbol(symbolFlags, name);
            if (symbolFlags & (8 /* EnumMember */ | 106500 /* ClassMember */)) {
                symbol.parent = container.symbol;
            }
            addDeclarationToSymbol(symbol, node, symbolFlags);
            return symbol;
        }
        function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
            switch (blockScopeContainer.kind) {
                case 249 /* ModuleDeclaration */:
                    declareModuleMember(node, symbolFlags, symbolExcludes);
                    break;
                case 290 /* SourceFile */:
                    if (ts.isExternalOrCommonJsModule(container)) {
                        declareModuleMember(node, symbolFlags, symbolExcludes);
                        break;
                    }
                // falls through
                default:
                    if (!blockScopeContainer.locals) {
                        blockScopeContainer.locals = ts.createSymbolTable();
                        addToContainerChain(blockScopeContainer);
                    }
                    declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
            }
        }
        function delayedBindJSDocTypedefTag() {
            if (!delayedTypeAliases) {
                return;
            }
            var saveContainer = container;
            var saveLastContainer = lastContainer;
            var saveBlockScopeContainer = blockScopeContainer;
            var saveParent = parent;
            var saveCurrentFlow = currentFlow;
            for (var _i = 0, delayedTypeAliases_1 = delayedTypeAliases; _i < delayedTypeAliases_1.length; _i++) {
                var typeAlias = delayedTypeAliases_1[_i];
                var host = ts.getJSDocHost(typeAlias);
                container = ts.findAncestor(host.parent, function (n) { return !!(getContainerFlags(n) & 1 /* IsContainer */); }) || file;
                blockScopeContainer = ts.getEnclosingBlockScopeContainer(host) || file;
                currentFlow = initFlowNode({ flags: 2 /* Start */ });
                parent = typeAlias;
                bind(typeAlias.typeExpression);
                var declName = ts.getNameOfDeclaration(typeAlias);
                if ((ts.isJSDocEnumTag(typeAlias) || !typeAlias.fullName) && declName && ts.isPropertyAccessEntityNameExpression(declName.parent)) {
                    // typedef anchored to an A.B.C assignment - we need to bind into B's namespace under name C
                    var isTopLevel = isTopLevelNamespaceAssignment(declName.parent);
                    if (isTopLevel) {
                        bindPotentiallyMissingNamespaces(file.symbol, declName.parent, isTopLevel, !!ts.findAncestor(declName, function (d) { return ts.isPropertyAccessExpression(d) && d.name.escapedText === "prototype"; }), /*containerIsClass*/ false);
                        var oldContainer = container;
                        switch (ts.getAssignmentDeclarationPropertyAccessKind(declName.parent)) {
                            case 1 /* ExportsProperty */:
                            case 2 /* ModuleExports */:
                                if (!ts.isExternalOrCommonJsModule(file)) {
                                    container = undefined;
                                }
                                else {
                                    container = file;
                                }
                                break;
                            case 4 /* ThisProperty */:
                                container = declName.parent.expression;
                                break;
                            case 3 /* PrototypeProperty */:
                                container = declName.parent.expression.name;
                                break;
                            case 5 /* Property */:
                                container = isExportsOrModuleExportsOrAlias(file, declName.parent.expression) ? file
                                    : ts.isPropertyAccessExpression(declName.parent.expression) ? declName.parent.expression.name
                                        : declName.parent.expression;
                                break;
                            case 0 /* None */:
                                return ts.Debug.fail("Shouldn't have detected typedef or enum on non-assignment declaration");
                        }
                        if (container) {
                            declareModuleMember(typeAlias, 524288 /* TypeAlias */, 788968 /* TypeAliasExcludes */);
                        }
                        container = oldContainer;
                    }
                }
                else if (ts.isJSDocEnumTag(typeAlias) || !typeAlias.fullName || typeAlias.fullName.kind === 75 /* Identifier */) {
                    parent = typeAlias.parent;
                    bindBlockScopedDeclaration(typeAlias, 524288 /* TypeAlias */, 788968 /* TypeAliasExcludes */);
                }
                else {
                    bind(typeAlias.fullName);
                }
            }
            container = saveContainer;
            lastContainer = saveLastContainer;
            blockScopeContainer = saveBlockScopeContainer;
            parent = saveParent;
            currentFlow = saveCurrentFlow;
        }
        // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
        // check for reserved words used as identifiers in strict mode code.
        function checkStrictModeIdentifier(node) {
            if (inStrictMode &&
                node.originalKeywordKind >= 113 /* FirstFutureReservedWord */ &&
                node.originalKeywordKind <= 121 /* LastFutureReservedWord */ &&
                !ts.isIdentifierName(node) &&
                !(node.flags & 8388608 /* Ambient */) &&
                !(node.flags & 4194304 /* JSDoc */)) {
                // Report error only if there are no parse errors in file
                if (!file.parseDiagnostics.length) {
                    file.bindDiagnostics.push(createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
                }
            }
        }
        function getStrictModeIdentifierMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
        }
        // The binder visits every node, so this is a good place to check for
        // the reserved private name (there is only one)
        function checkPrivateIdentifier(node) {
            if (node.escapedText === "#constructor") {
                // Report error only if there are no parse errors in file
                if (!file.parseDiagnostics.length) {
                    file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.constructor_is_a_reserved_word, ts.declarationNameToString(node)));
                }
            }
        }
        function checkStrictModeBinaryExpression(node) {
            if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
                // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
                // Assignment operator(11.13) or of a PostfixExpression(11.3)
                checkStrictModeEvalOrArguments(node, node.left);
            }
        }
        function checkStrictModeCatchClause(node) {
            // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
            // Catch production is eval or arguments
            if (inStrictMode && node.variableDeclaration) {
                checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
            }
        }
        function checkStrictModeDeleteExpression(node) {
            // Grammar checking
            if (inStrictMode && node.expression.kind === 75 /* Identifier */) {
                // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
                // UnaryExpression is a direct reference to a variable, function argument, or function name
                var span = ts.getErrorSpanForNode(file, node.expression);
                file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
            }
        }
        function isEvalOrArgumentsIdentifier(node) {
            return ts.isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments");
        }
        function checkStrictModeEvalOrArguments(contextNode, name) {
            if (name && name.kind === 75 /* Identifier */) {
                var identifier = name;
                if (isEvalOrArgumentsIdentifier(identifier)) {
                    // We check first if the name is inside class declaration or class expression; if so give explicit message
                    // otherwise report generic error message.
                    var span = ts.getErrorSpanForNode(file, name);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), ts.idText(identifier)));
                }
            }
        }
        function getStrictModeEvalOrArgumentsMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
        }
        function checkStrictModeFunctionName(node) {
            if (inStrictMode) {
                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
                checkStrictModeEvalOrArguments(node, node.name);
            }
        }
        function getStrictModeBlockScopeFunctionDeclarationMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5;
        }
        function checkStrictModeFunctionDeclaration(node) {
            if (languageVersion < 2 /* ES2015 */) {
                // Report error if function is not top level function declaration
                if (blockScopeContainer.kind !== 290 /* SourceFile */ &&
                    blockScopeContainer.kind !== 249 /* ModuleDeclaration */ &&
                    !ts.isFunctionLike(blockScopeContainer)) {
                    // We check first if the name is inside class declaration or class expression; if so give explicit message
                    // otherwise report generic error message.
                    var errorSpan = ts.getErrorSpanForNode(file, node);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, errorSpan.start, errorSpan.length, getStrictModeBlockScopeFunctionDeclarationMessage(node)));
                }
            }
        }
        function checkStrictModeNumericLiteral(node) {
            if (inStrictMode && node.numericLiteralFlags & 32 /* Octal */) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
            }
        }
        function checkStrictModePostfixUnaryExpression(node) {
            // Grammar checking
            // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
            // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
            // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
            if (inStrictMode) {
                checkStrictModeEvalOrArguments(node, node.operand);
            }
        }
        function checkStrictModePrefixUnaryExpression(node) {
            // Grammar checking
            if (inStrictMode) {
                if (node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */) {
                    checkStrictModeEvalOrArguments(node, node.operand);
                }
            }
        }
        function checkStrictModeWithStatement(node) {
            // Grammar checking for withStatement
            if (inStrictMode) {
                errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
            }
        }
        function checkStrictModeLabeledStatement(node) {
            // Grammar checking for labeledStatement
            if (inStrictMode && options.target >= 2 /* ES2015 */) {
                if (ts.isDeclarationStatement(node.statement) || ts.isVariableStatement(node.statement)) {
                    errorOnFirstToken(node.label, ts.Diagnostics.A_label_is_not_allowed_here);
                }
            }
        }
        function errorOnFirstToken(node, message, arg0, arg1, arg2) {
            var span = ts.getSpanOfTokenAtPosition(file, node.pos);
            file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
        }
        function errorOrSuggestionOnNode(isError, node, message) {
            errorOrSuggestionOnRange(isError, node, node, message);
        }
        function errorOrSuggestionOnRange(isError, startNode, endNode, message) {
            addErrorOrSuggestionDiagnostic(isError, { pos: ts.getTokenPosOfNode(startNode, file), end: endNode.end }, message);
        }
        function addErrorOrSuggestionDiagnostic(isError, range, message) {
            var diag = ts.createFileDiagnostic(file, range.pos, range.end - range.pos, message);
            if (isError) {
                file.bindDiagnostics.push(diag);
            }
            else {
                file.bindSuggestionDiagnostics = ts.append(file.bindSuggestionDiagnostics, __assign(__assign({}, diag), { category: ts.DiagnosticCategory.Suggestion }));
            }
        }
        function bind(node) {
            if (!node) {
                return;
            }
            node.parent = parent;
            var saveInStrictMode = inStrictMode;
            // Even though in the AST the jsdoc @typedef node belongs to the current node,
            // its symbol might be in the same scope with the current node's symbol. Consider:
            //
            //     /** @typedef {string | number} MyType */
            //     function foo();
            //
            // Here the current node is "foo", which is a container, but the scope of "MyType" should
            // not be inside "foo". Therefore we always bind @typedef before bind the parent node,
            // and skip binding this tag later when binding all the other jsdoc tags.
            // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
            // and then potentially add the symbol to an appropriate symbol table. Possible
            // destination symbol tables are:
            //
            //  1) The 'exports' table of the current container's symbol.
            //  2) The 'members' table of the current container's symbol.
            //  3) The 'locals' table of the current container.
            //
            // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
            // (like TypeLiterals for example) will not be put in any table.
            bindWorker(node);
            // Then we recurse into the children of the node to bind them as well. For certain
            // symbols we do specialized work when we recurse. For example, we'll keep track of
            // the current 'container' node when it changes. This helps us know which symbol table
            // a local should go into for example. Since terminal nodes are known not to have
            // children, as an optimization we don't process those.
            if (node.kind > 152 /* LastToken */) {
                var saveParent = parent;
                parent = node;
                var containerFlags = getContainerFlags(node);
                if (containerFlags === 0 /* None */) {
                    bindChildren(node);
                }
                else {
                    bindContainer(node, containerFlags);
                }
                parent = saveParent;
            }
            else if (!skipTransformFlagAggregation && (node.transformFlags & 536870912 /* HasComputedFlags */) === 0) {
                subtreeTransformFlags |= computeTransformFlagsForNode(node, 0);
                var saveParent = parent;
                if (node.kind === 1 /* EndOfFileToken */)
                    parent = node;
                bindJSDoc(node);
                parent = saveParent;
            }
            inStrictMode = saveInStrictMode;
        }
        function bindJSDoc(node) {
            if (ts.hasJSDocNodes(node)) {
                if (ts.isInJSFile(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var j = _a[_i];
                        bind(j);
                    }
                }
                else {
                    for (var _b = 0, _c = node.jsDoc; _b < _c.length; _b++) {
                        var j = _c[_b];
                        setParentPointers(node, j);
                    }
                }
            }
        }
        function updateStrictModeStatementList(statements) {
            if (!inStrictMode) {
                for (var _i = 0, statements_2 = statements; _i < statements_2.length; _i++) {
                    var statement = statements_2[_i];
                    if (!ts.isPrologueDirective(statement)) {
                        return;
                    }
                    if (isUseStrictPrologueDirective(statement)) {
                        inStrictMode = true;
                        return;
                    }
                }
            }
        }
        /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
        function isUseStrictPrologueDirective(node) {
            var nodeText = ts.getSourceTextOfNodeFromSourceFile(file, node.expression);
            // Note: the node text must be exactly "use strict" or 'use strict'.  It is not ok for the
            // string to contain unicode escapes (as per ES5).
            return nodeText === '"use strict"' || nodeText === "'use strict'";
        }
        function bindWorker(node) {
            switch (node.kind) {
                /* Strict mode checks */
                case 75 /* Identifier */:
                    // for typedef type names with namespaces, bind the new jsdoc type symbol here
                    // because it requires all containing namespaces to be in effect, namely the
                    // current "blockScopeContainer" needs to be set to its immediate namespace parent.
                    if (node.isInJSDocNamespace) {
                        var parentNode = node.parent;
                        while (parentNode && !ts.isJSDocTypeAlias(parentNode)) {
                            parentNode = parentNode.parent;
                        }
                        bindBlockScopedDeclaration(parentNode, 524288 /* TypeAlias */, 788968 /* TypeAliasExcludes */);
                        break;
                    }
                // falls through
                case 104 /* ThisKeyword */:
                    if (currentFlow && (ts.isExpression(node) || parent.kind === 282 /* ShorthandPropertyAssignment */)) {
                        node.flowNode = currentFlow;
                    }
                    return checkStrictModeIdentifier(node);
                case 76 /* PrivateIdentifier */:
                    return checkPrivateIdentifier(node);
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    var expr = node;
                    if (currentFlow && isNarrowableReference(expr)) {
                        expr.flowNode = currentFlow;
                    }
                    if (ts.isSpecialPropertyDeclaration(expr)) {
                        bindSpecialPropertyDeclaration(expr);
                    }
                    if (ts.isInJSFile(expr) &&
                        file.commonJsModuleIndicator &&
                        ts.isModuleExportsAccessExpression(expr) &&
                        !lookupSymbolForNameWorker(blockScopeContainer, "module")) {
                        declareSymbol(file.locals, /*parent*/ undefined, expr.expression, 1 /* FunctionScopedVariable */ | 134217728 /* ModuleExports */, 111550 /* FunctionScopedVariableExcludes */);
                    }
                    break;
                case 209 /* BinaryExpression */:
                    var specialKind = ts.getAssignmentDeclarationKind(node);
                    switch (specialKind) {
                        case 1 /* ExportsProperty */:
                            bindExportsPropertyAssignment(node);
                            break;
                        case 2 /* ModuleExports */:
                            bindModuleExportsAssignment(node);
                            break;
                        case 3 /* PrototypeProperty */:
                            bindPrototypePropertyAssignment(node.left, node);
                            break;
                        case 6 /* Prototype */:
                            bindPrototypeAssignment(node);
                            break;
                        case 4 /* ThisProperty */:
                            bindThisPropertyAssignment(node);
                            break;
                        case 5 /* Property */:
                            bindSpecialPropertyAssignment(node);
                            break;
                        case 0 /* None */:
                            // Nothing to do
                            break;
                        default:
                            ts.Debug.fail("Unknown binary expression special property assignment kind");
                    }
                    return checkStrictModeBinaryExpression(node);
                case 280 /* CatchClause */:
                    return checkStrictModeCatchClause(node);
                case 203 /* DeleteExpression */:
                    return checkStrictModeDeleteExpression(node);
                case 8 /* NumericLiteral */:
                    return checkStrictModeNumericLiteral(node);
                case 208 /* PostfixUnaryExpression */:
                    return checkStrictModePostfixUnaryExpression(node);
                case 207 /* PrefixUnaryExpression */:
                    return checkStrictModePrefixUnaryExpression(node);
                case 236 /* WithStatement */:
                    return checkStrictModeWithStatement(node);
                case 238 /* LabeledStatement */:
                    return checkStrictModeLabeledStatement(node);
                case 183 /* ThisType */:
                    seenThisKeyword = true;
                    return;
                case 168 /* TypePredicate */:
                    break; // Binding the children will handle everything
                case 155 /* TypeParameter */:
                    return bindTypeParameter(node);
                case 156 /* Parameter */:
                    return bindParameter(node);
                case 242 /* VariableDeclaration */:
                    return bindVariableDeclarationOrBindingElement(node);
                case 191 /* BindingElement */:
                    node.flowNode = currentFlow;
                    return bindVariableDeclarationOrBindingElement(node);
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    return bindPropertyWorker(node);
                case 281 /* PropertyAssignment */:
                case 282 /* ShorthandPropertyAssignment */:
                    return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */);
                case 284 /* EnumMember */:
                    return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 900095 /* EnumMemberExcludes */);
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 167 /* IndexSignature */:
                    return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    // If this is an ObjectLiteralExpression method, then it sits in the same space
                    // as other properties in the object literal.  So we use SymbolFlags.PropertyExcludes
                    // so that it will conflict with any other object literal members with the same
                    // name.
                    return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 103359 /* MethodExcludes */);
                case 244 /* FunctionDeclaration */:
                    return bindFunctionDeclaration(node);
                case 162 /* Constructor */:
                    return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
                case 163 /* GetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 46015 /* GetAccessorExcludes */);
                case 164 /* SetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 78783 /* SetAccessorExcludes */);
                case 170 /* FunctionType */:
                case 300 /* JSDocFunctionType */:
                case 305 /* JSDocSignature */:
                case 171 /* ConstructorType */:
                    return bindFunctionOrConstructorType(node);
                case 173 /* TypeLiteral */:
                case 304 /* JSDocTypeLiteral */:
                case 186 /* MappedType */:
                    return bindAnonymousTypeWorker(node);
                case 310 /* JSDocClassTag */:
                    return bindJSDocClassTag(node);
                case 193 /* ObjectLiteralExpression */:
                    return bindObjectLiteralExpression(node);
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return bindFunctionExpression(node);
                case 196 /* CallExpression */:
                    var assignmentKind = ts.getAssignmentDeclarationKind(node);
                    switch (assignmentKind) {
                        case 7 /* ObjectDefinePropertyValue */:
                            return bindObjectDefinePropertyAssignment(node);
                        case 8 /* ObjectDefinePropertyExports */:
                            return bindObjectDefinePropertyExport(node);
                        case 9 /* ObjectDefinePrototypeProperty */:
                            return bindObjectDefinePrototypeProperty(node);
                        case 0 /* None */:
                            break; // Nothing to do
                        default:
                            return ts.Debug.fail("Unknown call expression assignment declaration kind");
                    }
                    if (ts.isInJSFile(node)) {
                        bindCallExpression(node);
                    }
                    break;
                // Members of classes, interfaces, and modules
                case 214 /* ClassExpression */:
                case 245 /* ClassDeclaration */:
                    // All classes are automatically in strict mode in ES6.
                    inStrictMode = true;
                    return bindClassLikeDeclaration(node);
                case 246 /* InterfaceDeclaration */:
                    return bindBlockScopedDeclaration(node, 64 /* Interface */, 788872 /* InterfaceExcludes */);
                case 247 /* TypeAliasDeclaration */:
                    return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 788968 /* TypeAliasExcludes */);
                case 248 /* EnumDeclaration */:
                    return bindEnumDeclaration(node);
                case 249 /* ModuleDeclaration */:
                    return bindModuleDeclaration(node);
                // Jsx-attributes
                case 274 /* JsxAttributes */:
                    return bindJsxAttributes(node);
                case 273 /* JsxAttribute */:
                    return bindJsxAttribute(node, 4 /* Property */, 0 /* PropertyExcludes */);
                // Imports and exports
                case 253 /* ImportEqualsDeclaration */:
                case 256 /* NamespaceImport */:
                case 258 /* ImportSpecifier */:
                case 263 /* ExportSpecifier */:
                    return declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
                case 252 /* NamespaceExportDeclaration */:
                    return bindNamespaceExportDeclaration(node);
                case 255 /* ImportClause */:
                    return bindImportClause(node);
                case 260 /* ExportDeclaration */:
                    return bindExportDeclaration(node);
                case 259 /* ExportAssignment */:
                    return bindExportAssignment(node);
                case 290 /* SourceFile */:
                    updateStrictModeStatementList(node.statements);
                    return bindSourceFileIfExternalModule();
                case 223 /* Block */:
                    if (!ts.isFunctionLike(node.parent)) {
                        return;
                    }
                // falls through
                case 250 /* ModuleBlock */:
                    return updateStrictModeStatementList(node.statements);
                case 317 /* JSDocParameterTag */:
                    if (node.parent.kind === 305 /* JSDocSignature */) {
                        return bindParameter(node);
                    }
                    if (node.parent.kind !== 304 /* JSDocTypeLiteral */) {
                        break;
                    }
                // falls through
                case 323 /* JSDocPropertyTag */:
                    var propTag = node;
                    var flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === 299 /* JSDocOptionalType */ ?
                        4 /* Property */ | 16777216 /* Optional */ :
                        4 /* Property */;
                    return declareSymbolAndAddToSymbolTable(propTag, flags, 0 /* PropertyExcludes */);
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 316 /* JSDocEnumTag */:
                    return (delayedTypeAliases || (delayedTypeAliases = [])).push(node);
            }
        }
        function bindPropertyWorker(node) {
            return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
        }
        function bindAnonymousTypeWorker(node) {
            return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type" /* Type */);
        }
        function bindSourceFileIfExternalModule() {
            setExportContextFlag(file);
            if (ts.isExternalModule(file)) {
                bindSourceFileAsExternalModule();
            }
            else if (ts.isJsonSourceFile(file)) {
                bindSourceFileAsExternalModule();
                // Create symbol equivalent for the module.exports = {}
                var originalSymbol = file.symbol;
                declareSymbol(file.symbol.exports, file.symbol, file, 4 /* Property */, 67108863 /* All */);
                file.symbol = originalSymbol;
            }
        }
        function bindSourceFileAsExternalModule() {
            bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
        }
        function bindExportAssignment(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export assignment in some sort of block construct
                bindAnonymousDeclaration(node, 2097152 /* Alias */, getDeclarationName(node));
            }
            else {
                var flags = ts.exportAssignmentIsAlias(node)
                    // An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression;
                    ? 2097152 /* Alias */
                    // An export default clause with any other expression exports a value
                    : 4 /* Property */;
                // If there is an `export default x;` alias declaration, can't `export default` anything else.
                // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.)
                var symbol = declareSymbol(container.symbol.exports, container.symbol, node, flags, 67108863 /* All */);
                if (node.isExportEquals) {
                    // Will be an error later, since the module already has other exports. Just make sure this has a valueDeclaration set.
                    ts.setValueDeclaration(symbol, node);
                }
            }
        }
        function bindNamespaceExportDeclaration(node) {
            if (node.modifiers && node.modifiers.length) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here));
            }
            var diag = !ts.isSourceFile(node.parent) ? ts.Diagnostics.Global_module_exports_may_only_appear_at_top_level
                : !ts.isExternalModule(node.parent) ? ts.Diagnostics.Global_module_exports_may_only_appear_in_module_files
                    : !node.parent.isDeclarationFile ? ts.Diagnostics.Global_module_exports_may_only_appear_in_declaration_files
                        : undefined;
            if (diag) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, diag));
            }
            else {
                file.symbol.globalExports = file.symbol.globalExports || ts.createSymbolTable();
                declareSymbol(file.symbol.globalExports, file.symbol, node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function bindExportDeclaration(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export * in some sort of block construct
                bindAnonymousDeclaration(node, 8388608 /* ExportStar */, getDeclarationName(node));
            }
            else if (!node.exportClause) {
                // All export * declarations are collected in an __export symbol
                declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* ExportStar */, 0 /* None */);
            }
            else if (ts.isNamespaceExport(node.exportClause)) {
                // declareSymbol walks up parents to find name text, parent _must_ be set
                // but won't be set by the normal binder walk until `bindChildren` later on.
                node.exportClause.parent = node;
                declareSymbol(container.symbol.exports, container.symbol, node.exportClause, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function bindImportClause(node) {
            if (node.name) {
                declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function setCommonJsModuleIndicator(node) {
            if (file.externalModuleIndicator) {
                return false;
            }
            if (!file.commonJsModuleIndicator) {
                file.commonJsModuleIndicator = node;
                bindSourceFileAsExternalModule();
            }
            return true;
        }
        function bindObjectDefinePropertyExport(node) {
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var symbol = forEachIdentifierInEntityName(node.arguments[0], /*parent*/ undefined, function (id, symbol) {
                if (symbol) {
                    addDeclarationToSymbol(symbol, id, 1536 /* Module */ | 67108864 /* Assignment */);
                }
                return symbol;
            });
            if (symbol) {
                var flags = 4 /* Property */ | 1048576 /* ExportValue */;
                declareSymbol(symbol.exports, symbol, node, flags, 0 /* None */);
            }
        }
        function bindExportsPropertyAssignment(node) {
            // When we create a property via 'exports.foo = bar', the 'exports.foo' property access
            // expression is the declaration
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var symbol = forEachIdentifierInEntityName(node.left.expression, /*parent*/ undefined, function (id, symbol) {
                if (symbol) {
                    addDeclarationToSymbol(symbol, id, 1536 /* Module */ | 67108864 /* Assignment */);
                }
                return symbol;
            });
            if (symbol) {
                var flags = ts.isClassExpression(node.right) ?
                    4 /* Property */ | 1048576 /* ExportValue */ | 32 /* Class */ :
                    4 /* Property */ | 1048576 /* ExportValue */;
                declareSymbol(symbol.exports, symbol, node.left, flags, 0 /* None */);
            }
        }
        function bindModuleExportsAssignment(node) {
            // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
            // is still pointing to 'module.exports'.
            // We do not want to consider this as 'export=' since a module can have only one of these.
            // Similarly we do not want to treat 'module.exports = exports' as an 'export='.
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var assignedExpression = ts.getRightMostAssignedExpression(node.right);
            if (ts.isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) {
                return;
            }
            // 'module.exports = expr' assignment
            var flags = ts.exportAssignmentIsAlias(node)
                ? 2097152 /* Alias */
                : 4 /* Property */ | 1048576 /* ExportValue */ | 512 /* ValueModule */;
            var symbol = declareSymbol(file.symbol.exports, file.symbol, node, flags | 67108864 /* Assignment */, 0 /* None */);
            ts.setValueDeclaration(symbol, node);
        }
        function bindThisPropertyAssignment(node) {
            ts.Debug.assert(ts.isInJSFile(node));
            // private identifiers *must* be declared (even in JS files)
            var hasPrivateIdentifier = (ts.isBinaryExpression(node) && ts.isPropertyAccessExpression(node.left) && ts.isPrivateIdentifier(node.left.name))
                || (ts.isPropertyAccessExpression(node) && ts.isPrivateIdentifier(node.name));
            if (hasPrivateIdentifier) {
                return;
            }
            var thisContainer = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            switch (thisContainer.kind) {
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                    var constructorSymbol = thisContainer.symbol;
                    // For `f.prototype.m = function() { this.x = 0; }`, `this.x = 0` should modify `f`'s members, not the function expression.
                    if (ts.isBinaryExpression(thisContainer.parent) && thisContainer.parent.operatorToken.kind === 62 /* EqualsToken */) {
                        var l = thisContainer.parent.left;
                        if (ts.isBindableStaticAccessExpression(l) && ts.isPrototypeAccess(l.expression)) {
                            constructorSymbol = lookupSymbolForPropertyAccess(l.expression.expression, thisParentContainer);
                        }
                    }
                    if (constructorSymbol && constructorSymbol.valueDeclaration) {
                        // Declare a 'member' if the container is an ES5 class or ES6 constructor
                        constructorSymbol.members = constructorSymbol.members || ts.createSymbolTable();
                        // It's acceptable for multiple 'this' assignments of the same identifier to occur
                        if (ts.hasDynamicName(node)) {
                            bindDynamicallyNamedThisPropertyAssignment(node, constructorSymbol);
                        }
                        else {
                            declareSymbol(constructorSymbol.members, constructorSymbol, node, 4 /* Property */ | 67108864 /* Assignment */, 0 /* PropertyExcludes */ & ~4 /* Property */);
                        }
                        addDeclarationToSymbol(constructorSymbol, constructorSymbol.valueDeclaration, 32 /* Class */);
                    }
                    break;
                case 162 /* Constructor */:
                case 159 /* PropertyDeclaration */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    // this.foo assignment in a JavaScript class
                    // Bind this property to the containing class
                    var containingClass = thisContainer.parent;
                    var symbolTable = ts.hasModifier(thisContainer, 32 /* Static */) ? containingClass.symbol.exports : containingClass.symbol.members;
                    if (ts.hasDynamicName(node)) {
                        bindDynamicallyNamedThisPropertyAssignment(node, containingClass.symbol);
                    }
                    else {
                        declareSymbol(symbolTable, containingClass.symbol, node, 4 /* Property */ | 67108864 /* Assignment */, 0 /* None */, /*isReplaceableByMethod*/ true);
                    }
                    break;
                case 290 /* SourceFile */:
                    // this.property = assignment in a source file -- declare symbol in exports for a module, in locals for a script
                    if (ts.hasDynamicName(node)) {
                        break;
                    }
                    else if (thisContainer.commonJsModuleIndicator) {
                        declareSymbol(thisContainer.symbol.exports, thisContainer.symbol, node, 4 /* Property */ | 1048576 /* ExportValue */, 0 /* None */);
                    }
                    else {
                        declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 111550 /* FunctionScopedVariableExcludes */);
                    }
                    break;
                default:
                    ts.Debug.failBadSyntaxKind(thisContainer);
            }
        }
        function bindDynamicallyNamedThisPropertyAssignment(node, symbol) {
            bindAnonymousDeclaration(node, 4 /* Property */, "__computed" /* Computed */);
            addLateBoundAssignmentDeclarationToSymbol(node, symbol);
        }
        function addLateBoundAssignmentDeclarationToSymbol(node, symbol) {
            if (symbol) {
                var members = symbol.assignmentDeclarationMembers || (symbol.assignmentDeclarationMembers = ts.createMap());
                members.set("" + ts.getNodeId(node), node);
            }
        }
        function bindSpecialPropertyDeclaration(node) {
            if (node.expression.kind === 104 /* ThisKeyword */) {
                bindThisPropertyAssignment(node);
            }
            else if (ts.isBindableStaticAccessExpression(node) && node.parent.parent.kind === 290 /* SourceFile */) {
                if (ts.isPrototypeAccess(node.expression)) {
                    bindPrototypePropertyAssignment(node, node.parent);
                }
                else {
                    bindStaticPropertyAssignment(node);
                }
            }
        }
        /** For `x.prototype = { p, ... }`, declare members p,... if `x` is function/class/{}, or not declared. */
        function bindPrototypeAssignment(node) {
            node.left.parent = node;
            node.right.parent = node;
            bindPropertyAssignment(node.left.expression, node.left, /*isPrototypeProperty*/ false, /*containerIsClass*/ true);
        }
        function bindObjectDefinePrototypeProperty(node) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0].expression);
            if (namespaceSymbol && namespaceSymbol.valueDeclaration) {
                // Ensure the namespace symbol becomes class-like
                addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, 32 /* Class */);
            }
            bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ true);
        }
        /**
         * For `x.prototype.y = z`, declare a member `y` on `x` if `x` is a function or class, or not declared.
         * Note that jsdoc preceding an ExpressionStatement like `x.prototype.y;` is also treated as a declaration.
         */
        function bindPrototypePropertyAssignment(lhs, parent) {
            // Look up the function in the local scope, since prototype assignments should
            // follow the function declaration
            var classPrototype = lhs.expression;
            var constructorFunction = classPrototype.expression;
            // Fix up parent pointers since we're going to use these nodes before we bind into them
            lhs.parent = parent;
            constructorFunction.parent = classPrototype;
            classPrototype.parent = lhs;
            bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true, /*containerIsClass*/ true);
        }
        function bindObjectDefinePropertyAssignment(node) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0]);
            var isToplevel = node.parent.parent.kind === 290 /* SourceFile */;
            namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, node.arguments[0], isToplevel, /*isPrototypeProperty*/ false, /*containerIsClass*/ false);
            bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ false);
        }
        function bindSpecialPropertyAssignment(node) {
            // Class declarations in Typescript do not allow property declarations
            var parentSymbol = lookupSymbolForPropertyAccess(node.left.expression);
            if (!ts.isInJSFile(node) && !ts.isFunctionSymbol(parentSymbol)) {
                return;
            }
            // Fix up parent pointers since we're going to use these nodes before we bind into them
            node.left.parent = node;
            node.right.parent = node;
            if (ts.isIdentifier(node.left.expression) && container === file && isExportsOrModuleExportsOrAlias(file, node.left.expression)) {
                // This can be an alias for the 'exports' or 'module.exports' names, e.g.
                //    var util = module.exports;
                //    util.property = function ...
                bindExportsPropertyAssignment(node);
            }
            else if (ts.hasDynamicName(node)) {
                bindAnonymousDeclaration(node, 4 /* Property */ | 67108864 /* Assignment */, "__computed" /* Computed */);
                var sym = bindPotentiallyMissingNamespaces(parentSymbol, node.left.expression, isTopLevelNamespaceAssignment(node.left), /*isPrototype*/ false, /*containerIsClass*/ false);
                addLateBoundAssignmentDeclarationToSymbol(node, sym);
            }
            else {
                bindStaticPropertyAssignment(ts.cast(node.left, ts.isBindableStaticNameExpression));
            }
        }
        /**
         * For nodes like `x.y = z`, declare a member 'y' on 'x' if x is a function (or IIFE) or class or {}, or not declared.
         * Also works for expression statements preceded by JSDoc, like / ** @type number * / x.y;
         */
        function bindStaticPropertyAssignment(node) {
            ts.Debug.assert(!ts.isIdentifier(node));
            node.expression.parent = node;
            bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false, /*containerIsClass*/ false);
        }
        function bindPotentiallyMissingNamespaces(namespaceSymbol, entityName, isToplevel, isPrototypeProperty, containerIsClass) {
            if (isToplevel && !isPrototypeProperty) {
                // make symbols or add declarations for intermediate containers
                var flags_1 = 1536 /* Module */ | 67108864 /* Assignment */;
                var excludeFlags_1 = 110735 /* ValueModuleExcludes */ & ~67108864 /* Assignment */;
                namespaceSymbol = forEachIdentifierInEntityName(entityName, namespaceSymbol, function (id, symbol, parent) {
                    if (symbol) {
                        addDeclarationToSymbol(symbol, id, flags_1);
                        return symbol;
                    }
                    else {
                        var table = parent ? parent.exports :
                            file.jsGlobalAugmentations || (file.jsGlobalAugmentations = ts.createSymbolTable());
                        return declareSymbol(table, parent, id, flags_1, excludeFlags_1);
                    }
                });
            }
            if (containerIsClass && namespaceSymbol && namespaceSymbol.valueDeclaration) {
                addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, 32 /* Class */);
            }
            return namespaceSymbol;
        }
        function bindPotentiallyNewExpandoMemberToNamespace(declaration, namespaceSymbol, isPrototypeProperty) {
            if (!namespaceSymbol || !isExpandoSymbol(namespaceSymbol)) {
                return;
            }
            // Set up the members collection if it doesn't exist already
            var symbolTable = isPrototypeProperty ?
                (namespaceSymbol.members || (namespaceSymbol.members = ts.createSymbolTable())) :
                (namespaceSymbol.exports || (namespaceSymbol.exports = ts.createSymbolTable()));
            var includes = 0 /* None */;
            var excludes = 0 /* None */;
            // Method-like
            if (ts.isFunctionLikeDeclaration(ts.getAssignedExpandoInitializer(declaration))) {
                includes = 8192 /* Method */;
                excludes = 103359 /* MethodExcludes */;
            }
            // Maybe accessor-like
            else if (ts.isCallExpression(declaration) && ts.isBindableObjectDefinePropertyCall(declaration)) {
                if (ts.some(declaration.arguments[2].properties, function (p) {
                    var id = ts.getNameOfDeclaration(p);
                    return !!id && ts.isIdentifier(id) && ts.idText(id) === "set";
                })) {
                    // We mix in `SymbolFLags.Property` so in the checker `getTypeOfVariableParameterOrProperty` is used for this
                    // symbol, instead of `getTypeOfAccessor` (which will assert as there is no real accessor declaration)
                    includes |= 65536 /* SetAccessor */ | 4 /* Property */;
                    excludes |= 78783 /* SetAccessorExcludes */;
                }
                if (ts.some(declaration.arguments[2].properties, function (p) {
                    var id = ts.getNameOfDeclaration(p);
                    return !!id && ts.isIdentifier(id) && ts.idText(id) === "get";
                })) {
                    includes |= 32768 /* GetAccessor */ | 4 /* Property */;
                    excludes |= 46015 /* GetAccessorExcludes */;
                }
            }
            if (includes === 0 /* None */) {
                includes = 4 /* Property */;
                excludes = 0 /* PropertyExcludes */;
            }
            declareSymbol(symbolTable, namespaceSymbol, declaration, includes | 67108864 /* Assignment */, excludes & ~67108864 /* Assignment */);
        }
        function isTopLevelNamespaceAssignment(propertyAccess) {
            return ts.isBinaryExpression(propertyAccess.parent)
                ? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === 290 /* SourceFile */
                : propertyAccess.parent.parent.kind === 290 /* SourceFile */;
        }
        function bindPropertyAssignment(name, propertyAccess, isPrototypeProperty, containerIsClass) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(name);
            var isToplevel = isTopLevelNamespaceAssignment(propertyAccess);
            namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty, containerIsClass);
            bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty);
        }
        /**
         * Javascript expando values are:
         * - Functions
         * - classes
         * - namespaces
         * - variables initialized with function expressions
         * -                       with class expressions
         * -                       with empty object literals
         * -                       with non-empty object literals if assigned to the prototype property
         */
        function isExpandoSymbol(symbol) {
            if (symbol.flags & (16 /* Function */ | 32 /* Class */ | 1024 /* NamespaceModule */)) {
                return true;
            }
            var node = symbol.valueDeclaration;
            if (node && ts.isCallExpression(node)) {
                return !!ts.getAssignedExpandoInitializer(node);
            }
            var init = !node ? undefined :
                ts.isVariableDeclaration(node) ? node.initializer :
                    ts.isBinaryExpression(node) ? node.right :
                        ts.isPropertyAccessExpression(node) && ts.isBinaryExpression(node.parent) ? node.parent.right :
                            undefined;
            init = init && ts.getRightMostAssignedExpression(init);
            if (init) {
                var isPrototypeAssignment = ts.isPrototypeAccess(ts.isVariableDeclaration(node) ? node.name : ts.isBinaryExpression(node) ? node.left : node);
                return !!ts.getExpandoInitializer(ts.isBinaryExpression(init) && (init.operatorToken.kind === 56 /* BarBarToken */ || init.operatorToken.kind === 60 /* QuestionQuestionToken */) ? init.right : init, isPrototypeAssignment);
            }
            return false;
        }
        function getParentOfBinaryExpression(expr) {
            while (ts.isBinaryExpression(expr.parent)) {
                expr = expr.parent;
            }
            return expr.parent;
        }
        function lookupSymbolForPropertyAccess(node, lookupContainer) {
            if (lookupContainer === void 0) { lookupContainer = container; }
            if (ts.isIdentifier(node)) {
                return lookupSymbolForNameWorker(lookupContainer, node.escapedText);
            }
            else {
                var symbol = lookupSymbolForPropertyAccess(node.expression);
                return symbol && symbol.exports && symbol.exports.get(ts.getElementOrPropertyAccessName(node));
            }
        }
        function forEachIdentifierInEntityName(e, parent, action) {
            if (isExportsOrModuleExportsOrAlias(file, e)) {
                return file.symbol;
            }
            else if (ts.isIdentifier(e)) {
                return action(e, lookupSymbolForPropertyAccess(e), parent);
            }
            else {
                var s = forEachIdentifierInEntityName(e.expression, parent, action);
                var name = ts.getNameOrArgument(e);
                // unreachable
                if (ts.isPrivateIdentifier(name)) {
                    ts.Debug.fail("unexpected PrivateIdentifier");
                }
                return action(name, s && s.exports && s.exports.get(ts.getElementOrPropertyAccessName(e)), s);
            }
        }
        function bindCallExpression(node) {
            // We're only inspecting call expressions to detect CommonJS modules, so we can skip
            // this check if we've already seen the module indicator
            if (!file.commonJsModuleIndicator && ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ false)) {
                setCommonJsModuleIndicator(node);
            }
        }
        function bindClassLikeDeclaration(node) {
            if (node.kind === 245 /* ClassDeclaration */) {
                bindBlockScopedDeclaration(node, 32 /* Class */, 899503 /* ClassExcludes */);
            }
            else {
                var bindingName = node.name ? node.name.escapedText : "__class" /* Class */;
                bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
                // Add name of class expression into the map for semantic classifier
                if (node.name) {
                    classifiableNames.set(node.name.escapedText, true);
                }
            }
            var symbol = node.symbol;
            // TypeScript 1.0 spec (April 2014): 8.4
            // Every class automatically contains a static property member named 'prototype', the
            // type of which is an instantiation of the class type with type Any supplied as a type
            // argument for each type parameter. It is an error to explicitly declare a static
            // property member with the name 'prototype'.
            //
            // Note: we check for this here because this class may be merging into a module.  The
            // module might have an exported variable called 'prototype'.  We can't allow that as
            // that would clash with the built-in 'prototype' for the class.
            var prototypeSymbol = createSymbol(4 /* Property */ | 4194304 /* Prototype */, "prototype");
            var symbolExport = symbol.exports.get(prototypeSymbol.escapedName);
            if (symbolExport) {
                if (node.name) {
                    node.name.parent = node;
                }
                file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(prototypeSymbol)));
            }
            symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol);
            prototypeSymbol.parent = symbol;
        }
        function bindEnumDeclaration(node) {
            return ts.isEnumConst(node)
                ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */)
                : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */);
        }
        function bindVariableDeclarationOrBindingElement(node) {
            if (inStrictMode) {
                checkStrictModeEvalOrArguments(node, node.name);
            }
            if (!ts.isBindingPattern(node.name)) {
                if (ts.isBlockOrCatchScoped(node)) {
                    bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 111551 /* BlockScopedVariableExcludes */);
                }
                else if (ts.isParameterDeclaration(node)) {
                    // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration
                    // because its parent chain has already been set up, since parents are set before descending into children.
                    //
                    // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
                    // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
                    // For example:
                    //      function foo([a,a]) {} // Duplicate Identifier error
                    //      function bar(a,a) {}   // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
                    //                             // which correctly set excluded symbols
                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 111551 /* ParameterExcludes */);
                }
                else {
                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 111550 /* FunctionScopedVariableExcludes */);
                }
            }
        }
        function bindParameter(node) {
            if (node.kind === 317 /* JSDocParameterTag */ && container.kind !== 305 /* JSDocSignature */) {
                return;
            }
            if (inStrictMode && !(node.flags & 8388608 /* Ambient */)) {
                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
                // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
                checkStrictModeEvalOrArguments(node, node.name);
            }
            if (ts.isBindingPattern(node.name)) {
                bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, "__" + node.parent.parameters.indexOf(node));
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 111551 /* ParameterExcludes */);
            }
            // If this is a property-parameter, then also declare the property symbol into the
            // containing class.
            if (ts.isParameterPropertyDeclaration(node, node.parent)) {
                var classDeclaration = node.parent.parent;
                declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
            }
        }
        function bindFunctionDeclaration(node) {
            if (!file.isDeclarationFile && !(node.flags & 8388608 /* Ambient */)) {
                if (ts.isAsyncFunction(node)) {
                    emitFlags |= 2048 /* HasAsyncFunctions */;
                }
            }
            checkStrictModeFunctionName(node);
            if (inStrictMode) {
                checkStrictModeFunctionDeclaration(node);
                bindBlockScopedDeclaration(node, 16 /* Function */, 110991 /* FunctionExcludes */);
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 110991 /* FunctionExcludes */);
            }
        }
        function bindFunctionExpression(node) {
            if (!file.isDeclarationFile && !(node.flags & 8388608 /* Ambient */)) {
                if (ts.isAsyncFunction(node)) {
                    emitFlags |= 2048 /* HasAsyncFunctions */;
                }
            }
            if (currentFlow) {
                node.flowNode = currentFlow;
            }
            checkStrictModeFunctionName(node);
            var bindingName = node.name ? node.name.escapedText : "__function" /* Function */;
            return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
        }
        function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
            if (!file.isDeclarationFile && !(node.flags & 8388608 /* Ambient */) && ts.isAsyncFunction(node)) {
                emitFlags |= 2048 /* HasAsyncFunctions */;
            }
            if (currentFlow && ts.isObjectLiteralOrClassExpressionMethod(node)) {
                node.flowNode = currentFlow;
            }
            return ts.hasDynamicName(node)
                ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */)
                : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        function getInferTypeContainer(node) {
            var extendsType = ts.findAncestor(node, function (n) { return n.parent && ts.isConditionalTypeNode(n.parent) && n.parent.extendsType === n; });
            return extendsType && extendsType.parent;
        }
        function bindTypeParameter(node) {
            if (ts.isJSDocTemplateTag(node.parent)) {
                var container_1 = ts.find(node.parent.parent.tags, ts.isJSDocTypeAlias) || ts.getHostSignatureFromJSDoc(node.parent); // TODO: GH#18217
                if (container_1) {
                    if (!container_1.locals) {
                        container_1.locals = ts.createSymbolTable();
                    }
                    declareSymbol(container_1.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 526824 /* TypeParameterExcludes */);
                }
                else {
                    declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 526824 /* TypeParameterExcludes */);
                }
            }
            else if (node.parent.kind === 181 /* InferType */) {
                var container_2 = getInferTypeContainer(node.parent);
                if (container_2) {
                    if (!container_2.locals) {
                        container_2.locals = ts.createSymbolTable();
                    }
                    declareSymbol(container_2.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 526824 /* TypeParameterExcludes */);
                }
                else {
                    bindAnonymousDeclaration(node, 262144 /* TypeParameter */, getDeclarationName(node)); // TODO: GH#18217
                }
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 526824 /* TypeParameterExcludes */);
            }
        }
        // reachability checks
        function shouldReportErrorOnModuleDeclaration(node) {
            var instanceState = getModuleInstanceState(node);
            return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && !!options.preserveConstEnums);
        }
        function checkUnreachable(node) {
            if (!(currentFlow.flags & 1 /* Unreachable */)) {
                return false;
            }
            if (currentFlow === unreachableFlow) {
                var reportError = 
                // report error on all statements except empty ones
                (ts.isStatementButNotDeclaration(node) && node.kind !== 224 /* EmptyStatement */) ||
                    // report error on class declarations
                    node.kind === 245 /* ClassDeclaration */ ||
                    // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
                    (node.kind === 249 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node));
                if (reportError) {
                    currentFlow = reportedUnreachableFlow;
                    if (!options.allowUnreachableCode) {
                        // unreachable code is reported if
                        // - user has explicitly asked about it AND
                        // - statement is in not ambient context (statements in ambient context is already an error
                        //   so we should not report extras) AND
                        //   - node is not variable statement OR
                        //   - node is block scoped variable statement OR
                        //   - node is not block scoped variable statement and at least one variable declaration has initializer
                        //   Rationale: we don't want to report errors on non-initialized var's since they are hoisted
                        //   On the other side we do want to report errors on non-initialized 'lets' because of TDZ
                        var isError_1 = ts.unreachableCodeIsError(options) &&
                            !(node.flags & 8388608 /* Ambient */) &&
                            (!ts.isVariableStatement(node) ||
                                !!(ts.getCombinedNodeFlags(node.declarationList) & 3 /* BlockScoped */) ||
                                node.declarationList.declarations.some(function (d) { return !!d.initializer; }));
                        eachUnreachableRange(node, function (start, end) { return errorOrSuggestionOnRange(isError_1, start, end, ts.Diagnostics.Unreachable_code_detected); });
                    }
                }
            }
            return true;
        }
    }
    function eachUnreachableRange(node, cb) {
        if (ts.isStatement(node) && isExecutableStatement(node) && ts.isBlock(node.parent)) {
            var statements = node.parent.statements;
            var slice_1 = ts.sliceAfter(statements, node);
            ts.getRangesWhere(slice_1, isExecutableStatement, function (start, afterEnd) { return cb(slice_1[start], slice_1[afterEnd - 1]); });
        }
        else {
            cb(node, node);
        }
    }
    // As opposed to a pure declaration like an `interface`
    function isExecutableStatement(s) {
        // Don't remove statements that can validly be used before they appear.
        return !ts.isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !ts.isEnumDeclaration(s) &&
            // `var x;` may declare a variable used above
            !(ts.isVariableStatement(s) && !(ts.getCombinedNodeFlags(s) & (1 /* Let */ | 2 /* Const */)) && s.declarationList.declarations.some(function (d) { return !d.initializer; }));
    }
    function isPurelyTypeDeclaration(s) {
        switch (s.kind) {
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
                return true;
            case 249 /* ModuleDeclaration */:
                return getModuleInstanceState(s) !== 1 /* Instantiated */;
            case 248 /* EnumDeclaration */:
                return ts.hasModifier(s, 2048 /* Const */);
            default:
                return false;
        }
    }
    function isExportsOrModuleExportsOrAlias(sourceFile, node) {
        var i = 0;
        var q = [node];
        while (q.length && i < 100) {
            i++;
            node = q.shift();
            if (ts.isExportsIdentifier(node) || ts.isModuleExportsAccessExpression(node)) {
                return true;
            }
            else if (ts.isIdentifier(node)) {
                var symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText);
                if (!!symbol && !!symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) && !!symbol.valueDeclaration.initializer) {
                    var init = symbol.valueDeclaration.initializer;
                    q.push(init);
                    if (ts.isAssignmentExpression(init, /*excludeCompoundAssignment*/ true)) {
                        q.push(init.left);
                        q.push(init.right);
                    }
                }
            }
        }
        return false;
    }
    ts.isExportsOrModuleExportsOrAlias = isExportsOrModuleExportsOrAlias;
    function lookupSymbolForNameWorker(container, name) {
        var local = container.locals && container.locals.get(name);
        if (local) {
            return local.exportSymbol || local;
        }
        if (ts.isSourceFile(container) && container.jsGlobalAugmentations && container.jsGlobalAugmentations.has(name)) {
            return container.jsGlobalAugmentations.get(name);
        }
        return container.symbol && container.symbol.exports && container.symbol.exports.get(name);
    }
    /**
     * Computes the transform flags for a node, given the transform flags of its subtree
     *
     * @param node The node to analyze
     * @param subtreeFlags Transform flags computed for this node's subtree
     */
    function computeTransformFlagsForNode(node, subtreeFlags) {
        var kind = node.kind;
        switch (kind) {
            case 196 /* CallExpression */:
                return computeCallExpression(node, subtreeFlags);
            case 197 /* NewExpression */:
                return computeNewExpression(node, subtreeFlags);
            case 249 /* ModuleDeclaration */:
                return computeModuleDeclaration(node, subtreeFlags);
            case 200 /* ParenthesizedExpression */:
                return computeParenthesizedExpression(node, subtreeFlags);
            case 209 /* BinaryExpression */:
                return computeBinaryExpression(node, subtreeFlags);
            case 226 /* ExpressionStatement */:
                return computeExpressionStatement(node, subtreeFlags);
            case 156 /* Parameter */:
                return computeParameter(node, subtreeFlags);
            case 202 /* ArrowFunction */:
                return computeArrowFunction(node, subtreeFlags);
            case 201 /* FunctionExpression */:
                return computeFunctionExpression(node, subtreeFlags);
            case 244 /* FunctionDeclaration */:
                return computeFunctionDeclaration(node, subtreeFlags);
            case 242 /* VariableDeclaration */:
                return computeVariableDeclaration(node, subtreeFlags);
            case 243 /* VariableDeclarationList */:
                return computeVariableDeclarationList(node, subtreeFlags);
            case 225 /* VariableStatement */:
                return computeVariableStatement(node, subtreeFlags);
            case 238 /* LabeledStatement */:
                return computeLabeledStatement(node, subtreeFlags);
            case 245 /* ClassDeclaration */:
                return computeClassDeclaration(node, subtreeFlags);
            case 214 /* ClassExpression */:
                return computeClassExpression(node, subtreeFlags);
            case 279 /* HeritageClause */:
                return computeHeritageClause(node, subtreeFlags);
            case 280 /* CatchClause */:
                return computeCatchClause(node, subtreeFlags);
            case 216 /* ExpressionWithTypeArguments */:
                return computeExpressionWithTypeArguments(node, subtreeFlags);
            case 162 /* Constructor */:
                return computeConstructor(node, subtreeFlags);
            case 159 /* PropertyDeclaration */:
                return computePropertyDeclaration(node, subtreeFlags);
            case 161 /* MethodDeclaration */:
                return computeMethod(node, subtreeFlags);
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
                return computeAccessor(node, subtreeFlags);
            case 253 /* ImportEqualsDeclaration */:
                return computeImportEquals(node, subtreeFlags);
            case 194 /* PropertyAccessExpression */:
                return computePropertyAccess(node, subtreeFlags);
            case 195 /* ElementAccessExpression */:
                return computeElementAccess(node, subtreeFlags);
            case 267 /* JsxSelfClosingElement */:
            case 268 /* JsxOpeningElement */:
                return computeJsxOpeningLikeElement(node, subtreeFlags);
            default:
                return computeOther(node, kind, subtreeFlags);
        }
    }
    ts.computeTransformFlagsForNode = computeTransformFlagsForNode;
    function computeCallExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var callee = ts.skipOuterExpressions(node.expression);
        var expression = node.expression;
        if (node.flags & 32 /* OptionalChain */) {
            transformFlags |= 8 /* ContainsES2020 */;
        }
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        if (subtreeFlags & 8192 /* ContainsRestOrSpread */ || ts.isSuperOrSuperProperty(callee)) {
            // If the this node contains a SpreadExpression, or is a super call, then it is an ES6
            // node.
            transformFlags |= 256 /* AssertES2015 */;
            if (ts.isSuperProperty(callee)) {
                transformFlags |= 4096 /* ContainsLexicalThis */;
            }
        }
        if (expression.kind === 96 /* ImportKeyword */) {
            transformFlags |= 2097152 /* ContainsDynamicImport */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536879104 /* ArrayLiteralOrCallOrNewExcludes */;
    }
    function computeNewExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        if (subtreeFlags & 8192 /* ContainsRestOrSpread */) {
            // If the this node contains a SpreadElementExpression then it is an ES6
            // node.
            transformFlags |= 256 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536879104 /* ArrayLiteralOrCallOrNewExcludes */;
    }
    function computeJsxOpeningLikeElement(node, subtreeFlags) {
        var transformFlags = subtreeFlags | 2 /* AssertJsx */;
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeBinaryExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var operatorTokenKind = node.operatorToken.kind;
        var leftKind = node.left.kind;
        if (operatorTokenKind === 60 /* QuestionQuestionToken */) {
            transformFlags |= 8 /* AssertES2020 */;
        }
        else if (operatorTokenKind === 62 /* EqualsToken */ && leftKind === 193 /* ObjectLiteralExpression */) {
            // Destructuring object assignments with are ES2015 syntax
            // and possibly ES2018 if they contain rest
            transformFlags |= 32 /* AssertES2018 */ | 256 /* AssertES2015 */ | 1024 /* AssertDestructuringAssignment */;
        }
        else if (operatorTokenKind === 62 /* EqualsToken */ && leftKind === 192 /* ArrayLiteralExpression */) {
            // Destructuring assignments are ES2015 syntax.
            transformFlags |= 256 /* AssertES2015 */ | 1024 /* AssertDestructuringAssignment */;
        }
        else if (operatorTokenKind === 42 /* AsteriskAsteriskToken */
            || operatorTokenKind === 66 /* AsteriskAsteriskEqualsToken */) {
            // Exponentiation is ES2016 syntax.
            transformFlags |= 128 /* AssertES2016 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeParameter(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var name = node.name;
        var initializer = node.initializer;
        var dotDotDotToken = node.dotDotDotToken;
        // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript
        // syntax.
        if (node.questionToken
            || node.type
            || (subtreeFlags & 2048 /* ContainsTypeScriptClassSyntax */ && ts.some(node.decorators))
            || ts.isThisIdentifier(name)) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // If a parameter has an accessibility modifier, then it is TypeScript syntax.
        if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
            transformFlags |= 1 /* AssertTypeScript */ | 2048 /* ContainsTypeScriptClassSyntax */;
        }
        // parameters with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        // If a parameter has an initializer, a binding pattern or a dotDotDot token, then
        // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
        if (subtreeFlags & 131072 /* ContainsBindingPattern */ || initializer || dotDotDotToken) {
            transformFlags |= 256 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* ParameterExcludes */;
    }
    function computeParenthesizedExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var expression = node.expression;
        var expressionKind = expression.kind;
        // If the node is synthesized, it means the emitter put the parentheses there,
        // not the user. If we didn't want them, the emitter would not have put them
        // there.
        if (expressionKind === 217 /* AsExpression */
            || expressionKind === 199 /* TypeAssertionExpression */) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* OuterExpressionExcludes */;
    }
    function computeClassDeclaration(node, subtreeFlags) {
        var transformFlags;
        if (ts.hasModifier(node, 2 /* Ambient */)) {
            // An ambient declaration is TypeScript syntax.
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            // A ClassDeclaration is ES6 syntax.
            transformFlags = subtreeFlags | 256 /* AssertES2015 */;
            // A class with a parameter property assignment or decorator is TypeScript syntax.
            // An exported declaration may be TypeScript syntax, but is handled by the visitor
            // for a namespace declaration.
            if ((subtreeFlags & 2048 /* ContainsTypeScriptClassSyntax */)
                || node.typeParameters) {
                transformFlags |= 1 /* AssertTypeScript */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536905728 /* ClassExcludes */;
    }
    function computeClassExpression(node, subtreeFlags) {
        // A ClassExpression is ES6 syntax.
        var transformFlags = subtreeFlags | 256 /* AssertES2015 */;
        // A class with a parameter property assignment or decorator is TypeScript syntax.
        if (subtreeFlags & 2048 /* ContainsTypeScriptClassSyntax */
            || node.typeParameters) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536905728 /* ClassExcludes */;
    }
    function computeHeritageClause(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        switch (node.token) {
            case 90 /* ExtendsKeyword */:
                // An `extends` HeritageClause is ES6 syntax.
                transformFlags |= 256 /* AssertES2015 */;
                break;
            case 113 /* ImplementsKeyword */:
                // An `implements` HeritageClause is TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                break;
            default:
                ts.Debug.fail("Unexpected token for heritage clause");
                break;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeCatchClause(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (!node.variableDeclaration) {
            transformFlags |= 16 /* AssertES2019 */;
        }
        else if (ts.isBindingPattern(node.variableDeclaration.name)) {
            transformFlags |= 256 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536887296 /* CatchClauseExcludes */;
    }
    function computeExpressionWithTypeArguments(node, subtreeFlags) {
        // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
        // extends clause of a class.
        var transformFlags = subtreeFlags | 256 /* AssertES2015 */;
        // If an ExpressionWithTypeArguments contains type arguments, then it
        // is TypeScript syntax.
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeConstructor(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // TypeScript-specific modifiers and overloads are TypeScript syntax
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || !node.body) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~538923008 /* ConstructorExcludes */;
    }
    function computeMethod(node, subtreeFlags) {
        // A MethodDeclaration is ES6 syntax.
        var transformFlags = subtreeFlags | 256 /* AssertES2015 */;
        // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and
        // overloads are TypeScript syntax.
        if (node.decorators
            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type
            || !node.body
            || node.questionToken) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        // An async method declaration is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= node.asteriskToken ? 32 /* AssertES2018 */ : 64 /* AssertES2017 */;
        }
        if (node.asteriskToken) {
            transformFlags |= 512 /* AssertGenerator */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~538923008 /* MethodOrAccessorExcludes */);
    }
    function computeAccessor(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // Decorators, TypeScript-specific modifiers, type annotations, and overloads are
        // TypeScript syntax.
        if (node.decorators
            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.type
            || !node.body) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~538923008 /* MethodOrAccessorExcludes */);
    }
    function computePropertyDeclaration(node, subtreeFlags) {
        var transformFlags = subtreeFlags | 4194304 /* ContainsClassFields */;
        // Decorators, TypeScript-specific modifiers, and type annotations are TypeScript syntax.
        if (ts.some(node.decorators) || ts.hasModifier(node, 2270 /* TypeScriptModifier */) || node.type || node.questionToken || node.exclamationToken) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // Hoisted variables related to class properties should live within the TypeScript class wrapper.
        if (ts.isComputedPropertyName(node.name) || (ts.hasStaticModifier(node) && node.initializer)) {
            transformFlags |= 2048 /* ContainsTypeScriptClassSyntax */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~536875008 /* PropertyExcludes */);
    }
    function computeFunctionDeclaration(node, subtreeFlags) {
        var transformFlags;
        var modifierFlags = ts.getModifierFlags(node);
        var body = node.body;
        if (!body || (modifierFlags & 2 /* Ambient */)) {
            // An ambient declaration is TypeScript syntax.
            // A FunctionDeclaration without a body is an overload and is TypeScript syntax.
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            transformFlags = subtreeFlags | 1048576 /* ContainsHoistedDeclarationOrCompletion */;
            // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
            // syntax.
            if (modifierFlags & 2270 /* TypeScriptModifier */
                || node.typeParameters
                || node.type) {
                transformFlags |= 1 /* AssertTypeScript */;
            }
            // An async function declaration is ES2017 syntax.
            if (modifierFlags & 256 /* Async */) {
                transformFlags |= node.asteriskToken ? 32 /* AssertES2018 */ : 64 /* AssertES2017 */;
            }
            // function declarations with object rest destructuring are ES2018 syntax
            if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
                transformFlags |= 32 /* AssertES2018 */;
            }
            // If a FunctionDeclaration is generator function and is the body of a
            // transformed async function, then this node can be transformed to a
            // down-level generator.
            // Currently we do not support transforming any other generator functions
            // down level.
            if (node.asteriskToken) {
                transformFlags |= 512 /* AssertGenerator */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~538925056 /* FunctionExcludes */;
    }
    function computeFunctionExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
        // syntax.
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // An async function expression is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= node.asteriskToken ? 32 /* AssertES2018 */ : 64 /* AssertES2017 */;
        }
        // function expressions with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        // If a FunctionExpression is generator function and is the body of a
        // transformed async function, then this node can be transformed to a
        // down-level generator.
        if (node.asteriskToken) {
            transformFlags |= 512 /* AssertGenerator */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~538925056 /* FunctionExcludes */;
    }
    function computeArrowFunction(node, subtreeFlags) {
        // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
        var transformFlags = subtreeFlags | 256 /* AssertES2015 */;
        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
        // syntax.
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // An async arrow function is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= 64 /* AssertES2017 */;
        }
        // arrow functions with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~538920960 /* ArrowFunctionExcludes */;
    }
    function computePropertyAccess(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (node.flags & 32 /* OptionalChain */) {
            transformFlags |= 8 /* ContainsES2020 */;
        }
        // If a PropertyAccessExpression starts with a super keyword, then it is
        // ES6 syntax, and requires a lexical `this` binding.
        if (node.expression.kind === 102 /* SuperKeyword */) {
            // super inside of an async function requires hoisting the super access (ES2017).
            // same for super inside of an async generator, which is ES2018.
            transformFlags |= 64 /* ContainsES2017 */ | 32 /* ContainsES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* PropertyAccessExcludes */;
    }
    function computeElementAccess(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (node.flags & 32 /* OptionalChain */) {
            transformFlags |= 8 /* ContainsES2020 */;
        }
        // If an ElementAccessExpression starts with a super keyword, then it is
        // ES6 syntax, and requires a lexical `this` binding.
        if (node.expression.kind === 102 /* SuperKeyword */) {
            // super inside of an async function requires hoisting the super access (ES2017).
            // same for super inside of an async generator, which is ES2018.
            transformFlags |= 64 /* ContainsES2017 */ | 32 /* ContainsES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* PropertyAccessExcludes */;
    }
    function computeVariableDeclaration(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        transformFlags |= 256 /* AssertES2015 */ | 131072 /* ContainsBindingPattern */; // TODO(rbuckton): Why are these set unconditionally?
        // A VariableDeclaration containing ObjectRest is ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        // Type annotations are TypeScript syntax.
        if (node.type || node.exclamationToken) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeVariableStatement(node, subtreeFlags) {
        var transformFlags;
        var declarationListTransformFlags = node.declarationList.transformFlags;
        // An ambient declaration is TypeScript syntax.
        if (ts.hasModifier(node, 2 /* Ambient */)) {
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            transformFlags = subtreeFlags;
            if (declarationListTransformFlags & 131072 /* ContainsBindingPattern */) {
                transformFlags |= 256 /* AssertES2015 */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeLabeledStatement(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // A labeled statement containing a block scoped binding *may* need to be transformed from ES6.
        if (subtreeFlags & 65536 /* ContainsBlockScopedBinding */
            && ts.isIterationStatement(node, /*lookInLabeledStatements*/ true)) {
            transformFlags |= 256 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeImportEquals(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // An ImportEqualsDeclaration with a namespace reference is TypeScript.
        if (!ts.isExternalModuleImportEqualsDeclaration(node)) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeExpressionStatement(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeModuleDeclaration(node, subtreeFlags) {
        var transformFlags = 1 /* AssertTypeScript */;
        var modifierFlags = ts.getModifierFlags(node);
        if ((modifierFlags & 2 /* Ambient */) === 0) {
            transformFlags |= subtreeFlags;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537991168 /* ModuleExcludes */;
    }
    function computeVariableDeclarationList(node, subtreeFlags) {
        var transformFlags = subtreeFlags | 1048576 /* ContainsHoistedDeclarationOrCompletion */;
        if (subtreeFlags & 131072 /* ContainsBindingPattern */) {
            transformFlags |= 256 /* AssertES2015 */;
        }
        // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
        if (node.flags & 3 /* BlockScoped */) {
            transformFlags |= 256 /* AssertES2015 */ | 65536 /* ContainsBlockScopedBinding */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537018368 /* VariableDeclarationListExcludes */;
    }
    function computeOther(node, kind, subtreeFlags) {
        // Mark transformations needed for each node
        var transformFlags = subtreeFlags;
        var excludeFlags = 536870912 /* NodeExcludes */;
        switch (kind) {
            case 126 /* AsyncKeyword */:
                // async is ES2017 syntax, but may be ES2018 syntax (for async generators)
                transformFlags |= 32 /* AssertES2018 */ | 64 /* AssertES2017 */;
                break;
            case 206 /* AwaitExpression */:
                // await is ES2017 syntax, but may be ES2018 syntax (for async generators)
                transformFlags |= 32 /* AssertES2018 */ | 64 /* AssertES2017 */ | 524288 /* ContainsAwait */;
                break;
            case 199 /* TypeAssertionExpression */:
            case 217 /* AsExpression */:
            case 326 /* PartiallyEmittedExpression */:
                // These nodes are TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                excludeFlags = 536870912 /* OuterExpressionExcludes */;
                break;
            case 119 /* PublicKeyword */:
            case 117 /* PrivateKeyword */:
            case 118 /* ProtectedKeyword */:
            case 122 /* AbstractKeyword */:
            case 130 /* DeclareKeyword */:
            case 81 /* ConstKeyword */:
            case 248 /* EnumDeclaration */:
            case 284 /* EnumMember */:
            case 218 /* NonNullExpression */:
            case 138 /* ReadonlyKeyword */:
                // These nodes are TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                break;
            case 266 /* JsxElement */:
            case 11 /* JsxText */:
            case 269 /* JsxClosingElement */:
            case 270 /* JsxFragment */:
            case 271 /* JsxOpeningFragment */:
            case 272 /* JsxClosingFragment */:
            case 273 /* JsxAttribute */:
            case 274 /* JsxAttributes */:
            case 275 /* JsxSpreadAttribute */:
            case 276 /* JsxExpression */:
                // These nodes are Jsx syntax.
                transformFlags |= 2 /* AssertJsx */;
                break;
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 15 /* TemplateHead */:
            case 16 /* TemplateMiddle */:
            case 17 /* TemplateTail */:
                if (node.templateFlags) {
                    transformFlags |= 32 /* AssertES2018 */;
                    break;
                }
            // falls through
            case 198 /* TaggedTemplateExpression */:
                if (ts.hasInvalidEscape(node.template)) {
                    transformFlags |= 32 /* AssertES2018 */;
                    break;
                }
            // falls through
            case 211 /* TemplateExpression */:
            case 282 /* ShorthandPropertyAssignment */:
            case 120 /* StaticKeyword */:
            case 219 /* MetaProperty */:
                // These nodes are ES6 syntax.
                transformFlags |= 256 /* AssertES2015 */;
                break;
            case 10 /* StringLiteral */:
                if (node.hasExtendedUnicodeEscape) {
                    transformFlags |= 256 /* AssertES2015 */;
                }
                break;
            case 8 /* NumericLiteral */:
                if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) {
                    transformFlags |= 256 /* AssertES2015 */;
                }
                break;
            case 9 /* BigIntLiteral */:
                transformFlags |= 4 /* AssertESNext */;
                break;
            case 232 /* ForOfStatement */:
                // This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
                if (node.awaitModifier) {
                    transformFlags |= 32 /* AssertES2018 */;
                }
                transformFlags |= 256 /* AssertES2015 */;
                break;
            case 212 /* YieldExpression */:
                // This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async
                // generator).
                transformFlags |= 32 /* AssertES2018 */ | 256 /* AssertES2015 */ | 262144 /* ContainsYield */;
                break;
            case 125 /* AnyKeyword */:
            case 140 /* NumberKeyword */:
            case 151 /* BigIntKeyword */:
            case 137 /* NeverKeyword */:
            case 141 /* ObjectKeyword */:
            case 143 /* StringKeyword */:
            case 128 /* BooleanKeyword */:
            case 144 /* SymbolKeyword */:
            case 110 /* VoidKeyword */:
            case 155 /* TypeParameter */:
            case 158 /* PropertySignature */:
            case 160 /* MethodSignature */:
            case 165 /* CallSignature */:
            case 166 /* ConstructSignature */:
            case 167 /* IndexSignature */:
            case 168 /* TypePredicate */:
            case 169 /* TypeReference */:
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
            case 172 /* TypeQuery */:
            case 173 /* TypeLiteral */:
            case 174 /* ArrayType */:
            case 175 /* TupleType */:
            case 176 /* OptionalType */:
            case 177 /* RestType */:
            case 178 /* UnionType */:
            case 179 /* IntersectionType */:
            case 180 /* ConditionalType */:
            case 181 /* InferType */:
            case 182 /* ParenthesizedType */:
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 183 /* ThisType */:
            case 184 /* TypeOperator */:
            case 185 /* IndexedAccessType */:
            case 186 /* MappedType */:
            case 187 /* LiteralType */:
            case 252 /* NamespaceExportDeclaration */:
                // Types and signatures are TypeScript syntax, and exclude all other facts.
                transformFlags = 1 /* AssertTypeScript */;
                excludeFlags = -2 /* TypeExcludes */;
                break;
            case 154 /* ComputedPropertyName */:
                // Even though computed property names are ES6, we don't treat them as such.
                // This is so that they can flow through PropertyName transforms unaffected.
                // Instead, we mark the container as ES6, so that it can properly handle the transform.
                transformFlags |= 32768 /* ContainsComputedPropertyName */;
                break;
            case 213 /* SpreadElement */:
                transformFlags |= 256 /* AssertES2015 */ | 8192 /* ContainsRestOrSpread */;
                break;
            case 283 /* SpreadAssignment */:
                transformFlags |= 32 /* AssertES2018 */ | 16384 /* ContainsObjectRestOrSpread */;
                break;
            case 102 /* SuperKeyword */:
                // This node is ES6 syntax.
                transformFlags |= 256 /* AssertES2015 */;
                excludeFlags = 536870912 /* OuterExpressionExcludes */; // must be set to persist `Super`
                break;
            case 104 /* ThisKeyword */:
                // Mark this node and its ancestors as containing a lexical `this` keyword.
                transformFlags |= 4096 /* ContainsLexicalThis */;
                break;
            case 189 /* ObjectBindingPattern */:
                transformFlags |= 256 /* AssertES2015 */ | 131072 /* ContainsBindingPattern */;
                if (subtreeFlags & 8192 /* ContainsRestOrSpread */) {
                    transformFlags |= 32 /* AssertES2018 */ | 16384 /* ContainsObjectRestOrSpread */;
                }
                excludeFlags = 536879104 /* BindingPatternExcludes */;
                break;
            case 190 /* ArrayBindingPattern */:
                transformFlags |= 256 /* AssertES2015 */ | 131072 /* ContainsBindingPattern */;
                excludeFlags = 536879104 /* BindingPatternExcludes */;
                break;
            case 191 /* BindingElement */:
                transformFlags |= 256 /* AssertES2015 */;
                if (node.dotDotDotToken) {
                    transformFlags |= 8192 /* ContainsRestOrSpread */;
                }
                break;
            case 157 /* Decorator */:
                // This node is TypeScript syntax, and marks its container as also being TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */ | 2048 /* ContainsTypeScriptClassSyntax */;
                break;
            case 193 /* ObjectLiteralExpression */:
                excludeFlags = 536922112 /* ObjectLiteralExcludes */;
                if (subtreeFlags & 32768 /* ContainsComputedPropertyName */) {
                    // If an ObjectLiteralExpression contains a ComputedPropertyName, then it
                    // is an ES6 node.
                    transformFlags |= 256 /* AssertES2015 */;
                }
                if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
                    // If an ObjectLiteralExpression contains a spread element, then it
                    // is an ES2018 node.
                    transformFlags |= 32 /* AssertES2018 */;
                }
                break;
            case 192 /* ArrayLiteralExpression */:
                excludeFlags = 536879104 /* ArrayLiteralOrCallOrNewExcludes */;
                break;
            case 228 /* DoStatement */:
            case 229 /* WhileStatement */:
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
                // A loop containing a block scoped binding *may* need to be transformed from ES6.
                if (subtreeFlags & 65536 /* ContainsBlockScopedBinding */) {
                    transformFlags |= 256 /* AssertES2015 */;
                }
                break;
            case 290 /* SourceFile */:
                break;
            case 262 /* NamespaceExport */:
                transformFlags |= 4 /* AssertESNext */;
                break;
            case 235 /* ReturnStatement */:
                // Return statements may require an `await` in ES2018.
                transformFlags |= 1048576 /* ContainsHoistedDeclarationOrCompletion */ | 32 /* AssertES2018 */;
                break;
            case 233 /* ContinueStatement */:
            case 234 /* BreakStatement */:
                transformFlags |= 1048576 /* ContainsHoistedDeclarationOrCompletion */;
                break;
            case 76 /* PrivateIdentifier */:
                transformFlags |= 4194304 /* ContainsClassFields */;
                break;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~excludeFlags;
    }
    function propagatePropertyNameFlags(node, transformFlags) {
        return transformFlags | (node.transformFlags & 4096 /* PropertyNamePropagatingFlags */);
    }
    /**
     * Gets the transform flags to exclude when unioning the transform flags of a subtree.
     *
     * NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`.
     *       For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
     *       than calling this function.
     */
    function getTransformFlagsSubtreeExclusions(kind) {
        if (kind >= 168 /* FirstTypeNode */ && kind <= 188 /* LastTypeNode */) {
            return -2 /* TypeExcludes */;
        }
        switch (kind) {
            case 196 /* CallExpression */:
            case 197 /* NewExpression */:
            case 192 /* ArrayLiteralExpression */:
                return 536879104 /* ArrayLiteralOrCallOrNewExcludes */;
            case 249 /* ModuleDeclaration */:
                return 537991168 /* ModuleExcludes */;
            case 156 /* Parameter */:
                return 536870912 /* ParameterExcludes */;
            case 202 /* ArrowFunction */:
                return 538920960 /* ArrowFunctionExcludes */;
            case 201 /* FunctionExpression */:
            case 244 /* FunctionDeclaration */:
                return 538925056 /* FunctionExcludes */;
            case 243 /* VariableDeclarationList */:
                return 537018368 /* VariableDeclarationListExcludes */;
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
                return 536905728 /* ClassExcludes */;
            case 162 /* Constructor */:
                return 538923008 /* ConstructorExcludes */;
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
                return 538923008 /* MethodOrAccessorExcludes */;
            case 125 /* AnyKeyword */:
            case 140 /* NumberKeyword */:
            case 151 /* BigIntKeyword */:
            case 137 /* NeverKeyword */:
            case 143 /* StringKeyword */:
            case 141 /* ObjectKeyword */:
            case 128 /* BooleanKeyword */:
            case 144 /* SymbolKeyword */:
            case 110 /* VoidKeyword */:
            case 155 /* TypeParameter */:
            case 158 /* PropertySignature */:
            case 160 /* MethodSignature */:
            case 165 /* CallSignature */:
            case 166 /* ConstructSignature */:
            case 167 /* IndexSignature */:
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
                return -2 /* TypeExcludes */;
            case 193 /* ObjectLiteralExpression */:
                return 536922112 /* ObjectLiteralExcludes */;
            case 280 /* CatchClause */:
                return 536887296 /* CatchClauseExcludes */;
            case 189 /* ObjectBindingPattern */:
            case 190 /* ArrayBindingPattern */:
                return 536879104 /* BindingPatternExcludes */;
            case 199 /* TypeAssertionExpression */:
            case 217 /* AsExpression */:
            case 326 /* PartiallyEmittedExpression */:
            case 200 /* ParenthesizedExpression */:
            case 102 /* SuperKeyword */:
                return 536870912 /* OuterExpressionExcludes */;
            case 194 /* PropertyAccessExpression */:
            case 195 /* ElementAccessExpression */:
                return 536870912 /* PropertyAccessExcludes */;
            default:
                return 536870912 /* NodeExcludes */;
        }
    }
    ts.getTransformFlagsSubtreeExclusions = getTransformFlagsSubtreeExclusions;
    /**
     * "Binds" JSDoc nodes in TypeScript code.
     * Since we will never create symbols for JSDoc, we just set parent pointers instead.
     */
    function setParentPointers(parent, child) {
        child.parent = parent;
        ts.forEachChild(child, function (grandchild) { return setParentPointers(child, grandchild); });
    }
})(ts || (ts = {}));
/** @internal */
var ts;
(function (ts) {
    function createGetSymbolWalker(getRestTypeOfSignature, getTypePredicateOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintOfTypeParameter, getFirstIdentifier, getTypeArguments) {
        return getSymbolWalker;
        function getSymbolWalker(accept) {
            if (accept === void 0) { accept = function () { return true; }; }
            var visitedTypes = []; // Sparse array from id to type
            var visitedSymbols = []; // Sparse array from id to symbol
            return {
                walkType: function (type) {
                    try {
                        visitType(type);
                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
                    }
                    finally {
                        ts.clear(visitedTypes);
                        ts.clear(visitedSymbols);
                    }
                },
                walkSymbol: function (symbol) {
                    try {
                        visitSymbol(symbol);
                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
                    }
                    finally {
                        ts.clear(visitedTypes);
                        ts.clear(visitedSymbols);
                    }
                },
            };
            function visitType(type) {
                if (!type) {
                    return;
                }
                if (visitedTypes[type.id]) {
                    return;
                }
                visitedTypes[type.id] = type;
                // Reuse visitSymbol to visit the type's symbol,
                //  but be sure to bail on recuring into the type if accept declines the symbol.
                var shouldBail = visitSymbol(type.symbol);
                if (shouldBail)
                    return;
                // Visit the type's related types, if any
                if (type.flags & 524288 /* Object */) {
                    var objectType = type;
                    var objectFlags = objectType.objectFlags;
                    if (objectFlags & 4 /* Reference */) {
                        visitTypeReference(type);
                    }
                    if (objectFlags & 32 /* Mapped */) {
                        visitMappedType(type);
                    }
                    if (objectFlags & (1 /* Class */ | 2 /* Interface */)) {
                        visitInterfaceType(type);
                    }
                    if (objectFlags & (8 /* Tuple */ | 16 /* Anonymous */)) {
                        visitObjectType(objectType);
                    }
                }
                if (type.flags & 262144 /* TypeParameter */) {
                    visitTypeParameter(type);
                }
                if (type.flags & 3145728 /* UnionOrIntersection */) {
                    visitUnionOrIntersectionType(type);
                }
                if (type.flags & 4194304 /* Index */) {
                    visitIndexType(type);
                }
                if (type.flags & 8388608 /* IndexedAccess */) {
                    visitIndexedAccessType(type);
                }
            }
            function visitTypeReference(type) {
                visitType(type.target);
                ts.forEach(getTypeArguments(type), visitType);
            }
            function visitTypeParameter(type) {
                visitType(getConstraintOfTypeParameter(type));
            }
            function visitUnionOrIntersectionType(type) {
                ts.forEach(type.types, visitType);
            }
            function visitIndexType(type) {
                visitType(type.type);
            }
            function visitIndexedAccessType(type) {
                visitType(type.objectType);
                visitType(type.indexType);
                visitType(type.constraint);
            }
            function visitMappedType(type) {
                visitType(type.typeParameter);
                visitType(type.constraintType);
                visitType(type.templateType);
                visitType(type.modifiersType);
            }
            function visitSignature(signature) {
                var typePredicate = getTypePredicateOfSignature(signature);
                if (typePredicate) {
                    visitType(typePredicate.type);
                }
                ts.forEach(signature.typeParameters, visitType);
                for (var _i = 0, _a = signature.parameters; _i < _a.length; _i++) {
                    var parameter = _a[_i];
                    visitSymbol(parameter);
                }
                visitType(getRestTypeOfSignature(signature));
                visitType(getReturnTypeOfSignature(signature));
            }
            function visitInterfaceType(interfaceT) {
                visitObjectType(interfaceT);
                ts.forEach(interfaceT.typeParameters, visitType);
                ts.forEach(getBaseTypes(interfaceT), visitType);
                visitType(interfaceT.thisType);
            }
            function visitObjectType(type) {
                var stringIndexType = getIndexTypeOfStructuredType(type, 0 /* String */);
                visitType(stringIndexType);
                var numberIndexType = getIndexTypeOfStructuredType(type, 1 /* Number */);
                visitType(numberIndexType);
                // The two checks above *should* have already resolved the type (if needed), so this should be cached
                var resolved = resolveStructuredTypeMembers(type);
                for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    visitSignature(signature);
                }
                for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) {
                    var signature = _c[_b];
                    visitSignature(signature);
                }
                for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) {
                    var p = _e[_d];
                    visitSymbol(p);
                }
            }
            function visitSymbol(symbol) {
                if (!symbol) {
                    return false;
                }
                var symbolId = ts.getSymbolId(symbol);
                if (visitedSymbols[symbolId]) {
                    return false;
                }
                visitedSymbols[symbolId] = symbol;
                if (!accept(symbol)) {
                    return true;
                }
                var t = getTypeOfSymbol(symbol);
                visitType(t); // Should handle members on classes and such
                if (symbol.exports) {
                    symbol.exports.forEach(visitSymbol);
                }
                ts.forEach(symbol.declarations, function (d) {
                    // Type queries are too far resolved when we just visit the symbol's type
                    //  (their type resolved directly to the member deeply referenced)
                    // So to get the intervening symbols, we need to check if there's a type
                    // query node on any of the symbol's declarations and get symbols there
                    if (d.type && d.type.kind === 172 /* TypeQuery */) {
                        var query = d.type;
                        var entity = getResolvedSymbol(getFirstIdentifier(query.exprName));
                        visitSymbol(entity);
                    }
                });
                return false;
            }
        }
    }
    ts.createGetSymbolWalker = createGetSymbolWalker;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var ambientModuleSymbolRegex = /^".+"$/;
    var anon = "(anonymous)";
    var nextSymbolId = 1;
    var nextNodeId = 1;
    var nextMergeId = 1;
    var nextFlowId = 1;
    var IterationUse;
    (function (IterationUse) {
        IterationUse[IterationUse["AllowsSyncIterablesFlag"] = 1] = "AllowsSyncIterablesFlag";
        IterationUse[IterationUse["AllowsAsyncIterablesFlag"] = 2] = "AllowsAsyncIterablesFlag";
        IterationUse[IterationUse["AllowsStringInputFlag"] = 4] = "AllowsStringInputFlag";
        IterationUse[IterationUse["ForOfFlag"] = 8] = "ForOfFlag";
        IterationUse[IterationUse["YieldStarFlag"] = 16] = "YieldStarFlag";
        IterationUse[IterationUse["SpreadFlag"] = 32] = "SpreadFlag";
        IterationUse[IterationUse["DestructuringFlag"] = 64] = "DestructuringFlag";
        // Spread, Destructuring, Array element assignment
        IterationUse[IterationUse["Element"] = 1] = "Element";
        IterationUse[IterationUse["Spread"] = 33] = "Spread";
        IterationUse[IterationUse["Destructuring"] = 65] = "Destructuring";
        IterationUse[IterationUse["ForOf"] = 13] = "ForOf";
        IterationUse[IterationUse["ForAwaitOf"] = 15] = "ForAwaitOf";
        IterationUse[IterationUse["YieldStar"] = 17] = "YieldStar";
        IterationUse[IterationUse["AsyncYieldStar"] = 19] = "AsyncYieldStar";
        IterationUse[IterationUse["GeneratorReturnType"] = 1] = "GeneratorReturnType";
        IterationUse[IterationUse["AsyncGeneratorReturnType"] = 2] = "AsyncGeneratorReturnType";
    })(IterationUse || (IterationUse = {}));
    var IterationTypeKind;
    (function (IterationTypeKind) {
        IterationTypeKind[IterationTypeKind["Yield"] = 0] = "Yield";
        IterationTypeKind[IterationTypeKind["Return"] = 1] = "Return";
        IterationTypeKind[IterationTypeKind["Next"] = 2] = "Next";
    })(IterationTypeKind || (IterationTypeKind = {}));
    var WideningKind;
    (function (WideningKind) {
        WideningKind[WideningKind["Normal"] = 0] = "Normal";
        WideningKind[WideningKind["FunctionReturn"] = 1] = "FunctionReturn";
        WideningKind[WideningKind["GeneratorNext"] = 2] = "GeneratorNext";
        WideningKind[WideningKind["GeneratorYield"] = 3] = "GeneratorYield";
    })(WideningKind || (WideningKind = {}));
    var TypeFacts;
    (function (TypeFacts) {
        TypeFacts[TypeFacts["None"] = 0] = "None";
        TypeFacts[TypeFacts["TypeofEQString"] = 1] = "TypeofEQString";
        TypeFacts[TypeFacts["TypeofEQNumber"] = 2] = "TypeofEQNumber";
        TypeFacts[TypeFacts["TypeofEQBigInt"] = 4] = "TypeofEQBigInt";
        TypeFacts[TypeFacts["TypeofEQBoolean"] = 8] = "TypeofEQBoolean";
        TypeFacts[TypeFacts["TypeofEQSymbol"] = 16] = "TypeofEQSymbol";
        TypeFacts[TypeFacts["TypeofEQObject"] = 32] = "TypeofEQObject";
        TypeFacts[TypeFacts["TypeofEQFunction"] = 64] = "TypeofEQFunction";
        TypeFacts[TypeFacts["TypeofEQHostObject"] = 128] = "TypeofEQHostObject";
        TypeFacts[TypeFacts["TypeofNEString"] = 256] = "TypeofNEString";
        TypeFacts[TypeFacts["TypeofNENumber"] = 512] = "TypeofNENumber";
        TypeFacts[TypeFacts["TypeofNEBigInt"] = 1024] = "TypeofNEBigInt";
        TypeFacts[TypeFacts["TypeofNEBoolean"] = 2048] = "TypeofNEBoolean";
        TypeFacts[TypeFacts["TypeofNESymbol"] = 4096] = "TypeofNESymbol";
        TypeFacts[TypeFacts["TypeofNEObject"] = 8192] = "TypeofNEObject";
        TypeFacts[TypeFacts["TypeofNEFunction"] = 16384] = "TypeofNEFunction";
        TypeFacts[TypeFacts["TypeofNEHostObject"] = 32768] = "TypeofNEHostObject";
        TypeFacts[TypeFacts["EQUndefined"] = 65536] = "EQUndefined";
        TypeFacts[TypeFacts["EQNull"] = 131072] = "EQNull";
        TypeFacts[TypeFacts["EQUndefinedOrNull"] = 262144] = "EQUndefinedOrNull";
        TypeFacts[TypeFacts["NEUndefined"] = 524288] = "NEUndefined";
        TypeFacts[TypeFacts["NENull"] = 1048576] = "NENull";
        TypeFacts[TypeFacts["NEUndefinedOrNull"] = 2097152] = "NEUndefinedOrNull";
        TypeFacts[TypeFacts["Truthy"] = 4194304] = "Truthy";
        TypeFacts[TypeFacts["Falsy"] = 8388608] = "Falsy";
        TypeFacts[TypeFacts["All"] = 16777215] = "All";
        // The following members encode facts about particular kinds of types for use in the getTypeFacts function.
        // The presence of a particular fact means that the given test is true for some (and possibly all) values
        // of that kind of type.
        TypeFacts[TypeFacts["BaseStringStrictFacts"] = 3735041] = "BaseStringStrictFacts";
        TypeFacts[TypeFacts["BaseStringFacts"] = 12582401] = "BaseStringFacts";
        TypeFacts[TypeFacts["StringStrictFacts"] = 16317953] = "StringStrictFacts";
        TypeFacts[TypeFacts["StringFacts"] = 16776705] = "StringFacts";
        TypeFacts[TypeFacts["EmptyStringStrictFacts"] = 12123649] = "EmptyStringStrictFacts";
        TypeFacts[TypeFacts["EmptyStringFacts"] = 12582401] = "EmptyStringFacts";
        TypeFacts[TypeFacts["NonEmptyStringStrictFacts"] = 7929345] = "NonEmptyStringStrictFacts";
        TypeFacts[TypeFacts["NonEmptyStringFacts"] = 16776705] = "NonEmptyStringFacts";
        TypeFacts[TypeFacts["BaseNumberStrictFacts"] = 3734786] = "BaseNumberStrictFacts";
        TypeFacts[TypeFacts["BaseNumberFacts"] = 12582146] = "BaseNumberFacts";
        TypeFacts[TypeFacts["NumberStrictFacts"] = 16317698] = "NumberStrictFacts";
        TypeFacts[TypeFacts["NumberFacts"] = 16776450] = "NumberFacts";
        TypeFacts[TypeFacts["ZeroNumberStrictFacts"] = 12123394] = "ZeroNumberStrictFacts";
        TypeFacts[TypeFacts["ZeroNumberFacts"] = 12582146] = "ZeroNumberFacts";
        TypeFacts[TypeFacts["NonZeroNumberStrictFacts"] = 7929090] = "NonZeroNumberStrictFacts";
        TypeFacts[TypeFacts["NonZeroNumberFacts"] = 16776450] = "NonZeroNumberFacts";
        TypeFacts[TypeFacts["BaseBigIntStrictFacts"] = 3734276] = "BaseBigIntStrictFacts";
        TypeFacts[TypeFacts["BaseBigIntFacts"] = 12581636] = "BaseBigIntFacts";
        TypeFacts[TypeFacts["BigIntStrictFacts"] = 16317188] = "BigIntStrictFacts";
        TypeFacts[TypeFacts["BigIntFacts"] = 16775940] = "BigIntFacts";
        TypeFacts[TypeFacts["ZeroBigIntStrictFacts"] = 12122884] = "ZeroBigIntStrictFacts";
        TypeFacts[TypeFacts["ZeroBigIntFacts"] = 12581636] = "ZeroBigIntFacts";
        TypeFacts[TypeFacts["NonZeroBigIntStrictFacts"] = 7928580] = "NonZeroBigIntStrictFacts";
        TypeFacts[TypeFacts["NonZeroBigIntFacts"] = 16775940] = "NonZeroBigIntFacts";
        TypeFacts[TypeFacts["BaseBooleanStrictFacts"] = 3733256] = "BaseBooleanStrictFacts";
        TypeFacts[TypeFacts["BaseBooleanFacts"] = 12580616] = "BaseBooleanFacts";
        TypeFacts[TypeFacts["BooleanStrictFacts"] = 16316168] = "BooleanStrictFacts";
        TypeFacts[TypeFacts["BooleanFacts"] = 16774920] = "BooleanFacts";
        TypeFacts[TypeFacts["FalseStrictFacts"] = 12121864] = "FalseStrictFacts";
        TypeFacts[TypeFacts["FalseFacts"] = 12580616] = "FalseFacts";
        TypeFacts[TypeFacts["TrueStrictFacts"] = 7927560] = "TrueStrictFacts";
        TypeFacts[TypeFacts["TrueFacts"] = 16774920] = "TrueFacts";
        TypeFacts[TypeFacts["SymbolStrictFacts"] = 7925520] = "SymbolStrictFacts";
        TypeFacts[TypeFacts["SymbolFacts"] = 16772880] = "SymbolFacts";
        TypeFacts[TypeFacts["ObjectStrictFacts"] = 7888800] = "ObjectStrictFacts";
        TypeFacts[TypeFacts["ObjectFacts"] = 16736160] = "ObjectFacts";
        TypeFacts[TypeFacts["FunctionStrictFacts"] = 7880640] = "FunctionStrictFacts";
        TypeFacts[TypeFacts["FunctionFacts"] = 16728000] = "FunctionFacts";
        TypeFacts[TypeFacts["UndefinedFacts"] = 9830144] = "UndefinedFacts";
        TypeFacts[TypeFacts["NullFacts"] = 9363232] = "NullFacts";
        TypeFacts[TypeFacts["EmptyObjectStrictFacts"] = 16318463] = "EmptyObjectStrictFacts";
        TypeFacts[TypeFacts["EmptyObjectFacts"] = 16777215] = "EmptyObjectFacts";
    })(TypeFacts || (TypeFacts = {}));
    var typeofEQFacts = ts.createMapFromTemplate({
        string: 1 /* TypeofEQString */,
        number: 2 /* TypeofEQNumber */,
        bigint: 4 /* TypeofEQBigInt */,
        boolean: 8 /* TypeofEQBoolean */,
        symbol: 16 /* TypeofEQSymbol */,
        undefined: 65536 /* EQUndefined */,
        object: 32 /* TypeofEQObject */,
        function: 64 /* TypeofEQFunction */
    });
    var typeofNEFacts = ts.createMapFromTemplate({
        string: 256 /* TypeofNEString */,
        number: 512 /* TypeofNENumber */,
        bigint: 1024 /* TypeofNEBigInt */,
        boolean: 2048 /* TypeofNEBoolean */,
        symbol: 4096 /* TypeofNESymbol */,
        undefined: 524288 /* NEUndefined */,
        object: 8192 /* TypeofNEObject */,
        function: 16384 /* TypeofNEFunction */
    });
    var TypeSystemPropertyName;
    (function (TypeSystemPropertyName) {
        TypeSystemPropertyName[TypeSystemPropertyName["Type"] = 0] = "Type";
        TypeSystemPropertyName[TypeSystemPropertyName["ResolvedBaseConstructorType"] = 1] = "ResolvedBaseConstructorType";
        TypeSystemPropertyName[TypeSystemPropertyName["DeclaredType"] = 2] = "DeclaredType";
        TypeSystemPropertyName[TypeSystemPropertyName["ResolvedReturnType"] = 3] = "ResolvedReturnType";
        TypeSystemPropertyName[TypeSystemPropertyName["ImmediateBaseConstraint"] = 4] = "ImmediateBaseConstraint";
        TypeSystemPropertyName[TypeSystemPropertyName["EnumTagType"] = 5] = "EnumTagType";
        TypeSystemPropertyName[TypeSystemPropertyName["ResolvedTypeArguments"] = 6] = "ResolvedTypeArguments";
    })(TypeSystemPropertyName || (TypeSystemPropertyName = {}));
    var CheckMode;
    (function (CheckMode) {
        CheckMode[CheckMode["Normal"] = 0] = "Normal";
        CheckMode[CheckMode["Contextual"] = 1] = "Contextual";
        CheckMode[CheckMode["Inferential"] = 2] = "Inferential";
        CheckMode[CheckMode["SkipContextSensitive"] = 4] = "SkipContextSensitive";
        CheckMode[CheckMode["SkipGenericFunctions"] = 8] = "SkipGenericFunctions";
        CheckMode[CheckMode["IsForSignatureHelp"] = 16] = "IsForSignatureHelp";
    })(CheckMode || (CheckMode = {}));
    var AccessFlags;
    (function (AccessFlags) {
        AccessFlags[AccessFlags["None"] = 0] = "None";
        AccessFlags[AccessFlags["NoIndexSignatures"] = 1] = "NoIndexSignatures";
        AccessFlags[AccessFlags["Writing"] = 2] = "Writing";
        AccessFlags[AccessFlags["CacheSymbol"] = 4] = "CacheSymbol";
        AccessFlags[AccessFlags["NoTupleBoundsCheck"] = 8] = "NoTupleBoundsCheck";
    })(AccessFlags || (AccessFlags = {}));
    var SignatureCheckMode;
    (function (SignatureCheckMode) {
        SignatureCheckMode[SignatureCheckMode["BivariantCallback"] = 1] = "BivariantCallback";
        SignatureCheckMode[SignatureCheckMode["StrictCallback"] = 2] = "StrictCallback";
        SignatureCheckMode[SignatureCheckMode["IgnoreReturnTypes"] = 4] = "IgnoreReturnTypes";
        SignatureCheckMode[SignatureCheckMode["StrictArity"] = 8] = "StrictArity";
        SignatureCheckMode[SignatureCheckMode["Callback"] = 3] = "Callback";
    })(SignatureCheckMode || (SignatureCheckMode = {}));
    var IntersectionState;
    (function (IntersectionState) {
        IntersectionState[IntersectionState["None"] = 0] = "None";
        IntersectionState[IntersectionState["Source"] = 1] = "Source";
        IntersectionState[IntersectionState["Target"] = 2] = "Target";
        IntersectionState[IntersectionState["PropertyCheck"] = 4] = "PropertyCheck";
        IntersectionState[IntersectionState["InPropertyCheck"] = 8] = "InPropertyCheck";
    })(IntersectionState || (IntersectionState = {}));
    var MappedTypeModifiers;
    (function (MappedTypeModifiers) {
        MappedTypeModifiers[MappedTypeModifiers["IncludeReadonly"] = 1] = "IncludeReadonly";
        MappedTypeModifiers[MappedTypeModifiers["ExcludeReadonly"] = 2] = "ExcludeReadonly";
        MappedTypeModifiers[MappedTypeModifiers["IncludeOptional"] = 4] = "IncludeOptional";
        MappedTypeModifiers[MappedTypeModifiers["ExcludeOptional"] = 8] = "ExcludeOptional";
    })(MappedTypeModifiers || (MappedTypeModifiers = {}));
    var ExpandingFlags;
    (function (ExpandingFlags) {
        ExpandingFlags[ExpandingFlags["None"] = 0] = "None";
        ExpandingFlags[ExpandingFlags["Source"] = 1] = "Source";
        ExpandingFlags[ExpandingFlags["Target"] = 2] = "Target";
        ExpandingFlags[ExpandingFlags["Both"] = 3] = "Both";
    })(ExpandingFlags || (ExpandingFlags = {}));
    var MembersOrExportsResolutionKind;
    (function (MembersOrExportsResolutionKind) {
        MembersOrExportsResolutionKind["resolvedExports"] = "resolvedExports";
        MembersOrExportsResolutionKind["resolvedMembers"] = "resolvedMembers";
    })(MembersOrExportsResolutionKind || (MembersOrExportsResolutionKind = {}));
    var UnusedKind;
    (function (UnusedKind) {
        UnusedKind[UnusedKind["Local"] = 0] = "Local";
        UnusedKind[UnusedKind["Parameter"] = 1] = "Parameter";
    })(UnusedKind || (UnusedKind = {}));
    var isNotOverloadAndNotAccessor = ts.and(isNotOverload, isNotAccessor);
    var DeclarationMeaning;
    (function (DeclarationMeaning) {
        DeclarationMeaning[DeclarationMeaning["GetAccessor"] = 1] = "GetAccessor";
        DeclarationMeaning[DeclarationMeaning["SetAccessor"] = 2] = "SetAccessor";
        DeclarationMeaning[DeclarationMeaning["PropertyAssignment"] = 4] = "PropertyAssignment";
        DeclarationMeaning[DeclarationMeaning["Method"] = 8] = "Method";
        DeclarationMeaning[DeclarationMeaning["GetOrSetAccessor"] = 3] = "GetOrSetAccessor";
        DeclarationMeaning[DeclarationMeaning["PropertyAssignmentOrMethod"] = 12] = "PropertyAssignmentOrMethod";
    })(DeclarationMeaning || (DeclarationMeaning = {}));
    var DeclarationSpaces;
    (function (DeclarationSpaces) {
        DeclarationSpaces[DeclarationSpaces["None"] = 0] = "None";
        DeclarationSpaces[DeclarationSpaces["ExportValue"] = 1] = "ExportValue";
        DeclarationSpaces[DeclarationSpaces["ExportType"] = 2] = "ExportType";
        DeclarationSpaces[DeclarationSpaces["ExportNamespace"] = 4] = "ExportNamespace";
    })(DeclarationSpaces || (DeclarationSpaces = {}));
    function SymbolLinks() {
    }
    function NodeLinks() {
        this.flags = 0;
    }
    function getNodeId(node) {
        if (!node.id) {
            node.id = nextNodeId;
            nextNodeId++;
        }
        return node.id;
    }
    ts.getNodeId = getNodeId;
    function getSymbolId(symbol) {
        if (!symbol.id) {
            symbol.id = nextSymbolId;
            nextSymbolId++;
        }
        return symbol.id;
    }
    ts.getSymbolId = getSymbolId;
    function isInstantiatedModule(node, preserveConstEnums) {
        var moduleState = ts.getModuleInstanceState(node);
        return moduleState === 1 /* Instantiated */ ||
            (preserveConstEnums && moduleState === 2 /* ConstEnumOnly */);
    }
    ts.isInstantiatedModule = isInstantiatedModule;
    function createTypeChecker(host, produceDiagnostics) {
        var getPackagesSet = ts.memoize(function () {
            var set = ts.createMap();
            host.getSourceFiles().forEach(function (sf) {
                if (!sf.resolvedModules)
                    return;
                ts.forEachEntry(sf.resolvedModules, function (r) {
                    if (r && r.packageId)
                        set.set(r.packageId.name, true);
                });
            });
            return set;
        });
        // Cancellation that controls whether or not we can cancel in the middle of type checking.
        // In general cancelling is *not* safe for the type checker.  We might be in the middle of
        // computing something, and we will leave our internals in an inconsistent state.  Callers
        // who set the cancellation token should catch if a cancellation exception occurs, and
        // should throw away and create a new TypeChecker.
        //
        // Currently we only support setting the cancellation token when getting diagnostics.  This
        // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
        // they no longer need the information (for example, if the user started editing again).
        var cancellationToken;
        var requestedExternalEmitHelpers;
        var externalHelpersModule;
        var Symbol = ts.objectAllocator.getSymbolConstructor();
        var Type = ts.objectAllocator.getTypeConstructor();
        var Signature = ts.objectAllocator.getSignatureConstructor();
        var typeCount = 0;
        var symbolCount = 0;
        var enumCount = 0;
        var totalInstantiationCount = 0;
        var instantiationCount = 0;
        var instantiationDepth = 0;
        var constraintDepth = 0;
        var currentNode;
        var emptySymbols = ts.createSymbolTable();
        var arrayVariances = [1 /* Covariant */];
        var compilerOptions = host.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var allowSyntheticDefaultImports = ts.getAllowSyntheticDefaultImports(compilerOptions);
        var strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks");
        var strictFunctionTypes = ts.getStrictOptionValue(compilerOptions, "strictFunctionTypes");
        var strictBindCallApply = ts.getStrictOptionValue(compilerOptions, "strictBindCallApply");
        var strictPropertyInitialization = ts.getStrictOptionValue(compilerOptions, "strictPropertyInitialization");
        var noImplicitAny = ts.getStrictOptionValue(compilerOptions, "noImplicitAny");
        var noImplicitThis = ts.getStrictOptionValue(compilerOptions, "noImplicitThis");
        var keyofStringsOnly = !!compilerOptions.keyofStringsOnly;
        var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 32768 /* FreshLiteral */;
        var emitResolver = createResolver();
        var nodeBuilder = createNodeBuilder();
        var globals = ts.createSymbolTable();
        var undefinedSymbol = createSymbol(4 /* Property */, "undefined");
        undefinedSymbol.declarations = [];
        var globalThisSymbol = createSymbol(1536 /* Module */, "globalThis", 8 /* Readonly */);
        globalThisSymbol.exports = globals;
        globalThisSymbol.declarations = [];
        globals.set(globalThisSymbol.escapedName, globalThisSymbol);
        var argumentsSymbol = createSymbol(4 /* Property */, "arguments");
        var requireSymbol = createSymbol(4 /* Property */, "require");
        /** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
        var apparentArgumentCount;
        // for public members that accept a Node or one of its subtypes, we must guard against
        // synthetic nodes created during transformations by calling `getParseTreeNode`.
        // for most of these, we perform the guard only on `checker` to avoid any possible
        // extra cost of calling `getParseTreeNode` when calling these functions from inside the
        // checker.
        var checker = {
            getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); },
            getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); },
            getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; },
            getTypeCount: function () { return typeCount; },
            getInstantiationCount: function () { return totalInstantiationCount; },
            getRelationCacheSizes: function () { return ({
                assignable: assignableRelation.size,
                identity: identityRelation.size,
                subtype: subtypeRelation.size,
                strictSubtype: strictSubtypeRelation.size,
            }); },
            isUndefinedSymbol: function (symbol) { return symbol === undefinedSymbol; },
            isArgumentsSymbol: function (symbol) { return symbol === argumentsSymbol; },
            isUnknownSymbol: function (symbol) { return symbol === unknownSymbol; },
            getMergedSymbol: getMergedSymbol,
            getDiagnostics: getDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getTypeOfSymbolAtLocation: function (symbol, location) {
                location = ts.getParseTreeNode(location);
                return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType;
            },
            getSymbolsOfParameterPropertyDeclaration: function (parameterIn, parameterName) {
                var parameter = ts.getParseTreeNode(parameterIn, ts.isParameter);
                if (parameter === undefined)
                    return ts.Debug.fail("Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node.");
                return getSymbolsOfParameterPropertyDeclaration(parameter, ts.escapeLeadingUnderscores(parameterName));
            },
            getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
            getPropertiesOfType: getPropertiesOfType,
            getPropertyOfType: function (type, name) { return getPropertyOfType(type, ts.escapeLeadingUnderscores(name)); },
            getPrivateIdentifierPropertyOfType: function (leftType, name, location) {
                var node = ts.getParseTreeNode(location);
                if (!node) {
                    return undefined;
                }
                var propName = ts.escapeLeadingUnderscores(name);
                var lexicallyScopedIdentifier = lookupSymbolForPrivateIdentifierDeclaration(propName, node);
                return lexicallyScopedIdentifier ? getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedIdentifier) : undefined;
            },
            getTypeOfPropertyOfType: function (type, name) { return getTypeOfPropertyOfType(type, ts.escapeLeadingUnderscores(name)); },
            getIndexInfoOfType: getIndexInfoOfType,
            getSignaturesOfType: getSignaturesOfType,
            getIndexTypeOfType: getIndexTypeOfType,
            getBaseTypes: getBaseTypes,
            getBaseTypeOfLiteralType: getBaseTypeOfLiteralType,
            getWidenedType: getWidenedType,
            getTypeFromTypeNode: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isTypeNode);
                return node ? getTypeFromTypeNode(node) : errorType;
            },
            getParameterType: getTypeAtPosition,
            getPromisedTypeOfPromise: getPromisedTypeOfPromise,
            getReturnTypeOfSignature: getReturnTypeOfSignature,
            isNullableType: isNullableType,
            getNullableType: getNullableType,
            getNonNullableType: getNonNullableType,
            getNonOptionalType: removeOptionalTypeMarker,
            getTypeArguments: getTypeArguments,
            typeToTypeNode: nodeBuilder.typeToTypeNode,
            indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration,
            signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration,
            symbolToEntityName: nodeBuilder.symbolToEntityName,
            symbolToExpression: nodeBuilder.symbolToExpression,
            symbolToTypeParameterDeclarations: nodeBuilder.symbolToTypeParameterDeclarations,
            symbolToParameterDeclaration: nodeBuilder.symbolToParameterDeclaration,
            typeParameterToDeclaration: nodeBuilder.typeParameterToDeclaration,
            getSymbolsInScope: function (location, meaning) {
                location = ts.getParseTreeNode(location);
                return location ? getSymbolsInScope(location, meaning) : [];
            },
            getSymbolAtLocation: function (node) {
                node = ts.getParseTreeNode(node);
                // set ignoreErrors: true because any lookups invoked by the API shouldn't cause any new errors
                return node ? getSymbolAtLocation(node, /*ignoreErrors*/ true) : undefined;
            },
            getShorthandAssignmentValueSymbol: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getShorthandAssignmentValueSymbol(node) : undefined;
            },
            getExportSpecifierLocalTargetSymbol: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isExportSpecifier);
                return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
            },
            getExportSymbolOfSymbol: function (symbol) {
                return getMergedSymbol(symbol.exportSymbol || symbol);
            },
            getTypeAtLocation: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getTypeOfNode(node) : errorType;
            },
            getTypeOfAssignmentPattern: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isAssignmentPattern);
                return node && getTypeOfAssignmentPattern(node) || errorType;
            },
            getPropertySymbolOfDestructuringAssignment: function (locationIn) {
                var location = ts.getParseTreeNode(locationIn, ts.isIdentifier);
                return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
            },
            signatureToString: function (signature, enclosingDeclaration, flags, kind) {
                return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind);
            },
            typeToString: function (type, enclosingDeclaration, flags) {
                return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags);
            },
            symbolToString: function (symbol, enclosingDeclaration, meaning, flags) {
                return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning, flags);
            },
            typePredicateToString: function (predicate, enclosingDeclaration, flags) {
                return typePredicateToString(predicate, ts.getParseTreeNode(enclosingDeclaration), flags);
            },
            writeSignature: function (signature, enclosingDeclaration, flags, kind, writer) {
                return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind, writer);
            },
            writeType: function (type, enclosingDeclaration, flags, writer) {
                return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags, writer);
            },
            writeSymbol: function (symbol, enclosingDeclaration, meaning, flags, writer) {
                return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning, flags, writer);
            },
            writeTypePredicate: function (predicate, enclosingDeclaration, flags, writer) {
                return typePredicateToString(predicate, ts.getParseTreeNode(enclosingDeclaration), flags, writer);
            },
            getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
            getRootSymbols: getRootSymbols,
            getContextualType: function (nodeIn, contextFlags) {
                var node = ts.getParseTreeNode(nodeIn, ts.isExpression);
                if (!node) {
                    return undefined;
                }
                var containingCall = ts.findAncestor(node, ts.isCallLikeExpression);
                var containingCallResolvedSignature = containingCall && getNodeLinks(containingCall).resolvedSignature;
                if (contextFlags & 4 /* Completions */ && containingCall) {
                    var toMarkSkip = node;
                    do {
                        getNodeLinks(toMarkSkip).skipDirectInference = true;
                        toMarkSkip = toMarkSkip.parent;
                    } while (toMarkSkip && toMarkSkip !== containingCall);
                    getNodeLinks(containingCall).resolvedSignature = undefined;
                }
                var result = getContextualType(node, contextFlags);
                if (contextFlags & 4 /* Completions */ && containingCall) {
                    var toMarkSkip = node;
                    do {
                        getNodeLinks(toMarkSkip).skipDirectInference = undefined;
                        toMarkSkip = toMarkSkip.parent;
                    } while (toMarkSkip && toMarkSkip !== containingCall);
                    getNodeLinks(containingCall).resolvedSignature = containingCallResolvedSignature;
                }
                return result;
            },
            getContextualTypeForObjectLiteralElement: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isObjectLiteralElementLike);
                return node ? getContextualTypeForObjectLiteralElement(node) : undefined;
            },
            getContextualTypeForArgumentAtIndex: function (nodeIn, argIndex) {
                var node = ts.getParseTreeNode(nodeIn, ts.isCallLikeExpression);
                return node && getContextualTypeForArgumentAtIndex(node, argIndex);
            },
            getContextualTypeForJsxAttribute: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isJsxAttributeLike);
                return node && getContextualTypeForJsxAttribute(node);
            },
            isContextSensitive: isContextSensitive,
            getFullyQualifiedName: getFullyQualifiedName,
            getResolvedSignature: function (node, candidatesOutArray, argumentCount) {
                return getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, 0 /* Normal */);
            },
            getResolvedSignatureForSignatureHelp: function (node, candidatesOutArray, argumentCount) {
                return getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, 16 /* IsForSignatureHelp */);
            },
            getExpandedParameters: getExpandedParameters,
            hasEffectiveRestParameter: hasEffectiveRestParameter,
            getConstantValue: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, canHaveConstantValue);
                return node ? getConstantValue(node) : undefined;
            },
            isValidPropertyAccess: function (nodeIn, propertyName) {
                var node = ts.getParseTreeNode(nodeIn, ts.isPropertyAccessOrQualifiedNameOrImportTypeNode);
                return !!node && isValidPropertyAccess(node, ts.escapeLeadingUnderscores(propertyName));
            },
            isValidPropertyAccessForCompletions: function (nodeIn, type, property) {
                var node = ts.getParseTreeNode(nodeIn, ts.isPropertyAccessExpression);
                return !!node && isValidPropertyAccessForCompletions(node, type, property);
            },
            getSignatureFromDeclaration: function (declarationIn) {
                var declaration = ts.getParseTreeNode(declarationIn, ts.isFunctionLike);
                return declaration ? getSignatureFromDeclaration(declaration) : undefined;
            },
            isImplementationOfOverload: function (node) {
                var parsed = ts.getParseTreeNode(node, ts.isFunctionLike);
                return parsed ? isImplementationOfOverload(parsed) : undefined;
            },
            getImmediateAliasedSymbol: getImmediateAliasedSymbol,
            getAliasedSymbol: resolveAlias,
            getEmitResolver: getEmitResolver,
            getExportsOfModule: getExportsOfModuleAsArray,
            getExportsAndPropertiesOfModule: getExportsAndPropertiesOfModule,
            getSymbolWalker: ts.createGetSymbolWalker(getRestTypeOfSignature, getTypePredicateOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintOfTypeParameter, ts.getFirstIdentifier, getTypeArguments),
            getAmbientModules: getAmbientModules,
            getJsxIntrinsicTagNamesAt: getJsxIntrinsicTagNamesAt,
            isOptionalParameter: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isParameter);
                return node ? isOptionalParameter(node) : false;
            },
            tryGetMemberInModuleExports: function (name, symbol) { return tryGetMemberInModuleExports(ts.escapeLeadingUnderscores(name), symbol); },
            tryGetMemberInModuleExportsAndProperties: function (name, symbol) { return tryGetMemberInModuleExportsAndProperties(ts.escapeLeadingUnderscores(name), symbol); },
            tryFindAmbientModuleWithoutAugmentations: function (moduleName) {
                // we deliberately exclude augmentations
                // since we are only interested in declarations of the module itself
                return tryFindAmbientModule(moduleName, /*withAugmentations*/ false);
            },
            getApparentType: getApparentType,
            getUnionType: getUnionType,
            isTypeAssignableTo: isTypeAssignableTo,
            createAnonymousType: createAnonymousType,
            createSignature: createSignature,
            createSymbol: createSymbol,
            createIndexInfo: createIndexInfo,
            getAnyType: function () { return anyType; },
            getStringType: function () { return stringType; },
            getNumberType: function () { return numberType; },
            createPromiseType: createPromiseType,
            createArrayType: createArrayType,
            getElementTypeOfArrayType: getElementTypeOfArrayType,
            getBooleanType: function () { return booleanType; },
            getFalseType: function (fresh) { return fresh ? falseType : regularFalseType; },
            getTrueType: function (fresh) { return fresh ? trueType : regularTrueType; },
            getVoidType: function () { return voidType; },
            getUndefinedType: function () { return undefinedType; },
            getNullType: function () { return nullType; },
            getESSymbolType: function () { return esSymbolType; },
            getNeverType: function () { return neverType; },
            getOptionalType: function () { return optionalType; },
            isSymbolAccessible: isSymbolAccessible,
            isArrayType: isArrayType,
            isTupleType: isTupleType,
            isArrayLikeType: isArrayLikeType,
            isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant,
            getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes,
            getSuggestedSymbolForNonexistentProperty: getSuggestedSymbolForNonexistentProperty,
            getSuggestionForNonexistentProperty: getSuggestionForNonexistentProperty,
            getSuggestedSymbolForNonexistentSymbol: function (location, name, meaning) { return getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); },
            getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); },
            getSuggestedSymbolForNonexistentModule: getSuggestedSymbolForNonexistentModule,
            getSuggestionForNonexistentExport: getSuggestionForNonexistentExport,
            getBaseConstraintOfType: getBaseConstraintOfType,
            getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; },
            resolveName: function (name, location, meaning, excludeGlobals) {
                return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals);
            },
            getJsxNamespace: function (n) { return ts.unescapeLeadingUnderscores(getJsxNamespace(n)); },
            getAccessibleSymbolChain: getAccessibleSymbolChain,
            getTypePredicateOfSignature: getTypePredicateOfSignature,
            resolveExternalModuleName: function (moduleSpecifier) {
                return resolveExternalModuleName(moduleSpecifier, moduleSpecifier, /*ignoreErrors*/ true);
            },
            resolveExternalModuleSymbol: resolveExternalModuleSymbol,
            tryGetThisTypeAt: function (node, includeGlobalThis) {
                node = ts.getParseTreeNode(node);
                return node && tryGetThisTypeAt(node, includeGlobalThis);
            },
            getTypeArgumentConstraint: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isTypeNode);
                return node && getTypeArgumentConstraint(node);
            },
            getSuggestionDiagnostics: function (file, ct) {
                if (ts.skipTypeChecking(file, compilerOptions, host)) {
                    return ts.emptyArray;
                }
                var diagnostics;
                try {
                    // Record the cancellation token so it can be checked later on during checkSourceElement.
                    // Do this in a finally block so we can ensure that it gets reset back to nothing after
                    // this call is done.
                    cancellationToken = ct;
                    // Ensure file is type checked
                    checkSourceFile(file);
                    ts.Debug.assert(!!(getNodeLinks(file).flags & 1 /* TypeChecked */));
                    diagnostics = ts.addRange(diagnostics, suggestionDiagnostics.getDiagnostics(file.fileName));
                    checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), function (containingNode, kind, diag) {
                        if (!ts.containsParseError(containingNode) && !unusedIsError(kind, !!(containingNode.flags & 8388608 /* Ambient */))) {
                            (diagnostics || (diagnostics = [])).push(__assign(__assign({}, diag), { category: ts.DiagnosticCategory.Suggestion }));
                        }
                    });
                    return diagnostics || ts.emptyArray;
                }
                finally {
                    cancellationToken = undefined;
                }
            },
            runWithCancellationToken: function (token, callback) {
                try {
                    cancellationToken = token;
                    return callback(checker);
                }
                finally {
                    cancellationToken = undefined;
                }
            },
            getLocalTypeParametersOfClassOrInterfaceOrTypeAlias: getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
            isDeclarationVisible: isDeclarationVisible,
        };
        function getResolvedSignatureWorker(nodeIn, candidatesOutArray, argumentCount, checkMode) {
            var node = ts.getParseTreeNode(nodeIn, ts.isCallLikeExpression);
            apparentArgumentCount = argumentCount;
            var res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
            apparentArgumentCount = undefined;
            return res;
        }
        var tupleTypes = ts.createMap();
        var unionTypes = ts.createMap();
        var intersectionTypes = ts.createMap();
        var literalTypes = ts.createMap();
        var indexedAccessTypes = ts.createMap();
        var substitutionTypes = ts.createMap();
        var evolvingArrayTypes = [];
        var undefinedProperties = ts.createMap();
        var unknownSymbol = createSymbol(4 /* Property */, "unknown");
        var resolvingSymbol = createSymbol(0, "__resolving__" /* Resolving */);
        var anyType = createIntrinsicType(1 /* Any */, "any");
        var autoType = createIntrinsicType(1 /* Any */, "any");
        var wildcardType = createIntrinsicType(1 /* Any */, "any");
        var errorType = createIntrinsicType(1 /* Any */, "error");
        var nonInferrableAnyType = createIntrinsicType(1 /* Any */, "any", 524288 /* ContainsWideningType */);
        var unknownType = createIntrinsicType(2 /* Unknown */, "unknown");
        var undefinedType = createIntrinsicType(32768 /* Undefined */, "undefined");
        var undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(32768 /* Undefined */, "undefined", 524288 /* ContainsWideningType */);
        var optionalType = createIntrinsicType(32768 /* Undefined */, "undefined");
        var nullType = createIntrinsicType(65536 /* Null */, "null");
        var nullWideningType = strictNullChecks ? nullType : createIntrinsicType(65536 /* Null */, "null", 524288 /* ContainsWideningType */);
        var stringType = createIntrinsicType(4 /* String */, "string");
        var numberType = createIntrinsicType(8 /* Number */, "number");
        var bigintType = createIntrinsicType(64 /* BigInt */, "bigint");
        var falseType = createIntrinsicType(512 /* BooleanLiteral */, "false");
        var regularFalseType = createIntrinsicType(512 /* BooleanLiteral */, "false");
        var trueType = createIntrinsicType(512 /* BooleanLiteral */, "true");
        var regularTrueType = createIntrinsicType(512 /* BooleanLiteral */, "true");
        trueType.regularType = regularTrueType;
        trueType.freshType = trueType;
        regularTrueType.regularType = regularTrueType;
        regularTrueType.freshType = trueType;
        falseType.regularType = regularFalseType;
        falseType.freshType = falseType;
        regularFalseType.regularType = regularFalseType;
        regularFalseType.freshType = falseType;
        var booleanType = createBooleanType([regularFalseType, regularTrueType]);
        // Also mark all combinations of fresh/regular booleans as "Boolean" so they print as `boolean` instead of `true | false`
        // (The union is cached, so simply doing the marking here is sufficient)
        createBooleanType([regularFalseType, trueType]);
        createBooleanType([falseType, regularTrueType]);
        createBooleanType([falseType, trueType]);
        var esSymbolType = createIntrinsicType(4096 /* ESSymbol */, "symbol");
        var voidType = createIntrinsicType(16384 /* Void */, "void");
        var neverType = createIntrinsicType(131072 /* Never */, "never");
        var silentNeverType = createIntrinsicType(131072 /* Never */, "never");
        var nonInferrableType = createIntrinsicType(131072 /* Never */, "never", 2097152 /* NonInferrableType */);
        var implicitNeverType = createIntrinsicType(131072 /* Never */, "never");
        var unreachableNeverType = createIntrinsicType(131072 /* Never */, "never");
        var nonPrimitiveType = createIntrinsicType(67108864 /* NonPrimitive */, "object");
        var stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
        var keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
        var numberOrBigIntType = getUnionType([numberType, bigintType]);
        var restrictiveMapper = makeFunctionTypeMapper(function (t) { return t.flags & 262144 /* TypeParameter */ ? getRestrictiveTypeParameter(t) : t; });
        var permissiveMapper = makeFunctionTypeMapper(function (t) { return t.flags & 262144 /* TypeParameter */ ? wildcardType : t; });
        var emptyObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var emptyJsxObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        emptyJsxObjectType.objectFlags |= 4096 /* JsxAttributes */;
        var emptyTypeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
        emptyTypeLiteralSymbol.members = ts.createSymbolTable();
        var emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var emptyGenericType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        emptyGenericType.instantiations = ts.createMap();
        var anyFunctionType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated
        // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes.
        anyFunctionType.objectFlags |= 2097152 /* NonInferrableType */;
        var noConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var circularConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var resolvingDefaultType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var markerSuperType = createTypeParameter();
        var markerSubType = createTypeParameter();
        markerSubType.constraint = markerSuperType;
        var markerOtherType = createTypeParameter();
        var noTypePredicate = createTypePredicate(1 /* Identifier */, "<<unresolved>>", 0, anyType);
        var anySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
        var unknownSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
        var resolvingSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
        var silentNeverSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
        var enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
        var iterationTypesCache = ts.createMap(); // cache for common IterationTypes instances
        var noIterationTypes = {
            get yieldType() { return ts.Debug.fail("Not supported"); },
            get returnType() { return ts.Debug.fail("Not supported"); },
            get nextType() { return ts.Debug.fail("Not supported"); },
        };
        var anyIterationTypes = createIterationTypes(anyType, anyType, anyType);
        var anyIterationTypesExceptNext = createIterationTypes(anyType, anyType, unknownType);
        var defaultIterationTypes = createIterationTypes(neverType, anyType, undefinedType); // default iteration types for `Iterator`.
        var asyncIterationTypesResolver = {
            iterableCacheKey: "iterationTypesOfAsyncIterable",
            iteratorCacheKey: "iterationTypesOfAsyncIterator",
            iteratorSymbolName: "asyncIterator",
            getGlobalIteratorType: getGlobalAsyncIteratorType,
            getGlobalIterableType: getGlobalAsyncIterableType,
            getGlobalIterableIteratorType: getGlobalAsyncIterableIteratorType,
            getGlobalGeneratorType: getGlobalAsyncGeneratorType,
            resolveIterationType: getAwaitedType,
            mustHaveANextMethodDiagnostic: ts.Diagnostics.An_async_iterator_must_have_a_next_method,
            mustBeAMethodDiagnostic: ts.Diagnostics.The_0_property_of_an_async_iterator_must_be_a_method,
            mustHaveAValueDiagnostic: ts.Diagnostics.The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property,
        };
        var syncIterationTypesResolver = {
            iterableCacheKey: "iterationTypesOfIterable",
            iteratorCacheKey: "iterationTypesOfIterator",
            iteratorSymbolName: "iterator",
            getGlobalIteratorType: getGlobalIteratorType,
            getGlobalIterableType: getGlobalIterableType,
            getGlobalIterableIteratorType: getGlobalIterableIteratorType,
            getGlobalGeneratorType: getGlobalGeneratorType,
            resolveIterationType: function (type, _errorNode) { return type; },
            mustHaveANextMethodDiagnostic: ts.Diagnostics.An_iterator_must_have_a_next_method,
            mustBeAMethodDiagnostic: ts.Diagnostics.The_0_property_of_an_iterator_must_be_a_method,
            mustHaveAValueDiagnostic: ts.Diagnostics.The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property,
        };
        /** Key is "/path/to/a.ts|/path/to/b.ts". */
        var amalgamatedDuplicates;
        var reverseMappedCache = ts.createMap();
        var ambientModulesCache;
        /**
         * List of every ambient module with a "*" wildcard.
         * Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches.
         * This is only used if there is no exact match.
         */
        var patternAmbientModules;
        var patternAmbientModuleAugmentations;
        var globalObjectType;
        var globalFunctionType;
        var globalCallableFunctionType;
        var globalNewableFunctionType;
        var globalArrayType;
        var globalReadonlyArrayType;
        var globalStringType;
        var globalNumberType;
        var globalBooleanType;
        var globalRegExpType;
        var globalThisType;
        var anyArrayType;
        var autoArrayType;
        var anyReadonlyArrayType;
        var deferredGlobalNonNullableTypeAlias;
        // The library files are only loaded when the feature is used.
        // This allows users to just specify library files they want to used through --lib
        // and they will not get an error from not having unrelated library files
        var deferredGlobalESSymbolConstructorSymbol;
        var deferredGlobalESSymbolType;
        var deferredGlobalTypedPropertyDescriptorType;
        var deferredGlobalPromiseType;
        var deferredGlobalPromiseLikeType;
        var deferredGlobalPromiseConstructorSymbol;
        var deferredGlobalPromiseConstructorLikeType;
        var deferredGlobalIterableType;
        var deferredGlobalIteratorType;
        var deferredGlobalIterableIteratorType;
        var deferredGlobalGeneratorType;
        var deferredGlobalIteratorYieldResultType;
        var deferredGlobalIteratorReturnResultType;
        var deferredGlobalAsyncIterableType;
        var deferredGlobalAsyncIteratorType;
        var deferredGlobalAsyncIterableIteratorType;
        var deferredGlobalAsyncGeneratorType;
        var deferredGlobalTemplateStringsArrayType;
        var deferredGlobalImportMetaType;
        var deferredGlobalExtractSymbol;
        var deferredGlobalOmitSymbol;
        var deferredGlobalBigIntType;
        var allPotentiallyUnusedIdentifiers = ts.createMap(); // key is file name
        var flowLoopStart = 0;
        var flowLoopCount = 0;
        var sharedFlowCount = 0;
        var flowAnalysisDisabled = false;
        var flowInvocationCount = 0;
        var lastFlowNode;
        var lastFlowNodeReachable;
        var flowTypeCache;
        var emptyStringType = getLiteralType("");
        var zeroType = getLiteralType(0);
        var zeroBigIntType = getLiteralType({ negative: false, base10Value: "0" });
        var resolutionTargets = [];
        var resolutionResults = [];
        var resolutionPropertyNames = [];
        var suggestionCount = 0;
        var maximumSuggestionCount = 10;
        var mergedSymbols = [];
        var symbolLinks = [];
        var nodeLinks = [];
        var flowLoopCaches = [];
        var flowLoopNodes = [];
        var flowLoopKeys = [];
        var flowLoopTypes = [];
        var sharedFlowNodes = [];
        var sharedFlowTypes = [];
        var flowNodeReachable = [];
        var potentialThisCollisions = [];
        var potentialNewTargetCollisions = [];
        var potentialWeakMapCollisions = [];
        var awaitedTypeStack = [];
        var diagnostics = ts.createDiagnosticCollection();
        var suggestionDiagnostics = ts.createDiagnosticCollection();
        var typeofTypesByName = ts.createMapFromTemplate({
            string: stringType,
            number: numberType,
            bigint: bigintType,
            boolean: booleanType,
            symbol: esSymbolType,
            undefined: undefinedType
        });
        var typeofType = createTypeofType();
        var _jsxNamespace;
        var _jsxFactoryEntity;
        var outofbandVarianceMarkerHandler;
        var subtypeRelation = ts.createMap();
        var strictSubtypeRelation = ts.createMap();
        var assignableRelation = ts.createMap();
        var comparableRelation = ts.createMap();
        var identityRelation = ts.createMap();
        var enumRelation = ts.createMap();
        var builtinGlobals = ts.createSymbolTable();
        builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
        initializeTypeChecker();
        return checker;
        function getJsxNamespace(location) {
            if (location) {
                var file = ts.getSourceFileOfNode(location);
                if (file) {
                    if (file.localJsxNamespace) {
                        return file.localJsxNamespace;
                    }
                    var jsxPragma = file.pragmas.get("jsx");
                    if (jsxPragma) {
                        var chosenpragma = ts.isArray(jsxPragma) ? jsxPragma[0] : jsxPragma;
                        file.localJsxFactory = ts.parseIsolatedEntityName(chosenpragma.arguments.factory, languageVersion);
                        ts.visitNode(file.localJsxFactory, markAsSynthetic);
                        if (file.localJsxFactory) {
                            return file.localJsxNamespace = ts.getFirstIdentifier(file.localJsxFactory).escapedText;
                        }
                    }
                }
            }
            if (!_jsxNamespace) {
                _jsxNamespace = "React";
                if (compilerOptions.jsxFactory) {
                    _jsxFactoryEntity = ts.parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
                    ts.visitNode(_jsxFactoryEntity, markAsSynthetic);
                    if (_jsxFactoryEntity) {
                        _jsxNamespace = ts.getFirstIdentifier(_jsxFactoryEntity).escapedText;
                    }
                }
                else if (compilerOptions.reactNamespace) {
                    _jsxNamespace = ts.escapeLeadingUnderscores(compilerOptions.reactNamespace);
                }
            }
            if (!_jsxFactoryEntity) {
                _jsxFactoryEntity = ts.createQualifiedName(ts.createIdentifier(ts.unescapeLeadingUnderscores(_jsxNamespace)), "createElement");
            }
            return _jsxNamespace;
            function markAsSynthetic(node) {
                node.pos = -1;
                node.end = -1;
                return ts.visitEachChild(node, markAsSynthetic, ts.nullTransformationContext);
            }
        }
        function getEmitResolver(sourceFile, cancellationToken) {
            // Ensure we have all the type information in place for this file so that all the
            // emitter questions of this resolver will return the right information.
            getDiagnostics(sourceFile, cancellationToken);
            return emitResolver;
        }
        function lookupOrIssueError(location, message, arg0, arg1, arg2, arg3) {
            var diagnostic = location
                ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3)
                : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3);
            var existing = diagnostics.lookup(diagnostic);
            if (existing) {
                return existing;
            }
            else {
                diagnostics.add(diagnostic);
                return diagnostic;
            }
        }
        function error(location, message, arg0, arg1, arg2, arg3) {
            var diagnostic = location
                ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3)
                : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3);
            diagnostics.add(diagnostic);
            return diagnostic;
        }
        function addErrorOrSuggestion(isError, diagnostic) {
            if (isError) {
                diagnostics.add(diagnostic);
            }
            else {
                suggestionDiagnostics.add(__assign(__assign({}, diagnostic), { category: ts.DiagnosticCategory.Suggestion }));
            }
        }
        function errorOrSuggestion(isError, location, message, arg0, arg1, arg2, arg3) {
            addErrorOrSuggestion(isError, "message" in message ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : ts.createDiagnosticForNodeFromMessageChain(location, message)); // eslint-disable-line no-in-operator
        }
        function errorAndMaybeSuggestAwait(location, maybeMissingAwait, message, arg0, arg1, arg2, arg3) {
            var diagnostic = error(location, message, arg0, arg1, arg2, arg3);
            if (maybeMissingAwait) {
                var related = ts.createDiagnosticForNode(location, ts.Diagnostics.Did_you_forget_to_use_await);
                ts.addRelatedInfo(diagnostic, related);
            }
            return diagnostic;
        }
        function createSymbol(flags, name, checkFlags) {
            symbolCount++;
            var symbol = (new Symbol(flags | 33554432 /* Transient */, name));
            symbol.checkFlags = checkFlags || 0;
            return symbol;
        }
        function getExcludedSymbolFlags(flags) {
            var result = 0;
            if (flags & 2 /* BlockScopedVariable */)
                result |= 111551 /* BlockScopedVariableExcludes */;
            if (flags & 1 /* FunctionScopedVariable */)
                result |= 111550 /* FunctionScopedVariableExcludes */;
            if (flags & 4 /* Property */)
                result |= 0 /* PropertyExcludes */;
            if (flags & 8 /* EnumMember */)
                result |= 900095 /* EnumMemberExcludes */;
            if (flags & 16 /* Function */)
                result |= 110991 /* FunctionExcludes */;
            if (flags & 32 /* Class */)
                result |= 899503 /* ClassExcludes */;
            if (flags & 64 /* Interface */)
                result |= 788872 /* InterfaceExcludes */;
            if (flags & 256 /* RegularEnum */)
                result |= 899327 /* RegularEnumExcludes */;
            if (flags & 128 /* ConstEnum */)
                result |= 899967 /* ConstEnumExcludes */;
            if (flags & 512 /* ValueModule */)
                result |= 110735 /* ValueModuleExcludes */;
            if (flags & 8192 /* Method */)
                result |= 103359 /* MethodExcludes */;
            if (flags & 32768 /* GetAccessor */)
                result |= 46015 /* GetAccessorExcludes */;
            if (flags & 65536 /* SetAccessor */)
                result |= 78783 /* SetAccessorExcludes */;
            if (flags & 262144 /* TypeParameter */)
                result |= 526824 /* TypeParameterExcludes */;
            if (flags & 524288 /* TypeAlias */)
                result |= 788968 /* TypeAliasExcludes */;
            if (flags & 2097152 /* Alias */)
                result |= 2097152 /* AliasExcludes */;
            return result;
        }
        function recordMergedSymbol(target, source) {
            if (!source.mergeId) {
                source.mergeId = nextMergeId;
                nextMergeId++;
            }
            mergedSymbols[source.mergeId] = target;
        }
        function cloneSymbol(symbol) {
            var result = createSymbol(symbol.flags, symbol.escapedName);
            result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
            result.parent = symbol.parent;
            if (symbol.valueDeclaration)
                result.valueDeclaration = symbol.valueDeclaration;
            if (symbol.constEnumOnlyModule)
                result.constEnumOnlyModule = true;
            if (symbol.members)
                result.members = ts.cloneMap(symbol.members);
            if (symbol.exports)
                result.exports = ts.cloneMap(symbol.exports);
            recordMergedSymbol(result, symbol);
            return result;
        }
        /**
         * Note: if target is transient, then it is mutable, and mergeSymbol with both mutate and return it.
         * If target is not transient, mergeSymbol will produce a transient clone, mutate that and return it.
         */
        function mergeSymbol(target, source, unidirectional) {
            if (unidirectional === void 0) { unidirectional = false; }
            if (!(target.flags & getExcludedSymbolFlags(source.flags)) ||
                (source.flags | target.flags) & 67108864 /* Assignment */) {
                if (source === target) {
                    // This can happen when an export assigned namespace exports something also erroneously exported at the top level
                    // See `declarationFileNoCrashOnExtraExportModifier` for an example
                    return target;
                }
                if (!(target.flags & 33554432 /* Transient */)) {
                    var resolvedTarget = resolveSymbol(target);
                    if (resolvedTarget === unknownSymbol) {
                        return source;
                    }
                    target = cloneSymbol(resolvedTarget);
                }
                // Javascript static-property-assignment declarations always merge, even though they are also values
                if (source.flags & 512 /* ValueModule */ && target.flags & 512 /* ValueModule */ && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
                    // reset flag when merging instantiated module into value module that has only const enums
                    target.constEnumOnlyModule = false;
                }
                target.flags |= source.flags;
                if (source.valueDeclaration) {
                    ts.setValueDeclaration(target, source.valueDeclaration);
                }
                ts.addRange(target.declarations, source.declarations);
                if (source.members) {
                    if (!target.members)
                        target.members = ts.createSymbolTable();
                    mergeSymbolTable(target.members, source.members, unidirectional);
                }
                if (source.exports) {
                    if (!target.exports)
                        target.exports = ts.createSymbolTable();
                    mergeSymbolTable(target.exports, source.exports, unidirectional);
                }
                if (!unidirectional) {
                    recordMergedSymbol(target, source);
                }
            }
            else if (target.flags & 1024 /* NamespaceModule */) {
                // Do not report an error when merging `var globalThis` with the built-in `globalThis`,
                // as we will already report a "Declaration name conflicts..." error, and this error
                // won't make much sense.
                if (target !== globalThisSymbol) {
                    error(ts.getNameOfDeclaration(source.declarations[0]), ts.Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
                }
            }
            else { // error
                var isEitherEnum = !!(target.flags & 384 /* Enum */ || source.flags & 384 /* Enum */);
                var isEitherBlockScoped_1 = !!(target.flags & 2 /* BlockScopedVariable */ || source.flags & 2 /* BlockScopedVariable */);
                var message = isEitherEnum
                    ? ts.Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations
                    : isEitherBlockScoped_1
                        ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
                        : ts.Diagnostics.Duplicate_identifier_0;
                var sourceSymbolFile = source.declarations && ts.getSourceFileOfNode(source.declarations[0]);
                var targetSymbolFile = target.declarations && ts.getSourceFileOfNode(target.declarations[0]);
                var symbolName_1 = symbolToString(source);
                // Collect top-level duplicate identifier errors into one mapping, so we can then merge their diagnostics if there are a bunch
                if (sourceSymbolFile && targetSymbolFile && amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile !== targetSymbolFile) {
                    var firstFile_1 = ts.comparePaths(sourceSymbolFile.path, targetSymbolFile.path) === -1 /* LessThan */ ? sourceSymbolFile : targetSymbolFile;
                    var secondFile_1 = firstFile_1 === sourceSymbolFile ? targetSymbolFile : sourceSymbolFile;
                    var filesDuplicates = ts.getOrUpdate(amalgamatedDuplicates, firstFile_1.path + "|" + secondFile_1.path, function () {
                        return ({ firstFile: firstFile_1, secondFile: secondFile_1, conflictingSymbols: ts.createMap() });
                    });
                    var conflictingSymbolInfo = ts.getOrUpdate(filesDuplicates.conflictingSymbols, symbolName_1, function () {
                        return ({ isBlockScoped: isEitherBlockScoped_1, firstFileLocations: [], secondFileLocations: [] });
                    });
                    addDuplicateLocations(conflictingSymbolInfo.firstFileLocations, source);
                    addDuplicateLocations(conflictingSymbolInfo.secondFileLocations, target);
                }
                else {
                    addDuplicateDeclarationErrorsForSymbols(source, message, symbolName_1, target);
                    addDuplicateDeclarationErrorsForSymbols(target, message, symbolName_1, source);
                }
            }
            return target;
            function addDuplicateLocations(locs, symbol) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    ts.pushIfUnique(locs, decl);
                }
            }
        }
        function addDuplicateDeclarationErrorsForSymbols(target, message, symbolName, source) {
            ts.forEach(target.declarations, function (node) {
                addDuplicateDeclarationError(node, message, symbolName, source.declarations);
            });
        }
        function addDuplicateDeclarationError(node, message, symbolName, relatedNodes) {
            var errorNode = (ts.getExpandoInitializer(node, /*isPrototypeAssignment*/ false) ? ts.getNameOfExpando(node) : ts.getNameOfDeclaration(node)) || node;
            var err = lookupOrIssueError(errorNode, message, symbolName);
            var _loop_6 = function (relatedNode) {
                var adjustedNode = (ts.getExpandoInitializer(relatedNode, /*isPrototypeAssignment*/ false) ? ts.getNameOfExpando(relatedNode) : ts.getNameOfDeclaration(relatedNode)) || relatedNode;
                if (adjustedNode === errorNode)
                    return "continue";
                err.relatedInformation = err.relatedInformation || [];
                var leadingMessage = ts.createDiagnosticForNode(adjustedNode, ts.Diagnostics._0_was_also_declared_here, symbolName);
                var followOnMessage = ts.createDiagnosticForNode(adjustedNode, ts.Diagnostics.and_here);
                if (ts.length(err.relatedInformation) >= 5 || ts.some(err.relatedInformation, function (r) { return ts.compareDiagnostics(r, followOnMessage) === 0 /* EqualTo */ || ts.compareDiagnostics(r, leadingMessage) === 0 /* EqualTo */; }))
                    return "continue";
                ts.addRelatedInfo(err, !ts.length(err.relatedInformation) ? leadingMessage : followOnMessage);
            };
            for (var _i = 0, _a = relatedNodes || ts.emptyArray; _i < _a.length; _i++) {
                var relatedNode = _a[_i];
                _loop_6(relatedNode);
            }
        }
        function combineSymbolTables(first, second) {
            if (!ts.hasEntries(first))
                return second;
            if (!ts.hasEntries(second))
                return first;
            var combined = ts.createSymbolTable();
            mergeSymbolTable(combined, first);
            mergeSymbolTable(combined, second);
            return combined;
        }
        function mergeSymbolTable(target, source, unidirectional) {
            if (unidirectional === void 0) { unidirectional = false; }
            source.forEach(function (sourceSymbol, id) {
                var targetSymbol = target.get(id);
                target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol);
            });
        }
        function mergeModuleAugmentation(moduleName) {
            var _a, _b;
            var moduleAugmentation = moduleName.parent;
            if (moduleAugmentation.symbol.declarations[0] !== moduleAugmentation) {
                // this is a combined symbol for multiple augmentations within the same file.
                // its symbol already has accumulated information for all declarations
                // so we need to add it just once - do the work only for first declaration
                ts.Debug.assert(moduleAugmentation.symbol.declarations.length > 1);
                return;
            }
            if (ts.isGlobalScopeAugmentation(moduleAugmentation)) {
                mergeSymbolTable(globals, moduleAugmentation.symbol.exports);
            }
            else {
                // find a module that about to be augmented
                // do not validate names of augmentations that are defined in ambient context
                var moduleNotFoundError = !(moduleName.parent.parent.flags & 8388608 /* Ambient */)
                    ? ts.Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found
                    : undefined;
                var mainModule_1 = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true);
                if (!mainModule_1) {
                    return;
                }
                // obtain item referenced by 'export='
                mainModule_1 = resolveExternalModuleSymbol(mainModule_1);
                if (mainModule_1.flags & 1920 /* Namespace */) {
                    // If we're merging an augmentation to a pattern ambient module, we want to
                    // perform the merge unidirectionally from the augmentation ('a.foo') to
                    // the pattern ('*.foo'), so that 'getMergedSymbol()' on a.foo gives you
                    // all the exports both from the pattern and from the augmentation, but
                    // 'getMergedSymbol()' on *.foo only gives you exports from *.foo.
                    if (ts.some(patternAmbientModules, function (module) { return mainModule_1 === module.symbol; })) {
                        var merged = mergeSymbol(moduleAugmentation.symbol, mainModule_1, /*unidirectional*/ true);
                        if (!patternAmbientModuleAugmentations) {
                            patternAmbientModuleAugmentations = ts.createMap();
                        }
                        // moduleName will be a StringLiteral since this is not `declare global`.
                        patternAmbientModuleAugmentations.set(moduleName.text, merged);
                    }
                    else {
                        if (((_a = mainModule_1.exports) === null || _a === void 0 ? void 0 : _a.get("__export" /* ExportStar */)) && ((_b = moduleAugmentation.symbol.exports) === null || _b === void 0 ? void 0 : _b.size)) {
                            // We may need to merge the module augmentation's exports into the target symbols of the resolved exports
                            var resolvedExports = getResolvedMembersOrExportsOfSymbol(mainModule_1, "resolvedExports" /* resolvedExports */);
                            for (var _i = 0, _c = ts.arrayFrom(moduleAugmentation.symbol.exports.entries()); _i < _c.length; _i++) {
                                var _d = _c[_i], key = _d[0], value = _d[1];
                                if (resolvedExports.has(key) && !mainModule_1.exports.has(key)) {
                                    mergeSymbol(resolvedExports.get(key), value);
                                }
                            }
                        }
                        mergeSymbol(mainModule_1, moduleAugmentation.symbol);
                    }
                }
                else {
                    // moduleName will be a StringLiteral since this is not `declare global`.
                    error(moduleName, ts.Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
                }
            }
        }
        function addToSymbolTable(target, source, message) {
            source.forEach(function (sourceSymbol, id) {
                var targetSymbol = target.get(id);
                if (targetSymbol) {
                    // Error on redeclarations
                    ts.forEach(targetSymbol.declarations, addDeclarationDiagnostic(ts.unescapeLeadingUnderscores(id), message));
                }
                else {
                    target.set(id, sourceSymbol);
                }
            });
            function addDeclarationDiagnostic(id, message) {
                return function (declaration) { return diagnostics.add(ts.createDiagnosticForNode(declaration, message, id)); };
            }
        }
        function getSymbolLinks(symbol) {
            if (symbol.flags & 33554432 /* Transient */)
                return symbol;
            var id = getSymbolId(symbol);
            return symbolLinks[id] || (symbolLinks[id] = new SymbolLinks());
        }
        function getNodeLinks(node) {
            var nodeId = getNodeId(node);
            return nodeLinks[nodeId] || (nodeLinks[nodeId] = new NodeLinks());
        }
        function isGlobalSourceFile(node) {
            return node.kind === 290 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node);
        }
        function getSymbol(symbols, name, meaning) {
            if (meaning) {
                var symbol = getMergedSymbol(symbols.get(name));
                if (symbol) {
                    ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
                    if (symbol.flags & meaning) {
                        return symbol;
                    }
                    if (symbol.flags & 2097152 /* Alias */) {
                        var target = resolveAlias(symbol);
                        // Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors
                        if (target === unknownSymbol || target.flags & meaning) {
                            return symbol;
                        }
                    }
                }
            }
            // return undefined if we can't find a symbol.
        }
        /**
         * Get symbols that represent parameter-property-declaration as parameter and as property declaration
         * @param parameter a parameterDeclaration node
         * @param parameterName a name of the parameter to get the symbols for.
         * @return a tuple of two symbols
         */
        function getSymbolsOfParameterPropertyDeclaration(parameter, parameterName) {
            var constructorDeclaration = parameter.parent;
            var classDeclaration = parameter.parent.parent;
            var parameterSymbol = getSymbol(constructorDeclaration.locals, parameterName, 111551 /* Value */);
            var propertySymbol = getSymbol(getMembersOfSymbol(classDeclaration.symbol), parameterName, 111551 /* Value */);
            if (parameterSymbol && propertySymbol) {
                return [parameterSymbol, propertySymbol];
            }
            return ts.Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration");
        }
        function isBlockScopedNameDeclaredBeforeUse(declaration, usage) {
            var declarationFile = ts.getSourceFileOfNode(declaration);
            var useFile = ts.getSourceFileOfNode(usage);
            var declContainer = ts.getEnclosingBlockScopeContainer(declaration);
            if (declarationFile !== useFile) {
                if ((moduleKind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
                    (!compilerOptions.outFile && !compilerOptions.out) ||
                    isInTypeQuery(usage) ||
                    declaration.flags & 8388608 /* Ambient */) {
                    // nodes are in different files and order cannot be determined
                    return true;
                }
                // declaration is after usage
                // can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
                if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
                    return true;
                }
                var sourceFiles = host.getSourceFiles();
                return sourceFiles.indexOf(declarationFile) <= sourceFiles.indexOf(useFile);
            }
            if (declaration.pos <= usage.pos) {
                // declaration is before usage
                if (declaration.kind === 191 /* BindingElement */) {
                    // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2])
                    var errorBindingElement = ts.getAncestor(usage, 191 /* BindingElement */);
                    if (errorBindingElement) {
                        return ts.findAncestor(errorBindingElement, ts.isBindingElement) !== ts.findAncestor(declaration, ts.isBindingElement) ||
                            declaration.pos < errorBindingElement.pos;
                    }
                    // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a)
                    return isBlockScopedNameDeclaredBeforeUse(ts.getAncestor(declaration, 242 /* VariableDeclaration */), usage);
                }
                else if (declaration.kind === 242 /* VariableDeclaration */) {
                    // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
                    return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage);
                }
                else if (ts.isClassDeclaration(declaration)) {
                    // still might be illegal if the usage is within a computed property name in the class (eg class A { static p = "a"; [A.p]() {} })
                    return !ts.findAncestor(usage, function (n) { return ts.isComputedPropertyName(n) && n.parent.parent === declaration; });
                }
                else if (ts.isPropertyDeclaration(declaration)) {
                    // still might be illegal if a self-referencing property initializer (eg private x = this.x)
                    return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ false);
                }
                else if (ts.isParameterPropertyDeclaration(declaration, declaration.parent)) {
                    // foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property
                    return !(compilerOptions.target === 99 /* ESNext */ && !!compilerOptions.useDefineForClassFields
                        && ts.getContainingClass(declaration) === ts.getContainingClass(usage)
                        && isUsedInFunctionOrInstanceProperty(usage, declaration));
                }
                return true;
            }
            // declaration is after usage, but it can still be legal if usage is deferred:
            // 1. inside an export specifier
            // 2. inside a function
            // 3. inside an instance property initializer, a reference to a non-instance property
            //    (except when target: "esnext" and useDefineForClassFields: true and the reference is to a parameter property)
            // 4. inside a static property initializer, a reference to a static method in the same class
            // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ)
            // or if usage is in a type context:
            // 1. inside a type query (typeof in type position)
            // 2. inside a jsdoc comment
            if (usage.parent.kind === 263 /* ExportSpecifier */ || (usage.parent.kind === 259 /* ExportAssignment */ && usage.parent.isExportEquals)) {
                // export specifiers do not use the variable, they only make it available for use
                return true;
            }
            // When resolving symbols for exports, the `usage` location passed in can be the export site directly
            if (usage.kind === 259 /* ExportAssignment */ && usage.isExportEquals) {
                return true;
            }
            if (!!(usage.flags & 4194304 /* JSDoc */) || isInTypeQuery(usage) || usageInTypeDeclaration()) {
                return true;
            }
            if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
                if (compilerOptions.target === 99 /* ESNext */ && !!compilerOptions.useDefineForClassFields
                    && ts.getContainingClass(declaration)
                    && (ts.isPropertyDeclaration(declaration) || ts.isParameterPropertyDeclaration(declaration, declaration.parent))) {
                    return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true);
                }
                else {
                    return true;
                }
            }
            return false;
            function usageInTypeDeclaration() {
                return !!ts.findAncestor(usage, function (node) { return ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node); });
            }
            function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) {
                switch (declaration.parent.parent.kind) {
                    case 225 /* VariableStatement */:
                    case 230 /* ForStatement */:
                    case 232 /* ForOfStatement */:
                        // variable statement/for/for-of statement case,
                        // use site should not be inside variable declaration (initializer of declaration or binding element)
                        if (isSameScopeDescendentOf(usage, declaration, declContainer)) {
                            return true;
                        }
                        break;
                }
                // ForIn/ForOf case - use site should not be used in expression part
                var grandparent = declaration.parent.parent;
                return ts.isForInOrOfStatement(grandparent) && isSameScopeDescendentOf(usage, grandparent.expression, declContainer);
            }
            function isUsedInFunctionOrInstanceProperty(usage, declaration) {
                return !!ts.findAncestor(usage, function (current) {
                    if (current === declContainer) {
                        return "quit";
                    }
                    if (ts.isFunctionLike(current)) {
                        return true;
                    }
                    var initializerOfProperty = current.parent &&
                        current.parent.kind === 159 /* PropertyDeclaration */ &&
                        current.parent.initializer === current;
                    if (initializerOfProperty) {
                        if (ts.hasModifier(current.parent, 32 /* Static */)) {
                            if (declaration.kind === 161 /* MethodDeclaration */) {
                                return true;
                            }
                        }
                        else {
                            var isDeclarationInstanceProperty = declaration.kind === 159 /* PropertyDeclaration */ && !ts.hasModifier(declaration, 32 /* Static */);
                            if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) {
                                return true;
                            }
                        }
                    }
                    return false;
                });
            }
            /** stopAtAnyPropertyDeclaration is used for detecting ES-standard class field use-before-def errors */
            function isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, stopAtAnyPropertyDeclaration) {
                // always legal if usage is after declaration
                if (usage.end > declaration.end) {
                    return false;
                }
                // still might be legal if usage is deferred (e.g. x: any = () => this.x)
                // otherwise illegal if immediately referenced within the declaration (e.g. x: any = this.x)
                var ancestorChangingReferenceScope = ts.findAncestor(usage, function (node) {
                    if (node === declaration) {
                        return "quit";
                    }
                    switch (node.kind) {
                        case 202 /* ArrowFunction */:
                            return true;
                        case 159 /* PropertyDeclaration */:
                            // even when stopping at any property declaration, they need to come from the same class
                            return stopAtAnyPropertyDeclaration &&
                                (ts.isPropertyDeclaration(declaration) && node.parent === declaration.parent
                                    || ts.isParameterPropertyDeclaration(declaration, declaration.parent) && node.parent === declaration.parent.parent)
                                ? "quit" : true;
                        case 223 /* Block */:
                            switch (node.parent.kind) {
                                case 163 /* GetAccessor */:
                                case 161 /* MethodDeclaration */:
                                case 164 /* SetAccessor */:
                                    return true;
                                default:
                                    return false;
                            }
                        default:
                            return false;
                    }
                });
                return ancestorChangingReferenceScope === undefined;
            }
        }
        function useOuterVariableScopeInParameter(result, location, lastLocation) {
            var target = ts.getEmitScriptTarget(compilerOptions);
            var functionLocation = location;
            if (ts.isParameter(lastLocation) && functionLocation.body && result.valueDeclaration.pos >= functionLocation.body.pos && result.valueDeclaration.end <= functionLocation.body.end) {
                // check for several cases where we introduce temporaries that require moving the name/initializer of the parameter to the body
                // - static field in a class expression
                // - optional chaining pre-es2020
                // - nullish coalesce pre-es2020
                // - spread assignment in binding pattern pre-es2017
                if (target >= 2 /* ES2015 */) {
                    var links = getNodeLinks(functionLocation);
                    if (links.declarationRequiresScopeChange === undefined) {
                        links.declarationRequiresScopeChange = ts.forEach(functionLocation.parameters, requiresScopeChange) || false;
                    }
                    return !links.declarationRequiresScopeChange;
                }
            }
            return false;
            function requiresScopeChange(node) {
                return requiresScopeChangeWorker(node.name)
                    || !!node.initializer && requiresScopeChangeWorker(node.initializer);
            }
            function requiresScopeChangeWorker(node) {
                switch (node.kind) {
                    case 202 /* ArrowFunction */:
                    case 201 /* FunctionExpression */:
                    case 244 /* FunctionDeclaration */:
                    case 162 /* Constructor */:
                        // do not descend into these
                        return false;
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 281 /* PropertyAssignment */:
                        return requiresScopeChangeWorker(node.name);
                    case 159 /* PropertyDeclaration */:
                        // static properties in classes introduce temporary variables
                        if (ts.hasStaticModifier(node)) {
                            return target < 99 /* ESNext */ || !compilerOptions.useDefineForClassFields;
                        }
                        return requiresScopeChangeWorker(node.name);
                    default:
                        // null coalesce and optional chain pre-es2020 produce temporary variables
                        if (ts.isNullishCoalesce(node) || ts.isOptionalChain(node)) {
                            return target < 7 /* ES2020 */;
                        }
                        if (ts.isBindingElement(node) && node.dotDotDotToken && ts.isObjectBindingPattern(node.parent)) {
                            return target < 4 /* ES2017 */;
                        }
                        if (ts.isTypeNode(node))
                            return false;
                        return ts.forEachChild(node, requiresScopeChangeWorker) || false;
                }
            }
        }
        /**
         * Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
         * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with
         * the given name can be found.
         *
         * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters.
         */
        function resolveName(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, suggestedNameNotFoundMessage) {
            if (excludeGlobals === void 0) { excludeGlobals = false; }
            return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol, suggestedNameNotFoundMessage);
        }
        function resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, lookup, suggestedNameNotFoundMessage) {
            var originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location
            var result;
            var lastLocation;
            var lastSelfReferenceLocation;
            var propertyWithInvalidInitializer;
            var associatedDeclarationForContainingInitializerOrBindingName;
            var withinDeferredContext = false;
            var errorLocation = location;
            var grandparent;
            var isInExternalModule = false;
            loop: while (location) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location.locals && !isGlobalSourceFile(location)) {
                    if (result = lookup(location.locals, name, meaning)) {
                        var useResult = true;
                        if (ts.isFunctionLike(location) && lastLocation && lastLocation !== location.body) {
                            // symbol lookup restrictions for function-like declarations
                            // - Type parameters of a function are in scope in the entire function declaration, including the parameter
                            //   list and return type. However, local types are only in scope in the function body.
                            // - parameters are only in the scope of function body
                            // This restriction does not apply to JSDoc comment types because they are parented
                            // at a higher level than type parameters would normally be
                            if (meaning & result.flags & 788968 /* Type */ && lastLocation.kind !== 303 /* JSDocComment */) {
                                useResult = result.flags & 262144 /* TypeParameter */
                                    // type parameters are visible in parameter list, return type and type parameter list
                                    ? lastLocation === location.type ||
                                        lastLocation.kind === 156 /* Parameter */ ||
                                        lastLocation.kind === 155 /* TypeParameter */
                                    // local types not visible outside the function body
                                    : false;
                            }
                            if (meaning & result.flags & 3 /* Variable */) {
                                // expression inside parameter will lookup as normal variable scope when targeting es2015+
                                if (useOuterVariableScopeInParameter(result, location, lastLocation)) {
                                    useResult = false;
                                }
                                else if (result.flags & 1 /* FunctionScopedVariable */) {
                                    // parameters are visible only inside function body, parameter list and return type
                                    // technically for parameter list case here we might mix parameters and variables declared in function,
                                    // however it is detected separately when checking initializers of parameters
                                    // to make sure that they reference no variables declared after them.
                                    useResult =
                                        lastLocation.kind === 156 /* Parameter */ ||
                                            (lastLocation === location.type &&
                                                !!ts.findAncestor(result.valueDeclaration, ts.isParameter));
                                }
                            }
                        }
                        else if (location.kind === 180 /* ConditionalType */) {
                            // A type parameter declared using 'infer T' in a conditional type is visible only in
                            // the true branch of the conditional type.
                            useResult = lastLocation === location.trueType;
                        }
                        if (useResult) {
                            break loop;
                        }
                        else {
                            result = undefined;
                        }
                    }
                }
                withinDeferredContext = withinDeferredContext || getIsDeferredContext(location, lastLocation);
                switch (location.kind) {
                    case 290 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location))
                            break;
                        isInExternalModule = true;
                    // falls through
                    case 249 /* ModuleDeclaration */:
                        var moduleExports = getSymbolOfNode(location).exports || emptySymbols;
                        if (location.kind === 290 /* SourceFile */ || (ts.isModuleDeclaration(location) && location.flags & 8388608 /* Ambient */ && !ts.isGlobalScopeAugmentation(location))) {
                            // It's an external module. First see if the module has an export default and if the local
                            // name of that export default matches.
                            if (result = moduleExports.get("default" /* Default */)) {
                                var localSymbol = ts.getLocalSymbolForExportDefault(result);
                                if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) {
                                    break loop;
                                }
                                result = undefined;
                            }
                            // Because of module/namespace merging, a module's exports are in scope,
                            // yet we never want to treat an export specifier as putting a member in scope.
                            // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
                            // Two things to note about this:
                            //     1. We have to check this without calling getSymbol. The problem with calling getSymbol
                            //        on an export specifier is that it might find the export specifier itself, and try to
                            //        resolve it as an alias. This will cause the checker to consider the export specifier
                            //        a circular alias reference when it might not be.
                            //     2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
                            //        an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
                            //        which is not the desired behavior.
                            var moduleExport = moduleExports.get(name);
                            if (moduleExport &&
                                moduleExport.flags === 2097152 /* Alias */ &&
                                (ts.getDeclarationOfKind(moduleExport, 263 /* ExportSpecifier */) || ts.getDeclarationOfKind(moduleExport, 262 /* NamespaceExport */))) {
                                break;
                            }
                        }
                        // ES6 exports are also visible locally (except for 'default'), but commonjs exports are not (except typedefs)
                        if (name !== "default" /* Default */ && (result = lookup(moduleExports, name, meaning & 2623475 /* ModuleMember */))) {
                            if (ts.isSourceFile(location) && location.commonJsModuleIndicator && !result.declarations.some(ts.isJSDocTypeAlias)) {
                                result = undefined;
                            }
                            else {
                                break loop;
                            }
                        }
                        break;
                    case 248 /* EnumDeclaration */:
                        if (result = lookup(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                            break loop;
                        }
                        break;
                    case 159 /* PropertyDeclaration */:
                        // TypeScript 1.0 spec (April 2014): 8.4.1
                        // Initializer expressions for instance member variables are evaluated in the scope
                        // of the class constructor body but are not permitted to reference parameters or
                        // local variables of the constructor. This effectively means that entities from outer scopes
                        // by the same name as a constructor parameter or local variable are inaccessible
                        // in initializer expressions for instance member variables.
                        if (!ts.hasModifier(location, 32 /* Static */)) {
                            var ctor = findConstructorDeclaration(location.parent);
                            if (ctor && ctor.locals) {
                                if (lookup(ctor.locals, name, meaning & 111551 /* Value */)) {
                                    // Remember the property node, it will be used later to report appropriate error
                                    propertyWithInvalidInitializer = location;
                                }
                            }
                        }
                        break;
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                        // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals
                        // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would
                        // trigger resolving late-bound names, which we may already be in the process of doing while we're here!
                        if (result = lookup(getSymbolOfNode(location).members || emptySymbols, name, meaning & 788968 /* Type */)) {
                            if (!isTypeParameterSymbolDeclaredInContainer(result, location)) {
                                // ignore type parameters not declared in this container
                                result = undefined;
                                break;
                            }
                            if (lastLocation && ts.hasModifier(lastLocation, 32 /* Static */)) {
                                // TypeScript 1.0 spec (April 2014): 3.4.1
                                // The scope of a type parameter extends over the entire declaration with which the type
                                // parameter list is associated, with the exception of static member declarations in classes.
                                error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters);
                                return undefined;
                            }
                            break loop;
                        }
                        if (location.kind === 214 /* ClassExpression */ && meaning & 32 /* Class */) {
                            var className = location.name;
                            if (className && name === className.escapedText) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 216 /* ExpressionWithTypeArguments */:
                        // The type parameters of a class are not in scope in the base class expression.
                        if (lastLocation === location.expression && location.parent.token === 90 /* ExtendsKeyword */) {
                            var container = location.parent.parent;
                            if (ts.isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & 788968 /* Type */))) {
                                if (nameNotFoundMessage) {
                                    error(errorLocation, ts.Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters);
                                }
                                return undefined;
                            }
                        }
                        break;
                    // It is not legal to reference a class's own type parameters from a computed property name that
                    // belongs to the class. For example:
                    //
                    //   function foo<T>() { return '' }
                    //   class C<T> { // <-- Class's own type parameter T
                    //       [foo<T>()]() { } // <-- Reference to T from class's own computed property
                    //   }
                    //
                    case 154 /* ComputedPropertyName */:
                        grandparent = location.parent.parent;
                        if (ts.isClassLike(grandparent) || grandparent.kind === 246 /* InterfaceDeclaration */) {
                            // A reference to this grandparent's type parameters would be an error
                            if (result = lookup(getSymbolOfNode(grandparent).members, name, meaning & 788968 /* Type */)) {
                                error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
                                return undefined;
                            }
                        }
                        break;
                    case 202 /* ArrowFunction */:
                        // when targeting ES6 or higher there is no 'arguments' in an arrow function
                        // for lower compile targets the resolved symbol is used to emit an error
                        if (compilerOptions.target >= 2 /* ES2015 */) {
                            break;
                        }
                    // falls through
                    case 161 /* MethodDeclaration */:
                    case 162 /* Constructor */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 244 /* FunctionDeclaration */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        break;
                    case 201 /* FunctionExpression */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        if (meaning & 16 /* Function */) {
                            var functionName = location.name;
                            if (functionName && name === functionName.escapedText) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 157 /* Decorator */:
                        // Decorators are resolved at the class declaration. Resolving at the parameter
                        // or member would result in looking up locals in the method.
                        //
                        //   function y() {}
                        //   class C {
                        //       method(@y x, y) {} // <-- decorator y should be resolved at the class declaration, not the parameter.
                        //   }
                        //
                        if (location.parent && location.parent.kind === 156 /* Parameter */) {
                            location = location.parent;
                        }
                        //
                        //   function y() {}
                        //   class C {
                        //       @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method.
                        //   }
                        //
                        // class Decorators are resolved outside of the class to avoid referencing type parameters of that class.
                        //
                        //   type T = number;
                        //   declare function y(x: T): any;
                        //   @param(1 as T) // <-- T should resolve to the type alias outside of class C
                        //   class C<T> {}
                        if (location.parent && (ts.isClassElement(location.parent) || location.parent.kind === 245 /* ClassDeclaration */)) {
                            location = location.parent;
                        }
                        break;
                    case 322 /* JSDocTypedefTag */:
                    case 315 /* JSDocCallbackTag */:
                    case 316 /* JSDocEnumTag */:
                        // js type aliases do not resolve names from their host, so skip past it
                        location = ts.getJSDocHost(location);
                        break;
                    case 156 /* Parameter */:
                        if (lastLocation && (lastLocation === location.initializer ||
                            lastLocation === location.name && ts.isBindingPattern(lastLocation))) {
                            if (!associatedDeclarationForContainingInitializerOrBindingName) {
                                associatedDeclarationForContainingInitializerOrBindingName = location;
                            }
                        }
                        break;
                    case 191 /* BindingElement */:
                        if (lastLocation && (lastLocation === location.initializer ||
                            lastLocation === location.name && ts.isBindingPattern(lastLocation))) {
                            var root = ts.getRootDeclaration(location);
                            if (root.kind === 156 /* Parameter */) {
                                if (!associatedDeclarationForContainingInitializerOrBindingName) {
                                    associatedDeclarationForContainingInitializerOrBindingName = location;
                                }
                            }
                        }
                        break;
                }
                if (isSelfReferenceLocation(location)) {
                    lastSelfReferenceLocation = location;
                }
                lastLocation = location;
                location = location.parent;
            }
            // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
            // If `result === lastSelfReferenceLocation.symbol`, that means that we are somewhere inside `lastSelfReferenceLocation` looking up a name, and resolving to `lastLocation` itself.
            // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
            if (isUse && result && (!lastSelfReferenceLocation || result !== lastSelfReferenceLocation.symbol)) {
                result.isReferenced |= meaning;
            }
            if (!result) {
                if (lastLocation) {
                    ts.Debug.assert(lastLocation.kind === 290 /* SourceFile */);
                    if (lastLocation.commonJsModuleIndicator && name === "exports" && meaning & lastLocation.symbol.flags) {
                        return lastLocation.symbol;
                    }
                }
                if (!excludeGlobals) {
                    result = lookup(globals, name, meaning);
                }
            }
            if (!result) {
                if (originalLocation && ts.isInJSFile(originalLocation) && originalLocation.parent) {
                    if (ts.isRequireCall(originalLocation.parent, /*checkArgumentIsStringLiteralLike*/ false)) {
                        return requireSymbol;
                    }
                }
            }
            if (!result) {
                if (nameNotFoundMessage) {
                    if (!errorLocation ||
                        !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && // TODO: GH#18217
                            !checkAndReportErrorForExtendingInterface(errorLocation) &&
                            !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
                            !checkAndReportErrorForExportingPrimitiveType(errorLocation, name) &&
                            !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) {
                        var suggestion = void 0;
                        if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) {
                            suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
                            if (suggestion) {
                                var suggestionName = symbolToString(suggestion);
                                var diagnostic = error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg), suggestionName);
                                if (suggestion.valueDeclaration) {
                                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName));
                                }
                            }
                        }
                        if (!suggestion) {
                            error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
                        }
                        suggestionCount++;
                    }
                }
                return undefined;
            }
            // Perform extra checks only if error reporting was requested
            if (nameNotFoundMessage) {
                if (propertyWithInvalidInitializer && !(compilerOptions.target === 99 /* ESNext */ && compilerOptions.useDefineForClassFields)) {
                    // We have a match, but the reference occurred within a property initializer and the identifier also binds
                    // to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
                    // with ESNext+useDefineForClassFields because the scope semantics are different.
                    var propertyName = propertyWithInvalidInitializer.name;
                    error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), diagnosticName(nameArg));
                    return undefined;
                }
                // Only check for block-scoped variable if we have an error location and are looking for the
                // name with variable meaning
                //      For example,
                //          declare module foo {
                //              interface bar {}
                //          }
                //      const foo/*1*/: foo/*2*/.bar;
                // The foo at /*1*/ and /*2*/ will share same symbol with two meanings:
                // block-scoped variable and namespace module. However, only when we
                // try to resolve name in /*1*/ which is used in variable position,
                // we want to check for block-scoped
                if (errorLocation &&
                    (meaning & 2 /* BlockScopedVariable */ ||
                        ((meaning & 32 /* Class */ || meaning & 384 /* Enum */) && (meaning & 111551 /* Value */) === 111551 /* Value */))) {
                    var exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
                    if (exportOrLocalSymbol.flags & 2 /* BlockScopedVariable */ || exportOrLocalSymbol.flags & 32 /* Class */ || exportOrLocalSymbol.flags & 384 /* Enum */) {
                        checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
                    }
                }
                // If we're in an external module, we can't reference value symbols created from UMD export declarations
                if (result && isInExternalModule && (meaning & 111551 /* Value */) === 111551 /* Value */ && !(originalLocation.flags & 4194304 /* JSDoc */)) {
                    var merged = getMergedSymbol(result);
                    if (ts.length(merged.declarations) && ts.every(merged.declarations, function (d) { return ts.isNamespaceExportDeclaration(d) || ts.isSourceFile(d) && !!d.symbol.globalExports; })) {
                        errorOrSuggestion(!compilerOptions.allowUmdGlobalAccess, errorLocation, ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, ts.unescapeLeadingUnderscores(name));
                    }
                }
                // If we're in a parameter initializer or binding name, we can't reference the values of the parameter whose initializer we're within or parameters to the right
                if (result && associatedDeclarationForContainingInitializerOrBindingName && !withinDeferredContext && (meaning & 111551 /* Value */) === 111551 /* Value */) {
                    var candidate = getMergedSymbol(getLateBoundSymbol(result));
                    var root = ts.getRootDeclaration(associatedDeclarationForContainingInitializerOrBindingName);
                    // A parameter initializer or binding pattern initializer within a parameter cannot refer to itself
                    if (candidate === getSymbolOfNode(associatedDeclarationForContainingInitializerOrBindingName)) {
                        error(errorLocation, ts.Diagnostics.Parameter_0_cannot_reference_itself, ts.declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name));
                    }
                    // And it cannot refer to any declarations which come after it
                    else if (candidate.valueDeclaration && candidate.valueDeclaration.pos > associatedDeclarationForContainingInitializerOrBindingName.pos && root.parent.locals && lookup(root.parent.locals, candidate.escapedName, meaning) === candidate) {
                        error(errorLocation, ts.Diagnostics.Parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name), ts.declarationNameToString(errorLocation));
                    }
                }
                if (result && errorLocation && meaning & 111551 /* Value */ && result.flags & 2097152 /* Alias */) {
                    checkSymbolUsageInExpressionContext(result, name, errorLocation);
                }
            }
            return result;
        }
        function checkSymbolUsageInExpressionContext(symbol, name, useSite) {
            if (!ts.isValidTypeOnlyAliasUseSite(useSite)) {
                var typeOnlyDeclaration = getTypeOnlyAliasDeclaration(symbol);
                if (typeOnlyDeclaration) {
                    var isExport = ts.typeOnlyDeclarationIsExport(typeOnlyDeclaration);
                    var message = isExport
                        ? ts.Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type
                        : ts.Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type;
                    var relatedMessage = isExport
                        ? ts.Diagnostics._0_was_exported_here
                        : ts.Diagnostics._0_was_imported_here;
                    var unescapedName = ts.unescapeLeadingUnderscores(name);
                    ts.addRelatedInfo(error(useSite, message, unescapedName), ts.createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, unescapedName));
                }
            }
        }
        function getIsDeferredContext(location, lastLocation) {
            if (location.kind !== 202 /* ArrowFunction */ && location.kind !== 201 /* FunctionExpression */) {
                // initializers in instance property declaration of class like entities are executed in constructor and thus deferred
                return ts.isTypeQueryNode(location) || ((ts.isFunctionLikeDeclaration(location) ||
                    (location.kind === 159 /* PropertyDeclaration */ && !ts.hasModifier(location, 32 /* Static */))) && (!lastLocation || lastLocation !== location.name)); // A name is evaluated within the enclosing scope - so it shouldn't count as deferred
            }
            if (lastLocation && lastLocation === location.name) {
                return false;
            }
            // generator functions and async functions are not inlined in control flow when immediately invoked
            if (location.asteriskToken || ts.hasModifier(location, 256 /* Async */)) {
                return true;
            }
            return !ts.getImmediatelyInvokedFunctionExpression(location);
        }
        function isSelfReferenceLocation(node) {
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                case 245 /* ClassDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 248 /* EnumDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 249 /* ModuleDeclaration */: // For `namespace N { N; }`
                    return true;
                default:
                    return false;
            }
        }
        function diagnosticName(nameArg) {
            return ts.isString(nameArg) ? ts.unescapeLeadingUnderscores(nameArg) : ts.declarationNameToString(nameArg);
        }
        function isTypeParameterSymbolDeclaredInContainer(symbol, container) {
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (decl.kind === 155 /* TypeParameter */) {
                    var parent = ts.isJSDocTemplateTag(decl.parent) ? ts.getJSDocHost(decl.parent) : decl.parent;
                    if (parent === container) {
                        return !(ts.isJSDocTemplateTag(decl.parent) && ts.find(decl.parent.parent.tags, ts.isJSDocTypeAlias)); // TODO: GH#18217
                    }
                }
            }
            return false;
        }
        function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) {
            if (!ts.isIdentifier(errorLocation) || errorLocation.escapedText !== name || isTypeReferenceIdentifier(errorLocation) || isInTypeQuery(errorLocation)) {
                return false;
            }
            var container = ts.getThisContainer(errorLocation, /*includeArrowFunctions*/ false);
            var location = container;
            while (location) {
                if (ts.isClassLike(location.parent)) {
                    var classSymbol = getSymbolOfNode(location.parent);
                    if (!classSymbol) {
                        break;
                    }
                    // Check to see if a static member exists.
                    var constructorType = getTypeOfSymbol(classSymbol);
                    if (getPropertyOfType(constructorType, name)) {
                        error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol));
                        return true;
                    }
                    // No static member is present.
                    // Check if we're in an instance method and look for a relevant instance member.
                    if (location === container && !ts.hasModifier(location, 32 /* Static */)) {
                        var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; // TODO: GH#18217
                        if (getPropertyOfType(instanceType, name)) {
                            error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg));
                            return true;
                        }
                    }
                }
                location = location.parent;
            }
            return false;
        }
        function checkAndReportErrorForExtendingInterface(errorLocation) {
            var expression = getEntityNameForExtendingInterface(errorLocation);
            if (expression && resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)) {
                error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression));
                return true;
            }
            return false;
        }
        /**
         * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression,
         * but returns undefined if that expression is not an EntityNameExpression.
         */
        function getEntityNameForExtendingInterface(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                case 194 /* PropertyAccessExpression */:
                    return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
                case 216 /* ExpressionWithTypeArguments */:
                    if (ts.isEntityNameExpression(node.expression)) {
                        return node.expression;
                    }
                // falls through
                default:
                    return undefined;
            }
        }
        function checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) {
            var namespaceMeaning = 1920 /* Namespace */ | (ts.isInJSFile(errorLocation) ? 111551 /* Value */ : 0);
            if (meaning === namespaceMeaning) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 788968 /* Type */ & ~namespaceMeaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                var parent = errorLocation.parent;
                if (symbol) {
                    if (ts.isQualifiedName(parent)) {
                        ts.Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace");
                        var propName = parent.right.escapedText;
                        var propType = getPropertyOfType(getDeclaredTypeOfSymbol(symbol), propName);
                        if (propType) {
                            error(parent, ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, ts.unescapeLeadingUnderscores(name), ts.unescapeLeadingUnderscores(propName));
                            return true;
                        }
                    }
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning) {
            if (meaning & (788968 /* Type */ & ~1920 /* Namespace */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, ~788968 /* Type */ & 111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol && !(symbol.flags & 1920 /* Namespace */)) {
                    error(errorLocation, ts.Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function isPrimitiveTypeName(name) {
            return name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never" || name === "unknown";
        }
        function checkAndReportErrorForExportingPrimitiveType(errorLocation, name) {
            if (isPrimitiveTypeName(name) && errorLocation.parent.kind === 263 /* ExportSpecifier */) {
                error(errorLocation, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, name);
                return true;
            }
            return false;
        }
        function checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) {
            if (meaning & (111551 /* Value */ & ~1024 /* NamespaceModule */)) {
                if (isPrimitiveTypeName(name)) {
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
                var symbol = resolveSymbol(resolveName(errorLocation, name, 788968 /* Type */ & ~111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol && !(symbol.flags & 1024 /* NamespaceModule */)) {
                    var message = isES2015OrLaterConstructorName(name)
                        ? ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later
                        : ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here;
                    error(errorLocation, message, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function isES2015OrLaterConstructorName(n) {
            switch (n) {
                case "Promise":
                case "Symbol":
                case "Map":
                case "WeakMap":
                case "Set":
                case "WeakSet":
                    return true;
            }
            return false;
        }
        function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) {
            if (meaning & (111551 /* Value */ & ~1024 /* NamespaceModule */ & ~788968 /* Type */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 1024 /* NamespaceModule */ & ~111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol) {
                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_value, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            else if (meaning & (788968 /* Type */ & ~1024 /* NamespaceModule */ & ~111551 /* Value */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, (512 /* ValueModule */ | 1024 /* NamespaceModule */) & ~788968 /* Type */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol) {
                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_type, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkResolvedBlockScopedVariable(result, errorLocation) {
            ts.Debug.assert(!!(result.flags & 2 /* BlockScopedVariable */ || result.flags & 32 /* Class */ || result.flags & 384 /* Enum */));
            if (result.flags & (16 /* Function */ | 1 /* FunctionScopedVariable */ | 67108864 /* Assignment */) && result.flags & 32 /* Class */) {
                // constructor functions aren't block scoped
                return;
            }
            // Block-scoped variables cannot be used before their definition
            var declaration = ts.find(result.declarations, function (d) { return ts.isBlockOrCatchScoped(d) || ts.isClassLike(d) || (d.kind === 248 /* EnumDeclaration */); });
            if (declaration === undefined)
                return ts.Debug.fail("checkResolvedBlockScopedVariable could not find block-scoped declaration");
            if (!(declaration.flags & 8388608 /* Ambient */) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
                var diagnosticMessage = void 0;
                var declarationName = ts.declarationNameToString(ts.getNameOfDeclaration(declaration));
                if (result.flags & 2 /* BlockScopedVariable */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationName);
                }
                else if (result.flags & 32 /* Class */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
                }
                else if (result.flags & 256 /* RegularEnum */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Enum_0_used_before_its_declaration, declarationName);
                }
                else {
                    ts.Debug.assert(!!(result.flags & 128 /* ConstEnum */));
                    if (compilerOptions.preserveConstEnums) {
                        diagnosticMessage = error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
                    }
                }
                if (diagnosticMessage) {
                    ts.addRelatedInfo(diagnosticMessage, ts.createDiagnosticForNode(declaration, ts.Diagnostics._0_is_declared_here, declarationName));
                }
            }
        }
        /* Starting from 'initial' node walk up the parent chain until 'stopAt' node is reached.
         * If at any point current node is equal to 'parent' node - return true.
         * Return false if 'stopAt' node is reached or isFunctionLike(current) === true.
         */
        function isSameScopeDescendentOf(initial, parent, stopAt) {
            return !!parent && !!ts.findAncestor(initial, function (n) { return n === stopAt || ts.isFunctionLike(n) ? "quit" : n === parent; });
        }
        function getAnyImportSyntax(node) {
            switch (node.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    return node;
                case 255 /* ImportClause */:
                    return node.parent;
                case 256 /* NamespaceImport */:
                    return node.parent.parent;
                case 258 /* ImportSpecifier */:
                    return node.parent.parent.parent;
                default:
                    return undefined;
            }
        }
        function getDeclarationOfAliasSymbol(symbol) {
            return ts.find(symbol.declarations, isAliasSymbolDeclaration);
        }
        /**
         * An alias symbol is created by one of the following declarations:
         * import <symbol> = ...
         * import <symbol> from ...
         * import * as <symbol> from ...
         * import { x as <symbol> } from ...
         * export { x as <symbol> } from ...
         * export * as ns <symbol> from ...
         * export = <EntityNameExpression>
         * export default <EntityNameExpression>
         * module.exports = <EntityNameExpression>
         * {<Identifier>}
         * {name: <EntityNameExpression>}
         */
        function isAliasSymbolDeclaration(node) {
            return node.kind === 253 /* ImportEqualsDeclaration */ ||
                node.kind === 252 /* NamespaceExportDeclaration */ ||
                node.kind === 255 /* ImportClause */ && !!node.name ||
                node.kind === 256 /* NamespaceImport */ ||
                node.kind === 262 /* NamespaceExport */ ||
                node.kind === 258 /* ImportSpecifier */ ||
                node.kind === 263 /* ExportSpecifier */ ||
                node.kind === 259 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node) ||
                ts.isBinaryExpression(node) && ts.getAssignmentDeclarationKind(node) === 2 /* ModuleExports */ && ts.exportAssignmentIsAlias(node) ||
                ts.isPropertyAccessExpression(node)
                    && ts.isBinaryExpression(node.parent)
                    && node.parent.left === node
                    && node.parent.operatorToken.kind === 62 /* EqualsToken */
                    && isAliasableOrJsExpression(node.parent.right) ||
                node.kind === 282 /* ShorthandPropertyAssignment */ ||
                node.kind === 281 /* PropertyAssignment */ && isAliasableOrJsExpression(node.initializer);
        }
        function isAliasableOrJsExpression(e) {
            return ts.isAliasableExpression(e) || ts.isFunctionExpression(e) && isJSConstructor(e);
        }
        function getTargetOfImportEqualsDeclaration(node, dontResolveAlias) {
            if (node.moduleReference.kind === 265 /* ExternalModuleReference */) {
                var immediate = resolveExternalModuleName(node, ts.getExternalModuleImportEqualsDeclarationExpression(node));
                var resolved_4 = resolveExternalModuleSymbol(immediate);
                markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved_4, /*overwriteEmpty*/ false);
                return resolved_4;
            }
            var resolved = getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias);
            checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node, resolved);
            return resolved;
        }
        function checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node, resolved) {
            if (markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false)) {
                var typeOnlyDeclaration = getTypeOnlyAliasDeclaration(getSymbolOfNode(node));
                var isExport = ts.typeOnlyDeclarationIsExport(typeOnlyDeclaration);
                var message = isExport
                    ? ts.Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type
                    : ts.Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type;
                var relatedMessage = isExport
                    ? ts.Diagnostics._0_was_exported_here
                    : ts.Diagnostics._0_was_imported_here;
                // Non-null assertion is safe because the optionality comes from ImportClause,
                // but if an ImportClause was the typeOnlyDeclaration, it had to have a `name`.
                var name = ts.unescapeLeadingUnderscores(typeOnlyDeclaration.name.escapedText);
                ts.addRelatedInfo(error(node.moduleReference, message), ts.createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, name));
            }
        }
        function resolveExportByName(moduleSymbol, name, sourceNode, dontResolveAlias) {
            var exportValue = moduleSymbol.exports.get("export=" /* ExportEquals */);
            if (exportValue) {
                return getPropertyOfType(getTypeOfSymbol(exportValue), name);
            }
            var exportSymbol = moduleSymbol.exports.get(name);
            var resolved = resolveSymbol(exportSymbol, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(sourceNode, exportSymbol, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function isSyntacticDefault(node) {
            return ((ts.isExportAssignment(node) && !node.isExportEquals) || ts.hasModifier(node, 512 /* Default */) || ts.isExportSpecifier(node));
        }
        function canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias) {
            if (!allowSyntheticDefaultImports) {
                return false;
            }
            // Declaration files (and ambient modules)
            if (!file || file.isDeclarationFile) {
                // Definitely cannot have a synthetic default if they have a syntactic default member specified
                var defaultExportSymbol = resolveExportByName(moduleSymbol, "default" /* Default */, /*sourceNode*/ undefined, /*dontResolveAlias*/ true); // Dont resolve alias because we want the immediately exported symbol's declaration
                if (defaultExportSymbol && ts.some(defaultExportSymbol.declarations, isSyntacticDefault)) {
                    return false;
                }
                // It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member
                // So we check a bit more,
                if (resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias)) {
                    // If there is an `__esModule` specified in the declaration (meaning someone explicitly added it or wrote it in their code),
                    // it definitely is a module and does not have a synthetic default
                    return false;
                }
                // There are _many_ declaration files not written with esmodules in mind that still get compiled into a format with __esModule set
                // Meaning there may be no default at runtime - however to be on the permissive side, we allow access to a synthetic default member
                // as there is no marker to indicate if the accompanying JS has `__esModule` or not, or is even native esm
                return true;
            }
            // TypeScript files never have a synthetic default (as they are always emitted with an __esModule marker) _unless_ they contain an export= statement
            if (!ts.isSourceFileJS(file)) {
                return hasExportAssignmentSymbol(moduleSymbol);
            }
            // JS files have a synthetic default if they do not contain ES2015+ module syntax (export = is not valid in js) _and_ do not have an __esModule marker
            return !file.externalModuleIndicator && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias);
        }
        function getTargetOfImportClause(node, dontResolveAlias) {
            var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier);
            if (moduleSymbol) {
                var exportDefaultSymbol = void 0;
                if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                    exportDefaultSymbol = moduleSymbol;
                }
                else {
                    exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* Default */, node, dontResolveAlias);
                }
                var file = ts.find(moduleSymbol.declarations, ts.isSourceFile);
                var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias);
                if (!exportDefaultSymbol && !hasSyntheticDefault) {
                    if (hasExportAssignmentSymbol(moduleSymbol)) {
                        var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop";
                        var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* ExportEquals */);
                        var exportAssignment = exportEqualsSymbol.valueDeclaration;
                        var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName);
                        ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName));
                    }
                    else {
                        reportNonDefaultExport(moduleSymbol, node);
                    }
                }
                else if (hasSyntheticDefault) {
                    // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present
                    var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
                    markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false);
                    return resolved;
                }
                markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false);
                return exportDefaultSymbol;
            }
        }
        function reportNonDefaultExport(moduleSymbol, node) {
            var _a, _b;
            if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has(node.symbol.escapedName)) {
                error(node.name, ts.Diagnostics.Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead, symbolToString(moduleSymbol), symbolToString(node.symbol));
            }
            else {
                var diagnostic = error(node.name, ts.Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
                var exportStar = (_b = moduleSymbol.exports) === null || _b === void 0 ? void 0 : _b.get("__export" /* ExportStar */);
                if (exportStar) {
                    var defaultExport = ts.find(exportStar.declarations, function (decl) {
                        var _a, _b;
                        return !!(ts.isExportDeclaration(decl) && decl.moduleSpecifier && ((_b = (_a = resolveExternalModuleName(decl, decl.moduleSpecifier)) === null || _a === void 0 ? void 0 : _a.exports) === null || _b === void 0 ? void 0 : _b.has("default" /* Default */)));
                    });
                    if (defaultExport) {
                        ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(defaultExport, ts.Diagnostics.export_Asterisk_does_not_re_export_a_default));
                    }
                }
            }
        }
        function getTargetOfNamespaceImport(node, dontResolveAlias) {
            var moduleSpecifier = node.parent.parent.moduleSpecifier;
            var immediate = resolveExternalModuleName(node, moduleSpecifier);
            var resolved = resolveESModuleSymbol(immediate, moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
            markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfNamespaceExport(node, dontResolveAlias) {
            var moduleSpecifier = node.parent.moduleSpecifier;
            var immediate = moduleSpecifier && resolveExternalModuleName(node, moduleSpecifier);
            var resolved = moduleSpecifier && resolveESModuleSymbol(immediate, moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
            markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        // This function creates a synthetic symbol that combines the value side of one symbol with the
        // type/namespace side of another symbol. Consider this example:
        //
        //   declare module graphics {
        //       interface Point {
        //           x: number;
        //           y: number;
        //       }
        //   }
        //   declare var graphics: {
        //       Point: new (x: number, y: number) => graphics.Point;
        //   }
        //   declare module "graphics" {
        //       export = graphics;
        //   }
        //
        // An 'import { Point } from "graphics"' needs to create a symbol that combines the value side 'Point'
        // property with the type/namespace side interface 'Point'.
        function combineValueAndTypeSymbols(valueSymbol, typeSymbol) {
            if (valueSymbol === unknownSymbol && typeSymbol === unknownSymbol) {
                return unknownSymbol;
            }
            if (valueSymbol.flags & (788968 /* Type */ | 1920 /* Namespace */)) {
                return valueSymbol;
            }
            var result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName);
            result.declarations = ts.deduplicate(ts.concatenate(valueSymbol.declarations, typeSymbol.declarations), ts.equateValues);
            result.parent = valueSymbol.parent || typeSymbol.parent;
            if (valueSymbol.valueDeclaration)
                result.valueDeclaration = valueSymbol.valueDeclaration;
            if (typeSymbol.members)
                result.members = ts.cloneMap(typeSymbol.members);
            if (valueSymbol.exports)
                result.exports = ts.cloneMap(valueSymbol.exports);
            return result;
        }
        function getExportOfModule(symbol, specifier, dontResolveAlias) {
            var _a;
            if (symbol.flags & 1536 /* Module */) {
                var name = ((_a = specifier.propertyName) !== null && _a !== void 0 ? _a : specifier.name).escapedText;
                var exportSymbol = getExportsOfSymbol(symbol).get(name);
                var resolved = resolveSymbol(exportSymbol, dontResolveAlias);
                markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false);
                return resolved;
            }
        }
        function getPropertyOfVariable(symbol, name) {
            if (symbol.flags & 3 /* Variable */) {
                var typeAnnotation = symbol.valueDeclaration.type;
                if (typeAnnotation) {
                    return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name));
                }
            }
        }
        function getExternalModuleMember(node, specifier, dontResolveAlias) {
            var _a;
            if (dontResolveAlias === void 0) { dontResolveAlias = false; }
            var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); // TODO: GH#18217
            var name = specifier.propertyName || specifier.name;
            var suppressInteropError = name.escapedText === "default" /* Default */ && !!(compilerOptions.allowSyntheticDefaultImports || compilerOptions.esModuleInterop);
            var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias, suppressInteropError);
            if (targetSymbol) {
                if (name.escapedText) {
                    if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                        return moduleSymbol;
                    }
                    var symbolFromVariable = void 0;
                    // First check if module was specified with "export=". If so, get the member from the resolved type
                    if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=" /* ExportEquals */)) {
                        symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText);
                    }
                    else {
                        symbolFromVariable = getPropertyOfVariable(targetSymbol, name.escapedText);
                    }
                    // if symbolFromVariable is export - get its final target
                    symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
                    var symbolFromModule = getExportOfModule(targetSymbol, specifier, dontResolveAlias);
                    if (symbolFromModule === undefined && name.escapedText === "default" /* Default */) {
                        var file = ts.find(moduleSymbol.declarations, ts.isSourceFile);
                        if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) {
                            symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
                        }
                    }
                    var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ?
                        combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
                        symbolFromModule || symbolFromVariable;
                    if (!symbol) {
                        var moduleName = getFullyQualifiedName(moduleSymbol, node);
                        var declarationName = ts.declarationNameToString(name);
                        var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
                        if (suggestion !== undefined) {
                            var suggestionName = symbolToString(suggestion);
                            var diagnostic = error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
                            if (suggestion.valueDeclaration) {
                                ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName));
                            }
                        }
                        else {
                            if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has("default" /* Default */)) {
                                error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName);
                            }
                            else {
                                reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName);
                            }
                        }
                    }
                    return symbol;
                }
            }
        }
        function reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName) {
            var _a;
            var localSymbol = (_a = moduleSymbol.valueDeclaration.locals) === null || _a === void 0 ? void 0 : _a.get(name.escapedText);
            var exports = moduleSymbol.exports;
            if (localSymbol) {
                var exportedEqualsSymbol = exports === null || exports === void 0 ? void 0 : exports.get("export=" /* ExportEquals */);
                if (exportedEqualsSymbol) {
                    getSymbolIfSameReference(exportedEqualsSymbol, localSymbol) ? reportInvalidImportEqualsExportMember(node, name, declarationName, moduleName) :
                        error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
                }
                else {
                    var exportedSymbol = exports ? ts.find(symbolsToArray(exports), function (symbol) { return !!getSymbolIfSameReference(symbol, localSymbol); }) : undefined;
                    var diagnostic = exportedSymbol ? error(name, ts.Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol)) :
                        error(name, ts.Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName);
                    ts.addRelatedInfo.apply(void 0, __spreadArrays([diagnostic], ts.map(localSymbol.declarations, function (decl, index) {
                        return ts.createDiagnosticForNode(decl, index === 0 ? ts.Diagnostics._0_is_declared_here : ts.Diagnostics.and_here, declarationName);
                    })));
                }
            }
            else {
                error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
            }
        }
        function reportInvalidImportEqualsExportMember(node, name, declarationName, moduleName) {
            if (moduleKind >= ts.ModuleKind.ES2015) {
                var message = compilerOptions.esModuleInterop ? ts.Diagnostics._0_can_only_be_imported_by_using_a_default_import :
                    ts.Diagnostics._0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
                error(name, message, declarationName);
            }
            else {
                if (ts.isInJSFile(node)) {
                    var message = compilerOptions.esModuleInterop ? ts.Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import :
                        ts.Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
                    error(name, message, declarationName);
                }
                else {
                    var message = compilerOptions.esModuleInterop ? ts.Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import :
                        ts.Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
                    error(name, message, declarationName, declarationName, moduleName);
                }
            }
        }
        function getTargetOfImportSpecifier(node, dontResolveAlias) {
            var resolved = getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfNamespaceExportDeclaration(node, dontResolveAlias) {
            var resolved = resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) {
            var resolved = node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node, dontResolveAlias) :
                resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfExportAssignment(node, dontResolveAlias) {
            var expression = ts.isExportAssignment(node) ? node.expression : node.right;
            var resolved = getTargetOfAliasLikeExpression(expression, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfAliasLikeExpression(expression, dontResolveAlias) {
            if (ts.isClassExpression(expression)) {
                return checkExpressionCached(expression).symbol;
            }
            if (!ts.isEntityName(expression) && !ts.isEntityNameExpression(expression)) {
                return undefined;
            }
            var aliasLike = resolveEntityName(expression, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ true, dontResolveAlias);
            if (aliasLike) {
                return aliasLike;
            }
            checkExpressionCached(expression);
            return getNodeLinks(expression).resolvedSymbol;
        }
        function getTargetOfPropertyAssignment(node, dontRecursivelyResolve) {
            var expression = node.initializer;
            return getTargetOfAliasLikeExpression(expression, dontRecursivelyResolve);
        }
        function getTargetOfPropertyAccessExpression(node, dontRecursivelyResolve) {
            if (!(ts.isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === 62 /* EqualsToken */)) {
                return undefined;
            }
            return getTargetOfAliasLikeExpression(node.parent.right, dontRecursivelyResolve);
        }
        function getTargetOfAliasDeclaration(node, dontRecursivelyResolve) {
            if (dontRecursivelyResolve === void 0) { dontRecursivelyResolve = false; }
            switch (node.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    return getTargetOfImportEqualsDeclaration(node, dontRecursivelyResolve);
                case 255 /* ImportClause */:
                    return getTargetOfImportClause(node, dontRecursivelyResolve);
                case 256 /* NamespaceImport */:
                    return getTargetOfNamespaceImport(node, dontRecursivelyResolve);
                case 262 /* NamespaceExport */:
                    return getTargetOfNamespaceExport(node, dontRecursivelyResolve);
                case 258 /* ImportSpecifier */:
                    return getTargetOfImportSpecifier(node, dontRecursivelyResolve);
                case 263 /* ExportSpecifier */:
                    return getTargetOfExportSpecifier(node, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, dontRecursivelyResolve);
                case 259 /* ExportAssignment */:
                case 209 /* BinaryExpression */:
                    return getTargetOfExportAssignment(node, dontRecursivelyResolve);
                case 252 /* NamespaceExportDeclaration */:
                    return getTargetOfNamespaceExportDeclaration(node, dontRecursivelyResolve);
                case 282 /* ShorthandPropertyAssignment */:
                    return resolveEntityName(node.name, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ true, dontRecursivelyResolve);
                case 281 /* PropertyAssignment */:
                    return getTargetOfPropertyAssignment(node, dontRecursivelyResolve);
                case 194 /* PropertyAccessExpression */:
                    return getTargetOfPropertyAccessExpression(node, dontRecursivelyResolve);
                default:
                    return ts.Debug.fail();
            }
        }
        /**
         * Indicates that a symbol is an alias that does not merge with a local declaration.
         * OR Is a JSContainer which may merge an alias with a local declaration
         */
        function isNonLocalAlias(symbol, excludes) {
            if (excludes === void 0) { excludes = 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */; }
            if (!symbol)
                return false;
            return (symbol.flags & (2097152 /* Alias */ | excludes)) === 2097152 /* Alias */ || !!(symbol.flags & 2097152 /* Alias */ && symbol.flags & 67108864 /* Assignment */);
        }
        function resolveSymbol(symbol, dontResolveAlias) {
            return !dontResolveAlias && isNonLocalAlias(symbol) ? resolveAlias(symbol) : symbol;
        }
        function resolveAlias(symbol) {
            ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
            var links = getSymbolLinks(symbol);
            if (!links.target) {
                links.target = resolvingSymbol;
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                var target = getTargetOfAliasDeclaration(node);
                if (links.target === resolvingSymbol) {
                    links.target = target || unknownSymbol;
                }
                else {
                    error(node, ts.Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
                }
            }
            else if (links.target === resolvingSymbol) {
                links.target = unknownSymbol;
            }
            return links.target;
        }
        function tryResolveAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.target !== resolvingSymbol) {
                return resolveAlias(symbol);
            }
            return undefined;
        }
        /**
         * Marks a symbol as type-only if its declaration is syntactically type-only.
         * If it is not itself marked type-only, but resolves to a type-only alias
         * somewhere in its resolution chain, save a reference to the type-only alias declaration
         * so the alias _not_ marked type-only can be identified as _transitively_ type-only.
         *
         * This function is called on each alias declaration that could be type-only or resolve to
         * another type-only alias during `resolveAlias`, so that later, when an alias is used in a
         * JS-emitting expression, we can quickly determine if that symbol is effectively type-only
         * and issue an error if so.
         *
         * @param aliasDeclaration The alias declaration not marked as type-only
         * has already been marked as not resolving to a type-only alias. Used when recursively resolving qualified
         * names of import aliases, e.g. `import C = a.b.C`. If namespace `a` is not found to be type-only, the
         * import declaration will initially be marked as not resolving to a type-only symbol. But, namespace `b`
         * must still be checked for a type-only marker, overwriting the previous negative result if found.
         * @param immediateTarget The symbol to which the alias declaration immediately resolves
         * @param finalTarget The symbol to which the alias declaration ultimately resolves
         * @param overwriteEmpty Checks `resolvesToSymbol` for type-only declarations even if `aliasDeclaration`
         */
        function markSymbolOfAliasDeclarationIfTypeOnly(aliasDeclaration, immediateTarget, finalTarget, overwriteEmpty) {
            if (!aliasDeclaration)
                return false;
            // If the declaration itself is type-only, mark it and return.
            // No need to check what it resolves to.
            var sourceSymbol = getSymbolOfNode(aliasDeclaration);
            if (ts.isTypeOnlyImportOrExportDeclaration(aliasDeclaration)) {
                var links_1 = getSymbolLinks(sourceSymbol);
                links_1.typeOnlyDeclaration = aliasDeclaration;
                return true;
            }
            var links = getSymbolLinks(sourceSymbol);
            return markSymbolOfAliasDeclarationIfTypeOnlyWorker(links, immediateTarget, overwriteEmpty)
                || markSymbolOfAliasDeclarationIfTypeOnlyWorker(links, finalTarget, overwriteEmpty);
        }
        function markSymbolOfAliasDeclarationIfTypeOnlyWorker(aliasDeclarationLinks, target, overwriteEmpty) {
            var _a, _b, _c;
            if (target && (aliasDeclarationLinks.typeOnlyDeclaration === undefined || overwriteEmpty && aliasDeclarationLinks.typeOnlyDeclaration === false)) {
                var exportSymbol = (_b = (_a = target.exports) === null || _a === void 0 ? void 0 : _a.get("export=" /* ExportEquals */)) !== null && _b !== void 0 ? _b : target;
                var typeOnly = exportSymbol.declarations && ts.find(exportSymbol.declarations, ts.isTypeOnlyImportOrExportDeclaration);
                aliasDeclarationLinks.typeOnlyDeclaration = (_c = typeOnly !== null && typeOnly !== void 0 ? typeOnly : getSymbolLinks(exportSymbol).typeOnlyDeclaration) !== null && _c !== void 0 ? _c : false;
            }
            return !!aliasDeclarationLinks.typeOnlyDeclaration;
        }
        /** Indicates that a symbol directly or indirectly resolves to a type-only import or export. */
        function getTypeOnlyAliasDeclaration(symbol) {
            if (!(symbol.flags & 2097152 /* Alias */)) {
                return undefined;
            }
            var links = getSymbolLinks(symbol);
            return links.typeOnlyDeclaration || undefined;
        }
        function markExportAsReferenced(node) {
            var symbol = getSymbolOfNode(node);
            var target = resolveAlias(symbol);
            if (target) {
                var markAlias = target === unknownSymbol ||
                    ((target.flags & 111551 /* Value */) && !isConstEnumOrConstEnumOnlyModule(target) && !getTypeOnlyAliasDeclaration(symbol));
                if (markAlias) {
                    markAliasSymbolAsReferenced(symbol);
                }
            }
        }
        // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until
        // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of
        // the alias as an expression (which recursively takes us back here if the target references another alias).
        function markAliasSymbolAsReferenced(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.referenced) {
                links.referenced = true;
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                // We defer checking of the reference of an `import =` until the import itself is referenced,
                // This way a chain of imports can be elided if ultimately the final input is only used in a type
                // position.
                if (ts.isInternalModuleImportEqualsDeclaration(node)) {
                    var target = resolveSymbol(symbol);
                    if (target === unknownSymbol || target.flags & 111551 /* Value */) {
                        // import foo = <symbol>
                        checkExpressionCached(node.moduleReference);
                    }
                }
            }
        }
        // Aliases that resolve to const enums are not marked as referenced because they are not emitted,
        // but their usage in value positions must be tracked to determine if the import can be type-only.
        function markConstEnumAliasAsReferenced(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.constEnumReferenced) {
                links.constEnumReferenced = true;
            }
        }
        // This function is only for imports with entity names
        function getSymbolOfPartOfRightHandSideOfImportEquals(entityName, dontResolveAlias) {
            // There are three things we might try to look for. In the following examples,
            // the search term is enclosed in |...|:
            //
            //     import a = |b|; // Namespace
            //     import a = |b.c|; // Value, type, namespace
            //     import a = |b.c|.d; // Namespace
            if (entityName.kind === 75 /* Identifier */ && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                entityName = entityName.parent;
            }
            // Check for case 1 and 3 in the above example
            if (entityName.kind === 75 /* Identifier */ || entityName.parent.kind === 153 /* QualifiedName */) {
                return resolveEntityName(entityName, 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
            }
            else {
                // Case 2 in above example
                // entityName.kind could be a QualifiedName or a Missing identifier
                ts.Debug.assert(entityName.parent.kind === 253 /* ImportEqualsDeclaration */);
                return resolveEntityName(entityName, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
            }
        }
        function getFullyQualifiedName(symbol, containingLocation) {
            return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, 16 /* DoNotIncludeSymbolChain */ | 4 /* AllowAnyNodeKind */);
        }
        /**
         * Resolves a qualified name and any involved aliases.
         */
        function resolveEntityName(name, meaning, ignoreErrors, dontResolveAlias, location) {
            if (ts.nodeIsMissing(name)) {
                return undefined;
            }
            var namespaceMeaning = 1920 /* Namespace */ | (ts.isInJSFile(name) ? meaning & 111551 /* Value */ : 0);
            var symbol;
            if (name.kind === 75 /* Identifier */) {
                var message = meaning === namespaceMeaning || ts.nodeIsSynthesized(name) ? ts.Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(ts.getFirstIdentifier(name));
                var symbolFromJSPrototype = ts.isInJSFile(name) && !ts.nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined;
                symbol = getMergedSymbol(resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true));
                if (!symbol) {
                    return getMergedSymbol(symbolFromJSPrototype);
                }
            }
            else if (name.kind === 153 /* QualifiedName */ || name.kind === 194 /* PropertyAccessExpression */) {
                var left = name.kind === 153 /* QualifiedName */ ? name.left : name.expression;
                var right = name.kind === 153 /* QualifiedName */ ? name.right : name.name;
                var namespace = resolveEntityName(left, namespaceMeaning, ignoreErrors, /*dontResolveAlias*/ false, location);
                if (!namespace || ts.nodeIsMissing(right)) {
                    return undefined;
                }
                else if (namespace === unknownSymbol) {
                    return namespace;
                }
                if (ts.isInJSFile(name)) {
                    if (namespace.valueDeclaration &&
                        ts.isVariableDeclaration(namespace.valueDeclaration) &&
                        namespace.valueDeclaration.initializer &&
                        isCommonJsRequire(namespace.valueDeclaration.initializer)) {
                        var moduleName = namespace.valueDeclaration.initializer.arguments[0];
                        var moduleSym = resolveExternalModuleName(moduleName, moduleName);
                        if (moduleSym) {
                            var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
                            if (resolvedModuleSymbol) {
                                namespace = resolvedModuleSymbol;
                            }
                        }
                    }
                }
                symbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning));
                if (!symbol) {
                    if (!ignoreErrors) {
                        error(right, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(right));
                    }
                    return undefined;
                }
            }
            else {
                throw ts.Debug.assertNever(name, "Unknown entity name kind.");
            }
            ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
            if (!ts.nodeIsSynthesized(name) && ts.isEntityName(name) && (symbol.flags & 2097152 /* Alias */ || name.parent.kind === 259 /* ExportAssignment */)) {
                markSymbolOfAliasDeclarationIfTypeOnly(ts.getAliasDeclarationFromName(name), symbol, /*finalTarget*/ undefined, /*overwriteEmpty*/ true);
            }
            return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
        }
        /**
         * 1. For prototype-property methods like `A.prototype.m = function () ...`, try to resolve names in the scope of `A` too.
         * Note that prototype-property assignment to locations outside the current file (eg globals) doesn't work, so
         * name resolution won't work either.
         * 2. For property assignments like `{ x: function f () { } }`, try to resolve names in the scope of `f` too.
         */
        function resolveEntityNameFromAssignmentDeclaration(name, meaning) {
            if (isJSDocTypeReference(name.parent)) {
                var secondaryLocation = getAssignmentDeclarationLocation(name.parent);
                if (secondaryLocation) {
                    return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true);
                }
            }
        }
        function getAssignmentDeclarationLocation(node) {
            var typeAlias = ts.findAncestor(node, function (node) { return !(ts.isJSDocNode(node) || node.flags & 4194304 /* JSDoc */) ? "quit" : ts.isJSDocTypeAlias(node); });
            if (typeAlias) {
                return;
            }
            var host = ts.getJSDocHost(node);
            if (ts.isExpressionStatement(host) &&
                ts.isBinaryExpression(host.expression) &&
                ts.getAssignmentDeclarationKind(host.expression) === 3 /* PrototypeProperty */) {
                // X.prototype.m = /** @param {K} p */ function () { } <-- look for K on X's declaration
                var symbol = getSymbolOfNode(host.expression.left);
                if (symbol) {
                    return getDeclarationOfJSPrototypeContainer(symbol);
                }
            }
            if ((ts.isObjectLiteralMethod(host) || ts.isPropertyAssignment(host)) &&
                ts.isBinaryExpression(host.parent.parent) &&
                ts.getAssignmentDeclarationKind(host.parent.parent) === 6 /* Prototype */) {
                // X.prototype = { /** @param {K} p */m() { } } <-- look for K on X's declaration
                var symbol = getSymbolOfNode(host.parent.parent.left);
                if (symbol) {
                    return getDeclarationOfJSPrototypeContainer(symbol);
                }
            }
            var sig = ts.getEffectiveJSDocHost(node);
            if (sig && ts.isFunctionLike(sig)) {
                var symbol = getSymbolOfNode(sig);
                return symbol && symbol.valueDeclaration;
            }
        }
        function getDeclarationOfJSPrototypeContainer(symbol) {
            var decl = symbol.parent.valueDeclaration;
            if (!decl) {
                return undefined;
            }
            var initializer = ts.isAssignmentDeclaration(decl) ? ts.getAssignedExpandoInitializer(decl) :
                ts.hasOnlyExpressionInitializer(decl) ? ts.getDeclaredExpandoInitializer(decl) :
                    undefined;
            return initializer || decl;
        }
        /**
         * Get the real symbol of a declaration with an expando initializer.
         *
         * Normally, declarations have an associated symbol, but when a declaration has an expando
         * initializer, the expando's symbol is the one that has all the members merged into it.
         */
        function getExpandoSymbol(symbol) {
            var decl = symbol.valueDeclaration;
            if (!decl || !ts.isInJSFile(decl) || symbol.flags & 524288 /* TypeAlias */ || ts.getExpandoInitializer(decl, /*isPrototypeAssignment*/ false)) {
                return undefined;
            }
            var init = ts.isVariableDeclaration(decl) ? ts.getDeclaredExpandoInitializer(decl) : ts.getAssignedExpandoInitializer(decl);
            if (init) {
                var initSymbol = getSymbolOfNode(init);
                if (initSymbol) {
                    return mergeJSSymbols(initSymbol, symbol);
                }
            }
        }
        function resolveExternalModuleName(location, moduleReferenceExpression, ignoreErrors) {
            return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ignoreErrors ? undefined : ts.Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations);
        }
        function resolveExternalModuleNameWorker(location, moduleReferenceExpression, moduleNotFoundError, isForAugmentation) {
            if (isForAugmentation === void 0) { isForAugmentation = false; }
            return ts.isStringLiteralLike(moduleReferenceExpression)
                ? resolveExternalModule(location, moduleReferenceExpression.text, moduleNotFoundError, moduleReferenceExpression, isForAugmentation)
                : undefined;
        }
        function resolveExternalModule(location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation) {
            if (isForAugmentation === void 0) { isForAugmentation = false; }
            if (ts.startsWith(moduleReference, "@types/")) {
                var diag = ts.Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1;
                var withoutAtTypePrefix = ts.removePrefix(moduleReference, "@types/");
                error(errorNode, diag, withoutAtTypePrefix, moduleReference);
            }
            var ambientModule = tryFindAmbientModule(moduleReference, /*withAugmentations*/ true);
            if (ambientModule) {
                return ambientModule;
            }
            var currentSourceFile = ts.getSourceFileOfNode(location);
            var resolvedModule = ts.getResolvedModule(currentSourceFile, moduleReference); // TODO: GH#18217
            var resolutionDiagnostic = resolvedModule && ts.getResolutionDiagnostic(compilerOptions, resolvedModule);
            var sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName);
            if (sourceFile) {
                if (sourceFile.symbol) {
                    if (resolvedModule.isExternalLibraryImport && !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension)) {
                        errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference);
                    }
                    // merged symbol is module declaration symbol combined with all augmentations
                    return getMergedSymbol(sourceFile.symbol);
                }
                if (moduleNotFoundError) {
                    // report errors only if it was requested
                    error(errorNode, ts.Diagnostics.File_0_is_not_a_module, sourceFile.fileName);
                }
                return undefined;
            }
            if (patternAmbientModules) {
                var pattern = ts.findBestPatternMatch(patternAmbientModules, function (_) { return _.pattern; }, moduleReference);
                if (pattern) {
                    // If the module reference matched a pattern ambient module ('*.foo') but there's also a
                    // module augmentation by the specific name requested ('a.foo'), we store the merged symbol
                    // by the augmentation name ('a.foo'), because asking for *.foo should not give you exports
                    // from a.foo.
                    var augmentation = patternAmbientModuleAugmentations && patternAmbientModuleAugmentations.get(moduleReference);
                    if (augmentation) {
                        return getMergedSymbol(augmentation);
                    }
                    return getMergedSymbol(pattern.symbol);
                }
            }
            // May be an untyped module. If so, ignore resolutionDiagnostic.
            if (resolvedModule && !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
                if (isForAugmentation) {
                    var diag = ts.Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
                    error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
                }
                else {
                    errorOnImplicitAnyModule(/*isError*/ noImplicitAny && !!moduleNotFoundError, errorNode, resolvedModule, moduleReference);
                }
                // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first.
                return undefined;
            }
            if (moduleNotFoundError) {
                // See if this was possibly a projectReference redirect
                if (resolvedModule) {
                    var redirect = host.getProjectReferenceRedirect(resolvedModule.resolvedFileName);
                    if (redirect) {
                        error(errorNode, ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, resolvedModule.resolvedFileName);
                        return undefined;
                    }
                }
                if (resolutionDiagnostic) {
                    error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
                }
                else {
                    var tsExtension = ts.tryExtractTSExtension(moduleReference);
                    if (tsExtension) {
                        var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
                        error(errorNode, diag, tsExtension, ts.removeExtension(moduleReference, tsExtension));
                    }
                    else if (!compilerOptions.resolveJsonModule &&
                        ts.fileExtensionIs(moduleReference, ".json" /* Json */) &&
                        ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs &&
                        ts.hasJsonModuleEmitEnabled(compilerOptions)) {
                        error(errorNode, ts.Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference);
                    }
                    else {
                        error(errorNode, moduleNotFoundError, moduleReference);
                    }
                }
            }
            return undefined;
        }
        function errorOnImplicitAnyModule(isError, errorNode, _a, moduleReference) {
            var packageId = _a.packageId, resolvedFileName = _a.resolvedFileName;
            var errorInfo = !ts.isExternalModuleNameRelative(moduleReference) && packageId
                ? typesPackageExists(packageId.name)
                    ? ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, packageId.name, ts.mangleScopedPackageName(packageId.name))
                    : ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, moduleReference, ts.mangleScopedPackageName(packageId.name))
                : undefined;
            errorOrSuggestion(isError, errorNode, ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedFileName));
        }
        function typesPackageExists(packageName) {
            return getPackagesSet().has(ts.getTypesPackageName(packageName));
        }
        function resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) {
            if (moduleSymbol === null || moduleSymbol === void 0 ? void 0 : moduleSymbol.exports) {
                var exportEquals = resolveSymbol(moduleSymbol.exports.get("export=" /* ExportEquals */), dontResolveAlias);
                var exported = getCommonJsExportEquals(getMergedSymbol(exportEquals), getMergedSymbol(moduleSymbol));
                return getMergedSymbol(exported) || moduleSymbol;
            }
            return undefined;
        }
        function getCommonJsExportEquals(exported, moduleSymbol) {
            if (!exported || exported === unknownSymbol || exported === moduleSymbol || moduleSymbol.exports.size === 1 || exported.flags & 2097152 /* Alias */) {
                return exported;
            }
            var links = getSymbolLinks(exported);
            if (links.cjsExportMerged) {
                return links.cjsExportMerged;
            }
            var merged = exported.flags & 33554432 /* Transient */ ? exported : cloneSymbol(exported);
            merged.flags = merged.flags | 512 /* ValueModule */;
            if (merged.exports === undefined) {
                merged.exports = ts.createSymbolTable();
            }
            moduleSymbol.exports.forEach(function (s, name) {
                if (name === "export=" /* ExportEquals */)
                    return;
                merged.exports.set(name, merged.exports.has(name) ? mergeSymbol(merged.exports.get(name), s) : s);
            });
            getSymbolLinks(merged).cjsExportMerged = merged;
            return links.cjsExportMerged = merged;
        }
        // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
        // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may
        // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable).
        function resolveESModuleSymbol(moduleSymbol, referencingLocation, dontResolveAlias, suppressInteropError) {
            var symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias);
            if (!dontResolveAlias && symbol) {
                if (!suppressInteropError && !(symbol.flags & (1536 /* Module */ | 3 /* Variable */)) && !ts.getDeclarationOfKind(symbol, 290 /* SourceFile */)) {
                    var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015
                        ? "allowSyntheticDefaultImports"
                        : "esModuleInterop";
                    error(referencingLocation, ts.Diagnostics.This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export, compilerOptionName);
                    return symbol;
                }
                if (compilerOptions.esModuleInterop) {
                    var referenceParent = referencingLocation.parent;
                    if ((ts.isImportDeclaration(referenceParent) && ts.getNamespaceDeclarationNode(referenceParent)) ||
                        ts.isImportCall(referenceParent)) {
                        var type = getTypeOfSymbol(symbol);
                        var sigs = getSignaturesOfStructuredType(type, 0 /* Call */);
                        if (!sigs || !sigs.length) {
                            sigs = getSignaturesOfStructuredType(type, 1 /* Construct */);
                        }
                        if (sigs && sigs.length) {
                            var moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol);
                            // Create a new symbol which has the module's type less the call and construct signatures
                            var result = createSymbol(symbol.flags, symbol.escapedName);
                            result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
                            result.parent = symbol.parent;
                            result.target = symbol;
                            result.originatingImport = referenceParent;
                            if (symbol.valueDeclaration)
                                result.valueDeclaration = symbol.valueDeclaration;
                            if (symbol.constEnumOnlyModule)
                                result.constEnumOnlyModule = true;
                            if (symbol.members)
                                result.members = ts.cloneMap(symbol.members);
                            if (symbol.exports)
                                result.exports = ts.cloneMap(symbol.exports);
                            var resolvedModuleType = resolveStructuredTypeMembers(moduleType); // Should already be resolved from the signature checks above
                            result.type = createAnonymousType(result, resolvedModuleType.members, ts.emptyArray, ts.emptyArray, resolvedModuleType.stringIndexInfo, resolvedModuleType.numberIndexInfo);
                            return result;
                        }
                    }
                }
            }
            return symbol;
        }
        function hasExportAssignmentSymbol(moduleSymbol) {
            return moduleSymbol.exports.get("export=" /* ExportEquals */) !== undefined;
        }
        function getExportsOfModuleAsArray(moduleSymbol) {
            return symbolsToArray(getExportsOfModule(moduleSymbol));
        }
        function getExportsAndPropertiesOfModule(moduleSymbol) {
            var exports = getExportsOfModuleAsArray(moduleSymbol);
            var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
            if (exportEquals !== moduleSymbol) {
                ts.addRange(exports, getPropertiesOfType(getTypeOfSymbol(exportEquals)));
            }
            return exports;
        }
        function tryGetMemberInModuleExports(memberName, moduleSymbol) {
            var symbolTable = getExportsOfModule(moduleSymbol);
            if (symbolTable) {
                return symbolTable.get(memberName);
            }
        }
        function tryGetMemberInModuleExportsAndProperties(memberName, moduleSymbol) {
            var symbol = tryGetMemberInModuleExports(memberName, moduleSymbol);
            if (symbol) {
                return symbol;
            }
            var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
            if (exportEquals === moduleSymbol) {
                return undefined;
            }
            var type = getTypeOfSymbol(exportEquals);
            return type.flags & 131068 /* Primitive */ ||
                ts.getObjectFlags(type) & 1 /* Class */ ||
                isArrayOrTupleLikeType(type)
                ? undefined
                : getPropertyOfType(type, memberName);
        }
        function getExportsOfSymbol(symbol) {
            return symbol.flags & 6256 /* LateBindingContainer */ ? getResolvedMembersOrExportsOfSymbol(symbol, "resolvedExports" /* resolvedExports */) :
                symbol.flags & 1536 /* Module */ ? getExportsOfModule(symbol) :
                    symbol.exports || emptySymbols;
        }
        function getExportsOfModule(moduleSymbol) {
            var links = getSymbolLinks(moduleSymbol);
            return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol));
        }
        /**
         * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument
         * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables
         */
        function extendExportSymbols(target, source, lookupTable, exportNode) {
            if (!source)
                return;
            source.forEach(function (sourceSymbol, id) {
                if (id === "default" /* Default */)
                    return;
                var targetSymbol = target.get(id);
                if (!targetSymbol) {
                    target.set(id, sourceSymbol);
                    if (lookupTable && exportNode) {
                        lookupTable.set(id, {
                            specifierText: ts.getTextOfNode(exportNode.moduleSpecifier)
                        });
                    }
                }
                else if (lookupTable && exportNode && targetSymbol && resolveSymbol(targetSymbol) !== resolveSymbol(sourceSymbol)) {
                    var collisionTracker = lookupTable.get(id);
                    if (!collisionTracker.exportsWithDuplicate) {
                        collisionTracker.exportsWithDuplicate = [exportNode];
                    }
                    else {
                        collisionTracker.exportsWithDuplicate.push(exportNode);
                    }
                }
            });
        }
        function getExportsOfModuleWorker(moduleSymbol) {
            var visitedSymbols = [];
            // A module defined by an 'export=' consists of one export that needs to be resolved
            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
            return visit(moduleSymbol) || emptySymbols;
            // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
            // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error.
            function visit(symbol) {
                if (!(symbol && symbol.exports && ts.pushIfUnique(visitedSymbols, symbol))) {
                    return;
                }
                var symbols = ts.cloneMap(symbol.exports);
                // All export * declarations are collected in an __export symbol by the binder
                var exportStars = symbol.exports.get("__export" /* ExportStar */);
                if (exportStars) {
                    var nestedSymbols = ts.createSymbolTable();
                    var lookupTable_1 = ts.createMap();
                    for (var _i = 0, _a = exportStars.declarations; _i < _a.length; _i++) {
                        var node = _a[_i];
                        var resolvedModule = resolveExternalModuleName(node, node.moduleSpecifier);
                        var exportedSymbols = visit(resolvedModule);
                        extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable_1, node);
                    }
                    lookupTable_1.forEach(function (_a, id) {
                        var exportsWithDuplicate = _a.exportsWithDuplicate;
                        // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself
                        if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols.has(id)) {
                            return;
                        }
                        for (var _i = 0, exportsWithDuplicate_1 = exportsWithDuplicate; _i < exportsWithDuplicate_1.length; _i++) {
                            var node = exportsWithDuplicate_1[_i];
                            diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable_1.get(id).specifierText, ts.unescapeLeadingUnderscores(id)));
                        }
                    });
                    extendExportSymbols(symbols, nestedSymbols);
                }
                return symbols;
            }
        }
        function getMergedSymbol(symbol) {
            var merged;
            return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol;
        }
        function getSymbolOfNode(node) {
            return getMergedSymbol(node.symbol && getLateBoundSymbol(node.symbol));
        }
        function getParentOfSymbol(symbol) {
            return getMergedSymbol(symbol.parent && getLateBoundSymbol(symbol.parent));
        }
        function getAlternativeContainingModules(symbol, enclosingDeclaration) {
            var containingFile = ts.getSourceFileOfNode(enclosingDeclaration);
            var id = "" + getNodeId(containingFile);
            var links = getSymbolLinks(symbol);
            var results;
            if (links.extendedContainersByFile && (results = links.extendedContainersByFile.get(id))) {
                return results;
            }
            if (containingFile && containingFile.imports) {
                // Try to make an import using an import already in the enclosing file, if possible
                for (var _i = 0, _a = containingFile.imports; _i < _a.length; _i++) {
                    var importRef = _a[_i];
                    if (ts.nodeIsSynthesized(importRef))
                        continue; // Synthetic names can't be resolved by `resolveExternalModuleName` - they'll cause a debug assert if they error
                    var resolvedModule = resolveExternalModuleName(enclosingDeclaration, importRef, /*ignoreErrors*/ true);
                    if (!resolvedModule)
                        continue;
                    var ref = getAliasForSymbolInContainer(resolvedModule, symbol);
                    if (!ref)
                        continue;
                    results = ts.append(results, resolvedModule);
                }
                if (ts.length(results)) {
                    (links.extendedContainersByFile || (links.extendedContainersByFile = ts.createMap())).set(id, results);
                    return results;
                }
            }
            if (links.extendedContainers) {
                return links.extendedContainers;
            }
            // No results from files already being imported by this file - expand search (expensive, but not location-specific, so cached)
            var otherFiles = host.getSourceFiles();
            for (var _b = 0, otherFiles_1 = otherFiles; _b < otherFiles_1.length; _b++) {
                var file = otherFiles_1[_b];
                if (!ts.isExternalModule(file))
                    continue;
                var sym = getSymbolOfNode(file);
                var ref = getAliasForSymbolInContainer(sym, symbol);
                if (!ref)
                    continue;
                results = ts.append(results, sym);
            }
            return links.extendedContainers = results || ts.emptyArray;
        }
        /**
         * Attempts to find the symbol corresponding to the container a symbol is in - usually this
         * is just its' `.parent`, but for locals, this value is `undefined`
         */
        function getContainersOfSymbol(symbol, enclosingDeclaration) {
            var container = getParentOfSymbol(symbol);
            // Type parameters end up in the `members` lists but are not externally visible
            if (container && !(symbol.flags & 262144 /* TypeParameter */)) {
                var additionalContainers = ts.mapDefined(container.declarations, fileSymbolIfFileSymbolExportEqualsContainer);
                var reexportContainers = enclosingDeclaration && getAlternativeContainingModules(symbol, enclosingDeclaration);
                if (enclosingDeclaration && getAccessibleSymbolChain(container, enclosingDeclaration, 1920 /* Namespace */, /*externalOnly*/ false)) {
                    return ts.concatenate(ts.concatenate([container], additionalContainers), reexportContainers); // This order expresses a preference for the real container if it is in scope
                }
                var res = ts.append(additionalContainers, container);
                return ts.concatenate(res, reexportContainers);
            }
            var candidates = ts.mapDefined(symbol.declarations, function (d) {
                if (!ts.isAmbientModule(d) && d.parent && hasNonGlobalAugmentationExternalModuleSymbol(d.parent)) {
                    return getSymbolOfNode(d.parent);
                }
                if (ts.isClassExpression(d) && ts.isBinaryExpression(d.parent) && d.parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isAccessExpression(d.parent.left) && ts.isEntityNameExpression(d.parent.left.expression)) {
                    if (ts.isModuleExportsAccessExpression(d.parent.left) || ts.isExportsIdentifier(d.parent.left.expression)) {
                        return getSymbolOfNode(ts.getSourceFileOfNode(d));
                    }
                    checkExpressionCached(d.parent.left.expression);
                    return getNodeLinks(d.parent.left.expression).resolvedSymbol;
                }
            });
            if (!ts.length(candidates)) {
                return undefined;
            }
            return ts.mapDefined(candidates, function (candidate) { return getAliasForSymbolInContainer(candidate, symbol) ? candidate : undefined; });
            function fileSymbolIfFileSymbolExportEqualsContainer(d) {
                return container && getFileSymbolIfFileSymbolExportEqualsContainer(d, container);
            }
        }
        function getFileSymbolIfFileSymbolExportEqualsContainer(d, container) {
            var fileSymbol = getExternalModuleContainer(d);
            var exported = fileSymbol && fileSymbol.exports && fileSymbol.exports.get("export=" /* ExportEquals */);
            return exported && getSymbolIfSameReference(exported, container) ? fileSymbol : undefined;
        }
        function getAliasForSymbolInContainer(container, symbol) {
            if (container === getParentOfSymbol(symbol)) {
                // fast path, `symbol` is either already the alias or isn't aliased
                return symbol;
            }
            // Check if container is a thing with an `export=` which points directly at `symbol`, and if so, return
            // the container itself as the alias for the symbol
            var exportEquals = container.exports && container.exports.get("export=" /* ExportEquals */);
            if (exportEquals && getSymbolIfSameReference(exportEquals, symbol)) {
                return container;
            }
            var exports = getExportsOfSymbol(container);
            var quick = exports.get(symbol.escapedName);
            if (quick && getSymbolIfSameReference(quick, symbol)) {
                return quick;
            }
            return ts.forEachEntry(exports, function (exported) {
                if (getSymbolIfSameReference(exported, symbol)) {
                    return exported;
                }
            });
        }
        /**
         * Checks if two symbols, through aliasing and/or merging, refer to the same thing
         */
        function getSymbolIfSameReference(s1, s2) {
            if (getMergedSymbol(resolveSymbol(getMergedSymbol(s1))) === getMergedSymbol(resolveSymbol(getMergedSymbol(s2)))) {
                return s1;
            }
        }
        function getExportSymbolOfValueSymbolIfExported(symbol) {
            return getMergedSymbol(symbol && (symbol.flags & 1048576 /* ExportValue */) !== 0 ? symbol.exportSymbol : symbol);
        }
        function symbolIsValue(symbol) {
            return !!(symbol.flags & 111551 /* Value */ || symbol.flags & 2097152 /* Alias */ && resolveAlias(symbol).flags & 111551 /* Value */ && !getTypeOnlyAliasDeclaration(symbol));
        }
        function findConstructorDeclaration(node) {
            var members = node.members;
            for (var _i = 0, members_3 = members; _i < members_3.length; _i++) {
                var member = members_3[_i];
                if (member.kind === 162 /* Constructor */ && ts.nodeIsPresent(member.body)) {
                    return member;
                }
            }
        }
        function createType(flags) {
            var result = new Type(checker, flags);
            typeCount++;
            result.id = typeCount;
            return result;
        }
        function createIntrinsicType(kind, intrinsicName, objectFlags) {
            if (objectFlags === void 0) { objectFlags = 0; }
            var type = createType(kind);
            type.intrinsicName = intrinsicName;
            type.objectFlags = objectFlags;
            return type;
        }
        function createBooleanType(trueFalseTypes) {
            var type = getUnionType(trueFalseTypes);
            type.flags |= 16 /* Boolean */;
            type.intrinsicName = "boolean";
            return type;
        }
        function createObjectType(objectFlags, symbol) {
            var type = createType(524288 /* Object */);
            type.objectFlags = objectFlags;
            type.symbol = symbol;
            type.members = undefined;
            type.properties = undefined;
            type.callSignatures = undefined;
            type.constructSignatures = undefined;
            type.stringIndexInfo = undefined;
            type.numberIndexInfo = undefined;
            return type;
        }
        function createTypeofType() {
            return getUnionType(ts.arrayFrom(typeofEQFacts.keys(), getLiteralType));
        }
        function createTypeParameter(symbol) {
            var type = createType(262144 /* TypeParameter */);
            if (symbol)
                type.symbol = symbol;
            return type;
        }
        // A reserved member name starts with two underscores, but the third character cannot be an underscore,
        // @, or #. A third underscore indicates an escaped form of an identifier that started
        // with at least two underscores. The @ character indicates that the name is denoted by a well known ES
        // Symbol instance and the # character indicates that the name is a PrivateIdentifier.
        function isReservedMemberName(name) {
            return name.charCodeAt(0) === 95 /* _ */ &&
                name.charCodeAt(1) === 95 /* _ */ &&
                name.charCodeAt(2) !== 95 /* _ */ &&
                name.charCodeAt(2) !== 64 /* at */ &&
                name.charCodeAt(2) !== 35 /* hash */;
        }
        function getNamedMembers(members) {
            var result;
            members.forEach(function (symbol, id) {
                if (!isReservedMemberName(id) && symbolIsValue(symbol)) {
                    (result || (result = [])).push(symbol);
                }
            });
            return result || ts.emptyArray;
        }
        function setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
            type.members = members;
            type.properties = members === emptySymbols ? ts.emptyArray : getNamedMembers(members);
            type.callSignatures = callSignatures;
            type.constructSignatures = constructSignatures;
            type.stringIndexInfo = stringIndexInfo;
            type.numberIndexInfo = numberIndexInfo;
            return type;
        }
        function createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
            return setStructuredTypeMembers(createObjectType(16 /* Anonymous */, symbol), members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function forEachSymbolTableInScope(enclosingDeclaration, callback) {
            var result;
            var _loop_7 = function (location) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location.locals && !isGlobalSourceFile(location)) {
                    if (result = callback(location.locals)) {
                        return { value: result };
                    }
                }
                switch (location.kind) {
                    case 290 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location)) {
                            break;
                        }
                    // falls through
                    case 249 /* ModuleDeclaration */:
                        var sym = getSymbolOfNode(location);
                        // `sym` may not have exports if this module declaration is backed by the symbol for a `const` that's being rewritten
                        // into a namespace - in such cases, it's best to just let the namespace appear empty (the const members couldn't have referred
                        // to one another anyway)
                        if (result = callback((sym === null || sym === void 0 ? void 0 : sym.exports) || emptySymbols)) {
                            return { value: result };
                        }
                        break;
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                        // Type parameters are bound into `members` lists so they can merge across declarations
                        // This is troublesome, since in all other respects, they behave like locals :cries:
                        // TODO: the below is shared with similar code in `resolveName` - in fact, rephrasing all this symbol
                        // lookup logic in terms of `resolveName` would be nice
                        // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals
                        // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would
                        // trigger resolving late-bound names, which we may already be in the process of doing while we're here!
                        var table_1;
                        // TODO: Should this filtered table be cached in some way?
                        (getSymbolOfNode(location).members || emptySymbols).forEach(function (memberSymbol, key) {
                            if (memberSymbol.flags & (788968 /* Type */ & ~67108864 /* Assignment */)) {
                                (table_1 || (table_1 = ts.createSymbolTable())).set(key, memberSymbol);
                            }
                        });
                        if (table_1 && (result = callback(table_1))) {
                            return { value: result };
                        }
                        break;
                }
            };
            for (var location = enclosingDeclaration; location; location = location.parent) {
                var state_2 = _loop_7(location);
                if (typeof state_2 === "object")
                    return state_2.value;
            }
            return callback(globals);
        }
        function getQualifiedLeftMeaning(rightMeaning) {
            // If we are looking in value space, the parent meaning is value, other wise it is namespace
            return rightMeaning === 111551 /* Value */ ? 111551 /* Value */ : 1920 /* Namespace */;
        }
        function getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing, visitedSymbolTablesMap) {
            if (visitedSymbolTablesMap === void 0) { visitedSymbolTablesMap = ts.createMap(); }
            if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) {
                return undefined;
            }
            var id = "" + getSymbolId(symbol);
            var visitedSymbolTables = visitedSymbolTablesMap.get(id);
            if (!visitedSymbolTables) {
                visitedSymbolTablesMap.set(id, visitedSymbolTables = []);
            }
            return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
            /**
             * @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already)
             */
            function getAccessibleSymbolChainFromSymbolTable(symbols, ignoreQualification) {
                if (!ts.pushIfUnique(visitedSymbolTables, symbols)) {
                    return undefined;
                }
                var result = trySymbolTable(symbols, ignoreQualification);
                visitedSymbolTables.pop();
                return result;
            }
            function canQualifySymbol(symbolFromSymbolTable, meaning) {
                // If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
                return !needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning) ||
                    // If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too
                    !!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing, visitedSymbolTablesMap);
            }
            function isAccessible(symbolFromSymbolTable, resolvedAliasSymbol, ignoreQualification) {
                return (symbol === (resolvedAliasSymbol || symbolFromSymbolTable) || getMergedSymbol(symbol) === getMergedSymbol(resolvedAliasSymbol || symbolFromSymbolTable)) &&
                    // if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
                    // and if symbolFromSymbolTable or alias resolution matches the symbol,
                    // check the symbol can be qualified, it is only then this symbol is accessible
                    !ts.some(symbolFromSymbolTable.declarations, hasNonGlobalAugmentationExternalModuleSymbol) &&
                    (ignoreQualification || canQualifySymbol(getMergedSymbol(symbolFromSymbolTable), meaning));
            }
            function trySymbolTable(symbols, ignoreQualification) {
                // If symbol is directly available by its name in the symbol table
                if (isAccessible(symbols.get(symbol.escapedName), /*resolvedAliasSymbol*/ undefined, ignoreQualification)) {
                    return [symbol];
                }
                // Check if symbol is any of the aliases in scope
                var result = ts.forEachEntry(symbols, function (symbolFromSymbolTable) {
                    if (symbolFromSymbolTable.flags & 2097152 /* Alias */
                        && symbolFromSymbolTable.escapedName !== "export=" /* ExportEquals */
                        && symbolFromSymbolTable.escapedName !== "default" /* Default */
                        && !(ts.isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && ts.isExternalModule(ts.getSourceFileOfNode(enclosingDeclaration)))
                        // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
                        && (!useOnlyExternalAliasing || ts.some(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration))
                        // While exports are generally considered to be in scope, export-specifier declared symbols are _not_
                        // See similar comment in `resolveName` for details
                        && (ignoreQualification || !ts.getDeclarationOfKind(symbolFromSymbolTable, 263 /* ExportSpecifier */))) {
                        var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
                        var candidate = getCandidateListForSymbol(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification);
                        if (candidate) {
                            return candidate;
                        }
                    }
                    if (symbolFromSymbolTable.escapedName === symbol.escapedName && symbolFromSymbolTable.exportSymbol) {
                        if (isAccessible(getMergedSymbol(symbolFromSymbolTable.exportSymbol), /*aliasSymbol*/ undefined, ignoreQualification)) {
                            return [symbol];
                        }
                    }
                });
                // If there's no result and we're looking at the global symbol table, treat `globalThis` like an alias and try to lookup thru that
                return result || (symbols === globals ? getCandidateListForSymbol(globalThisSymbol, globalThisSymbol, ignoreQualification) : undefined);
            }
            function getCandidateListForSymbol(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification) {
                if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification)) {
                    return [symbolFromSymbolTable];
                }
                // Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
                // but only if the symbolFromSymbolTable can be qualified
                var candidateTable = getExportsOfSymbol(resolvedImportedSymbol);
                var accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable, /*ignoreQualification*/ true);
                if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
                    return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
                }
            }
        }
        function needsQualification(symbol, enclosingDeclaration, meaning) {
            var qualify = false;
            forEachSymbolTableInScope(enclosingDeclaration, function (symbolTable) {
                // If symbol of this name is not available in the symbol table we are ok
                var symbolFromSymbolTable = getMergedSymbol(symbolTable.get(symbol.escapedName));
                if (!symbolFromSymbolTable) {
                    // Continue to the next symbol table
                    return false;
                }
                // If the symbol with this name is present it should refer to the symbol
                if (symbolFromSymbolTable === symbol) {
                    // No need to qualify
                    return true;
                }
                // Qualify if the symbol from symbol table has same meaning as expected
                symbolFromSymbolTable = (symbolFromSymbolTable.flags & 2097152 /* Alias */ && !ts.getDeclarationOfKind(symbolFromSymbolTable, 263 /* ExportSpecifier */)) ? resolveAlias(symbolFromSymbolTable) : symbolFromSymbolTable;
                if (symbolFromSymbolTable.flags & meaning) {
                    qualify = true;
                    return true;
                }
                // Continue to the next symbol table
                return false;
            });
            return qualify;
        }
        function isPropertyOrMethodDeclarationSymbol(symbol) {
            if (symbol.declarations && symbol.declarations.length) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    switch (declaration.kind) {
                        case 159 /* PropertyDeclaration */:
                        case 161 /* MethodDeclaration */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                            continue;
                        default:
                            return false;
                    }
                }
                return true;
            }
            return false;
        }
        function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) {
            var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 788968 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false);
            return access.accessibility === 0 /* Accessible */;
        }
        function isValueSymbolAccessible(typeSymbol, enclosingDeclaration) {
            var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 111551 /* Value */, /*shouldComputeAliasesToMakeVisible*/ false);
            return access.accessibility === 0 /* Accessible */;
        }
        function isAnySymbolAccessible(symbols, enclosingDeclaration, initialSymbol, meaning, shouldComputeAliasesToMakeVisible) {
            if (!ts.length(symbols))
                return;
            var hadAccessibleChain;
            var earlyModuleBail = false;
            for (var _i = 0, _a = symbols; _i < _a.length; _i++) {
                var symbol = _a[_i];
                // Symbol is accessible if it by itself is accessible
                var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false);
                if (accessibleSymbolChain) {
                    hadAccessibleChain = symbol;
                    var hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible);
                    if (hasAccessibleDeclarations) {
                        return hasAccessibleDeclarations;
                    }
                }
                else {
                    if (ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                        if (shouldComputeAliasesToMakeVisible) {
                            earlyModuleBail = true;
                            // Generally speaking, we want to use the aliases that already exist to refer to a module, if present
                            // In order to do so, we need to find those aliases in order to retain them in declaration emit; so
                            // if we are in declaration emit, we cannot use the fast path for module visibility until we've exhausted
                            // all other visibility options (in order to capture the possible aliases used to reference the module)
                            continue;
                        }
                        // Any meaning of a module symbol is always accessible via an `import` type
                        return {
                            accessibility: 0 /* Accessible */
                        };
                    }
                }
                // If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible.
                // It could be a qualified symbol and hence verify the path
                // e.g.:
                // module m {
                //     export class c {
                //     }
                // }
                // const x: typeof m.c
                // In the above example when we start with checking if typeof m.c symbol is accessible,
                // we are going to see if c can be accessed in scope directly.
                // But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
                // It is accessible if the parent m is accessible because then m.c can be accessed through qualification
                var containers = getContainersOfSymbol(symbol, enclosingDeclaration);
                // If we're trying to reference some object literal in, eg `var a = { x: 1 }`, the symbol for the literal, `__object`, is distinct
                // from the symbol of the declaration it is being assigned to. Since we can use the declaration to refer to the literal, however,
                // we'd like to make that connection here - potentially causing us to paint the declaration's visibility, and therefore the literal.
                var firstDecl = !!ts.length(symbol.declarations) && ts.first(symbol.declarations);
                if (!ts.length(containers) && meaning & 111551 /* Value */ && firstDecl && ts.isObjectLiteralExpression(firstDecl)) {
                    if (firstDecl.parent && ts.isVariableDeclaration(firstDecl.parent) && firstDecl === firstDecl.parent.initializer) {
                        containers = [getSymbolOfNode(firstDecl.parent)];
                    }
                }
                var parentResult = isAnySymbolAccessible(containers, enclosingDeclaration, initialSymbol, initialSymbol === symbol ? getQualifiedLeftMeaning(meaning) : meaning, shouldComputeAliasesToMakeVisible);
                if (parentResult) {
                    return parentResult;
                }
            }
            if (earlyModuleBail) {
                return {
                    accessibility: 0 /* Accessible */
                };
            }
            if (hadAccessibleChain) {
                return {
                    accessibility: 1 /* NotAccessible */,
                    errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                    errorModuleName: hadAccessibleChain !== initialSymbol ? symbolToString(hadAccessibleChain, enclosingDeclaration, 1920 /* Namespace */) : undefined,
                };
            }
        }
        /**
         * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested
         *
         * @param symbol a Symbol to check if accessible
         * @param enclosingDeclaration a Node containing reference to the symbol
         * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible
         * @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible
         */
        function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) {
            if (symbol && enclosingDeclaration) {
                var result = isAnySymbolAccessible([symbol], enclosingDeclaration, symbol, meaning, shouldComputeAliasesToMakeVisible);
                if (result) {
                    return result;
                }
                // This could be a symbol that is not exported in the external module
                // or it could be a symbol from different external module that is not aliased and hence cannot be named
                var symbolExternalModule = ts.forEach(symbol.declarations, getExternalModuleContainer);
                if (symbolExternalModule) {
                    var enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration);
                    if (symbolExternalModule !== enclosingExternalModule) {
                        // name from different external module that is not visible
                        return {
                            accessibility: 2 /* CannotBeNamed */,
                            errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning),
                            errorModuleName: symbolToString(symbolExternalModule)
                        };
                    }
                }
                // Just a local name that is not accessible
                return {
                    accessibility: 1 /* NotAccessible */,
                    errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning),
                };
            }
            return { accessibility: 0 /* Accessible */ };
        }
        function getExternalModuleContainer(declaration) {
            var node = ts.findAncestor(declaration, hasExternalModuleSymbol);
            return node && getSymbolOfNode(node);
        }
        function hasExternalModuleSymbol(declaration) {
            return ts.isAmbientModule(declaration) || (declaration.kind === 290 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
        }
        function hasNonGlobalAugmentationExternalModuleSymbol(declaration) {
            return ts.isModuleWithStringLiteralName(declaration) || (declaration.kind === 290 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
        }
        function hasVisibleDeclarations(symbol, shouldComputeAliasToMakeVisible) {
            var aliasesToMakeVisible;
            if (!ts.every(ts.filter(symbol.declarations, function (d) { return d.kind !== 75 /* Identifier */; }), getIsDeclarationVisible)) {
                return undefined;
            }
            return { accessibility: 0 /* Accessible */, aliasesToMakeVisible: aliasesToMakeVisible };
            function getIsDeclarationVisible(declaration) {
                if (!isDeclarationVisible(declaration)) {
                    // Mark the unexported alias as visible if its parent is visible
                    // because these kind of aliases can be used to name types in declaration file
                    var anyImportSyntax = getAnyImportSyntax(declaration);
                    if (anyImportSyntax &&
                        !ts.hasModifier(anyImportSyntax, 1 /* Export */) && // import clause without export
                        isDeclarationVisible(anyImportSyntax.parent)) {
                        return addVisibleAlias(declaration, anyImportSyntax);
                    }
                    else if (ts.isVariableDeclaration(declaration) && ts.isVariableStatement(declaration.parent.parent) &&
                        !ts.hasModifier(declaration.parent.parent, 1 /* Export */) && // unexported variable statement
                        isDeclarationVisible(declaration.parent.parent.parent)) {
                        return addVisibleAlias(declaration, declaration.parent.parent);
                    }
                    else if (ts.isLateVisibilityPaintedStatement(declaration) // unexported top-level statement
                        && !ts.hasModifier(declaration, 1 /* Export */)
                        && isDeclarationVisible(declaration.parent)) {
                        return addVisibleAlias(declaration, declaration);
                    }
                    // Declaration is not visible
                    return false;
                }
                return true;
            }
            function addVisibleAlias(declaration, aliasingStatement) {
                // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types,
                // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time
                // since we will do the emitting later in trackSymbol.
                if (shouldComputeAliasToMakeVisible) {
                    getNodeLinks(declaration).isVisible = true;
                    aliasesToMakeVisible = ts.appendIfUnique(aliasesToMakeVisible, aliasingStatement);
                }
                return true;
            }
        }
        function isEntityNameVisible(entityName, enclosingDeclaration) {
            // get symbol of the first identifier of the entityName
            var meaning;
            if (entityName.parent.kind === 172 /* TypeQuery */ ||
                ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent) ||
                entityName.parent.kind === 154 /* ComputedPropertyName */) {
                // Typeof value
                meaning = 111551 /* Value */ | 1048576 /* ExportValue */;
            }
            else if (entityName.kind === 153 /* QualifiedName */ || entityName.kind === 194 /* PropertyAccessExpression */ ||
                entityName.parent.kind === 253 /* ImportEqualsDeclaration */) {
                // Left identifier from type reference or TypeAlias
                // Entity name of the import declaration
                meaning = 1920 /* Namespace */;
            }
            else {
                // Type Reference or TypeAlias entity = Identifier
                meaning = 788968 /* Type */;
            }
            var firstIdentifier = ts.getFirstIdentifier(entityName);
            var symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
            // Verify if the symbol is accessible
            return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || {
                accessibility: 1 /* NotAccessible */,
                errorSymbolName: ts.getTextOfNode(firstIdentifier),
                errorNode: firstIdentifier
            };
        }
        function symbolToString(symbol, enclosingDeclaration, meaning, flags, writer) {
            if (flags === void 0) { flags = 4 /* AllowAnyNodeKind */; }
            var nodeFlags = 70221824 /* IgnoreErrors */;
            if (flags & 2 /* UseOnlyExternalAliasing */) {
                nodeFlags |= 128 /* UseOnlyExternalAliasing */;
            }
            if (flags & 1 /* WriteTypeParametersOrArguments */) {
                nodeFlags |= 512 /* WriteTypeParametersInQualifiedName */;
            }
            if (flags & 8 /* UseAliasDefinedOutsideCurrentScope */) {
                nodeFlags |= 16384 /* UseAliasDefinedOutsideCurrentScope */;
            }
            if (flags & 16 /* DoNotIncludeSymbolChain */) {
                nodeFlags |= 134217728 /* DoNotIncludeSymbolChain */;
            }
            var builder = flags & 4 /* AllowAnyNodeKind */ ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName;
            return writer ? symbolToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(symbolToStringWorker);
            function symbolToStringWorker(writer) {
                var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); // TODO: GH#18217
                var printer = ts.createPrinter({ removeComments: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, entity, /*sourceFile*/ sourceFile, writer);
                return writer;
            }
        }
        function signatureToString(signature, enclosingDeclaration, flags, kind, writer) {
            if (flags === void 0) { flags = 0 /* None */; }
            return writer ? signatureToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(signatureToStringWorker);
            function signatureToStringWorker(writer) {
                var sigOutput;
                if (flags & 262144 /* WriteArrowStyleSignature */) {
                    sigOutput = kind === 1 /* Construct */ ? 171 /* ConstructorType */ : 170 /* FunctionType */;
                }
                else {
                    sigOutput = kind === 1 /* Construct */ ? 166 /* ConstructSignature */ : 165 /* CallSignature */;
                }
                var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | 512 /* WriteTypeParametersInQualifiedName */);
                var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, sig, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217
                return writer;
            }
        }
        function typeToString(type, enclosingDeclaration, flags, writer) {
            if (flags === void 0) { flags = 1048576 /* AllowUniqueESSymbolType */ | 16384 /* UseAliasDefinedOutsideCurrentScope */; }
            if (writer === void 0) { writer = ts.createTextWriter(""); }
            var noTruncation = compilerOptions.noErrorTruncation || flags & 1 /* NoTruncation */;
            var typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | (noTruncation ? 1 /* NoTruncation */ : 0), writer);
            if (typeNode === undefined)
                return ts.Debug.fail("should always get typenode");
            var options = { removeComments: true };
            var printer = ts.createPrinter(options);
            var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
            printer.writeNode(4 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer);
            var result = writer.getText();
            var maxLength = noTruncation ? ts.noTruncationMaximumTruncationLength * 2 : ts.defaultMaximumTruncationLength * 2;
            if (maxLength && result && result.length >= maxLength) {
                return result.substr(0, maxLength - "...".length) + "...";
            }
            return result;
        }
        function getTypeNamesForErrorDisplay(left, right) {
            var leftStr = symbolValueDeclarationIsContextSensitive(left.symbol) ? typeToString(left, left.symbol.valueDeclaration) : typeToString(left);
            var rightStr = symbolValueDeclarationIsContextSensitive(right.symbol) ? typeToString(right, right.symbol.valueDeclaration) : typeToString(right);
            if (leftStr === rightStr) {
                leftStr = typeToString(left, /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */);
                rightStr = typeToString(right, /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */);
            }
            return [leftStr, rightStr];
        }
        function symbolValueDeclarationIsContextSensitive(symbol) {
            return symbol && symbol.valueDeclaration && ts.isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration);
        }
        function toNodeBuilderFlags(flags) {
            if (flags === void 0) { flags = 0 /* None */; }
            return flags & 814775659 /* NodeBuilderFlagsMask */;
        }
        function createNodeBuilder() {
            return {
                typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); });
                },
                indexInfoToIndexSignatureDeclaration: function (indexInfo, kind, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context); });
                },
                signatureToSignatureDeclaration: function (signature, kind, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return signatureToSignatureDeclarationHelper(signature, kind, context); });
                },
                symbolToEntityName: function (symbol, meaning, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false); });
                },
                symbolToExpression: function (symbol, meaning, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToExpression(symbol, context, meaning); });
                },
                symbolToTypeParameterDeclarations: function (symbol, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeParametersToTypeParameterDeclarations(symbol, context); });
                },
                symbolToParameterDeclaration: function (symbol, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToParameterDeclaration(symbol, context); });
                },
                typeParameterToDeclaration: function (parameter, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeParameterToDeclaration(parameter, context); });
                },
                symbolTableToDeclarationStatements: function (symbolTable, enclosingDeclaration, flags, tracker, bundled) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolTableToDeclarationStatements(symbolTable, context, bundled); });
                },
            };
            function withContext(enclosingDeclaration, flags, tracker, cb) {
                ts.Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & 8 /* Synthesized */) === 0);
                var context = {
                    enclosingDeclaration: enclosingDeclaration,
                    flags: flags || 0 /* None */,
                    // If no full tracker is provided, fake up a dummy one with a basic limited-functionality moduleResolverHost
                    tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: ts.noop, moduleResolverHost: flags & 134217728 /* DoNotIncludeSymbolChain */ ? {
                            getCommonSourceDirectory: !!host.getCommonSourceDirectory ? function () { return host.getCommonSourceDirectory(); } : function () { return ""; },
                            getSourceFiles: function () { return host.getSourceFiles(); },
                            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
                            getProbableSymlinks: ts.maybeBind(host, host.getProbableSymlinks),
                            useCaseSensitiveFileNames: ts.maybeBind(host, host.useCaseSensitiveFileNames),
                            redirectTargetsMap: host.redirectTargetsMap,
                            getProjectReferenceRedirect: function (fileName) { return host.getProjectReferenceRedirect(fileName); },
                            isSourceOfProjectReferenceRedirect: function (fileName) { return host.isSourceOfProjectReferenceRedirect(fileName); },
                            fileExists: function (fileName) { return host.fileExists(fileName); },
                        } : undefined },
                    encounteredError: false,
                    visitedTypes: undefined,
                    symbolDepth: undefined,
                    inferTypeParameters: undefined,
                    approximateLength: 0
                };
                var resultingNode = cb(context);
                return context.encounteredError ? undefined : resultingNode;
            }
            function checkTruncationLength(context) {
                if (context.truncating)
                    return context.truncating;
                return context.truncating = context.approximateLength > ((context.flags & 1 /* NoTruncation */) ? ts.noTruncationMaximumTruncationLength : ts.defaultMaximumTruncationLength);
            }
            function typeToTypeNodeHelper(type, context) {
                if (cancellationToken && cancellationToken.throwIfCancellationRequested) {
                    cancellationToken.throwIfCancellationRequested();
                }
                var inTypeAlias = context.flags & 8388608 /* InTypeAlias */;
                context.flags &= ~8388608 /* InTypeAlias */;
                if (!type) {
                    if (!(context.flags & 262144 /* AllowEmptyUnionOrIntersection */)) {
                        context.encounteredError = true;
                        return undefined; // TODO: GH#18217
                    }
                    context.approximateLength += 3;
                    return ts.createKeywordTypeNode(125 /* AnyKeyword */);
                }
                if (!(context.flags & 536870912 /* NoTypeReduction */)) {
                    type = getReducedType(type);
                }
                if (type.flags & 1 /* Any */) {
                    context.approximateLength += 3;
                    return ts.createKeywordTypeNode(125 /* AnyKeyword */);
                }
                if (type.flags & 2 /* Unknown */) {
                    return ts.createKeywordTypeNode(148 /* UnknownKeyword */);
                }
                if (type.flags & 4 /* String */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(143 /* StringKeyword */);
                }
                if (type.flags & 8 /* Number */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(140 /* NumberKeyword */);
                }
                if (type.flags & 64 /* BigInt */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(151 /* BigIntKeyword */);
                }
                if (type.flags & 16 /* Boolean */) {
                    context.approximateLength += 7;
                    return ts.createKeywordTypeNode(128 /* BooleanKeyword */);
                }
                if (type.flags & 1024 /* EnumLiteral */ && !(type.flags & 1048576 /* Union */)) {
                    var parentSymbol = getParentOfSymbol(type.symbol);
                    var parentName = symbolToTypeNode(parentSymbol, context, 788968 /* Type */);
                    var enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type
                        ? parentName
                        : appendReferenceToType(parentName, ts.createTypeReferenceNode(ts.symbolName(type.symbol), /*typeArguments*/ undefined));
                    return enumLiteralName;
                }
                if (type.flags & 1056 /* EnumLike */) {
                    return symbolToTypeNode(type.symbol, context, 788968 /* Type */);
                }
                if (type.flags & 128 /* StringLiteral */) {
                    context.approximateLength += (type.value.length + 2);
                    return ts.createLiteralTypeNode(ts.setEmitFlags(ts.createLiteral(type.value, !!(context.flags & 268435456 /* UseSingleQuotesForStringLiteralType */)), 16777216 /* NoAsciiEscaping */));
                }
                if (type.flags & 256 /* NumberLiteral */) {
                    var value = type.value;
                    context.approximateLength += ("" + value).length;
                    return ts.createLiteralTypeNode(value < 0 ? ts.createPrefix(40 /* MinusToken */, ts.createLiteral(-value)) : ts.createLiteral(value));
                }
                if (type.flags & 2048 /* BigIntLiteral */) {
                    context.approximateLength += (ts.pseudoBigIntToString(type.value).length) + 1;
                    return ts.createLiteralTypeNode((ts.createLiteral(type.value)));
                }
                if (type.flags & 512 /* BooleanLiteral */) {
                    context.approximateLength += type.intrinsicName.length;
                    return type.intrinsicName === "true" ? ts.createTrue() : ts.createFalse();
                }
                if (type.flags & 8192 /* UniqueESSymbol */) {
                    if (!(context.flags & 1048576 /* AllowUniqueESSymbolType */)) {
                        if (isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                            context.approximateLength += 6;
                            return symbolToTypeNode(type.symbol, context, 111551 /* Value */);
                        }
                        if (context.tracker.reportInaccessibleUniqueSymbolError) {
                            context.tracker.reportInaccessibleUniqueSymbolError();
                        }
                    }
                    context.approximateLength += 13;
                    return ts.createTypeOperatorNode(147 /* UniqueKeyword */, ts.createKeywordTypeNode(144 /* SymbolKeyword */));
                }
                if (type.flags & 16384 /* Void */) {
                    context.approximateLength += 4;
                    return ts.createKeywordTypeNode(110 /* VoidKeyword */);
                }
                if (type.flags & 32768 /* Undefined */) {
                    context.approximateLength += 9;
                    return ts.createKeywordTypeNode(146 /* UndefinedKeyword */);
                }
                if (type.flags & 65536 /* Null */) {
                    context.approximateLength += 4;
                    return ts.createKeywordTypeNode(100 /* NullKeyword */);
                }
                if (type.flags & 131072 /* Never */) {
                    context.approximateLength += 5;
                    return ts.createKeywordTypeNode(137 /* NeverKeyword */);
                }
                if (type.flags & 4096 /* ESSymbol */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(144 /* SymbolKeyword */);
                }
                if (type.flags & 67108864 /* NonPrimitive */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(141 /* ObjectKeyword */);
                }
                if (isThisTypeParameter(type)) {
                    if (context.flags & 4194304 /* InObjectTypeLiteral */) {
                        if (!context.encounteredError && !(context.flags & 32768 /* AllowThisInObjectLiteral */)) {
                            context.encounteredError = true;
                        }
                        if (context.tracker.reportInaccessibleThisError) {
                            context.tracker.reportInaccessibleThisError();
                        }
                    }
                    context.approximateLength += 4;
                    return ts.createThis();
                }
                if (!inTypeAlias && type.aliasSymbol && (context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */ || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) {
                    var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
                    if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & 32 /* Class */))
                        return ts.createTypeReferenceNode(ts.createIdentifier(""), typeArgumentNodes);
                    return symbolToTypeNode(type.aliasSymbol, context, 788968 /* Type */, typeArgumentNodes);
                }
                var objectFlags = ts.getObjectFlags(type);
                if (objectFlags & 4 /* Reference */) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    return type.node ? visitAndTransformType(type, typeReferenceToTypeNode) : typeReferenceToTypeNode(type);
                }
                if (type.flags & 262144 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) {
                    if (type.flags & 262144 /* TypeParameter */ && ts.contains(context.inferTypeParameters, type)) {
                        context.approximateLength += (ts.symbolName(type.symbol).length + 6);
                        return ts.createInferTypeNode(typeParameterToDeclarationWithConstraint(type, context, /*constraintNode*/ undefined));
                    }
                    if (context.flags & 4 /* GenerateNamesForShadowedTypeParams */ &&
                        type.flags & 262144 /* TypeParameter */ &&
                        !isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                        var name = typeParameterToName(type, context);
                        context.approximateLength += ts.idText(name).length;
                        return ts.createTypeReferenceNode(ts.createIdentifier(ts.idText(name)), /*typeArguments*/ undefined);
                    }
                    // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
                    return type.symbol
                        ? symbolToTypeNode(type.symbol, context, 788968 /* Type */)
                        : ts.createTypeReferenceNode(ts.createIdentifier("?"), /*typeArguments*/ undefined);
                }
                if (type.flags & (1048576 /* Union */ | 2097152 /* Intersection */)) {
                    var types = type.flags & 1048576 /* Union */ ? formatUnionTypes(type.types) : type.types;
                    if (ts.length(types) === 1) {
                        return typeToTypeNodeHelper(types[0], context);
                    }
                    var typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true);
                    if (typeNodes && typeNodes.length > 0) {
                        var unionOrIntersectionTypeNode = ts.createUnionOrIntersectionTypeNode(type.flags & 1048576 /* Union */ ? 178 /* UnionType */ : 179 /* IntersectionType */, typeNodes);
                        return unionOrIntersectionTypeNode;
                    }
                    else {
                        if (!context.encounteredError && !(context.flags & 262144 /* AllowEmptyUnionOrIntersection */)) {
                            context.encounteredError = true;
                        }
                        return undefined; // TODO: GH#18217
                    }
                }
                if (objectFlags & (16 /* Anonymous */ | 32 /* Mapped */)) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    // The type is an object literal type.
                    return createAnonymousTypeNode(type);
                }
                if (type.flags & 4194304 /* Index */) {
                    var indexedType = type.type;
                    context.approximateLength += 6;
                    var indexTypeNode = typeToTypeNodeHelper(indexedType, context);
                    return ts.createTypeOperatorNode(indexTypeNode);
                }
                if (type.flags & 8388608 /* IndexedAccess */) {
                    var objectTypeNode = typeToTypeNodeHelper(type.objectType, context);
                    var indexTypeNode = typeToTypeNodeHelper(type.indexType, context);
                    context.approximateLength += 2;
                    return ts.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
                }
                if (type.flags & 16777216 /* Conditional */) {
                    var checkTypeNode = typeToTypeNodeHelper(type.checkType, context);
                    var saveInferTypeParameters = context.inferTypeParameters;
                    context.inferTypeParameters = type.root.inferTypeParameters;
                    var extendsTypeNode = typeToTypeNodeHelper(type.extendsType, context);
                    context.inferTypeParameters = saveInferTypeParameters;
                    var trueTypeNode = typeToTypeNodeOrCircularityElision(getTrueTypeFromConditionalType(type));
                    var falseTypeNode = typeToTypeNodeOrCircularityElision(getFalseTypeFromConditionalType(type));
                    context.approximateLength += 15;
                    return ts.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode);
                }
                if (type.flags & 33554432 /* Substitution */) {
                    return typeToTypeNodeHelper(type.baseType, context);
                }
                return ts.Debug.fail("Should be unreachable.");
                function typeToTypeNodeOrCircularityElision(type) {
                    var _a, _b;
                    if (type.flags & 1048576 /* Union */) {
                        if (context.visitedTypes && context.visitedTypes.has("" + getTypeId(type))) {
                            if (!(context.flags & 131072 /* AllowAnonymousIdentifier */)) {
                                context.encounteredError = true;
                                (_b = (_a = context.tracker) === null || _a === void 0 ? void 0 : _a.reportCyclicStructureError) === null || _b === void 0 ? void 0 : _b.call(_a);
                            }
                            return createElidedInformationPlaceholder(context);
                        }
                        return visitAndTransformType(type, function (type) { return typeToTypeNodeHelper(type, context); });
                    }
                    return typeToTypeNodeHelper(type, context);
                }
                function createMappedTypeNodeFromType(type) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    var readonlyToken = type.declaration.readonlyToken ? ts.createToken(type.declaration.readonlyToken.kind) : undefined;
                    var questionToken = type.declaration.questionToken ? ts.createToken(type.declaration.questionToken.kind) : undefined;
                    var appropriateConstraintTypeNode;
                    if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                        // We have a { [P in keyof T]: X }
                        // We do this to ensure we retain the toplevel keyof-ness of the type which may be lost due to keyof distribution during `getConstraintTypeFromMappedType`
                        appropriateConstraintTypeNode = ts.createTypeOperatorNode(typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context));
                    }
                    else {
                        appropriateConstraintTypeNode = typeToTypeNodeHelper(getConstraintTypeFromMappedType(type), context);
                    }
                    var typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode);
                    var templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context);
                    var mappedTypeNode = ts.createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
                    context.approximateLength += 10;
                    return ts.setEmitFlags(mappedTypeNode, 1 /* SingleLine */);
                }
                function createAnonymousTypeNode(type) {
                    var typeId = "" + type.id;
                    var symbol = type.symbol;
                    if (symbol) {
                        if (isJSConstructor(symbol.valueDeclaration)) {
                            // Instance and static types share the same symbol; only add 'typeof' for the static side.
                            var isInstanceType = type === getDeclaredTypeOfClassOrInterface(symbol) ? 788968 /* Type */ : 111551 /* Value */;
                            return symbolToTypeNode(symbol, context, isInstanceType);
                        }
                        // Always use 'typeof T' for type of class, enum, and module objects
                        else if (symbol.flags & 32 /* Class */ && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === 214 /* ClassExpression */ && context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */) ||
                            symbol.flags & (384 /* Enum */ | 512 /* ValueModule */) ||
                            shouldWriteTypeOfFunctionSymbol()) {
                            return symbolToTypeNode(symbol, context, 111551 /* Value */);
                        }
                        else if (context.visitedTypes && context.visitedTypes.has(typeId)) {
                            // If type is an anonymous type literal in a type alias declaration, use type alias name
                            var typeAlias = getTypeAliasForTypeLiteral(type);
                            if (typeAlias) {
                                // The specified symbol flags need to be reinterpreted as type flags
                                return symbolToTypeNode(typeAlias, context, 788968 /* Type */);
                            }
                            else {
                                return createElidedInformationPlaceholder(context);
                            }
                        }
                        else {
                            return visitAndTransformType(type, createTypeNodeFromObjectType);
                        }
                    }
                    else {
                        // Anonymous types without a symbol are never circular.
                        return createTypeNodeFromObjectType(type);
                    }
                    function shouldWriteTypeOfFunctionSymbol() {
                        var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method
                            ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); });
                        var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) &&
                            (symbol.parent || // is exported function symbol
                                ts.forEach(symbol.declarations, function (declaration) {
                                    return declaration.parent.kind === 290 /* SourceFile */ || declaration.parent.kind === 250 /* ModuleBlock */;
                                }));
                        if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
                            // typeof is allowed only for static/non local functions
                            return (!!(context.flags & 4096 /* UseTypeOfFunction */) || (context.visitedTypes && context.visitedTypes.has(typeId))) && // it is type of the symbol uses itself recursively
                                (!(context.flags & 8 /* UseStructuralFallback */) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // And the build is going to succeed without visibility error or there is no structural fallback allowed
                        }
                    }
                }
                function visitAndTransformType(type, transform) {
                    var typeId = "" + type.id;
                    var isConstructorObject = ts.getObjectFlags(type) & 16 /* Anonymous */ && type.symbol && type.symbol.flags & 32 /* Class */;
                    var id = ts.getObjectFlags(type) & 4 /* Reference */ && type.node ? "N" + getNodeId(type.node) :
                        type.symbol ? (isConstructorObject ? "+" : "") + getSymbolId(type.symbol) :
                            undefined;
                    // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
                    // of types allows us to catch circular references to instantiations of the same anonymous type
                    if (!context.visitedTypes) {
                        context.visitedTypes = ts.createMap();
                    }
                    if (id && !context.symbolDepth) {
                        context.symbolDepth = ts.createMap();
                    }
                    var depth;
                    if (id) {
                        depth = context.symbolDepth.get(id) || 0;
                        if (depth > 10) {
                            return createElidedInformationPlaceholder(context);
                        }
                        context.symbolDepth.set(id, depth + 1);
                    }
                    context.visitedTypes.set(typeId, true);
                    var result = transform(type);
                    context.visitedTypes.delete(typeId);
                    if (id) {
                        context.symbolDepth.set(id, depth);
                    }
                    return result;
                }
                function createTypeNodeFromObjectType(type) {
                    if (isGenericMappedType(type)) {
                        return createMappedTypeNodeFromType(type);
                    }
                    var resolved = resolveStructuredTypeMembers(type);
                    if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                        if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
                            context.approximateLength += 2;
                            return ts.setEmitFlags(ts.createTypeLiteralNode(/*members*/ undefined), 1 /* SingleLine */);
                        }
                        if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
                            var signature = resolved.callSignatures[0];
                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 170 /* FunctionType */, context);
                            return signatureNode;
                        }
                        if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
                            var signature = resolved.constructSignatures[0];
                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 171 /* ConstructorType */, context);
                            return signatureNode;
                        }
                    }
                    var savedFlags = context.flags;
                    context.flags |= 4194304 /* InObjectTypeLiteral */;
                    var members = createTypeNodesFromResolvedType(resolved);
                    context.flags = savedFlags;
                    var typeLiteralNode = ts.createTypeLiteralNode(members);
                    context.approximateLength += 2;
                    return ts.setEmitFlags(typeLiteralNode, (context.flags & 1024 /* MultilineObjectLiterals */) ? 0 : 1 /* SingleLine */);
                }
                function typeReferenceToTypeNode(type) {
                    var typeArguments = getTypeArguments(type);
                    if (type.target === globalArrayType || type.target === globalReadonlyArrayType) {
                        if (context.flags & 2 /* WriteArrayAsGenericType */) {
                            var typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
                            return ts.createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray", [typeArgumentNode]);
                        }
                        var elementType = typeToTypeNodeHelper(typeArguments[0], context);
                        var arrayType = ts.createArrayTypeNode(elementType);
                        return type.target === globalArrayType ? arrayType : ts.createTypeOperatorNode(138 /* ReadonlyKeyword */, arrayType);
                    }
                    else if (type.target.objectFlags & 8 /* Tuple */) {
                        if (typeArguments.length > 0) {
                            var arity = getTypeReferenceArity(type);
                            var tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context);
                            var hasRestElement = type.target.hasRestElement;
                            if (tupleConstituentNodes) {
                                for (var i = type.target.minLength; i < Math.min(arity, tupleConstituentNodes.length); i++) {
                                    tupleConstituentNodes[i] = hasRestElement && i === arity - 1 ?
                                        ts.createRestTypeNode(ts.createArrayTypeNode(tupleConstituentNodes[i])) :
                                        ts.createOptionalTypeNode(tupleConstituentNodes[i]);
                                }
                                var tupleTypeNode = ts.createTupleTypeNode(tupleConstituentNodes);
                                return type.target.readonly ? ts.createTypeOperatorNode(138 /* ReadonlyKeyword */, tupleTypeNode) : tupleTypeNode;
                            }
                        }
                        if (context.encounteredError || (context.flags & 524288 /* AllowEmptyTuple */)) {
                            var tupleTypeNode = ts.createTupleTypeNode([]);
                            return type.target.readonly ? ts.createTypeOperatorNode(138 /* ReadonlyKeyword */, tupleTypeNode) : tupleTypeNode;
                        }
                        context.encounteredError = true;
                        return undefined; // TODO: GH#18217
                    }
                    else if (context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */ &&
                        type.symbol.valueDeclaration &&
                        ts.isClassLike(type.symbol.valueDeclaration) &&
                        !isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                        return createAnonymousTypeNode(type);
                    }
                    else {
                        var outerTypeParameters = type.target.outerTypeParameters;
                        var i = 0;
                        var resultType = void 0;
                        if (outerTypeParameters) {
                            var length_2 = outerTypeParameters.length;
                            while (i < length_2) {
                                // Find group of type arguments for type parameters with the same declaring container.
                                var start = i;
                                var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]);
                                do {
                                    i++;
                                } while (i < length_2 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent);
                                // When type parameters are their own type arguments for the whole group (i.e. we have
                                // the default outer type arguments), we don't show the group.
                                if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) {
                                    var typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context);
                                    var flags_2 = context.flags;
                                    context.flags |= 16 /* ForbidIndexedAccessSymbolReferences */;
                                    var ref = symbolToTypeNode(parent, context, 788968 /* Type */, typeArgumentSlice);
                                    context.flags = flags_2;
                                    resultType = !resultType ? ref : appendReferenceToType(resultType, ref);
                                }
                            }
                        }
                        var typeArgumentNodes = void 0;
                        if (typeArguments.length > 0) {
                            var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length;
                            typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
                        }
                        var flags = context.flags;
                        context.flags |= 16 /* ForbidIndexedAccessSymbolReferences */;
                        var finalRef = symbolToTypeNode(type.symbol, context, 788968 /* Type */, typeArgumentNodes);
                        context.flags = flags;
                        return !resultType ? finalRef : appendReferenceToType(resultType, finalRef);
                    }
                }
                function appendReferenceToType(root, ref) {
                    if (ts.isImportTypeNode(root)) {
                        // first shift type arguments
                        var innerParams = root.typeArguments;
                        if (root.qualifier) {
                            (ts.isIdentifier(root.qualifier) ? root.qualifier : root.qualifier.right).typeArguments = innerParams;
                        }
                        root.typeArguments = ref.typeArguments;
                        // then move qualifiers
                        var ids = getAccessStack(ref);
                        for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
                            var id = ids_1[_i];
                            root.qualifier = root.qualifier ? ts.createQualifiedName(root.qualifier, id) : id;
                        }
                        return root;
                    }
                    else {
                        // first shift type arguments
                        var innerParams = root.typeArguments;
                        (ts.isIdentifier(root.typeName) ? root.typeName : root.typeName.right).typeArguments = innerParams;
                        root.typeArguments = ref.typeArguments;
                        // then move qualifiers
                        var ids = getAccessStack(ref);
                        for (var _a = 0, ids_2 = ids; _a < ids_2.length; _a++) {
                            var id = ids_2[_a];
                            root.typeName = ts.createQualifiedName(root.typeName, id);
                        }
                        return root;
                    }
                }
                function getAccessStack(ref) {
                    var state = ref.typeName;
                    var ids = [];
                    while (!ts.isIdentifier(state)) {
                        ids.unshift(state.right);
                        state = state.left;
                    }
                    ids.unshift(state);
                    return ids;
                }
                function createTypeNodesFromResolvedType(resolvedType) {
                    if (checkTruncationLength(context)) {
                        return [ts.createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)];
                    }
                    var typeElements = [];
                    for (var _i = 0, _a = resolvedType.callSignatures; _i < _a.length; _i++) {
                        var signature = _a[_i];
                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 165 /* CallSignature */, context));
                    }
                    for (var _b = 0, _c = resolvedType.constructSignatures; _b < _c.length; _b++) {
                        var signature = _c[_b];
                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 166 /* ConstructSignature */, context));
                    }
                    if (resolvedType.stringIndexInfo) {
                        var indexSignature = void 0;
                        if (resolvedType.objectFlags & 2048 /* ReverseMapped */) {
                            indexSignature = indexInfoToIndexSignatureDeclarationHelper(createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration), 0 /* String */, context);
                            indexSignature.type = createElidedInformationPlaceholder(context);
                        }
                        else {
                            indexSignature = indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, 0 /* String */, context);
                        }
                        typeElements.push(indexSignature);
                    }
                    if (resolvedType.numberIndexInfo) {
                        typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, 1 /* Number */, context));
                    }
                    var properties = resolvedType.properties;
                    if (!properties) {
                        return typeElements;
                    }
                    var i = 0;
                    for (var _d = 0, properties_1 = properties; _d < properties_1.length; _d++) {
                        var propertySymbol = properties_1[_d];
                        i++;
                        if (context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */) {
                            if (propertySymbol.flags & 4194304 /* Prototype */) {
                                continue;
                            }
                            if (ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & (8 /* Private */ | 16 /* Protected */) && context.tracker.reportPrivateInBaseOfClassExpression) {
                                context.tracker.reportPrivateInBaseOfClassExpression(ts.unescapeLeadingUnderscores(propertySymbol.escapedName));
                            }
                        }
                        if (checkTruncationLength(context) && (i + 2 < properties.length - 1)) {
                            typeElements.push(ts.createPropertySignature(/*modifiers*/ undefined, "... " + (properties.length - i) + " more ...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined));
                            addPropertyToElementList(properties[properties.length - 1], context, typeElements);
                            break;
                        }
                        addPropertyToElementList(propertySymbol, context, typeElements);
                    }
                    return typeElements.length ? typeElements : undefined;
                }
            }
            function createElidedInformationPlaceholder(context) {
                context.approximateLength += 3;
                if (!(context.flags & 1 /* NoTruncation */)) {
                    return ts.createTypeReferenceNode(ts.createIdentifier("..."), /*typeArguments*/ undefined);
                }
                return ts.createKeywordTypeNode(125 /* AnyKeyword */);
            }
            function addPropertyToElementList(propertySymbol, context, typeElements) {
                var propertyIsReverseMapped = !!(ts.getCheckFlags(propertySymbol) & 8192 /* ReverseMapped */);
                var propertyType = propertyIsReverseMapped && context.flags & 33554432 /* InReverseMappedType */ ?
                    anyType : getTypeOfSymbol(propertySymbol);
                var saveEnclosingDeclaration = context.enclosingDeclaration;
                context.enclosingDeclaration = undefined;
                if (context.tracker.trackSymbol && ts.getCheckFlags(propertySymbol) & 4096 /* Late */) {
                    var decl = ts.first(propertySymbol.declarations);
                    if (hasLateBindableName(decl)) {
                        if (ts.isBinaryExpression(decl)) {
                            var name = ts.getNameOfDeclaration(decl);
                            if (name && ts.isElementAccessExpression(name) && ts.isPropertyAccessEntityNameExpression(name.argumentExpression)) {
                                trackComputedName(name.argumentExpression, saveEnclosingDeclaration, context);
                            }
                        }
                        else {
                            trackComputedName(decl.name.expression, saveEnclosingDeclaration, context);
                        }
                    }
                }
                context.enclosingDeclaration = saveEnclosingDeclaration;
                var propertyName = getPropertyNameNodeForSymbol(propertySymbol, context);
                context.approximateLength += (ts.symbolName(propertySymbol).length + 1);
                var optionalToken = propertySymbol.flags & 16777216 /* Optional */ ? ts.createToken(57 /* QuestionToken */) : undefined;
                if (propertySymbol.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) {
                    var signatures = getSignaturesOfType(filterType(propertyType, function (t) { return !(t.flags & 32768 /* Undefined */); }), 0 /* Call */);
                    for (var _i = 0, signatures_1 = signatures; _i < signatures_1.length; _i++) {
                        var signature = signatures_1[_i];
                        var methodDeclaration = signatureToSignatureDeclarationHelper(signature, 160 /* MethodSignature */, context);
                        methodDeclaration.name = propertyName;
                        methodDeclaration.questionToken = optionalToken;
                        typeElements.push(preserveCommentsOn(methodDeclaration));
                    }
                }
                else {
                    var savedFlags = context.flags;
                    context.flags |= propertyIsReverseMapped ? 33554432 /* InReverseMappedType */ : 0;
                    var propertyTypeNode = void 0;
                    if (propertyIsReverseMapped && !!(savedFlags & 33554432 /* InReverseMappedType */)) {
                        propertyTypeNode = createElidedInformationPlaceholder(context);
                    }
                    else {
                        propertyTypeNode = propertyType ? serializeTypeForDeclaration(context, propertyType, propertySymbol, saveEnclosingDeclaration) : ts.createKeywordTypeNode(125 /* AnyKeyword */);
                    }
                    context.flags = savedFlags;
                    var modifiers = isReadonlySymbol(propertySymbol) ? [ts.createToken(138 /* ReadonlyKeyword */)] : undefined;
                    if (modifiers) {
                        context.approximateLength += 9;
                    }
                    var propertySignature = ts.createPropertySignature(modifiers, propertyName, optionalToken, propertyTypeNode, 
                    /*initializer*/ undefined);
                    typeElements.push(preserveCommentsOn(propertySignature));
                }
                function preserveCommentsOn(node) {
                    if (ts.some(propertySymbol.declarations, function (d) { return d.kind === 323 /* JSDocPropertyTag */; })) {
                        var d = ts.find(propertySymbol.declarations, function (d) { return d.kind === 323 /* JSDocPropertyTag */; });
                        var commentText = d.comment;
                        if (commentText) {
                            ts.setSyntheticLeadingComments(node, [{ kind: 3 /* MultiLineCommentTrivia */, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]);
                        }
                    }
                    else if (propertySymbol.valueDeclaration) {
                        // Copy comments to node for declaration emit
                        ts.setCommentRange(node, propertySymbol.valueDeclaration);
                    }
                    return node;
                }
            }
            function mapToTypeNodes(types, context, isBareList) {
                if (ts.some(types)) {
                    if (checkTruncationLength(context)) {
                        if (!isBareList) {
                            return [ts.createTypeReferenceNode("...", /*typeArguments*/ undefined)];
                        }
                        else if (types.length > 2) {
                            return [
                                typeToTypeNodeHelper(types[0], context),
                                ts.createTypeReferenceNode("... " + (types.length - 2) + " more ...", /*typeArguments*/ undefined),
                                typeToTypeNodeHelper(types[types.length - 1], context)
                            ];
                        }
                    }
                    var mayHaveNameCollisions = !(context.flags & 64 /* UseFullyQualifiedType */);
                    /** Map from type reference identifier text to [type, index in `result` where the type node is] */
                    var seenNames = mayHaveNameCollisions ? ts.createUnderscoreEscapedMultiMap() : undefined;
                    var result_3 = [];
                    var i = 0;
                    for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
                        var type = types_1[_i];
                        i++;
                        if (checkTruncationLength(context) && (i + 2 < types.length - 1)) {
                            result_3.push(ts.createTypeReferenceNode("... " + (types.length - i) + " more ...", /*typeArguments*/ undefined));
                            var typeNode_1 = typeToTypeNodeHelper(types[types.length - 1], context);
                            if (typeNode_1) {
                                result_3.push(typeNode_1);
                            }
                            break;
                        }
                        context.approximateLength += 2; // Account for whitespace + separator
                        var typeNode = typeToTypeNodeHelper(type, context);
                        if (typeNode) {
                            result_3.push(typeNode);
                            if (seenNames && ts.isIdentifierTypeReference(typeNode)) {
                                seenNames.add(typeNode.typeName.escapedText, [type, result_3.length - 1]);
                            }
                        }
                    }
                    if (seenNames) {
                        // To avoid printing types like `[Foo, Foo]` or `Bar & Bar` where
                        // occurrences of the same name actually come from different
                        // namespaces, go through the single-identifier type reference nodes
                        // we just generated, and see if any names were generated more than
                        // once while referring to different types. If so, regenerate the
                        // type node for each entry by that name with the
                        // `UseFullyQualifiedType` flag enabled.
                        var saveContextFlags = context.flags;
                        context.flags |= 64 /* UseFullyQualifiedType */;
                        seenNames.forEach(function (types) {
                            if (!ts.arrayIsHomogeneous(types, function (_a, _b) {
                                var a = _a[0];
                                var b = _b[0];
                                return typesAreSameReference(a, b);
                            })) {
                                for (var _i = 0, types_2 = types; _i < types_2.length; _i++) {
                                    var _a = types_2[_i], type = _a[0], resultIndex = _a[1];
                                    result_3[resultIndex] = typeToTypeNodeHelper(type, context);
                                }
                            }
                        });
                        context.flags = saveContextFlags;
                    }
                    return result_3;
                }
            }
            function typesAreSameReference(a, b) {
                return a === b
                    || !!a.symbol && a.symbol === b.symbol
                    || !!a.aliasSymbol && a.aliasSymbol === b.aliasSymbol;
            }
            function indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context) {
                var name = ts.getNameFromIndexInfo(indexInfo) || "x";
                var indexerTypeNode = ts.createKeywordTypeNode(kind === 0 /* String */ ? 143 /* StringKeyword */ : 140 /* NumberKeyword */);
                var indexingParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, name, 
                /*questionToken*/ undefined, indexerTypeNode, 
                /*initializer*/ undefined);
                var typeNode = typeToTypeNodeHelper(indexInfo.type || anyType, context);
                if (!indexInfo.type && !(context.flags & 2097152 /* AllowEmptyIndexInfoType */)) {
                    context.encounteredError = true;
                }
                context.approximateLength += (name.length + 4);
                return ts.createIndexSignature(
                /*decorators*/ undefined, indexInfo.isReadonly ? [ts.createToken(138 /* ReadonlyKeyword */)] : undefined, [indexingParameter], typeNode);
            }
            function signatureToSignatureDeclarationHelper(signature, kind, context, privateSymbolVisitor, bundledImports) {
                var suppressAny = context.flags & 256 /* SuppressAnyReturnType */;
                if (suppressAny)
                    context.flags &= ~256 /* SuppressAnyReturnType */; // suppress only toplevel `any`s
                var typeParameters;
                var typeArguments;
                if (context.flags & 32 /* WriteTypeArgumentsOfSignature */ && signature.target && signature.mapper && signature.target.typeParameters) {
                    typeArguments = signature.target.typeParameters.map(function (parameter) { return typeToTypeNodeHelper(instantiateType(parameter, signature.mapper), context); });
                }
                else {
                    typeParameters = signature.typeParameters && signature.typeParameters.map(function (parameter) { return typeParameterToDeclaration(parameter, context); });
                }
                var parameters = getExpandedParameters(signature).map(function (parameter) { return symbolToParameterDeclaration(parameter, context, kind === 162 /* Constructor */, privateSymbolVisitor, bundledImports); });
                if (signature.thisParameter) {
                    var thisParameter = symbolToParameterDeclaration(signature.thisParameter, context);
                    parameters.unshift(thisParameter);
                }
                var returnTypeNode;
                var typePredicate = getTypePredicateOfSignature(signature);
                if (typePredicate) {
                    var assertsModifier = typePredicate.kind === 2 /* AssertsThis */ || typePredicate.kind === 3 /* AssertsIdentifier */ ?
                        ts.createToken(124 /* AssertsKeyword */) :
                        undefined;
                    var parameterName = typePredicate.kind === 1 /* Identifier */ || typePredicate.kind === 3 /* AssertsIdentifier */ ?
                        ts.setEmitFlags(ts.createIdentifier(typePredicate.parameterName), 16777216 /* NoAsciiEscaping */) :
                        ts.createThisTypeNode();
                    var typeNode = typePredicate.type && typeToTypeNodeHelper(typePredicate.type, context);
                    returnTypeNode = ts.createTypePredicateNodeWithModifier(assertsModifier, parameterName, typeNode);
                }
                else {
                    var returnType = getReturnTypeOfSignature(signature);
                    if (returnType && !(suppressAny && isTypeAny(returnType))) {
                        returnTypeNode = serializeReturnTypeForSignature(context, returnType, signature, privateSymbolVisitor, bundledImports);
                    }
                    else if (!suppressAny) {
                        returnTypeNode = ts.createKeywordTypeNode(125 /* AnyKeyword */);
                    }
                }
                context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
                return ts.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments);
            }
            function typeParameterToDeclarationWithConstraint(type, context, constraintNode) {
                var savedContextFlags = context.flags;
                context.flags &= ~512 /* WriteTypeParametersInQualifiedName */; // Avoids potential infinite loop when building for a claimspace with a generic
                var name = typeParameterToName(type, context);
                var defaultParameter = getDefaultFromTypeParameter(type);
                var defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context);
                context.flags = savedContextFlags;
                return ts.createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
            }
            function typeParameterToDeclaration(type, context, constraint) {
                if (constraint === void 0) { constraint = getConstraintOfTypeParameter(type); }
                var constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
                return typeParameterToDeclarationWithConstraint(type, context, constraintNode);
            }
            function symbolToParameterDeclaration(parameterSymbol, context, preserveModifierFlags, privateSymbolVisitor, bundledImports) {
                var parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 156 /* Parameter */);
                if (!parameterDeclaration && !ts.isTransientSymbol(parameterSymbol)) {
                    parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 317 /* JSDocParameterTag */);
                }
                var parameterType = getTypeOfSymbol(parameterSymbol);
                if (parameterDeclaration && isRequiredInitializedParameter(parameterDeclaration)) {
                    parameterType = getOptionalType(parameterType);
                }
                var parameterTypeNode = serializeTypeForDeclaration(context, parameterType, parameterSymbol, context.enclosingDeclaration, privateSymbolVisitor, bundledImports);
                var modifiers = !(context.flags & 8192 /* OmitParameterModifiers */) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(ts.getSynthesizedClone) : undefined;
                var isRest = parameterDeclaration && ts.isRestParameter(parameterDeclaration) || ts.getCheckFlags(parameterSymbol) & 32768 /* RestParameter */;
                var dotDotDotToken = isRest ? ts.createToken(25 /* DotDotDotToken */) : undefined;
                var name = parameterDeclaration ? parameterDeclaration.name ?
                    parameterDeclaration.name.kind === 75 /* Identifier */ ? ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name), 16777216 /* NoAsciiEscaping */) :
                        parameterDeclaration.name.kind === 153 /* QualifiedName */ ? ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name.right), 16777216 /* NoAsciiEscaping */) :
                            cloneBindingName(parameterDeclaration.name) :
                    ts.symbolName(parameterSymbol) :
                    ts.symbolName(parameterSymbol);
                var isOptional = parameterDeclaration && isOptionalParameter(parameterDeclaration) || ts.getCheckFlags(parameterSymbol) & 16384 /* OptionalParameter */;
                var questionToken = isOptional ? ts.createToken(57 /* QuestionToken */) : undefined;
                var parameterNode = ts.createParameter(
                /*decorators*/ undefined, modifiers, dotDotDotToken, name, questionToken, parameterTypeNode, 
                /*initializer*/ undefined);
                context.approximateLength += ts.symbolName(parameterSymbol).length + 3;
                return parameterNode;
                function cloneBindingName(node) {
                    return elideInitializerAndSetEmitFlags(node);
                    function elideInitializerAndSetEmitFlags(node) {
                        if (context.tracker.trackSymbol && ts.isComputedPropertyName(node) && isLateBindableName(node)) {
                            trackComputedName(node.expression, context.enclosingDeclaration, context);
                        }
                        var visited = ts.visitEachChild(node, elideInitializerAndSetEmitFlags, ts.nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags);
                        var clone = ts.nodeIsSynthesized(visited) ? visited : ts.getSynthesizedClone(visited);
                        if (clone.kind === 191 /* BindingElement */) {
                            clone.initializer = undefined;
                        }
                        return ts.setEmitFlags(clone, 1 /* SingleLine */ | 16777216 /* NoAsciiEscaping */);
                    }
                }
            }
            function trackComputedName(accessExpression, enclosingDeclaration, context) {
                if (!context.tracker.trackSymbol)
                    return;
                // get symbol of the first identifier of the entityName
                var firstIdentifier = ts.getFirstIdentifier(accessExpression);
                var name = resolveName(firstIdentifier, firstIdentifier.escapedText, 111551 /* Value */ | 1048576 /* ExportValue */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
                if (name) {
                    context.tracker.trackSymbol(name, enclosingDeclaration, 111551 /* Value */);
                }
            }
            function lookupSymbolChain(symbol, context, meaning, yieldModuleSymbol) {
                context.tracker.trackSymbol(symbol, context.enclosingDeclaration, meaning); // TODO: GH#18217
                return lookupSymbolChainWorker(symbol, context, meaning, yieldModuleSymbol);
            }
            function lookupSymbolChainWorker(symbol, context, meaning, yieldModuleSymbol) {
                // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
                var chain;
                var isTypeParameter = symbol.flags & 262144 /* TypeParameter */;
                if (!isTypeParameter && (context.enclosingDeclaration || context.flags & 64 /* UseFullyQualifiedType */) && !(context.flags & 134217728 /* DoNotIncludeSymbolChain */)) {
                    chain = ts.Debug.checkDefined(getSymbolChain(symbol, meaning, /*endOfChain*/ true));
                    ts.Debug.assert(chain && chain.length > 0);
                }
                else {
                    chain = [symbol];
                }
                return chain;
                /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
                function getSymbolChain(symbol, meaning, endOfChain) {
                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128 /* UseOnlyExternalAliasing */));
                    var parentSpecifiers;
                    if (!accessibleSymbolChain ||
                        needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
                        // Go up and add our parent.
                        var parents_1 = getContainersOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol, context.enclosingDeclaration);
                        if (ts.length(parents_1)) {
                            parentSpecifiers = parents_1.map(function (symbol) {
                                return ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)
                                    ? getSpecifierForModuleSymbol(symbol, context)
                                    : undefined;
                            });
                            var indices = parents_1.map(function (_, i) { return i; });
                            indices.sort(sortByBestName);
                            var sortedParents = indices.map(function (i) { return parents_1[i]; });
                            for (var _i = 0, sortedParents_1 = sortedParents; _i < sortedParents_1.length; _i++) {
                                var parent = sortedParents_1[_i];
                                var parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false);
                                if (parentChain) {
                                    if (parent.exports && parent.exports.get("export=" /* ExportEquals */) &&
                                        getSymbolIfSameReference(parent.exports.get("export=" /* ExportEquals */), symbol)) {
                                        // parentChain root _is_ symbol - symbol is a module export=, so it kinda looks like it's own parent
                                        // No need to lookup an alias for the symbol in itself
                                        accessibleSymbolChain = parentChain;
                                        break;
                                    }
                                    accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [getAliasForSymbolInContainer(parent, symbol) || symbol]);
                                    break;
                                }
                            }
                        }
                    }
                    if (accessibleSymbolChain) {
                        return accessibleSymbolChain;
                    }
                    if (
                    // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
                    endOfChain ||
                        // If a parent symbol is an anonymous type, don't write it.
                        !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) {
                        // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
                        if (!endOfChain && !yieldModuleSymbol && !!ts.forEach(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                            return;
                        }
                        return [symbol];
                    }
                    function sortByBestName(a, b) {
                        var specifierA = parentSpecifiers[a];
                        var specifierB = parentSpecifiers[b];
                        if (specifierA && specifierB) {
                            var isBRelative = ts.pathIsRelative(specifierB);
                            if (ts.pathIsRelative(specifierA) === isBRelative) {
                                // Both relative or both non-relative, sort by number of parts
                                return ts.moduleSpecifiers.countPathComponents(specifierA) - ts.moduleSpecifiers.countPathComponents(specifierB);
                            }
                            if (isBRelative) {
                                // A is non-relative, B is relative: prefer A
                                return -1;
                            }
                            // A is relative, B is non-relative: prefer B
                            return 1;
                        }
                        return 0;
                    }
                }
            }
            function typeParametersToTypeParameterDeclarations(symbol, context) {
                var typeParameterNodes;
                var targetSymbol = getTargetSymbol(symbol);
                if (targetSymbol.flags & (32 /* Class */ | 64 /* Interface */ | 524288 /* TypeAlias */)) {
                    typeParameterNodes = ts.createNodeArray(ts.map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), function (tp) { return typeParameterToDeclaration(tp, context); }));
                }
                return typeParameterNodes;
            }
            function lookupTypeParameterNodes(chain, index, context) {
                ts.Debug.assert(chain && 0 <= index && index < chain.length);
                var symbol = chain[index];
                var symbolId = "" + getSymbolId(symbol);
                if (context.typeParameterSymbolList && context.typeParameterSymbolList.get(symbolId)) {
                    return undefined;
                }
                (context.typeParameterSymbolList || (context.typeParameterSymbolList = ts.createMap())).set(symbolId, true);
                var typeParameterNodes;
                if (context.flags & 512 /* WriteTypeParametersInQualifiedName */ && index < (chain.length - 1)) {
                    var parentSymbol = symbol;
                    var nextSymbol_1 = chain[index + 1];
                    if (ts.getCheckFlags(nextSymbol_1) & 1 /* Instantiated */) {
                        var params = getTypeParametersOfClassOrInterface(parentSymbol.flags & 2097152 /* Alias */ ? resolveAlias(parentSymbol) : parentSymbol);
                        typeParameterNodes = mapToTypeNodes(ts.map(params, function (t) { return getMappedType(t, nextSymbol_1.mapper); }), context);
                    }
                    else {
                        typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context);
                    }
                }
                return typeParameterNodes;
            }
            /**
             * Given A[B][C][D], finds A[B]
             */
            function getTopmostIndexedAccessType(top) {
                if (ts.isIndexedAccessTypeNode(top.objectType)) {
                    return getTopmostIndexedAccessType(top.objectType);
                }
                return top;
            }
            function getSpecifierForModuleSymbol(symbol, context) {
                var file = ts.getDeclarationOfKind(symbol, 290 /* SourceFile */);
                if (!file) {
                    var equivalentFileSymbol = ts.firstDefined(symbol.declarations, function (d) { return getFileSymbolIfFileSymbolExportEqualsContainer(d, symbol); });
                    if (equivalentFileSymbol) {
                        file = ts.getDeclarationOfKind(equivalentFileSymbol, 290 /* SourceFile */);
                    }
                }
                if (file && file.moduleName !== undefined) {
                    // Use the amd name if it is available
                    return file.moduleName;
                }
                if (!file) {
                    if (context.tracker.trackReferencedAmbientModule) {
                        var ambientDecls = ts.filter(symbol.declarations, ts.isAmbientModule);
                        if (ts.length(ambientDecls)) {
                            for (var _i = 0, ambientDecls_1 = ambientDecls; _i < ambientDecls_1.length; _i++) {
                                var decl = ambientDecls_1[_i];
                                context.tracker.trackReferencedAmbientModule(decl, symbol);
                            }
                        }
                    }
                    if (ambientModuleSymbolRegex.test(symbol.escapedName)) {
                        return symbol.escapedName.substring(1, symbol.escapedName.length - 1);
                    }
                }
                if (!context.enclosingDeclaration || !context.tracker.moduleResolverHost) {
                    // If there's no context declaration, we can't lookup a non-ambient specifier, so we just use the symbol name
                    if (ambientModuleSymbolRegex.test(symbol.escapedName)) {
                        return symbol.escapedName.substring(1, symbol.escapedName.length - 1);
                    }
                    return ts.getSourceFileOfNode(ts.getNonAugmentationDeclaration(symbol)).fileName; // A resolver may not be provided for baselines and errors - in those cases we use the fileName in full
                }
                var contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration));
                var links = getSymbolLinks(symbol);
                var specifier = links.specifierCache && links.specifierCache.get(contextFile.path);
                if (!specifier) {
                    var isBundle_1 = (compilerOptions.out || compilerOptions.outFile);
                    // For declaration bundles, we need to generate absolute paths relative to the common source dir for imports,
                    // just like how the declaration emitter does for the ambient module declarations - we can easily accomplish this
                    // using the `baseUrl` compiler option (which we would otherwise never use in declaration emit) and a non-relative
                    // specifier preference
                    var moduleResolverHost = context.tracker.moduleResolverHost;
                    var specifierCompilerOptions = isBundle_1 ? __assign(__assign({}, compilerOptions), { baseUrl: moduleResolverHost.getCommonSourceDirectory() }) : compilerOptions;
                    specifier = ts.first(ts.moduleSpecifiers.getModuleSpecifiers(symbol, specifierCompilerOptions, contextFile, moduleResolverHost, { importModuleSpecifierPreference: isBundle_1 ? "non-relative" : "relative" }));
                    links.specifierCache = links.specifierCache || ts.createMap();
                    links.specifierCache.set(contextFile.path, specifier);
                }
                return specifier;
            }
            function symbolToTypeNode(symbol, context, meaning, overrideTypeArguments) {
                var chain = lookupSymbolChain(symbol, context, meaning, !(context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */)); // If we're using aliases outside the current scope, dont bother with the module
                var isTypeOf = meaning === 111551 /* Value */;
                if (ts.some(chain[0].declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                    // module is root, must use `ImportTypeNode`
                    var nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined;
                    var typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context);
                    var specifier = getSpecifierForModuleSymbol(chain[0], context);
                    if (!(context.flags & 67108864 /* AllowNodeModulesRelativePaths */) && ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs && specifier.indexOf("/node_modules/") >= 0) {
                        // If ultimately we can only name the symbol with a reference that dives into a `node_modules` folder, we should error
                        // since declaration files with these kinds of references are liable to fail when published :(
                        context.encounteredError = true;
                        if (context.tracker.reportLikelyUnsafeImportRequiredError) {
                            context.tracker.reportLikelyUnsafeImportRequiredError(specifier);
                        }
                    }
                    var lit = ts.createLiteralTypeNode(ts.createLiteral(specifier));
                    if (context.tracker.trackExternalModuleSymbolOfImportTypeNode)
                        context.tracker.trackExternalModuleSymbolOfImportTypeNode(chain[0]);
                    context.approximateLength += specifier.length + 10; // specifier + import("")
                    if (!nonRootParts || ts.isEntityName(nonRootParts)) {
                        if (nonRootParts) {
                            var lastId = ts.isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right;
                            lastId.typeArguments = undefined;
                        }
                        return ts.createImportTypeNode(lit, nonRootParts, typeParameterNodes, isTypeOf);
                    }
                    else {
                        var splitNode = getTopmostIndexedAccessType(nonRootParts);
                        var qualifier = splitNode.objectType.typeName;
                        return ts.createIndexedAccessTypeNode(ts.createImportTypeNode(lit, qualifier, typeParameterNodes, isTypeOf), splitNode.indexType);
                    }
                }
                var entityName = createAccessFromSymbolChain(chain, chain.length - 1, 0);
                if (ts.isIndexedAccessTypeNode(entityName)) {
                    return entityName; // Indexed accesses can never be `typeof`
                }
                if (isTypeOf) {
                    return ts.createTypeQueryNode(entityName);
                }
                else {
                    var lastId = ts.isIdentifier(entityName) ? entityName : entityName.right;
                    var lastTypeArgs = lastId.typeArguments;
                    lastId.typeArguments = undefined;
                    return ts.createTypeReferenceNode(entityName, lastTypeArgs);
                }
                function createAccessFromSymbolChain(chain, index, stopper) {
                    var typeParameterNodes = index === (chain.length - 1) ? overrideTypeArguments : lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    var parent = chain[index - 1];
                    var symbolName;
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                        symbolName = getNameOfSymbolAsWritten(symbol, context);
                        context.approximateLength += (symbolName ? symbolName.length : 0) + 1;
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    else {
                        if (parent && getExportsOfSymbol(parent)) {
                            var exports_1 = getExportsOfSymbol(parent);
                            ts.forEachEntry(exports_1, function (ex, name) {
                                if (getSymbolIfSameReference(ex, symbol) && !isLateBoundName(name) && name !== "export=" /* ExportEquals */) {
                                    symbolName = ts.unescapeLeadingUnderscores(name);
                                    return true;
                                }
                            });
                        }
                    }
                    if (!symbolName) {
                        symbolName = getNameOfSymbolAsWritten(symbol, context);
                    }
                    context.approximateLength += symbolName.length + 1;
                    if (!(context.flags & 16 /* ForbidIndexedAccessSymbolReferences */) && parent &&
                        getMembersOfSymbol(parent) && getMembersOfSymbol(parent).get(symbol.escapedName) &&
                        getSymbolIfSameReference(getMembersOfSymbol(parent).get(symbol.escapedName), symbol)) {
                        // Should use an indexed access
                        var LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
                        if (ts.isIndexedAccessTypeNode(LHS)) {
                            return ts.createIndexedAccessTypeNode(LHS, ts.createLiteralTypeNode(ts.createLiteral(symbolName)));
                        }
                        else {
                            return ts.createIndexedAccessTypeNode(ts.createTypeReferenceNode(LHS, typeParameterNodes), ts.createLiteralTypeNode(ts.createLiteral(symbolName)));
                        }
                    }
                    var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                    identifier.symbol = symbol;
                    if (index > stopper) {
                        var LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
                        if (!ts.isEntityName(LHS)) {
                            return ts.Debug.fail("Impossible construct - an export of an indexed access cannot be reachable");
                        }
                        return ts.createQualifiedName(LHS, identifier);
                    }
                    return identifier;
                }
            }
            function typeParameterShadowsNameInScope(escapedName, context, type) {
                var result = resolveName(context.enclosingDeclaration, escapedName, 788968 /* Type */, /*nameNotFoundArg*/ undefined, escapedName, /*isUse*/ false);
                if (result) {
                    if (result.flags & 262144 /* TypeParameter */ && result === type.symbol) {
                        return false;
                    }
                    return true;
                }
                return false;
            }
            function typeParameterToName(type, context) {
                if (context.flags & 4 /* GenerateNamesForShadowedTypeParams */ && context.typeParameterNames) {
                    var cached = context.typeParameterNames.get("" + getTypeId(type));
                    if (cached) {
                        return cached;
                    }
                }
                var result = symbolToName(type.symbol, context, 788968 /* Type */, /*expectsIdentifier*/ true);
                if (!(result.kind & 75 /* Identifier */)) {
                    return ts.createIdentifier("(Missing type parameter)");
                }
                if (context.flags & 4 /* GenerateNamesForShadowedTypeParams */) {
                    var rawtext = result.escapedText;
                    var i = 0;
                    var text = rawtext;
                    while ((context.typeParameterNamesByText && context.typeParameterNamesByText.get(text)) || typeParameterShadowsNameInScope(text, context, type)) {
                        i++;
                        text = rawtext + "_" + i;
                    }
                    if (text !== rawtext) {
                        result = ts.createIdentifier(text, result.typeArguments);
                    }
                    (context.typeParameterNames || (context.typeParameterNames = ts.createMap())).set("" + getTypeId(type), result);
                    (context.typeParameterNamesByText || (context.typeParameterNamesByText = ts.createMap())).set(result.escapedText, true);
                }
                return result;
            }
            function symbolToName(symbol, context, meaning, expectsIdentifier) {
                var chain = lookupSymbolChain(symbol, context, meaning);
                if (expectsIdentifier && chain.length !== 1
                    && !context.encounteredError
                    && !(context.flags & 65536 /* AllowQualifedNameInPlaceOfIdentifier */)) {
                    context.encounteredError = true;
                }
                return createEntityNameFromSymbolChain(chain, chain.length - 1);
                function createEntityNameFromSymbolChain(chain, index) {
                    var typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                    }
                    var symbolName = getNameOfSymbolAsWritten(symbol, context);
                    if (index === 0) {
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                    identifier.symbol = symbol;
                    return index > 0 ? ts.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
                }
            }
            function symbolToExpression(symbol, context, meaning) {
                var chain = lookupSymbolChain(symbol, context, meaning);
                return createExpressionFromSymbolChain(chain, chain.length - 1);
                function createExpressionFromSymbolChain(chain, index) {
                    var typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                    }
                    var symbolName = getNameOfSymbolAsWritten(symbol, context);
                    if (index === 0) {
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    var firstChar = symbolName.charCodeAt(0);
                    if (ts.isSingleOrDoubleQuote(firstChar) && ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                        return ts.createLiteral(getSpecifierForModuleSymbol(symbol, context));
                    }
                    var canUsePropertyAccess = firstChar === 35 /* hash */ ?
                        symbolName.length > 1 && ts.isIdentifierStart(symbolName.charCodeAt(1), languageVersion) :
                        ts.isIdentifierStart(firstChar, languageVersion);
                    if (index === 0 || canUsePropertyAccess) {
                        var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                        identifier.symbol = symbol;
                        return index > 0 ? ts.createPropertyAccess(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier;
                    }
                    else {
                        if (firstChar === 91 /* openBracket */) {
                            symbolName = symbolName.substring(1, symbolName.length - 1);
                            firstChar = symbolName.charCodeAt(0);
                        }
                        var expression = void 0;
                        if (ts.isSingleOrDoubleQuote(firstChar)) {
                            expression = ts.createLiteral(symbolName.substring(1, symbolName.length - 1).replace(/\\./g, function (s) { return s.substring(1); }));
                            expression.singleQuote = firstChar === 39 /* singleQuote */;
                        }
                        else if (("" + +symbolName) === symbolName) {
                            expression = ts.createLiteral(+symbolName);
                        }
                        if (!expression) {
                            expression = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                            expression.symbol = symbol;
                        }
                        return ts.createElementAccess(createExpressionFromSymbolChain(chain, index - 1), expression);
                    }
                }
            }
            function isSingleQuotedStringNamed(d) {
                var name = ts.getNameOfDeclaration(d);
                if (name && ts.isStringLiteral(name) && (name.singleQuote ||
                    (!ts.nodeIsSynthesized(name) && ts.startsWith(ts.getTextOfNode(name, /*includeTrivia*/ false), "'")))) {
                    return true;
                }
                return false;
            }
            function getPropertyNameNodeForSymbol(symbol, context) {
                var singleQuote = !!ts.length(symbol.declarations) && ts.every(symbol.declarations, isSingleQuotedStringNamed);
                var fromNameType = getPropertyNameNodeForSymbolFromNameType(symbol, context, singleQuote);
                if (fromNameType) {
                    return fromNameType;
                }
                if (ts.isKnownSymbol(symbol)) {
                    return ts.createComputedPropertyName(ts.createPropertyAccess(ts.createIdentifier("Symbol"), symbol.escapedName.substr(3)));
                }
                var rawName = ts.unescapeLeadingUnderscores(symbol.escapedName);
                return createPropertyNameNodeForIdentifierOrLiteral(rawName, singleQuote);
            }
            // See getNameForSymbolFromNameType for a stringy equivalent
            function getPropertyNameNodeForSymbolFromNameType(symbol, context, singleQuote) {
                var nameType = getSymbolLinks(symbol).nameType;
                if (nameType) {
                    if (nameType.flags & 384 /* StringOrNumberLiteral */) {
                        var name = "" + nameType.value;
                        if (!ts.isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) {
                            return ts.createLiteral(name, !!singleQuote);
                        }
                        if (isNumericLiteralName(name) && ts.startsWith(name, "-")) {
                            return ts.createComputedPropertyName(ts.createLiteral(+name));
                        }
                        return createPropertyNameNodeForIdentifierOrLiteral(name);
                    }
                    if (nameType.flags & 8192 /* UniqueESSymbol */) {
                        return ts.createComputedPropertyName(symbolToExpression(nameType.symbol, context, 111551 /* Value */));
                    }
                }
            }
            function createPropertyNameNodeForIdentifierOrLiteral(name, singleQuote) {
                return ts.isIdentifierText(name, compilerOptions.target) ? ts.createIdentifier(name) : ts.createLiteral(isNumericLiteralName(name) && +name >= 0 ? +name : name, !!singleQuote);
            }
            function cloneNodeBuilderContext(context) {
                var initial = __assign({}, context);
                // Make type parameters created within this context not consume the name outside this context
                // The symbol serializer ends up creating many sibling scopes that all need "separate" contexts when
                // it comes to naming things - within a normal `typeToTypeNode` call, the node builder only ever descends
                // through the type tree, so the only cases where we could have used distinct sibling scopes was when there
                // were multiple generic overloads with similar generated type parameter names
                // The effect:
                // When we write out
                // export const x: <T>(x: T) => T
                // export const y: <T>(x: T) => T
                // we write it out like that, rather than as
                // export const x: <T>(x: T) => T
                // export const y: <T_1>(x: T_1) => T_1
                if (initial.typeParameterNames) {
                    initial.typeParameterNames = ts.cloneMap(initial.typeParameterNames);
                }
                if (initial.typeParameterNamesByText) {
                    initial.typeParameterNamesByText = ts.cloneMap(initial.typeParameterNamesByText);
                }
                if (initial.typeParameterSymbolList) {
                    initial.typeParameterSymbolList = ts.cloneMap(initial.typeParameterSymbolList);
                }
                return initial;
            }
            function getDeclarationWithTypeAnnotation(symbol, enclosingDeclaration) {
                return symbol.declarations && ts.find(symbol.declarations, function (s) { return !!ts.getEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!ts.findAncestor(s, function (n) { return n === enclosingDeclaration; })); });
            }
            function existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type) {
                return !(ts.getObjectFlags(type) & 4 /* Reference */) || !ts.isTypeReferenceNode(existing) || ts.length(existing.typeArguments) >= getMinTypeArgumentCount(type.target.typeParameters);
            }
            /**
             * Unlike `typeToTypeNodeHelper`, this handles setting up the `AllowUniqueESSymbolType` flag
             * so a `unique symbol` is returned when appropriate for the input symbol, rather than `typeof sym`
             */
            function serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled) {
                if (type !== errorType && enclosingDeclaration) {
                    var declWithExistingAnnotation = getDeclarationWithTypeAnnotation(symbol, enclosingDeclaration);
                    if (declWithExistingAnnotation && !ts.isFunctionLikeDeclaration(declWithExistingAnnotation)) {
                        // try to reuse the existing annotation
                        var existing = ts.getEffectiveTypeAnnotationNode(declWithExistingAnnotation);
                        if (getTypeFromTypeNode(existing) === type && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)) {
                            var result_4 = serializeExistingTypeNode(context, existing, includePrivateSymbol, bundled);
                            if (result_4) {
                                return result_4;
                            }
                        }
                    }
                }
                var oldFlags = context.flags;
                if (type.flags & 8192 /* UniqueESSymbol */ &&
                    type.symbol === symbol) {
                    context.flags |= 1048576 /* AllowUniqueESSymbolType */;
                }
                var result = typeToTypeNodeHelper(type, context);
                context.flags = oldFlags;
                return result;
            }
            function serializeReturnTypeForSignature(context, type, signature, includePrivateSymbol, bundled) {
                if (type !== errorType && context.enclosingDeclaration) {
                    var annotation = signature.declaration && ts.getEffectiveReturnTypeNode(signature.declaration);
                    if (!!ts.findAncestor(annotation, function (n) { return n === context.enclosingDeclaration; }) && annotation && instantiateType(getTypeFromTypeNode(annotation), signature.mapper) === type && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(annotation, type)) {
                        var result = serializeExistingTypeNode(context, annotation, includePrivateSymbol, bundled);
                        if (result) {
                            return result;
                        }
                    }
                }
                return typeToTypeNodeHelper(type, context);
            }
            function serializeExistingTypeNode(context, existing, includePrivateSymbol, bundled) {
                if (cancellationToken && cancellationToken.throwIfCancellationRequested) {
                    cancellationToken.throwIfCancellationRequested();
                }
                var hadError = false;
                var transformed = ts.visitNode(existing, visitExistingNodeTreeSymbols);
                if (hadError) {
                    return undefined;
                }
                return transformed === existing ? ts.getMutableClone(existing) : transformed;
                function visitExistingNodeTreeSymbols(node) {
                    var _a, _b;
                    // We don't _actually_ support jsdoc namepath types, emit `any` instead
                    if (ts.isJSDocAllType(node) || node.kind === 302 /* JSDocNamepathType */) {
                        return ts.createKeywordTypeNode(125 /* AnyKeyword */);
                    }
                    if (ts.isJSDocUnknownType(node)) {
                        return ts.createKeywordTypeNode(148 /* UnknownKeyword */);
                    }
                    if (ts.isJSDocNullableType(node)) {
                        return ts.createUnionTypeNode([ts.visitNode(node.type, visitExistingNodeTreeSymbols), ts.createKeywordTypeNode(100 /* NullKeyword */)]);
                    }
                    if (ts.isJSDocOptionalType(node)) {
                        return ts.createUnionTypeNode([ts.visitNode(node.type, visitExistingNodeTreeSymbols), ts.createKeywordTypeNode(146 /* UndefinedKeyword */)]);
                    }
                    if (ts.isJSDocNonNullableType(node)) {
                        return ts.visitNode(node.type, visitExistingNodeTreeSymbols);
                    }
                    if (ts.isJSDocVariadicType(node)) {
                        return ts.createArrayTypeNode(ts.visitNode(node.type, visitExistingNodeTreeSymbols));
                    }
                    if (ts.isJSDocTypeLiteral(node)) {
                        return ts.createTypeLiteralNode(ts.map(node.jsDocPropertyTags, function (t) {
                            var name = ts.isIdentifier(t.name) ? t.name : t.name.right;
                            var typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(node), name.escapedText);
                            var overrideTypeNode = typeViaParent && t.typeExpression && getTypeFromTypeNode(t.typeExpression.type) !== typeViaParent ? typeToTypeNodeHelper(typeViaParent, context) : undefined;
                            return ts.createPropertySignature(
                            /*modifiers*/ undefined, name, t.typeExpression && ts.isJSDocOptionalType(t.typeExpression.type) ? ts.createToken(57 /* QuestionToken */) : undefined, overrideTypeNode || (t.typeExpression && ts.visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || ts.createKeywordTypeNode(125 /* AnyKeyword */), 
                            /*initializer*/ undefined);
                        }));
                    }
                    if (ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "") {
                        return ts.setOriginalNode(ts.createKeywordTypeNode(125 /* AnyKeyword */), node);
                    }
                    if ((ts.isExpressionWithTypeArguments(node) || ts.isTypeReferenceNode(node)) && ts.isJSDocIndexSignature(node)) {
                        return ts.createTypeLiteralNode([ts.createIndexSignature(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, [ts.createParameter(
                                /*decorators*/ undefined, 
                                /*modifiers*/ undefined, 
                                /*dotdotdotToken*/ undefined, "x", 
                                /*questionToken*/ undefined, ts.visitNode(node.typeArguments[0], visitExistingNodeTreeSymbols))], ts.visitNode(node.typeArguments[1], visitExistingNodeTreeSymbols))]);
                    }
                    if (ts.isJSDocFunctionType(node)) {
                        if (ts.isJSDocConstructSignature(node)) {
                            var newTypeNode_1;
                            return ts.createConstructorTypeNode(ts.visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), ts.mapDefined(node.parameters, function (p, i) { return p.name && ts.isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode_1 = p.type, undefined) : ts.createParameter(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), p.name || getEffectiveDotDotDotForParameter(p) ? "args" : "arg" + i, p.questionToken, ts.visitNode(p.type, visitExistingNodeTreeSymbols), 
                            /*initializer*/ undefined); }), ts.visitNode(newTypeNode_1 || node.type, visitExistingNodeTreeSymbols));
                        }
                        else {
                            return ts.createFunctionTypeNode(ts.visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), ts.map(node.parameters, function (p, i) { return ts.createParameter(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), p.name || getEffectiveDotDotDotForParameter(p) ? "args" : "arg" + i, p.questionToken, ts.visitNode(p.type, visitExistingNodeTreeSymbols), 
                            /*initializer*/ undefined); }), ts.visitNode(node.type, visitExistingNodeTreeSymbols));
                        }
                    }
                    if (ts.isTypeReferenceNode(node) && ts.isInJSDoc(node) && (getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(getTypeReferenceName(node), 788968 /* Type */, /*ignoreErrors*/ true))) {
                        return ts.setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node);
                    }
                    if (ts.isLiteralImportTypeNode(node)) {
                        return ts.updateImportTypeNode(node, ts.updateLiteralTypeNode(node.argument, rewriteModuleSpecifier(node, node.argument.literal)), node.qualifier, ts.visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, ts.isTypeNode), node.isTypeOf);
                    }
                    if (ts.isEntityName(node) || ts.isEntityNameExpression(node)) {
                        var leftmost = ts.getFirstIdentifier(node);
                        if (ts.isInJSFile(node) && (ts.isExportsIdentifier(leftmost) || ts.isModuleExportsAccessExpression(leftmost.parent) || (ts.isQualifiedName(leftmost.parent) && ts.isModuleIdentifier(leftmost.parent.left) && ts.isExportsIdentifier(leftmost.parent.right)))) {
                            hadError = true;
                            return node;
                        }
                        var sym = resolveEntityName(leftmost, 67108863 /* All */, /*ignoreErrors*/ true, /*dontResolveALias*/ true);
                        if (sym) {
                            if (isSymbolAccessible(sym, context.enclosingDeclaration, 67108863 /* All */, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== 0 /* Accessible */) {
                                hadError = true;
                            }
                            else {
                                (_b = (_a = context.tracker) === null || _a === void 0 ? void 0 : _a.trackSymbol) === null || _b === void 0 ? void 0 : _b.call(_a, sym, context.enclosingDeclaration, 67108863 /* All */);
                                includePrivateSymbol === null || includePrivateSymbol === void 0 ? void 0 : includePrivateSymbol(sym);
                            }
                            if (ts.isIdentifier(node)) {
                                var name = sym.flags & 262144 /* TypeParameter */ ? typeParameterToName(getDeclaredTypeOfSymbol(sym), context) : ts.getMutableClone(node);
                                name.symbol = sym; // for quickinfo, which uses identifier symbol information
                                return ts.setEmitFlags(ts.setOriginalNode(name, node), 16777216 /* NoAsciiEscaping */);
                            }
                        }
                    }
                    return ts.visitEachChild(node, visitExistingNodeTreeSymbols, ts.nullTransformationContext);
                    function getEffectiveDotDotDotForParameter(p) {
                        return p.dotDotDotToken || (p.type && ts.isJSDocVariadicType(p.type) ? ts.createToken(25 /* DotDotDotToken */) : undefined);
                    }
                    function rewriteModuleSpecifier(parent, lit) {
                        if (bundled) {
                            if (context.tracker && context.tracker.moduleResolverHost) {
                                var targetFile = getExternalModuleFileFromDeclaration(parent);
                                if (targetFile) {
                                    var getCanonicalFileName = ts.createGetCanonicalFileName(!!host.useCaseSensitiveFileNames);
                                    var resolverHost = {
                                        getCanonicalFileName: getCanonicalFileName,
                                        getCurrentDirectory: function () { return context.tracker.moduleResolverHost.getCurrentDirectory(); },
                                        getCommonSourceDirectory: function () { return context.tracker.moduleResolverHost.getCommonSourceDirectory(); }
                                    };
                                    var newName = ts.getResolvedExternalModuleName(resolverHost, targetFile);
                                    return ts.createLiteral(newName);
                                }
                            }
                        }
                        else {
                            if (context.tracker && context.tracker.trackExternalModuleSymbolOfImportTypeNode) {
                                var moduleSym = resolveExternalModuleNameWorker(lit, lit, /*moduleNotFoundError*/ undefined);
                                if (moduleSym) {
                                    context.tracker.trackExternalModuleSymbolOfImportTypeNode(moduleSym);
                                }
                            }
                        }
                        return lit;
                    }
                }
            }
            function symbolTableToDeclarationStatements(symbolTable, context, bundled) {
                var serializePropertySymbolForClass = makeSerializePropertySymbol(ts.createProperty, 161 /* MethodDeclaration */, /*useAcessors*/ true);
                var serializePropertySymbolForInterfaceWorker = makeSerializePropertySymbol(function (_decorators, mods, name, question, type, initializer) { return ts.createPropertySignature(mods, name, question, type, initializer); }, 160 /* MethodSignature */, /*useAcessors*/ false);
                // TODO: Use `setOriginalNode` on original declaration names where possible so these declarations see some kind of
                // declaration mapping
                // We save the enclosing declaration off here so it's not adjusted by well-meaning declaration
                // emit codepaths which want to apply more specific contexts (so we can still refer to the root real declaration
                // we're trying to emit from later on)
                var enclosingDeclaration = context.enclosingDeclaration;
                var results = [];
                var visitedSymbols = ts.createMap();
                var deferredPrivates;
                var oldcontext = context;
                context = __assign(__assign({}, oldcontext), { usedSymbolNames: ts.createMap(), remappedSymbolNames: ts.createMap(), tracker: __assign(__assign({}, oldcontext.tracker), { trackSymbol: function (sym, decl, meaning) {
                            var accessibleResult = isSymbolAccessible(sym, decl, meaning, /*computeALiases*/ false);
                            if (accessibleResult.accessibility === 0 /* Accessible */) {
                                // Lookup the root symbol of the chain of refs we'll use to access it and serialize it
                                var chain = lookupSymbolChainWorker(sym, context, meaning);
                                if (!(sym.flags & 4 /* Property */)) {
                                    includePrivateSymbol(chain[0]);
                                }
                            }
                            else if (oldcontext.tracker && oldcontext.tracker.trackSymbol) {
                                oldcontext.tracker.trackSymbol(sym, decl, meaning);
                            }
                        } }) });
                if (oldcontext.usedSymbolNames) {
                    oldcontext.usedSymbolNames.forEach(function (_, name) {
                        context.usedSymbolNames.set(name, true);
                    });
                }
                ts.forEachEntry(symbolTable, function (symbol, name) {
                    var baseName = ts.unescapeLeadingUnderscores(name);
                    void getInternalSymbolName(symbol, baseName); // Called to cache values into `usedSymbolNames` and `remappedSymbolNames`
                });
                var addingDeclare = !bundled;
                var exportEquals = symbolTable.get("export=" /* ExportEquals */);
                if (exportEquals && symbolTable.size > 1 && exportEquals.flags & 2097152 /* Alias */) {
                    symbolTable = ts.createSymbolTable();
                    // Remove extraneous elements from root symbol table (they'll be mixed back in when the target of the `export=` is looked up)
                    symbolTable.set("export=" /* ExportEquals */, exportEquals);
                }
                visitSymbolTable(symbolTable);
                return mergeRedundantStatements(results);
                function isIdentifierAndNotUndefined(node) {
                    return !!node && node.kind === 75 /* Identifier */;
                }
                function getNamesOfDeclaration(statement) {
                    if (ts.isVariableStatement(statement)) {
                        return ts.filter(ts.map(statement.declarationList.declarations, ts.getNameOfDeclaration), isIdentifierAndNotUndefined);
                    }
                    return ts.filter([ts.getNameOfDeclaration(statement)], isIdentifierAndNotUndefined);
                }
                function flattenExportAssignedNamespace(statements) {
                    var exportAssignment = ts.find(statements, ts.isExportAssignment);
                    var ns = ts.find(statements, ts.isModuleDeclaration);
                    if (ns && exportAssignment && exportAssignment.isExportEquals &&
                        ts.isIdentifier(exportAssignment.expression) && ts.isIdentifier(ns.name) && ts.idText(ns.name) === ts.idText(exportAssignment.expression) &&
                        ns.body && ts.isModuleBlock(ns.body)) {
                        // Pass 0: Correct situations where a module has both an `export = ns` and multiple top-level exports by stripping the export modifiers from
                        //  the top-level exports and exporting them in the targeted ns, as can occur when a js file has both typedefs and `module.export` assignments
                        var excessExports = ts.filter(statements, function (s) { return !!(ts.getModifierFlags(s) & 1 /* Export */); });
                        if (ts.length(excessExports)) {
                            ns.body.statements = ts.createNodeArray(__spreadArrays(ns.body.statements, [ts.createExportDeclaration(
                                /*decorators*/ undefined, 
                                /*modifiers*/ undefined, ts.createNamedExports(ts.map(ts.flatMap(excessExports, function (e) { return getNamesOfDeclaration(e); }), function (id) { return ts.createExportSpecifier(/*alias*/ undefined, id); })), 
                                /*moduleSpecifier*/ undefined)]));
                        }
                        // Pass 1: Flatten `export namespace _exports {} export = _exports;` so long as the `export=` only points at a single namespace declaration
                        if (!ts.find(statements, function (s) { return s !== ns && ts.nodeHasName(s, ns.name); })) {
                            results = [];
                            ts.forEach(ns.body.statements, function (s) {
                                addResult(s, 0 /* None */); // Recalculates the ambient (and export, if applicable from above) flag
                            });
                            statements = __spreadArrays(ts.filter(statements, function (s) { return s !== ns && s !== exportAssignment; }), results);
                        }
                    }
                    return statements;
                }
                function mergeExportDeclarations(statements) {
                    // Pass 2: Combine all `export {}` declarations
                    var exports = ts.filter(statements, function (d) { return ts.isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && ts.isNamedExports(d.exportClause); });
                    if (ts.length(exports) > 1) {
                        var nonExports = ts.filter(statements, function (d) { return !ts.isExportDeclaration(d) || !!d.moduleSpecifier || !d.exportClause; });
                        statements = __spreadArrays(nonExports, [ts.createExportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createNamedExports(ts.flatMap(exports, function (e) { return ts.cast(e.exportClause, ts.isNamedExports).elements; })), 
                            /*moduleSpecifier*/ undefined)]);
                    }
                    // Pass 2b: Also combine all `export {} from "..."` declarations as needed
                    var reexports = ts.filter(statements, function (d) { return ts.isExportDeclaration(d) && !!d.moduleSpecifier && !!d.exportClause && ts.isNamedExports(d.exportClause); });
                    if (ts.length(reexports) > 1) {
                        var groups = ts.group(reexports, function (decl) { return ts.isStringLiteral(decl.moduleSpecifier) ? ">" + decl.moduleSpecifier.text : ">"; });
                        if (groups.length !== reexports.length) {
                            var _loop_8 = function (group_1) {
                                if (group_1.length > 1) {
                                    // remove group members from statements and then merge group members and add back to statements
                                    statements = __spreadArrays(ts.filter(statements, function (s) { return group_1.indexOf(s) === -1; }), [
                                        ts.createExportDeclaration(
                                        /*decorators*/ undefined, 
                                        /*modifiers*/ undefined, ts.createNamedExports(ts.flatMap(group_1, function (e) { return ts.cast(e.exportClause, ts.isNamedExports).elements; })), group_1[0].moduleSpecifier)
                                    ]);
                                }
                            };
                            for (var _i = 0, groups_1 = groups; _i < groups_1.length; _i++) {
                                var group_1 = groups_1[_i];
                                _loop_8(group_1);
                            }
                        }
                    }
                    return statements;
                }
                function inlineExportModifiers(statements) {
                    // Pass 3: Move all `export {}`'s to `export` modifiers where possible
                    var exportDecl = ts.find(statements, function (d) { return ts.isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause; });
                    if (exportDecl && exportDecl.exportClause && ts.isNamedExports(exportDecl.exportClause)) {
                        var replacements = ts.mapDefined(exportDecl.exportClause.elements, function (e) {
                            if (!e.propertyName) {
                                // export {name} - look thru `statements` for `name`, and if all results can take an `export` modifier, do so and filter it
                                var associated = ts.filter(statements, function (s) { return ts.nodeHasName(s, e.name); });
                                if (ts.length(associated) && ts.every(associated, canHaveExportModifier)) {
                                    ts.forEach(associated, addExportModifier);
                                    return undefined;
                                }
                            }
                            return e;
                        });
                        if (!ts.length(replacements)) {
                            // all clauses removed, filter the export declaration
                            statements = ts.filter(statements, function (s) { return s !== exportDecl; });
                        }
                        else {
                            // some items filtered, others not - update the export declaration
                            // (mutating because why not, we're building a whole new tree here anyway)
                            exportDecl.exportClause.elements = ts.createNodeArray(replacements);
                        }
                    }
                    return statements;
                }
                function mergeRedundantStatements(statements) {
                    statements = flattenExportAssignedNamespace(statements);
                    statements = mergeExportDeclarations(statements);
                    statements = inlineExportModifiers(statements);
                    // Not a cleanup, but as a final step: If there is a mix of `export` and non-`export` declarations, but no `export =` or `export {}` add a `export {};` so
                    // declaration privacy is respected.
                    if (enclosingDeclaration &&
                        ((ts.isSourceFile(enclosingDeclaration) && ts.isExternalOrCommonJsModule(enclosingDeclaration)) || ts.isModuleDeclaration(enclosingDeclaration)) &&
                        (!ts.some(statements, ts.isExternalModuleIndicator) || (!ts.hasScopeMarker(statements) && ts.some(statements, ts.needsScopeMarker)))) {
                        statements.push(ts.createEmptyExports());
                    }
                    return statements;
                }
                function canHaveExportModifier(node) {
                    return ts.isEnumDeclaration(node) ||
                        ts.isVariableStatement(node) ||
                        ts.isFunctionDeclaration(node) ||
                        ts.isClassDeclaration(node) ||
                        (ts.isModuleDeclaration(node) && !ts.isExternalModuleAugmentation(node) && !ts.isGlobalScopeAugmentation(node)) ||
                        ts.isInterfaceDeclaration(node) ||
                        isTypeDeclaration(node);
                }
                function addExportModifier(statement) {
                    var flags = (ts.getModifierFlags(statement) | 1 /* Export */) & ~2 /* Ambient */;
                    statement.modifiers = ts.createNodeArray(ts.createModifiersFromModifierFlags(flags));
                    statement.modifierFlagsCache = 0;
                }
                function visitSymbolTable(symbolTable, suppressNewPrivateContext, propertyAsAlias) {
                    var oldDeferredPrivates = deferredPrivates;
                    if (!suppressNewPrivateContext) {
                        deferredPrivates = ts.createMap();
                    }
                    symbolTable.forEach(function (symbol) {
                        serializeSymbol(symbol, /*isPrivate*/ false, !!propertyAsAlias);
                    });
                    if (!suppressNewPrivateContext) {
                        // deferredPrivates will be filled up by visiting the symbol table
                        // And will continue to iterate as elements are added while visited `deferredPrivates`
                        // (As that's how a map iterator is defined to work)
                        deferredPrivates.forEach(function (symbol) {
                            serializeSymbol(symbol, /*isPrivate*/ true, !!propertyAsAlias);
                        });
                    }
                    deferredPrivates = oldDeferredPrivates;
                }
                function serializeSymbol(symbol, isPrivate, propertyAsAlias) {
                    // cache visited list based on merged symbol, since we want to use the unmerged top-level symbol, but
                    // still skip reserializing it if we encounter the merged product later on
                    var visitedSym = getMergedSymbol(symbol);
                    if (visitedSymbols.has("" + getSymbolId(visitedSym))) {
                        return; // Already printed
                    }
                    visitedSymbols.set("" + getSymbolId(visitedSym), true);
                    // Only actually serialize symbols within the correct enclosing declaration, otherwise do nothing with the out-of-context symbol
                    var skipMembershipCheck = !isPrivate; // We only call this on exported symbols when we know they're in the correct scope
                    if (skipMembershipCheck || (!!ts.length(symbol.declarations) && ts.some(symbol.declarations, function (d) { return !!ts.findAncestor(d, function (n) { return n === enclosingDeclaration; }); }))) {
                        var oldContext = context;
                        context = cloneNodeBuilderContext(context);
                        var result = serializeSymbolWorker(symbol, isPrivate, propertyAsAlias);
                        context = oldContext;
                        return result;
                    }
                }
                // Synthesize declarations for a symbol - might be an Interface, a Class, a Namespace, a Type, a Variable (const, let, or var), an Alias
                // or a merge of some number of those.
                // An interesting challenge is ensuring that when classes merge with namespaces and interfaces, is keeping
                // each symbol in only one of the representations
                // Also, synthesizing a default export of some kind
                // If it's an alias: emit `export default ref`
                // If it's a property: emit `export default _default` with a `_default` prop
                // If it's a class/interface/function: emit a class/interface/function with a `default` modifier
                // These forms can merge, eg (`export default 12; export default interface A {}`)
                function serializeSymbolWorker(symbol, isPrivate, propertyAsAlias) {
                    var symbolName = ts.unescapeLeadingUnderscores(symbol.escapedName);
                    var isDefault = symbol.escapedName === "default" /* Default */;
                    if (!(context.flags & 131072 /* AllowAnonymousIdentifier */) && ts.isStringANonContextualKeyword(symbolName) && !isDefault) {
                        // Oh no. We cannot use this symbol's name as it's name... It's likely some jsdoc had an invalid name like `export` or `default` :(
                        context.encounteredError = true;
                        // TODO: Issue error via symbol tracker?
                        return; // If we need to emit a private with a keyword name, we're done for, since something else will try to refer to it by that name
                    }
                    var needsPostExportDefault = isDefault && !!(symbol.flags & -113 /* ExportDoesNotSupportDefaultModifier */
                        || (symbol.flags & 16 /* Function */ && ts.length(getPropertiesOfType(getTypeOfSymbol(symbol))))) && !(symbol.flags & 2097152 /* Alias */); // An alias symbol should preclude needing to make an alias ourselves
                    if (needsPostExportDefault) {
                        isPrivate = true;
                    }
                    var modifierFlags = (!isPrivate ? 1 /* Export */ : 0) | (isDefault && !needsPostExportDefault ? 512 /* Default */ : 0);
                    var isConstMergedWithNS = symbol.flags & 1536 /* Module */ &&
                        symbol.flags & (2 /* BlockScopedVariable */ | 1 /* FunctionScopedVariable */ | 4 /* Property */) &&
                        symbol.escapedName !== "export=" /* ExportEquals */;
                    var isConstMergedWithNSPrintableAsSignatureMerge = isConstMergedWithNS && isTypeRepresentableAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol);
                    if (symbol.flags & (16 /* Function */ | 8192 /* Method */) || isConstMergedWithNSPrintableAsSignatureMerge) {
                        serializeAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                    }
                    if (symbol.flags & 524288 /* TypeAlias */) {
                        serializeTypeAlias(symbol, symbolName, modifierFlags);
                    }
                    // Need to skip over export= symbols below - json source files get a single `Property` flagged
                    // symbol of name `export=` which needs to be handled like an alias. It's not great, but it is what it is.
                    if (symbol.flags & (2 /* BlockScopedVariable */ | 1 /* FunctionScopedVariable */ | 4 /* Property */)
                        && symbol.escapedName !== "export=" /* ExportEquals */
                        && !(symbol.flags & 4194304 /* Prototype */)
                        && !(symbol.flags & 32 /* Class */)
                        && !isConstMergedWithNSPrintableAsSignatureMerge) {
                        serializeVariableOrProperty(symbol, symbolName, isPrivate, needsPostExportDefault, propertyAsAlias, modifierFlags);
                    }
                    if (symbol.flags & 384 /* Enum */) {
                        serializeEnum(symbol, symbolName, modifierFlags);
                    }
                    if (symbol.flags & 32 /* Class */) {
                        if (symbol.flags & 4 /* Property */ && ts.isBinaryExpression(symbol.valueDeclaration.parent) && ts.isClassExpression(symbol.valueDeclaration.parent.right)) {
                            // Looks like a `module.exports.Sub = class {}` - if we serialize `symbol` as a class, the result will have no members,
                            // since the classiness is actually from the target of the effective alias the symbol is. yes. A BlockScopedVariable|Class|Property
                            // _really_ acts like an Alias, and none of a BlockScopedVariable, Class, or Property. This is the travesty of JS binding today.
                            serializeAsAlias(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                        }
                        else {
                            serializeAsClass(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                        }
                    }
                    if ((symbol.flags & (512 /* ValueModule */ | 1024 /* NamespaceModule */) && (!isConstMergedWithNS || isTypeOnlyNamespace(symbol))) || isConstMergedWithNSPrintableAsSignatureMerge) {
                        serializeModule(symbol, symbolName, modifierFlags);
                    }
                    if (symbol.flags & 64 /* Interface */) {
                        serializeInterface(symbol, symbolName, modifierFlags);
                    }
                    if (symbol.flags & 2097152 /* Alias */) {
                        serializeAsAlias(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                    }
                    if (symbol.flags & 4 /* Property */ && symbol.escapedName === "export=" /* ExportEquals */) {
                        serializeMaybeAliasAssignment(symbol);
                    }
                    if (symbol.flags & 8388608 /* ExportStar */) {
                        // synthesize export * from "moduleReference"
                        // Straightforward - only one thing to do - make an export declaration
                        for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                            var node = _a[_i];
                            var resolvedModule = resolveExternalModuleName(node, node.moduleSpecifier);
                            if (!resolvedModule)
                                continue;
                            addResult(ts.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*exportClause*/ undefined, ts.createLiteral(getSpecifierForModuleSymbol(resolvedModule, context))), 0 /* None */);
                        }
                    }
                    if (needsPostExportDefault) {
                        addResult(ts.createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportAssignment*/ false, ts.createIdentifier(getInternalSymbolName(symbol, symbolName))), 0 /* None */);
                    }
                }
                function includePrivateSymbol(symbol) {
                    if (ts.some(symbol.declarations, ts.isParameterDeclaration))
                        return;
                    ts.Debug.assertIsDefined(deferredPrivates);
                    getUnusedName(ts.unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol
                    deferredPrivates.set("" + getSymbolId(symbol), symbol);
                }
                function isExportingScope(enclosingDeclaration) {
                    return ((ts.isSourceFile(enclosingDeclaration) && (ts.isExternalOrCommonJsModule(enclosingDeclaration) || ts.isJsonSourceFile(enclosingDeclaration))) ||
                        (ts.isAmbientModule(enclosingDeclaration) && !ts.isGlobalScopeAugmentation(enclosingDeclaration)));
                }
                // Prepends a `declare` and/or `export` modifier if the context requires it, and then adds `node` to `result` and returns `node`
                // Note: This _mutates_ `node` without using `updateNode` - the assumption being that all nodes should be manufactured fresh by the node builder
                function addResult(node, additionalModifierFlags) {
                    var newModifierFlags = 0 /* None */;
                    if (additionalModifierFlags & 1 /* Export */ &&
                        enclosingDeclaration &&
                        isExportingScope(enclosingDeclaration) &&
                        canHaveExportModifier(node)) {
                        // Classes, namespaces, variables, functions, interfaces, and types should all be `export`ed in a module context if not private
                        newModifierFlags |= 1 /* Export */;
                    }
                    if (addingDeclare && !(newModifierFlags & 1 /* Export */) &&
                        (!enclosingDeclaration || !(enclosingDeclaration.flags & 8388608 /* Ambient */)) &&
                        (ts.isEnumDeclaration(node) || ts.isVariableStatement(node) || ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isModuleDeclaration(node))) {
                        // Classes, namespaces, variables, enums, and functions all need `declare` modifiers to be valid in a declaration file top-level scope
                        newModifierFlags |= 2 /* Ambient */;
                    }
                    if ((additionalModifierFlags & 512 /* Default */) && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isFunctionDeclaration(node))) {
                        newModifierFlags |= 512 /* Default */;
                    }
                    if (newModifierFlags) {
                        node.modifiers = ts.createNodeArray(ts.createModifiersFromModifierFlags(newModifierFlags | ts.getModifierFlags(node)));
                        node.modifierFlagsCache = 0; // Reset computed flags cache
                    }
                    results.push(node);
                }
                function serializeTypeAlias(symbol, symbolName, modifierFlags) {
                    var aliasType = getDeclaredTypeOfTypeAlias(symbol);
                    var typeParams = getSymbolLinks(symbol).typeParameters;
                    var typeParamDecls = ts.map(typeParams, function (p) { return typeParameterToDeclaration(p, context); });
                    var jsdocAliasDecl = ts.find(symbol.declarations, ts.isJSDocTypeAlias);
                    var commentText = jsdocAliasDecl ? jsdocAliasDecl.comment || jsdocAliasDecl.parent.comment : undefined;
                    var oldFlags = context.flags;
                    context.flags |= 8388608 /* InTypeAlias */;
                    addResult(ts.setSyntheticLeadingComments(ts.createTypeAliasDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, typeToTypeNodeHelper(aliasType, context)), !commentText ? [] : [{ kind: 3 /* MultiLineCommentTrivia */, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]), modifierFlags);
                    context.flags = oldFlags;
                }
                function serializeInterface(symbol, symbolName, modifierFlags) {
                    var interfaceType = getDeclaredTypeOfClassOrInterface(symbol);
                    var localParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    var typeParamDecls = ts.map(localParams, function (p) { return typeParameterToDeclaration(p, context); });
                    var baseTypes = getBaseTypes(interfaceType);
                    var baseType = ts.length(baseTypes) ? getIntersectionType(baseTypes) : undefined;
                    var members = ts.flatMap(getPropertiesOfType(interfaceType), function (p) { return serializePropertySymbolForInterface(p, baseType); });
                    var callSignatures = serializeSignatures(0 /* Call */, interfaceType, baseType, 165 /* CallSignature */);
                    var constructSignatures = serializeSignatures(1 /* Construct */, interfaceType, baseType, 166 /* ConstructSignature */);
                    var indexSignatures = serializeIndexSignatures(interfaceType, baseType);
                    var heritageClauses = !ts.length(baseTypes) ? undefined : [ts.createHeritageClause(90 /* ExtendsKeyword */, ts.mapDefined(baseTypes, function (b) { return trySerializeAsTypeReference(b); }))];
                    addResult(ts.createInterfaceDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, heritageClauses, __spreadArrays(indexSignatures, constructSignatures, callSignatures, members)), modifierFlags);
                }
                function getNamespaceMembersForSerialization(symbol) {
                    return !symbol.exports ? [] : ts.filter(ts.arrayFrom(symbol.exports.values()), isNamespaceMember);
                }
                function isTypeOnlyNamespace(symbol) {
                    return ts.every(getNamespaceMembersForSerialization(symbol), function (m) { return !(resolveSymbol(m).flags & 111551 /* Value */); });
                }
                function serializeModule(symbol, symbolName, modifierFlags) {
                    var members = getNamespaceMembersForSerialization(symbol);
                    // Split NS members up by declaration - members whose parent symbol is the ns symbol vs those whose is not (but were added in later via merging)
                    var locationMap = ts.arrayToMultiMap(members, function (m) { return m.parent && m.parent === symbol ? "real" : "merged"; });
                    var realMembers = locationMap.get("real") || ts.emptyArray;
                    var mergedMembers = locationMap.get("merged") || ts.emptyArray;
                    // TODO: `suppressNewPrivateContext` is questionable -we need to simply be emitting privates in whatever scope they were declared in, rather
                    // than whatever scope we traverse to them in. That's a bit of a complex rewrite, since we're not _actually_ tracking privates at all in advance,
                    // so we don't even have placeholders to fill in.
                    if (ts.length(realMembers)) {
                        var localName = getInternalSymbolName(symbol, symbolName);
                        serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & (16 /* Function */ | 67108864 /* Assignment */)));
                    }
                    if (ts.length(mergedMembers)) {
                        var containingFile_1 = ts.getSourceFileOfNode(context.enclosingDeclaration);
                        var localName = getInternalSymbolName(symbol, symbolName);
                        var nsBody = ts.createModuleBlock([ts.createExportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createNamedExports(ts.mapDefined(ts.filter(mergedMembers, function (n) { return n.escapedName !== "export=" /* ExportEquals */; }), function (s) {
                                var _a, _b;
                                var name = ts.unescapeLeadingUnderscores(s.escapedName);
                                var localName = getInternalSymbolName(s, name);
                                var aliasDecl = s.declarations && getDeclarationOfAliasSymbol(s);
                                if (containingFile_1 && (aliasDecl ? containingFile_1 !== ts.getSourceFileOfNode(aliasDecl) : !ts.some(s.declarations, function (d) { return ts.getSourceFileOfNode(d) === containingFile_1; }))) {
                                    (_b = (_a = context.tracker) === null || _a === void 0 ? void 0 : _a.reportNonlocalAugmentation) === null || _b === void 0 ? void 0 : _b.call(_a, containingFile_1, symbol, s);
                                    return undefined;
                                }
                                var target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true);
                                includePrivateSymbol(target || s);
                                var targetName = target ? getInternalSymbolName(target, ts.unescapeLeadingUnderscores(target.escapedName)) : localName;
                                return ts.createExportSpecifier(name === targetName ? undefined : targetName, name);
                            })))]);
                        addResult(ts.createModuleDeclaration(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, ts.createIdentifier(localName), nsBody, 16 /* Namespace */), 0 /* None */);
                    }
                }
                function serializeEnum(symbol, symbolName, modifierFlags) {
                    addResult(ts.createEnumDeclaration(
                    /*decorators*/ undefined, ts.createModifiersFromModifierFlags(isConstEnumSymbol(symbol) ? 2048 /* Const */ : 0), getInternalSymbolName(symbol, symbolName), ts.map(ts.filter(getPropertiesOfType(getTypeOfSymbol(symbol)), function (p) { return !!(p.flags & 8 /* EnumMember */); }), function (p) {
                        // TODO: Handle computed names
                        // I hate that to get the initialized value we need to walk back to the declarations here; but there's no
                        // other way to get the possible const value of an enum member that I'm aware of, as the value is cached
                        // _on the declaration_, not on the declaration's symbol...
                        var initializedValue = p.declarations && p.declarations[0] && ts.isEnumMember(p.declarations[0]) && getConstantValue(p.declarations[0]);
                        return ts.createEnumMember(ts.unescapeLeadingUnderscores(p.escapedName), initializedValue === undefined ? undefined : ts.createLiteral(initializedValue));
                    })), modifierFlags);
                }
                function serializeVariableOrProperty(symbol, symbolName, isPrivate, needsPostExportDefault, propertyAsAlias, modifierFlags) {
                    if (propertyAsAlias) {
                        serializeMaybeAliasAssignment(symbol);
                    }
                    else {
                        var type = getTypeOfSymbol(symbol);
                        var localName = getInternalSymbolName(symbol, symbolName);
                        if (!(symbol.flags & 16 /* Function */) && isTypeRepresentableAsFunctionNamespaceMerge(type, symbol)) {
                            // If the type looks like a function declaration + ns could represent it, and it's type is sourced locally, rewrite it into a function declaration + ns
                            serializeAsFunctionNamespaceMerge(type, symbol, localName, modifierFlags);
                        }
                        else {
                            // A Class + Property merge is made for a `module.exports.Member = class {}`, and it doesn't serialize well as either a class _or_ a property symbol - in fact, _it behaves like an alias!_
                            // `var` is `FunctionScopedVariable`, `const` and `let` are `BlockScopedVariable`, and `module.exports.thing =` is `Property`
                            var flags = !(symbol.flags & 2 /* BlockScopedVariable */) ? undefined
                                : isConstVariable(symbol) ? 2 /* Const */
                                    : 1 /* Let */;
                            var name = (needsPostExportDefault || !(symbol.flags & 4 /* Property */)) ? localName : getUnusedName(localName, symbol);
                            var textRange = symbol.declarations && ts.find(symbol.declarations, function (d) { return ts.isVariableDeclaration(d); });
                            if (textRange && ts.isVariableDeclarationList(textRange.parent) && textRange.parent.declarations.length === 1) {
                                textRange = textRange.parent.parent;
                            }
                            var statement = ts.setTextRange(ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([
                                ts.createVariableDeclaration(name, serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
                            ], flags)), textRange);
                            addResult(statement, name !== localName ? modifierFlags & ~1 /* Export */ : modifierFlags);
                            if (name !== localName && !isPrivate) {
                                // We rename the variable declaration we generate for Property symbols since they may have a name which
                                // conflicts with a local declaration. For example, given input:
                                // ```
                                // function g() {}
                                // module.exports.g = g
                                // ```
                                // In such a situation, we have a local variable named `g`, and a separate exported variable named `g`.
                                // Naively, we would emit
                                // ```
                                // function g() {}
                                // export const g: typeof g;
                                // ```
                                // That's obviously incorrect - the `g` in the type annotation needs to refer to the local `g`, but
                                // the export declaration shadows it.
                                // To work around that, we instead write
                                // ```
                                // function g() {}
                                // const g_1: typeof g;
                                // export { g_1 as g };
                                // ```
                                // To create an export named `g` that does _not_ shadow the local `g`
                                addResult(ts.createExportDeclaration(
                                /*decorators*/ undefined, 
                                /*modifiers*/ undefined, ts.createNamedExports([ts.createExportSpecifier(name, localName)])), 0 /* None */);
                            }
                        }
                    }
                }
                function serializeAsFunctionNamespaceMerge(type, symbol, localName, modifierFlags) {
                    var signatures = getSignaturesOfType(type, 0 /* Call */);
                    for (var _i = 0, signatures_2 = signatures; _i < signatures_2.length; _i++) {
                        var sig = signatures_2[_i];
                        // Each overload becomes a separate function declaration, in order
                        var decl = signatureToSignatureDeclarationHelper(sig, 244 /* FunctionDeclaration */, context, includePrivateSymbol, bundled);
                        decl.name = ts.createIdentifier(localName);
                        // for expressions assigned to `var`s, use the `var` as the text range
                        addResult(ts.setTextRange(decl, sig.declaration && ts.isVariableDeclaration(sig.declaration.parent) && sig.declaration.parent.parent || sig.declaration), modifierFlags);
                    }
                    // Module symbol emit will take care of module-y members, provided it has exports
                    if (!(symbol.flags & (512 /* ValueModule */ | 1024 /* NamespaceModule */) && !!symbol.exports && !!symbol.exports.size)) {
                        var props = ts.filter(getPropertiesOfType(type), isNamespaceMember);
                        serializeAsNamespaceDeclaration(props, localName, modifierFlags, /*suppressNewPrivateContext*/ true);
                    }
                }
                function serializeAsNamespaceDeclaration(props, localName, modifierFlags, suppressNewPrivateContext) {
                    if (ts.length(props)) {
                        var localVsRemoteMap = ts.arrayToMultiMap(props, function (p) {
                            return !ts.length(p.declarations) || ts.some(p.declarations, function (d) {
                                return ts.getSourceFileOfNode(d) === ts.getSourceFileOfNode(context.enclosingDeclaration);
                            }) ? "local" : "remote";
                        });
                        var localProps = localVsRemoteMap.get("local") || ts.emptyArray;
                        // handle remote props first - we need to make an `import` declaration that points at the module containing each remote
                        // prop in the outermost scope (TODO: a namespace within a namespace would need to be appropriately handled by this)
                        // Example:
                        // import Foo_1 = require("./exporter");
                        // export namespace ns {
                        //     import Foo = Foo_1.Foo;
                        //     export { Foo };
                        //     export const c: number;
                        // }
                        // This is needed because in JS, statements like `const x = require("./f")` support both type and value lookup, even if they're
                        // normally just value lookup (so it functions kinda like an alias even when it's not an alias)
                        // _Usually_, we'll simply print the top-level as an alias instead of a `var` in such situations, however is is theoretically
                        // possible to encounter a situation where a type has members from both the current file and other files - in those situations,
                        // emit akin to the above would be needed.
                        // Add a namespace
                        var fakespace = ts.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createIdentifier(localName), ts.createModuleBlock([]), 16 /* Namespace */);
                        fakespace.flags ^= 8 /* Synthesized */; // unset synthesized so it is usable as an enclosing declaration
                        fakespace.parent = enclosingDeclaration;
                        fakespace.locals = ts.createSymbolTable(props);
                        fakespace.symbol = props[0].parent;
                        var oldResults = results;
                        results = [];
                        var oldAddingDeclare = addingDeclare;
                        addingDeclare = false;
                        var subcontext = __assign(__assign({}, context), { enclosingDeclaration: fakespace });
                        var oldContext = context;
                        context = subcontext;
                        // TODO: implement handling for the localVsRemoteMap.get("remote") - should be difficult to trigger (see comment above), as only interesting cross-file js merges should make this possible
                        visitSymbolTable(ts.createSymbolTable(localProps), suppressNewPrivateContext, /*propertyAsAlias*/ true);
                        context = oldContext;
                        addingDeclare = oldAddingDeclare;
                        var declarations = results;
                        results = oldResults;
                        fakespace.flags ^= 8 /* Synthesized */; // reset synthesized
                        fakespace.parent = undefined;
                        fakespace.locals = undefined;
                        fakespace.symbol = undefined;
                        fakespace.body = ts.createModuleBlock(declarations);
                        addResult(fakespace, modifierFlags); // namespaces can never be default exported
                    }
                }
                function isNamespaceMember(p) {
                    return !(p.flags & 4194304 /* Prototype */ || p.escapedName === "prototype" || p.valueDeclaration && ts.isClassLike(p.valueDeclaration.parent));
                }
                function serializeAsClass(symbol, localName, modifierFlags) {
                    var localParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    var typeParamDecls = ts.map(localParams, function (p) { return typeParameterToDeclaration(p, context); });
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    var baseTypes = getBaseTypes(classType);
                    var implementsTypes = getImplementsTypes(classType);
                    var staticType = getTypeOfSymbol(symbol);
                    var staticBaseType = getBaseConstructorTypeOfClass(staticType);
                    var heritageClauses = __spreadArrays(!ts.length(baseTypes) ? [] : [ts.createHeritageClause(90 /* ExtendsKeyword */, ts.map(baseTypes, function (b) { return serializeBaseType(b, staticBaseType, localName); }))], !ts.length(implementsTypes) ? [] : [ts.createHeritageClause(113 /* ImplementsKeyword */, ts.map(implementsTypes, function (b) { return serializeBaseType(b, staticBaseType, localName); }))]);
                    var symbolProps = getNonInterhitedProperties(classType, baseTypes, getPropertiesOfType(classType));
                    var publicSymbolProps = ts.filter(symbolProps, function (s) {
                        // `valueDeclaration` could be undefined if inherited from
                        // a union/intersection base type, but inherited properties
                        // don't matter here.
                        var valueDecl = s.valueDeclaration;
                        return valueDecl && !(ts.isNamedDeclaration(valueDecl) && ts.isPrivateIdentifier(valueDecl.name));
                    });
                    var hasPrivateIdentifier = ts.some(symbolProps, function (s) {
                        // `valueDeclaration` could be undefined if inherited from
                        // a union/intersection base type, but inherited properties
                        // don't matter here.
                        var valueDecl = s.valueDeclaration;
                        return valueDecl && ts.isNamedDeclaration(valueDecl) && ts.isPrivateIdentifier(valueDecl.name);
                    });
                    // Boil down all private properties into a single one.
                    var privateProperties = hasPrivateIdentifier ?
                        [ts.createProperty(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createPrivateIdentifier("#private"), 
                            /*questionOrExclamationToken*/ undefined, 
                            /*type*/ undefined, 
                            /*initializer*/ undefined)] :
                        ts.emptyArray;
                    var publicProperties = ts.flatMap(publicSymbolProps, function (p) { return serializePropertySymbolForClass(p, /*isStatic*/ false, baseTypes[0]); });
                    // Consider static members empty if symbol also has function or module meaning - function namespacey emit will handle statics
                    var staticMembers = ts.flatMap(ts.filter(getPropertiesOfType(staticType), function (p) { return !(p.flags & 4194304 /* Prototype */) && p.escapedName !== "prototype" && !isNamespaceMember(p); }), function (p) { return serializePropertySymbolForClass(p, /*isStatic*/ true, staticBaseType); });
                    var constructors = serializeSignatures(1 /* Construct */, staticType, baseTypes[0], 162 /* Constructor */);
                    for (var _i = 0, constructors_1 = constructors; _i < constructors_1.length; _i++) {
                        var c = constructors_1[_i];
                        // A constructor's return type and type parameters are supposed to be controlled by the enclosing class declaration
                        // `signatureToSignatureDeclarationHelper` appends them regardless, so for now we delete them here
                        c.type = undefined;
                        c.typeParameters = undefined;
                    }
                    var indexSignatures = serializeIndexSignatures(classType, baseTypes[0]);
                    addResult(ts.setTextRange(ts.createClassDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, localName, typeParamDecls, heritageClauses, __spreadArrays(indexSignatures, staticMembers, constructors, publicProperties, privateProperties)), symbol.declarations && ts.filter(symbol.declarations, function (d) { return ts.isClassDeclaration(d) || ts.isClassExpression(d); })[0]), modifierFlags);
                }
                function serializeAsAlias(symbol, localName, modifierFlags) {
                    // synthesize an alias, eg `export { symbolName as Name }`
                    // need to mark the alias `symbol` points at
                    // as something we need to serialize as a private declaration as well
                    var node = getDeclarationOfAliasSymbol(symbol);
                    if (!node)
                        return ts.Debug.fail();
                    var target = getMergedSymbol(getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true));
                    if (!target) {
                        return;
                    }
                    var verbatimTargetName = ts.unescapeLeadingUnderscores(target.escapedName);
                    if (verbatimTargetName === "export=" /* ExportEquals */ && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) {
                        // target refers to an `export=` symbol that was hoisted into a synthetic default - rename here to match
                        verbatimTargetName = "default" /* Default */;
                    }
                    var targetName = getInternalSymbolName(target, verbatimTargetName);
                    includePrivateSymbol(target); // the target may be within the same scope - attempt to serialize it first
                    switch (node.kind) {
                        case 253 /* ImportEqualsDeclaration */:
                            // Could be a local `import localName = ns.member` or
                            // an external `import localName = require("whatever")`
                            var isLocalImport = !(target.flags & 512 /* ValueModule */);
                            addResult(ts.createImportEqualsDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createIdentifier(localName), isLocalImport
                                ? symbolToName(target, context, 67108863 /* All */, /*expectsIdentifier*/ false)
                                : ts.createExternalModuleReference(ts.createLiteral(getSpecifierForModuleSymbol(symbol, context)))), isLocalImport ? modifierFlags : 0 /* None */);
                            break;
                        case 252 /* NamespaceExportDeclaration */:
                            // export as namespace foo
                            // TODO: Not part of a file's local or export symbol tables
                            // Is bound into file.symbol.globalExports instead, which we don't currently traverse
                            addResult(ts.createNamespaceExportDeclaration(ts.idText(node.name)), 0 /* None */);
                            break;
                        case 255 /* ImportClause */:
                            addResult(ts.createImportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createImportClause(ts.createIdentifier(localName), /*namedBindings*/ undefined), 
                            // We use `target.parent || target` below as `target.parent` is unset when the target is a module which has been export assigned
                            // And then made into a default by the `esModuleInterop` or `allowSyntheticDefaultImports` flag
                            // In such cases, the `target` refers to the module itself already
                            ts.createLiteral(getSpecifierForModuleSymbol(target.parent || target, context))), 0 /* None */);
                            break;
                        case 256 /* NamespaceImport */:
                            addResult(ts.createImportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createImportClause(/*importClause*/ undefined, ts.createNamespaceImport(ts.createIdentifier(localName))), ts.createLiteral(getSpecifierForModuleSymbol(target, context))), 0 /* None */);
                            break;
                        case 262 /* NamespaceExport */:
                            addResult(ts.createExportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createNamespaceExport(ts.createIdentifier(localName)), ts.createLiteral(getSpecifierForModuleSymbol(target, context))), 0 /* None */);
                            break;
                        case 258 /* ImportSpecifier */:
                            addResult(ts.createImportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createImportClause(/*importClause*/ undefined, ts.createNamedImports([
                                ts.createImportSpecifier(localName !== verbatimTargetName ? ts.createIdentifier(verbatimTargetName) : undefined, ts.createIdentifier(localName))
                            ])), ts.createLiteral(getSpecifierForModuleSymbol(target.parent || target, context))), 0 /* None */);
                            break;
                        case 263 /* ExportSpecifier */:
                            // does not use localName because the symbol name in this case refers to the name in the exports table,
                            // which we must exactly preserve
                            var specifier = node.parent.parent.moduleSpecifier;
                            // targetName is only used when the target is local, as otherwise the target is an alias that points at
                            // another file
                            serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.createLiteral(specifier.text) : undefined);
                            break;
                        case 259 /* ExportAssignment */:
                            serializeMaybeAliasAssignment(symbol);
                            break;
                        case 209 /* BinaryExpression */:
                        case 194 /* PropertyAccessExpression */:
                            // Could be best encoded as though an export specifier or as though an export assignment
                            // If name is default or export=, do an export assignment
                            // Otherwise do an export specifier
                            if (symbol.escapedName === "default" /* Default */ || symbol.escapedName === "export=" /* ExportEquals */) {
                                serializeMaybeAliasAssignment(symbol);
                            }
                            else {
                                serializeExportSpecifier(localName, targetName);
                            }
                            break;
                        default:
                            return ts.Debug.failBadSyntaxKind(node, "Unhandled alias declaration kind in symbol serializer!");
                    }
                }
                function serializeExportSpecifier(localName, targetName, specifier) {
                    addResult(ts.createExportDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, ts.createNamedExports([ts.createExportSpecifier(localName !== targetName ? targetName : undefined, localName)]), specifier), 0 /* None */);
                }
                function serializeMaybeAliasAssignment(symbol) {
                    if (symbol.flags & 4194304 /* Prototype */) {
                        return;
                    }
                    var name = ts.unescapeLeadingUnderscores(symbol.escapedName);
                    var isExportEquals = name === "export=" /* ExportEquals */;
                    var isDefault = name === "default" /* Default */;
                    var isExportAssignment = isExportEquals || isDefault;
                    // synthesize export = ref
                    // ref should refer to either be a locally scoped symbol which we need to emit, or
                    // a reference to another namespace/module which we may need to emit an `import` statement for
                    var aliasDecl = symbol.declarations && getDeclarationOfAliasSymbol(symbol);
                    // serialize what the alias points to, preserve the declaration's initializer
                    var target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true);
                    // If the target resolves and resolves to a thing defined in this file, emit as an alias, otherwise emit as a const
                    if (target && ts.length(target.declarations) && ts.some(target.declarations, function (d) { return ts.getSourceFileOfNode(d) === ts.getSourceFileOfNode(enclosingDeclaration); })) {
                        // In case `target` refers to a namespace member, look at the declaration and serialize the leftmost symbol in it
                        // eg, `namespace A { export class B {} }; exports = A.B;`
                        // Technically, this is all that's required in the case where the assignment is an entity name expression
                        var expr = isExportAssignment ? ts.getExportAssignmentExpression(aliasDecl) : ts.getPropertyAssignmentAliasLikeExpression(aliasDecl);
                        var first_1 = ts.isEntityNameExpression(expr) ? getFirstNonModuleExportsIdentifier(expr) : undefined;
                        var referenced = first_1 && resolveEntityName(first_1, 67108863 /* All */, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, enclosingDeclaration);
                        if (referenced || target) {
                            includePrivateSymbol(referenced || target);
                        }
                        // We disable the context's symbol tracker for the duration of this name serialization
                        // as, by virtue of being here, the name is required to print something, and we don't want to
                        // issue a visibility error on it. Only anonymous classes that an alias points at _would_ issue
                        // a visibility error here (as they're not visible within any scope), but we want to hoist them
                        // into the containing scope anyway, so we want to skip the visibility checks.
                        var oldTrack = context.tracker.trackSymbol;
                        context.tracker.trackSymbol = ts.noop;
                        if (isExportAssignment) {
                            results.push(ts.createExportAssignment(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, isExportEquals, symbolToExpression(target, context, 67108863 /* All */)));
                        }
                        else {
                            if (first_1 === expr) {
                                // serialize as `export {target as name}`
                                serializeExportSpecifier(name, ts.idText(first_1));
                            }
                            else if (ts.isClassExpression(expr)) {
                                serializeExportSpecifier(name, getInternalSymbolName(target, ts.symbolName(target)));
                            }
                            else {
                                // serialize as `import _Ref = t.arg.et; export { _Ref as name }`
                                var varName = getUnusedName(name, symbol);
                                addResult(ts.createImportEqualsDeclaration(
                                /*decorators*/ undefined, 
                                /*modifiers*/ undefined, ts.createIdentifier(varName), symbolToName(target, context, 67108863 /* All */, /*expectsIdentifier*/ false)), 0 /* None */);
                                serializeExportSpecifier(name, varName);
                            }
                        }
                        context.tracker.trackSymbol = oldTrack;
                    }
                    else {
                        // serialize as an anonymous property declaration
                        var varName = getUnusedName(name, symbol);
                        // We have to use `getWidenedType` here since the object within a json file is unwidened within the file
                        // (Unwidened types can only exist in expression contexts and should never be serialized)
                        var typeToSerialize = getWidenedType(getTypeOfSymbol(getMergedSymbol(symbol)));
                        if (isTypeRepresentableAsFunctionNamespaceMerge(typeToSerialize, symbol)) {
                            // If there are no index signatures and `typeToSerialize` is an object type, emit as a namespace instead of a const
                            serializeAsFunctionNamespaceMerge(typeToSerialize, symbol, varName, isExportAssignment ? 0 /* None */ : 1 /* Export */);
                        }
                        else {
                            var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([
                                ts.createVariableDeclaration(varName, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
                            ], 2 /* Const */));
                            addResult(statement, name === varName ? 1 /* Export */ : 0 /* None */);
                        }
                        if (isExportAssignment) {
                            results.push(ts.createExportAssignment(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, isExportEquals, ts.createIdentifier(varName)));
                        }
                        else if (name !== varName) {
                            serializeExportSpecifier(name, varName);
                        }
                    }
                }
                function isTypeRepresentableAsFunctionNamespaceMerge(typeToSerialize, hostSymbol) {
                    // Only object types which are not constructable, or indexable, whose members all come from the
                    // context source file, and whose property names are all valid identifiers and not late-bound, _and_
                    // whose input is not type annotated (if the input symbol has an annotation we can reuse, we should prefer it)
                    var ctxSrc = ts.getSourceFileOfNode(context.enclosingDeclaration);
                    return ts.getObjectFlags(typeToSerialize) & (16 /* Anonymous */ | 32 /* Mapped */) &&
                        !getIndexInfoOfType(typeToSerialize, 0 /* String */) &&
                        !getIndexInfoOfType(typeToSerialize, 1 /* Number */) &&
                        !!(ts.length(getPropertiesOfType(typeToSerialize)) || ts.length(getSignaturesOfType(typeToSerialize, 0 /* Call */))) &&
                        !ts.length(getSignaturesOfType(typeToSerialize, 1 /* Construct */)) && // TODO: could probably serialize as function + ns + class, now that that's OK
                        !getDeclarationWithTypeAnnotation(hostSymbol, enclosingDeclaration) &&
                        !(typeToSerialize.symbol && ts.some(typeToSerialize.symbol.declarations, function (d) { return ts.getSourceFileOfNode(d) !== ctxSrc; })) &&
                        !ts.some(getPropertiesOfType(typeToSerialize), function (p) { return isLateBoundName(p.escapedName); }) &&
                        !ts.some(getPropertiesOfType(typeToSerialize), function (p) { return ts.some(p.declarations, function (d) { return ts.getSourceFileOfNode(d) !== ctxSrc; }); }) &&
                        ts.every(getPropertiesOfType(typeToSerialize), function (p) { return ts.isIdentifierText(ts.symbolName(p), languageVersion) && !ts.isStringAKeyword(ts.symbolName(p)); });
                }
                function makeSerializePropertySymbol(createProperty, methodKind, useAccessors) {
                    return function serializePropertySymbol(p, isStatic, baseType) {
                        var modifierFlags = ts.getDeclarationModifierFlagsFromSymbol(p);
                        var isPrivate = !!(modifierFlags & 8 /* Private */);
                        if (isStatic && (p.flags & (788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */))) {
                            // Only value-only-meaning symbols can be correctly encoded as class statics, type/namespace/alias meaning symbols
                            // need to be merged namespace members
                            return [];
                        }
                        if (p.flags & 4194304 /* Prototype */ ||
                            (baseType && getPropertyOfType(baseType, p.escapedName)
                                && isReadonlySymbol(getPropertyOfType(baseType, p.escapedName)) === isReadonlySymbol(p)
                                && (p.flags & 16777216 /* Optional */) === (getPropertyOfType(baseType, p.escapedName).flags & 16777216 /* Optional */)
                                && isTypeIdenticalTo(getTypeOfSymbol(p), getTypeOfPropertyOfType(baseType, p.escapedName)))) {
                            return [];
                        }
                        var flag = (modifierFlags & ~256 /* Async */) | (isStatic ? 32 /* Static */ : 0);
                        var name = getPropertyNameNodeForSymbol(p, context);
                        var firstPropertyLikeDecl = ts.find(p.declarations, ts.or(ts.isPropertyDeclaration, ts.isAccessor, ts.isVariableDeclaration, ts.isPropertySignature, ts.isBinaryExpression, ts.isPropertyAccessExpression));
                        if (p.flags & 98304 /* Accessor */ && useAccessors) {
                            var result = [];
                            if (p.flags & 65536 /* SetAccessor */) {
                                result.push(ts.setTextRange(ts.createSetAccessor(
                                /*decorators*/ undefined, ts.createModifiersFromModifierFlags(flag), name, [ts.createParameter(
                                    /*decorators*/ undefined, 
                                    /*modifiers*/ undefined, 
                                    /*dotDotDotToken*/ undefined, "arg", 
                                    /*questionToken*/ undefined, isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled))], 
                                /*body*/ undefined), ts.find(p.declarations, ts.isSetAccessor) || firstPropertyLikeDecl));
                            }
                            if (p.flags & 32768 /* GetAccessor */) {
                                var isPrivate_1 = modifierFlags & 8 /* Private */;
                                result.push(ts.setTextRange(ts.createGetAccessor(
                                /*decorators*/ undefined, ts.createModifiersFromModifierFlags(flag), name, [], isPrivate_1 ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), 
                                /*body*/ undefined), ts.find(p.declarations, ts.isGetAccessor) || firstPropertyLikeDecl));
                            }
                            return result;
                        }
                        // This is an else/if as accessors and properties can't merge in TS, but might in JS
                        // If this happens, we assume the accessor takes priority, as it imposes more constraints
                        else if (p.flags & (4 /* Property */ | 3 /* Variable */)) {
                            return ts.setTextRange(createProperty(
                            /*decorators*/ undefined, ts.createModifiersFromModifierFlags((isReadonlySymbol(p) ? 64 /* Readonly */ : 0) | flag), name, p.flags & 16777216 /* Optional */ ? ts.createToken(57 /* QuestionToken */) : undefined, isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), 
                            // TODO: https://github.com/microsoft/TypeScript/pull/32372#discussion_r328386357
                            // interface members can't have initializers, however class members _can_
                            /*initializer*/ undefined), ts.find(p.declarations, ts.or(ts.isPropertyDeclaration, ts.isVariableDeclaration)) || firstPropertyLikeDecl);
                        }
                        if (p.flags & (8192 /* Method */ | 16 /* Function */)) {
                            var type = getTypeOfSymbol(p);
                            var signatures = getSignaturesOfType(type, 0 /* Call */);
                            if (flag & 8 /* Private */) {
                                return ts.setTextRange(createProperty(
                                /*decorators*/ undefined, ts.createModifiersFromModifierFlags((isReadonlySymbol(p) ? 64 /* Readonly */ : 0) | flag), name, p.flags & 16777216 /* Optional */ ? ts.createToken(57 /* QuestionToken */) : undefined, 
                                /*type*/ undefined, 
                                /*initializer*/ undefined), ts.find(p.declarations, ts.isFunctionLikeDeclaration) || signatures[0] && signatures[0].declaration || p.declarations[0]);
                            }
                            var results_1 = [];
                            for (var _i = 0, signatures_3 = signatures; _i < signatures_3.length; _i++) {
                                var sig = signatures_3[_i];
                                // Each overload becomes a separate method declaration, in order
                                var decl = signatureToSignatureDeclarationHelper(sig, methodKind, context);
                                decl.name = name; // TODO: Clone
                                if (flag) {
                                    decl.modifiers = ts.createNodeArray(ts.createModifiersFromModifierFlags(flag));
                                }
                                if (p.flags & 16777216 /* Optional */) {
                                    decl.questionToken = ts.createToken(57 /* QuestionToken */);
                                }
                                results_1.push(ts.setTextRange(decl, sig.declaration));
                            }
                            return results_1;
                        }
                        // The `Constructor`'s symbol isn't in the class's properties lists, obviously, since it's a signature on the static
                        return ts.Debug.fail("Unhandled class member kind! " + (p.__debugFlags || p.flags));
                    };
                }
                function serializePropertySymbolForInterface(p, baseType) {
                    return serializePropertySymbolForInterfaceWorker(p, /*isStatic*/ false, baseType);
                }
                function serializeSignatures(kind, input, baseType, outputKind) {
                    var signatures = getSignaturesOfType(input, kind);
                    if (kind === 1 /* Construct */) {
                        if (!baseType && ts.every(signatures, function (s) { return ts.length(s.parameters) === 0; })) {
                            return []; // No base type, every constructor is empty - elide the extraneous `constructor()`
                        }
                        if (baseType) {
                            // If there is a base type, if every signature in the class is identical to a signature in the baseType, elide all the declarations
                            var baseSigs = getSignaturesOfType(baseType, 1 /* Construct */);
                            if (!ts.length(baseSigs) && ts.every(signatures, function (s) { return ts.length(s.parameters) === 0; })) {
                                return []; // Base had no explicit signatures, if all our signatures are also implicit, return an empty list
                            }
                            if (baseSigs.length === signatures.length) {
                                var failed = false;
                                for (var i = 0; i < baseSigs.length; i++) {
                                    if (!compareSignaturesIdentical(signatures[i], baseSigs[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
                                        failed = true;
                                        break;
                                    }
                                }
                                if (!failed) {
                                    return []; // Every signature was identical - elide constructor list as it is inherited
                                }
                            }
                        }
                        var privateProtected = 0;
                        for (var _i = 0, signatures_4 = signatures; _i < signatures_4.length; _i++) {
                            var s = signatures_4[_i];
                            if (s.declaration) {
                                privateProtected |= ts.getSelectedModifierFlags(s.declaration, 8 /* Private */ | 16 /* Protected */);
                            }
                        }
                        if (privateProtected) {
                            return [ts.setTextRange(ts.createConstructor(
                                /*decorators*/ undefined, ts.createModifiersFromModifierFlags(privateProtected), 
                                /*parameters*/ [], 
                                /*body*/ undefined), signatures[0].declaration)];
                        }
                    }
                    var results = [];
                    for (var _a = 0, signatures_5 = signatures; _a < signatures_5.length; _a++) {
                        var sig = signatures_5[_a];
                        // Each overload becomes a separate constructor declaration, in order
                        var decl = signatureToSignatureDeclarationHelper(sig, outputKind, context);
                        results.push(ts.setTextRange(decl, sig.declaration));
                    }
                    return results;
                }
                function serializeIndexSignatures(input, baseType) {
                    var results = [];
                    for (var _i = 0, _a = [0 /* String */, 1 /* Number */]; _i < _a.length; _i++) {
                        var type = _a[_i];
                        var info = getIndexInfoOfType(input, type);
                        if (info) {
                            if (baseType) {
                                var baseInfo = getIndexInfoOfType(baseType, type);
                                if (baseInfo) {
                                    if (isTypeIdenticalTo(info.type, baseInfo.type)) {
                                        continue; // elide identical index signatures
                                    }
                                }
                            }
                            results.push(indexInfoToIndexSignatureDeclarationHelper(info, type, context));
                        }
                    }
                    return results;
                }
                function serializeBaseType(t, staticType, rootName) {
                    var ref = trySerializeAsTypeReference(t);
                    if (ref) {
                        return ref;
                    }
                    var tempName = getUnusedName(rootName + "_base");
                    var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(tempName, typeToTypeNodeHelper(staticType, context))
                    ], 2 /* Const */));
                    addResult(statement, 0 /* None */);
                    return ts.createExpressionWithTypeArguments(/*typeArgs*/ undefined, ts.createIdentifier(tempName));
                }
                function trySerializeAsTypeReference(t) {
                    var typeArgs;
                    var reference;
                    // We don't use `isValueSymbolAccessible` below. since that considers alternative containers (like modules)
                    // which we can't write out in a syntactically valid way as an expression
                    if (t.target && getAccessibleSymbolChain(t.target.symbol, enclosingDeclaration, 111551 /* Value */, /*useOnlyExternalAliasing*/ false)) {
                        typeArgs = ts.map(getTypeArguments(t), function (t) { return typeToTypeNodeHelper(t, context); });
                        reference = symbolToExpression(t.target.symbol, context, 788968 /* Type */);
                    }
                    else if (t.symbol && getAccessibleSymbolChain(t.symbol, enclosingDeclaration, 111551 /* Value */, /*useOnlyExternalAliasing*/ false)) {
                        reference = symbolToExpression(t.symbol, context, 788968 /* Type */);
                    }
                    if (reference) {
                        return ts.createExpressionWithTypeArguments(typeArgs, reference);
                    }
                }
                function getUnusedName(input, symbol) {
                    if (symbol) {
                        if (context.remappedSymbolNames.has("" + getSymbolId(symbol))) {
                            return context.remappedSymbolNames.get("" + getSymbolId(symbol));
                        }
                    }
                    if (symbol) {
                        input = getNameCandidateWorker(symbol, input);
                    }
                    var i = 0;
                    var original = input;
                    while (context.usedSymbolNames.has(input)) {
                        i++;
                        input = original + "_" + i;
                    }
                    context.usedSymbolNames.set(input, true);
                    if (symbol) {
                        context.remappedSymbolNames.set("" + getSymbolId(symbol), input);
                    }
                    return input;
                }
                function getNameCandidateWorker(symbol, localName) {
                    if (localName === "default" /* Default */ || localName === "__class" /* Class */ || localName === "__function" /* Function */) {
                        var flags = context.flags;
                        context.flags |= 16777216 /* InInitialEntityName */;
                        var nameCandidate = getNameOfSymbolAsWritten(symbol, context);
                        context.flags = flags;
                        localName = nameCandidate.length > 0 && ts.isSingleOrDoubleQuote(nameCandidate.charCodeAt(0)) ? ts.stripQuotes(nameCandidate) : nameCandidate;
                    }
                    if (localName === "default" /* Default */) {
                        localName = "_default";
                    }
                    else if (localName === "export=" /* ExportEquals */) {
                        localName = "_exports";
                    }
                    localName = ts.isIdentifierText(localName, languageVersion) && !ts.isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-zA-Z0-9]/g, "_");
                    return localName;
                }
                function getInternalSymbolName(symbol, localName) {
                    if (context.remappedSymbolNames.has("" + getSymbolId(symbol))) {
                        return context.remappedSymbolNames.get("" + getSymbolId(symbol));
                    }
                    localName = getNameCandidateWorker(symbol, localName);
                    // The result of this is going to be used as the symbol's name - lock it in, so `getUnusedName` will also pick it up
                    context.remappedSymbolNames.set("" + getSymbolId(symbol), localName);
                    return localName;
                }
            }
        }
        function typePredicateToString(typePredicate, enclosingDeclaration, flags, writer) {
            if (flags === void 0) { flags = 16384 /* UseAliasDefinedOutsideCurrentScope */; }
            return writer ? typePredicateToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(typePredicateToStringWorker);
            function typePredicateToStringWorker(writer) {
                var predicate = ts.createTypePredicateNodeWithModifier(typePredicate.kind === 2 /* AssertsThis */ || typePredicate.kind === 3 /* AssertsIdentifier */ ? ts.createToken(124 /* AssertsKeyword */) : undefined, typePredicate.kind === 1 /* Identifier */ || typePredicate.kind === 3 /* AssertsIdentifier */ ? ts.createIdentifier(typePredicate.parameterName) : ts.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | 512 /* WriteTypeParametersInQualifiedName */) // TODO: GH#18217
                );
                var printer = ts.createPrinter({ removeComments: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, predicate, /*sourceFile*/ sourceFile, writer);
                return writer;
            }
        }
        function formatUnionTypes(types) {
            var result = [];
            var flags = 0;
            for (var i = 0; i < types.length; i++) {
                var t = types[i];
                flags |= t.flags;
                if (!(t.flags & 98304 /* Nullable */)) {
                    if (t.flags & (512 /* BooleanLiteral */ | 1024 /* EnumLiteral */)) {
                        var baseType = t.flags & 512 /* BooleanLiteral */ ? booleanType : getBaseTypeOfEnumLiteralType(t);
                        if (baseType.flags & 1048576 /* Union */) {
                            var count = baseType.types.length;
                            if (i + count <= types.length && getRegularTypeOfLiteralType(types[i + count - 1]) === getRegularTypeOfLiteralType(baseType.types[count - 1])) {
                                result.push(baseType);
                                i += count - 1;
                                continue;
                            }
                        }
                    }
                    result.push(t);
                }
            }
            if (flags & 65536 /* Null */)
                result.push(nullType);
            if (flags & 32768 /* Undefined */)
                result.push(undefinedType);
            return result || types;
        }
        function visibilityToString(flags) {
            if (flags === 8 /* Private */) {
                return "private";
            }
            if (flags === 16 /* Protected */) {
                return "protected";
            }
            return "public";
        }
        function getTypeAliasForTypeLiteral(type) {
            if (type.symbol && type.symbol.flags & 2048 /* TypeLiteral */) {
                var node = ts.findAncestor(type.symbol.declarations[0].parent, function (n) { return n.kind !== 182 /* ParenthesizedType */; });
                if (node.kind === 247 /* TypeAliasDeclaration */) {
                    return getSymbolOfNode(node);
                }
            }
            return undefined;
        }
        function isTopLevelInExternalModuleAugmentation(node) {
            return node && node.parent &&
                node.parent.kind === 250 /* ModuleBlock */ &&
                ts.isExternalModuleAugmentation(node.parent.parent);
        }
        function isDefaultBindingContext(location) {
            return location.kind === 290 /* SourceFile */ || ts.isAmbientModule(location);
        }
        function getNameOfSymbolFromNameType(symbol, context) {
            var nameType = getSymbolLinks(symbol).nameType;
            if (nameType) {
                if (nameType.flags & 384 /* StringOrNumberLiteral */) {
                    var name = "" + nameType.value;
                    if (!ts.isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) {
                        return "\"" + ts.escapeString(name, 34 /* doubleQuote */) + "\"";
                    }
                    if (isNumericLiteralName(name) && ts.startsWith(name, "-")) {
                        return "[" + name + "]";
                    }
                    return name;
                }
                if (nameType.flags & 8192 /* UniqueESSymbol */) {
                    return "[" + getNameOfSymbolAsWritten(nameType.symbol, context) + "]";
                }
            }
        }
        /**
         * Gets a human-readable name for a symbol.
         * Should *not* be used for the right-hand side of a `.` -- use `symbolName(symbol)` for that instead.
         *
         * Unlike `symbolName(symbol)`, this will include quotes if the name is from a string literal.
         * It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`.
         */
        function getNameOfSymbolAsWritten(symbol, context) {
            if (context && symbol.escapedName === "default" /* Default */ && !(context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */) &&
                // If it's not the first part of an entity name, it must print as `default`
                (!(context.flags & 16777216 /* InInitialEntityName */) ||
                    // if the symbol is synthesized, it will only be referenced externally it must print as `default`
                    !symbol.declarations ||
                    // if not in the same binding context (source file, module declaration), it must print as `default`
                    (context.enclosingDeclaration && ts.findAncestor(symbol.declarations[0], isDefaultBindingContext) !== ts.findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) {
                return "default";
            }
            if (symbol.declarations && symbol.declarations.length) {
                var declaration = ts.firstDefined(symbol.declarations, function (d) { return ts.getNameOfDeclaration(d) ? d : undefined; }); // Try using a declaration with a name, first
                var name_2 = declaration && ts.getNameOfDeclaration(declaration);
                if (declaration && name_2) {
                    if (ts.isCallExpression(declaration) && ts.isBindableObjectDefinePropertyCall(declaration)) {
                        return ts.symbolName(symbol);
                    }
                    if (ts.isComputedPropertyName(name_2) && !(ts.getCheckFlags(symbol) & 4096 /* Late */)) {
                        var nameType = getSymbolLinks(symbol).nameType;
                        if (nameType && nameType.flags & 384 /* StringOrNumberLiteral */) {
                            // Computed property name isn't late bound, but has a well-known name type - use name type to generate a symbol name
                            var result = getNameOfSymbolFromNameType(symbol, context);
                            if (result !== undefined) {
                                return result;
                            }
                        }
                    }
                    return ts.declarationNameToString(name_2);
                }
                if (!declaration) {
                    declaration = symbol.declarations[0]; // Declaration may be nameless, but we'll try anyway
                }
                if (declaration.parent && declaration.parent.kind === 242 /* VariableDeclaration */) {
                    return ts.declarationNameToString(declaration.parent.name);
                }
                switch (declaration.kind) {
                    case 214 /* ClassExpression */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                        if (context && !context.encounteredError && !(context.flags & 131072 /* AllowAnonymousIdentifier */)) {
                            context.encounteredError = true;
                        }
                        return declaration.kind === 214 /* ClassExpression */ ? "(Anonymous class)" : "(Anonymous function)";
                }
            }
            var name = getNameOfSymbolFromNameType(symbol, context);
            return name !== undefined ? name : ts.symbolName(symbol);
        }
        function isDeclarationVisible(node) {
            if (node) {
                var links = getNodeLinks(node);
                if (links.isVisible === undefined) {
                    links.isVisible = !!determineIfDeclarationIsVisible();
                }
                return links.isVisible;
            }
            return false;
            function determineIfDeclarationIsVisible() {
                switch (node.kind) {
                    case 315 /* JSDocCallbackTag */:
                    case 322 /* JSDocTypedefTag */:
                    case 316 /* JSDocEnumTag */:
                        // Top-level jsdoc type aliases are considered exported
                        // First parent is comment node, second is hosting declaration or token; we only care about those tokens or declarations whose parent is a source file
                        return !!(node.parent && node.parent.parent && node.parent.parent.parent && ts.isSourceFile(node.parent.parent.parent));
                    case 191 /* BindingElement */:
                        return isDeclarationVisible(node.parent.parent);
                    case 242 /* VariableDeclaration */:
                        if (ts.isBindingPattern(node.name) &&
                            !node.name.elements.length) {
                            // If the binding pattern is empty, this variable declaration is not visible
                            return false;
                        }
                    // falls through
                    case 249 /* ModuleDeclaration */:
                    case 245 /* ClassDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                    case 244 /* FunctionDeclaration */:
                    case 248 /* EnumDeclaration */:
                    case 253 /* ImportEqualsDeclaration */:
                        // external module augmentation is always visible
                        if (ts.isExternalModuleAugmentation(node)) {
                            return true;
                        }
                        var parent = getDeclarationContainer(node);
                        // If the node is not exported or it is not ambient module element (except import declaration)
                        if (!(ts.getCombinedModifierFlags(node) & 1 /* Export */) &&
                            !(node.kind !== 253 /* ImportEqualsDeclaration */ && parent.kind !== 290 /* SourceFile */ && parent.flags & 8388608 /* Ambient */)) {
                            return isGlobalSourceFile(parent);
                        }
                        // Exported members/ambient module elements (exception import declaration) are visible if parent is visible
                        return isDeclarationVisible(parent);
                    case 159 /* PropertyDeclaration */:
                    case 158 /* PropertySignature */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 161 /* MethodDeclaration */:
                    case 160 /* MethodSignature */:
                        if (ts.hasModifier(node, 8 /* Private */ | 16 /* Protected */)) {
                            // Private/protected properties/methods are not visible
                            return false;
                        }
                    // Public properties/methods are visible if its parents are visible, so:
                    // falls through
                    case 162 /* Constructor */:
                    case 166 /* ConstructSignature */:
                    case 165 /* CallSignature */:
                    case 167 /* IndexSignature */:
                    case 156 /* Parameter */:
                    case 250 /* ModuleBlock */:
                    case 170 /* FunctionType */:
                    case 171 /* ConstructorType */:
                    case 173 /* TypeLiteral */:
                    case 169 /* TypeReference */:
                    case 174 /* ArrayType */:
                    case 175 /* TupleType */:
                    case 178 /* UnionType */:
                    case 179 /* IntersectionType */:
                    case 182 /* ParenthesizedType */:
                        return isDeclarationVisible(node.parent);
                    // Default binding, import specifier and namespace import is visible
                    // only on demand so by default it is not visible
                    case 255 /* ImportClause */:
                    case 256 /* NamespaceImport */:
                    case 258 /* ImportSpecifier */:
                        return false;
                    // Type parameters are always visible
                    case 155 /* TypeParameter */:
                    // Source file and namespace export are always visible
                    // falls through
                    case 290 /* SourceFile */:
                    case 252 /* NamespaceExportDeclaration */:
                        return true;
                    // Export assignments do not create name bindings outside the module
                    case 259 /* ExportAssignment */:
                        return false;
                    default:
                        return false;
                }
            }
        }
        function collectLinkedAliases(node, setVisibility) {
            var exportSymbol;
            if (node.parent && node.parent.kind === 259 /* ExportAssignment */) {
                exportSymbol = resolveName(node, node.escapedText, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, /*nameNotFoundMessage*/ undefined, node, /*isUse*/ false);
            }
            else if (node.parent.kind === 263 /* ExportSpecifier */) {
                exportSymbol = getTargetOfExportSpecifier(node.parent, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
            }
            var result;
            var visited;
            if (exportSymbol) {
                visited = ts.createMap();
                visited.set("" + getSymbolId(exportSymbol), true);
                buildVisibleNodeList(exportSymbol.declarations);
            }
            return result;
            function buildVisibleNodeList(declarations) {
                ts.forEach(declarations, function (declaration) {
                    var resultNode = getAnyImportSyntax(declaration) || declaration;
                    if (setVisibility) {
                        getNodeLinks(declaration).isVisible = true;
                    }
                    else {
                        result = result || [];
                        ts.pushIfUnique(result, resultNode);
                    }
                    if (ts.isInternalModuleImportEqualsDeclaration(declaration)) {
                        // Add the referenced top container visible
                        var internalModuleReference = declaration.moduleReference;
                        var firstIdentifier = ts.getFirstIdentifier(internalModuleReference);
                        var importSymbol = resolveName(declaration, firstIdentifier.escapedText, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, undefined, undefined, /*isUse*/ false);
                        var id = importSymbol && "" + getSymbolId(importSymbol);
                        if (importSymbol && !visited.has(id)) {
                            visited.set(id, true);
                            buildVisibleNodeList(importSymbol.declarations);
                        }
                    }
                });
            }
        }
        /**
         * Push an entry on the type resolution stack. If an entry with the given target and the given property name
         * is already on the stack, and no entries in between already have a type, then a circularity has occurred.
         * In this case, the result values of the existing entry and all entries pushed after it are changed to false,
         * and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
         * In order to see if the same query has already been done before, the target object and the propertyName both
         * must match the one passed in.
         *
         * @param target The symbol, type, or signature whose type is being queried
         * @param propertyName The property name that should be used to query the target for its type
         */
        function pushTypeResolution(target, propertyName) {
            var resolutionCycleStartIndex = findResolutionCycleStartIndex(target, propertyName);
            if (resolutionCycleStartIndex >= 0) {
                // A cycle was found
                var length_3 = resolutionTargets.length;
                for (var i = resolutionCycleStartIndex; i < length_3; i++) {
                    resolutionResults[i] = false;
                }
                return false;
            }
            resolutionTargets.push(target);
            resolutionResults.push(/*items*/ true);
            resolutionPropertyNames.push(propertyName);
            return true;
        }
        function findResolutionCycleStartIndex(target, propertyName) {
            for (var i = resolutionTargets.length - 1; i >= 0; i--) {
                if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) {
                    return -1;
                }
                if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) {
                    return i;
                }
            }
            return -1;
        }
        function hasType(target, propertyName) {
            switch (propertyName) {
                case 0 /* Type */:
                    return !!getSymbolLinks(target).type;
                case 5 /* EnumTagType */:
                    return !!(getNodeLinks(target).resolvedEnumType);
                case 2 /* DeclaredType */:
                    return !!getSymbolLinks(target).declaredType;
                case 1 /* ResolvedBaseConstructorType */:
                    return !!target.resolvedBaseConstructorType;
                case 3 /* ResolvedReturnType */:
                    return !!target.resolvedReturnType;
                case 4 /* ImmediateBaseConstraint */:
                    return !!target.immediateBaseConstraint;
                case 6 /* ResolvedTypeArguments */:
                    return !!target.resolvedTypeArguments;
            }
            return ts.Debug.assertNever(propertyName);
        }
        /**
         * Pop an entry from the type resolution stack and return its associated result value. The result value will
         * be true if no circularities were detected, or false if a circularity was found.
         */
        function popTypeResolution() {
            resolutionTargets.pop();
            resolutionPropertyNames.pop();
            return resolutionResults.pop();
        }
        function getDeclarationContainer(node) {
            return ts.findAncestor(ts.getRootDeclaration(node), function (node) {
                switch (node.kind) {
                    case 242 /* VariableDeclaration */:
                    case 243 /* VariableDeclarationList */:
                    case 258 /* ImportSpecifier */:
                    case 257 /* NamedImports */:
                    case 256 /* NamespaceImport */:
                    case 255 /* ImportClause */:
                        return false;
                    default:
                        return true;
                }
            }).parent;
        }
        function getTypeOfPrototypeProperty(prototype) {
            // TypeScript 1.0 spec (April 2014): 8.4
            // Every class automatically contains a static property member named 'prototype',
            // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter.
            // It is an error to explicitly declare a static property member with the name 'prototype'.
            var classType = getDeclaredTypeOfSymbol(getParentOfSymbol(prototype));
            return classType.typeParameters ? createTypeReference(classType, ts.map(classType.typeParameters, function (_) { return anyType; })) : classType;
        }
        // Return the type of the given property in the given type, or undefined if no such property exists
        function getTypeOfPropertyOfType(type, name) {
            var prop = getPropertyOfType(type, name);
            return prop ? getTypeOfSymbol(prop) : undefined;
        }
        function getTypeOfPropertyOrIndexSignature(type, name) {
            return getTypeOfPropertyOfType(type, name) || isNumericLiteralName(name) && getIndexTypeOfType(type, 1 /* Number */) || getIndexTypeOfType(type, 0 /* String */) || unknownType;
        }
        function isTypeAny(type) {
            return type && (type.flags & 1 /* Any */) !== 0;
        }
        // Return the type of a binding element parent. We check SymbolLinks first to see if a type has been
        // assigned by contextual typing.
        function getTypeForBindingElementParent(node) {
            var symbol = getSymbolOfNode(node);
            return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false);
        }
        function getRestType(source, properties, symbol) {
            source = filterType(source, function (t) { return !(t.flags & 98304 /* Nullable */); });
            if (source.flags & 131072 /* Never */) {
                return emptyObjectType;
            }
            if (source.flags & 1048576 /* Union */) {
                return mapType(source, function (t) { return getRestType(t, properties, symbol); });
            }
            var omitKeyType = getUnionType(ts.map(properties, getLiteralTypeFromPropertyName));
            if (isGenericObjectType(source) || isGenericIndexType(omitKeyType)) {
                if (omitKeyType.flags & 131072 /* Never */) {
                    return source;
                }
                var omitTypeAlias = getGlobalOmitSymbol();
                if (!omitTypeAlias) {
                    return errorType;
                }
                return getTypeAliasInstantiation(omitTypeAlias, [source, omitKeyType]);
            }
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                var prop = _a[_i];
                if (!isTypeAssignableTo(getLiteralTypeFromProperty(prop, 8576 /* StringOrNumberLiteralOrUnique */), omitKeyType)
                    && !(ts.getDeclarationModifierFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */))
                    && isSpreadableProperty(prop)) {
                    members.set(prop.escapedName, getSpreadSymbol(prop, /*readonly*/ false));
                }
            }
            var stringIndexInfo = getIndexInfoOfType(source, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(source, 1 /* Number */);
            var result = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
            result.objectFlags |= 131072 /* ObjectRestType */;
            return result;
        }
        // Determine the control flow type associated with a destructuring declaration or assignment. The following
        // forms of destructuring are possible:
        //   let { x } = obj;  // BindingElement
        //   let [ x ] = obj;  // BindingElement
        //   { x } = obj;      // ShorthandPropertyAssignment
        //   { x: v } = obj;   // PropertyAssignment
        //   [ x ] = obj;      // Expression
        // We construct a synthetic element access expression corresponding to 'obj.x' such that the control
        // flow analyzer doesn't have to handle all the different syntactic forms.
        function getFlowTypeOfDestructuring(node, declaredType) {
            var reference = getSyntheticElementAccess(node);
            return reference ? getFlowTypeOfReference(reference, declaredType) : declaredType;
        }
        function getSyntheticElementAccess(node) {
            var parentAccess = getParentElementAccess(node);
            if (parentAccess && parentAccess.flowNode) {
                var propName = getDestructuringPropertyName(node);
                if (propName) {
                    var result = ts.createNode(195 /* ElementAccessExpression */, node.pos, node.end);
                    result.parent = node;
                    result.expression = parentAccess;
                    var literal = ts.createNode(10 /* StringLiteral */, node.pos, node.end);
                    literal.parent = result;
                    literal.text = propName;
                    result.argumentExpression = literal;
                    result.flowNode = parentAccess.flowNode;
                    return result;
                }
            }
        }
        function getParentElementAccess(node) {
            var ancestor = node.parent.parent;
            switch (ancestor.kind) {
                case 191 /* BindingElement */:
                case 281 /* PropertyAssignment */:
                    return getSyntheticElementAccess(ancestor);
                case 192 /* ArrayLiteralExpression */:
                    return getSyntheticElementAccess(node.parent);
                case 242 /* VariableDeclaration */:
                    return ancestor.initializer;
                case 209 /* BinaryExpression */:
                    return ancestor.right;
            }
        }
        function getDestructuringPropertyName(node) {
            var parent = node.parent;
            if (node.kind === 191 /* BindingElement */ && parent.kind === 189 /* ObjectBindingPattern */) {
                return getLiteralPropertyNameText(node.propertyName || node.name);
            }
            if (node.kind === 281 /* PropertyAssignment */ || node.kind === 282 /* ShorthandPropertyAssignment */) {
                return getLiteralPropertyNameText(node.name);
            }
            return "" + parent.elements.indexOf(node);
        }
        function getLiteralPropertyNameText(name) {
            var type = getLiteralTypeFromPropertyName(name);
            return type.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */) ? "" + type.value : undefined;
        }
        /** Return the inferred type for a binding element */
        function getTypeForBindingElement(declaration) {
            var pattern = declaration.parent;
            var parentType = getTypeForBindingElementParent(pattern.parent);
            // If no type or an any type was inferred for parent, infer that for the binding element
            if (!parentType || isTypeAny(parentType)) {
                return parentType;
            }
            // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
            if (strictNullChecks && declaration.flags & 8388608 /* Ambient */ && ts.isParameterDeclaration(declaration)) {
                parentType = getNonNullableType(parentType);
            }
            // Filter `undefined` from the type we check against if the parent has an initializer and that initializer is not possibly `undefined`
            else if (strictNullChecks && pattern.parent.initializer && !(getTypeFacts(getTypeOfInitializer(pattern.parent.initializer)) & 65536 /* EQUndefined */)) {
                parentType = getTypeWithFacts(parentType, 524288 /* NEUndefined */);
            }
            var type;
            if (pattern.kind === 189 /* ObjectBindingPattern */) {
                if (declaration.dotDotDotToken) {
                    parentType = getReducedType(parentType);
                    if (parentType.flags & 2 /* Unknown */ || !isValidSpreadType(parentType)) {
                        error(declaration, ts.Diagnostics.Rest_types_may_only_be_created_from_object_types);
                        return errorType;
                    }
                    var literalMembers = [];
                    for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                        var element = _a[_i];
                        if (!element.dotDotDotToken) {
                            literalMembers.push(element.propertyName || element.name);
                        }
                    }
                    type = getRestType(parentType, literalMembers, declaration.symbol);
                }
                else {
                    // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
                    var name = declaration.propertyName || declaration.name;
                    var indexType = getLiteralTypeFromPropertyName(name);
                    var declaredType = getConstraintForLocation(getIndexedAccessType(parentType, indexType, name), declaration.name);
                    type = getFlowTypeOfDestructuring(declaration, declaredType);
                }
            }
            else {
                // This elementType will be used if the specific property corresponding to this index is not
                // present (aka the tuple element property). This call also checks that the parentType is in
                // fact an iterable or array (depending on target language).
                var elementType = checkIteratedTypeOrElementType(65 /* Destructuring */, parentType, undefinedType, pattern);
                var index_1 = pattern.elements.indexOf(declaration);
                if (declaration.dotDotDotToken) {
                    // If the parent is a tuple type, the rest element has a tuple type of the
                    // remaining tuple element types. Otherwise, the rest element has an array type with same
                    // element type as the parent type.
                    type = everyType(parentType, isTupleType) ?
                        mapType(parentType, function (t) { return sliceTupleType(t, index_1); }) :
                        createArrayType(elementType);
                }
                else if (isArrayLikeType(parentType)) {
                    var indexType = getLiteralType(index_1);
                    var accessFlags = hasDefaultValue(declaration) ? 8 /* NoTupleBoundsCheck */ : 0;
                    var declaredType = getConstraintForLocation(getIndexedAccessTypeOrUndefined(parentType, indexType, declaration.name, accessFlags) || errorType, declaration.name);
                    type = getFlowTypeOfDestructuring(declaration, declaredType);
                }
                else {
                    type = elementType;
                }
            }
            if (!declaration.initializer) {
                return type;
            }
            if (ts.getEffectiveTypeAnnotationNode(ts.walkUpBindingElementsAndPatterns(declaration))) {
                // In strict null checking mode, if a default value of a non-undefined type is specified, remove
                // undefined from the final type.
                return strictNullChecks && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & 32768 /* Undefined */) ?
                    getTypeWithFacts(type, 524288 /* NEUndefined */) :
                    type;
            }
            return widenTypeInferredFromInitializer(declaration, getUnionType([getTypeWithFacts(type, 524288 /* NEUndefined */), checkDeclarationInitializer(declaration)], 2 /* Subtype */));
        }
        function getTypeForDeclarationFromJSDocComment(declaration) {
            var jsdocType = ts.getJSDocType(declaration);
            if (jsdocType) {
                return getTypeFromTypeNode(jsdocType);
            }
            return undefined;
        }
        function isNullOrUndefined(node) {
            var expr = ts.skipParentheses(node);
            return expr.kind === 100 /* NullKeyword */ || expr.kind === 75 /* Identifier */ && getResolvedSymbol(expr) === undefinedSymbol;
        }
        function isEmptyArrayLiteral(node) {
            var expr = ts.skipParentheses(node);
            return expr.kind === 192 /* ArrayLiteralExpression */ && expr.elements.length === 0;
        }
        function addOptionality(type, optional) {
            if (optional === void 0) { optional = true; }
            return strictNullChecks && optional ? getOptionalType(type) : type;
        }
        // Return the inferred type for a variable, parameter, or property declaration
        function getTypeForVariableLikeDeclaration(declaration, includeOptionality) {
            // A variable declared in a for..in statement is of type string, or of type keyof T when the
            // right hand expression is of a type parameter type.
            if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === 231 /* ForInStatement */) {
                var indexType = getIndexType(getNonNullableTypeIfNeeded(checkExpression(declaration.parent.parent.expression)));
                return indexType.flags & (262144 /* TypeParameter */ | 4194304 /* Index */) ? getExtractStringType(indexType) : stringType;
            }
            if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === 232 /* ForOfStatement */) {
                // checkRightHandSideOfForOf will return undefined if the for-of expression type was
                // missing properties/signatures required to get its iteratedType (like
                // [Symbol.iterator] or next). This may be because we accessed properties from anyType,
                // or it may have led to an error inside getElementTypeOfIterable.
                var forOfStatement = declaration.parent.parent;
                return checkRightHandSideOfForOf(forOfStatement) || anyType;
            }
            if (ts.isBindingPattern(declaration.parent)) {
                return getTypeForBindingElement(declaration);
            }
            var isOptional = includeOptionality && (ts.isParameter(declaration) && isJSDocOptionalParameter(declaration)
                || !ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken);
            // Use type from type annotation if one is present
            var declaredType = tryGetTypeFromEffectiveTypeNode(declaration);
            if (declaredType) {
                return addOptionality(declaredType, isOptional);
            }
            if ((noImplicitAny || ts.isInJSFile(declaration)) &&
                declaration.kind === 242 /* VariableDeclaration */ && !ts.isBindingPattern(declaration.name) &&
                !(ts.getCombinedModifierFlags(declaration) & 1 /* Export */) && !(declaration.flags & 8388608 /* Ambient */)) {
                // If --noImplicitAny is on or the declaration is in a Javascript file,
                // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no
                // initializer or a 'null' or 'undefined' initializer.
                if (!(ts.getCombinedNodeFlags(declaration) & 2 /* Const */) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) {
                    return autoType;
                }
                // Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array
                // literal initializer.
                if (declaration.initializer && isEmptyArrayLiteral(declaration.initializer)) {
                    return autoArrayType;
                }
            }
            if (declaration.kind === 156 /* Parameter */) {
                var func = declaration.parent;
                // For a parameter of a set accessor, use the type of the get accessor if one is present
                if (func.kind === 164 /* SetAccessor */ && !hasNonBindableDynamicName(func)) {
                    var getter = ts.getDeclarationOfKind(getSymbolOfNode(declaration.parent), 163 /* GetAccessor */);
                    if (getter) {
                        var getterSignature = getSignatureFromDeclaration(getter);
                        var thisParameter = getAccessorThisParameter(func);
                        if (thisParameter && declaration === thisParameter) {
                            // Use the type from the *getter*
                            ts.Debug.assert(!thisParameter.type);
                            return getTypeOfSymbol(getterSignature.thisParameter);
                        }
                        return getReturnTypeOfSignature(getterSignature);
                    }
                }
                if (ts.isInJSFile(declaration)) {
                    var typeTag = ts.getJSDocType(func);
                    if (typeTag && ts.isFunctionTypeNode(typeTag)) {
                        return getTypeAtPosition(getSignatureFromDeclaration(typeTag), func.parameters.indexOf(declaration));
                    }
                }
                // Use contextual parameter type if one is available
                var type = declaration.symbol.escapedName === "this" /* This */ ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
                if (type) {
                    return addOptionality(type, isOptional);
                }
            }
            else if (ts.isInJSFile(declaration)) {
                var containerObjectType = getJSContainerObjectType(declaration, getSymbolOfNode(declaration), ts.getDeclaredExpandoInitializer(declaration));
                if (containerObjectType) {
                    return containerObjectType;
                }
            }
            // Use the type of the initializer expression if one is present and the declaration is
            // not a parameter of a contextually typed function
            if (declaration.initializer) {
                var type = widenTypeInferredFromInitializer(declaration, checkDeclarationInitializer(declaration));
                return addOptionality(type, isOptional);
            }
            if (ts.isJsxAttribute(declaration)) {
                // if JSX attribute doesn't have initializer, by default the attribute will have boolean value of true.
                // I.e <Elem attr /> is sugar for <Elem attr={true} />
                return trueType;
            }
            // If the declaration specifies a binding pattern and is not a parameter of a contextually
            // typed function, use the type implied by the binding pattern
            if (ts.isBindingPattern(declaration.name)) {
                return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
            }
            // No type specified and nothing can be inferred
            return undefined;
        }
        function getWidenedTypeForAssignmentDeclaration(symbol, resolvedSymbol) {
            // function/class/{} initializers are themselves containers, so they won't merge in the same way as other initializers
            var container = ts.getAssignedExpandoInitializer(symbol.valueDeclaration);
            if (container) {
                var tag = ts.getJSDocTypeTag(container);
                if (tag && tag.typeExpression) {
                    return getTypeFromTypeNode(tag.typeExpression);
                }
                var containerObjectType = getJSContainerObjectType(symbol.valueDeclaration, symbol, container);
                return containerObjectType || getWidenedLiteralType(checkExpressionCached(container));
            }
            var definedInConstructor = false;
            var definedInMethod = false;
            var jsdocType;
            var types;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                var expression = (ts.isBinaryExpression(declaration) || ts.isCallExpression(declaration)) ? declaration :
                    ts.isAccessExpression(declaration) ? ts.isBinaryExpression(declaration.parent) ? declaration.parent : declaration :
                        undefined;
                if (!expression) {
                    continue; // Non-assignment declaration merged in (eg, an Identifier to mark the thing as a namespace) - skip over it and pull type info from elsewhere
                }
                var kind = ts.isAccessExpression(expression)
                    ? ts.getAssignmentDeclarationPropertyAccessKind(expression)
                    : ts.getAssignmentDeclarationKind(expression);
                if (kind === 4 /* ThisProperty */) {
                    if (isDeclarationInConstructor(expression)) {
                        definedInConstructor = true;
                    }
                    else {
                        definedInMethod = true;
                    }
                }
                if (!ts.isCallExpression(expression)) {
                    jsdocType = getAnnotatedTypeForAssignmentDeclaration(jsdocType, expression, symbol, declaration);
                }
                if (!jsdocType) {
                    (types || (types = [])).push((ts.isBinaryExpression(expression) || ts.isCallExpression(expression)) ? getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) : neverType);
                }
            }
            var type = jsdocType;
            if (!type) {
                if (!ts.length(types)) {
                    return errorType; // No types from any declarations :(
                }
                var constructorTypes = definedInConstructor ? getConstructorDefinedThisAssignmentTypes(types, symbol.declarations) : undefined;
                // use only the constructor types unless they were only assigned null | undefined (including widening variants)
                if (definedInMethod) {
                    var propType = getTypeOfAssignmentDeclarationPropertyOfBaseType(symbol);
                    if (propType) {
                        (constructorTypes || (constructorTypes = [])).push(propType);
                        definedInConstructor = true;
                    }
                }
                var sourceTypes = ts.some(constructorTypes, function (t) { return !!(t.flags & ~98304 /* Nullable */); }) ? constructorTypes : types; // TODO: GH#18217
                type = getUnionType(sourceTypes, 2 /* Subtype */);
            }
            var widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
            if (filterType(widened, function (t) { return !!(t.flags & ~98304 /* Nullable */); }) === neverType) {
                reportImplicitAny(symbol.valueDeclaration, anyType);
                return anyType;
            }
            return widened;
        }
        function getJSContainerObjectType(decl, symbol, init) {
            if (!ts.isInJSFile(decl) || !init || !ts.isObjectLiteralExpression(init) || init.properties.length) {
                return undefined;
            }
            var exports = ts.createSymbolTable();
            while (ts.isBinaryExpression(decl) || ts.isPropertyAccessExpression(decl)) {
                var s_2 = getSymbolOfNode(decl);
                if (s_2 && ts.hasEntries(s_2.exports)) {
                    mergeSymbolTable(exports, s_2.exports);
                }
                decl = ts.isBinaryExpression(decl) ? decl.parent : decl.parent.parent;
            }
            var s = getSymbolOfNode(decl);
            if (s && ts.hasEntries(s.exports)) {
                mergeSymbolTable(exports, s.exports);
            }
            var type = createAnonymousType(symbol, exports, ts.emptyArray, ts.emptyArray, undefined, undefined);
            type.objectFlags |= 16384 /* JSLiteral */;
            return type;
        }
        function getAnnotatedTypeForAssignmentDeclaration(declaredType, expression, symbol, declaration) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(expression.parent);
            if (typeNode) {
                var type = getWidenedType(getTypeFromTypeNode(typeNode));
                if (!declaredType) {
                    return type;
                }
                else if (declaredType !== errorType && type !== errorType && !isTypeIdenticalTo(declaredType, type)) {
                    errorNextVariableOrPropertyDeclarationMustHaveSameType(/*firstDeclaration*/ undefined, declaredType, declaration, type);
                }
            }
            if (symbol.parent) {
                var typeNode_2 = ts.getEffectiveTypeAnnotationNode(symbol.parent.valueDeclaration);
                if (typeNode_2) {
                    return getTypeOfPropertyOfType(getTypeFromTypeNode(typeNode_2), symbol.escapedName);
                }
            }
            return declaredType;
        }
        /** If we don't have an explicit JSDoc type, get the type from the initializer. */
        function getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) {
            if (ts.isCallExpression(expression)) {
                if (resolvedSymbol) {
                    return getTypeOfSymbol(resolvedSymbol); // This shouldn't happen except under some hopefully forbidden merges of export assignments and object define assignments
                }
                var objectLitType = checkExpressionCached(expression.arguments[2]);
                var valueType = getTypeOfPropertyOfType(objectLitType, "value");
                if (valueType) {
                    return valueType;
                }
                var getFunc = getTypeOfPropertyOfType(objectLitType, "get");
                if (getFunc) {
                    var getSig = getSingleCallSignature(getFunc);
                    if (getSig) {
                        return getReturnTypeOfSignature(getSig);
                    }
                }
                var setFunc = getTypeOfPropertyOfType(objectLitType, "set");
                if (setFunc) {
                    var setSig = getSingleCallSignature(setFunc);
                    if (setSig) {
                        return getTypeOfFirstParameterOfSignature(setSig);
                    }
                }
                return anyType;
            }
            if (containsSameNamedThisProperty(expression.left, expression.right)) {
                return anyType;
            }
            var type = resolvedSymbol ? getTypeOfSymbol(resolvedSymbol) : getWidenedLiteralType(checkExpressionCached(expression.right));
            if (type.flags & 524288 /* Object */ &&
                kind === 2 /* ModuleExports */ &&
                symbol.escapedName === "export=" /* ExportEquals */) {
                var exportedType = resolveStructuredTypeMembers(type);
                var members_4 = ts.createSymbolTable();
                ts.copyEntries(exportedType.members, members_4);
                if (resolvedSymbol && !resolvedSymbol.exports) {
                    resolvedSymbol.exports = ts.createSymbolTable();
                }
                (resolvedSymbol || symbol).exports.forEach(function (s, name) {
                    var _a;
                    var exportedMember = members_4.get(name);
                    if (exportedMember && exportedMember !== s) {
                        if (s.flags & 111551 /* Value */) {
                            // If the member has an additional value-like declaration, union the types from the two declarations,
                            // but issue an error if they occurred in two different files. The purpose is to support a JS file with
                            // a pattern like:
                            //
                            // module.exports = { a: true };
                            // module.exports.a = 3;
                            //
                            // but we may have a JS file with `module.exports = { a: true }` along with a TypeScript module augmentation
                            // declaring an `export const a: number`. In that case, we issue a duplicate identifier error, because
                            // it's unclear what that's supposed to mean, so it's probably a mistake.
                            if (ts.getSourceFileOfNode(s.valueDeclaration) !== ts.getSourceFileOfNode(exportedMember.valueDeclaration)) {
                                var unescapedName = ts.unescapeLeadingUnderscores(s.escapedName);
                                var exportedMemberName = ((_a = ts.tryCast(exportedMember.valueDeclaration, ts.isNamedDeclaration)) === null || _a === void 0 ? void 0 : _a.name) || exportedMember.valueDeclaration;
                                ts.addRelatedInfo(error(s.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0, unescapedName), ts.createDiagnosticForNode(exportedMemberName, ts.Diagnostics._0_was_also_declared_here, unescapedName));
                                ts.addRelatedInfo(error(exportedMemberName, ts.Diagnostics.Duplicate_identifier_0, unescapedName), ts.createDiagnosticForNode(s.valueDeclaration, ts.Diagnostics._0_was_also_declared_here, unescapedName));
                            }
                            var union = createSymbol(s.flags | exportedMember.flags, name);
                            union.type = getUnionType([getTypeOfSymbol(s), getTypeOfSymbol(exportedMember)]);
                            union.valueDeclaration = exportedMember.valueDeclaration;
                            union.declarations = ts.concatenate(exportedMember.declarations, s.declarations);
                            members_4.set(name, union);
                        }
                        else {
                            members_4.set(name, mergeSymbol(s, exportedMember));
                        }
                    }
                    else {
                        members_4.set(name, s);
                    }
                });
                var result = createAnonymousType(exportedType.symbol, members_4, exportedType.callSignatures, exportedType.constructSignatures, exportedType.stringIndexInfo, exportedType.numberIndexInfo);
                result.objectFlags |= (ts.getObjectFlags(type) & 16384 /* JSLiteral */); // Propagate JSLiteral flag
                return result;
            }
            if (isEmptyArrayLiteralType(type)) {
                reportImplicitAny(expression, anyArrayType);
                return anyArrayType;
            }
            return type;
        }
        function containsSameNamedThisProperty(thisProperty, expression) {
            return ts.isPropertyAccessExpression(thisProperty)
                && thisProperty.expression.kind === 104 /* ThisKeyword */
                && ts.forEachChildRecursively(expression, function (n) { return isMatchingReference(thisProperty, n); });
        }
        function isDeclarationInConstructor(expression) {
            var thisContainer = ts.getThisContainer(expression, /*includeArrowFunctions*/ false);
            // Properties defined in a constructor (or base constructor, or javascript constructor function) don't get undefined added.
            // Function expressions that are assigned to the prototype count as methods.
            return thisContainer.kind === 162 /* Constructor */ ||
                thisContainer.kind === 244 /* FunctionDeclaration */ ||
                (thisContainer.kind === 201 /* FunctionExpression */ && !ts.isPrototypePropertyAssignment(thisContainer.parent));
        }
        function getConstructorDefinedThisAssignmentTypes(types, declarations) {
            ts.Debug.assert(types.length === declarations.length);
            return types.filter(function (_, i) {
                var declaration = declarations[i];
                var expression = ts.isBinaryExpression(declaration) ? declaration :
                    ts.isBinaryExpression(declaration.parent) ? declaration.parent : undefined;
                return expression && isDeclarationInConstructor(expression);
            });
        }
        /** check for definition in base class if any declaration is in a class */
        function getTypeOfAssignmentDeclarationPropertyOfBaseType(property) {
            var parentDeclaration = ts.forEach(property.declarations, function (d) {
                var parent = ts.getThisContainer(d, /*includeArrowFunctions*/ false).parent;
                return ts.isClassLike(parent) && parent;
            });
            if (parentDeclaration) {
                var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(parentDeclaration));
                var baseClassType = classType && getBaseTypes(classType)[0];
                if (baseClassType) {
                    return getTypeOfPropertyOfType(baseClassType, property.escapedName);
                }
            }
        }
        // Return the type implied by a binding pattern element. This is the type of the initializer of the element if
        // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
        // pattern. Otherwise, it is the type any.
        function getTypeFromBindingElement(element, includePatternInType, reportErrors) {
            if (element.initializer) {
                // The type implied by a binding pattern is independent of context, so we check the initializer with no
                // contextual type or, if the element itself is a binding pattern, with the type implied by that binding
                // pattern.
                var contextualType = ts.isBindingPattern(element.name) ? getTypeFromBindingPattern(element.name, /*includePatternInType*/ true, /*reportErrors*/ false) : unknownType;
                return addOptionality(widenTypeInferredFromInitializer(element, checkDeclarationInitializer(element, contextualType)));
            }
            if (ts.isBindingPattern(element.name)) {
                return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors);
            }
            if (reportErrors && !declarationBelongsToPrivateAmbientMember(element)) {
                reportImplicitAny(element, anyType);
            }
            // When we're including the pattern in the type (an indication we're obtaining a contextual type), we
            // use the non-inferrable any type. Inference will never directly infer this type, but it is possible
            // to infer a type that contains it, e.g. for a binding pattern like [foo] or { foo }. In such cases,
            // widening of the binding pattern type substitutes a regular any for the non-inferrable any.
            return includePatternInType ? nonInferrableAnyType : anyType;
        }
        // Return the type implied by an object binding pattern
        function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) {
            var members = ts.createSymbolTable();
            var stringIndexInfo;
            var objectFlags = 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
            ts.forEach(pattern.elements, function (e) {
                var name = e.propertyName || e.name;
                if (e.dotDotDotToken) {
                    stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
                    return;
                }
                var exprType = getLiteralTypeFromPropertyName(name);
                if (!isTypeUsableAsPropertyName(exprType)) {
                    // do not include computed properties in the implied type
                    objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
                    return;
                }
                var text = getPropertyNameFromType(exprType);
                var flags = 4 /* Property */ | (e.initializer ? 16777216 /* Optional */ : 0);
                var symbol = createSymbol(flags, text);
                symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
                symbol.bindingElement = e;
                members.set(symbol.escapedName, symbol);
            });
            var result = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
            result.objectFlags |= objectFlags;
            if (includePatternInType) {
                result.pattern = pattern;
                result.objectFlags |= 1048576 /* ContainsObjectOrArrayLiteral */;
            }
            return result;
        }
        // Return the type implied by an array binding pattern
        function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) {
            var elements = pattern.elements;
            var lastElement = ts.lastOrUndefined(elements);
            var hasRestElement = !!(lastElement && lastElement.kind === 191 /* BindingElement */ && lastElement.dotDotDotToken);
            if (elements.length === 0 || elements.length === 1 && hasRestElement) {
                return languageVersion >= 2 /* ES2015 */ ? createIterableType(anyType) : anyArrayType;
            }
            var elementTypes = ts.map(elements, function (e) { return ts.isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); });
            var minLength = ts.findLastIndex(elements, function (e) { return !ts.isOmittedExpression(e) && !hasDefaultValue(e); }, elements.length - (hasRestElement ? 2 : 1)) + 1;
            var result = createTupleType(elementTypes, minLength, hasRestElement);
            if (includePatternInType) {
                result = cloneTypeReference(result);
                result.pattern = pattern;
                result.objectFlags |= 1048576 /* ContainsObjectOrArrayLiteral */;
            }
            return result;
        }
        // Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself
        // and without regard to its context (i.e. without regard any type annotation or initializer associated with the
        // declaration in which the binding pattern is contained). For example, the implied type of [x, y] is [any, any]
        // and the implied type of { x, y: z = 1 } is { x: any; y: number; }. The type implied by a binding pattern is
        // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring
        // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of
        // the parameter.
        function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) {
            if (includePatternInType === void 0) { includePatternInType = false; }
            if (reportErrors === void 0) { reportErrors = false; }
            return pattern.kind === 189 /* ObjectBindingPattern */
                ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors)
                : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors);
        }
        // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type
        // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it
        // is a bit more involved. For example:
        //
        //   var [x, s = ""] = [1, "one"];
        //
        // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the
        // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the
        // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string.
        function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) {
            return widenTypeForVariableLikeDeclaration(getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true), declaration, reportErrors);
        }
        function widenTypeForVariableLikeDeclaration(type, declaration, reportErrors) {
            if (type) {
                if (reportErrors) {
                    reportErrorsFromWidening(declaration, type);
                }
                // always widen a 'unique symbol' type if the type was created for a different declaration.
                if (type.flags & 8192 /* UniqueESSymbol */ && (ts.isBindingElement(declaration) || !declaration.type) && type.symbol !== getSymbolOfNode(declaration)) {
                    type = esSymbolType;
                }
                return getWidenedType(type);
            }
            // Rest parameters default to type any[], other parameters default to type any
            type = ts.isParameter(declaration) && declaration.dotDotDotToken ? anyArrayType : anyType;
            // Report implicit any errors unless this is a private property within an ambient declaration
            if (reportErrors) {
                if (!declarationBelongsToPrivateAmbientMember(declaration)) {
                    reportImplicitAny(declaration, type);
                }
            }
            return type;
        }
        function declarationBelongsToPrivateAmbientMember(declaration) {
            var root = ts.getRootDeclaration(declaration);
            var memberDeclaration = root.kind === 156 /* Parameter */ ? root.parent : root;
            return isPrivateWithinAmbient(memberDeclaration);
        }
        function tryGetTypeFromEffectiveTypeNode(declaration) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
        }
        function getTypeOfVariableOrParameterOrProperty(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                var type = getTypeOfVariableOrParameterOrPropertyWorker(symbol);
                // For a contextually typed parameter it is possible that a type has already
                // been assigned (in assignTypeToParameterAndFixTypeParameters), and we want
                // to preserve this type.
                if (!links.type) {
                    links.type = type;
                }
            }
            return links.type;
        }
        function getTypeOfVariableOrParameterOrPropertyWorker(symbol) {
            // Handle prototype property
            if (symbol.flags & 4194304 /* Prototype */) {
                return getTypeOfPrototypeProperty(symbol);
            }
            // CommonsJS require and module both have type any.
            if (symbol === requireSymbol) {
                return anyType;
            }
            if (symbol.flags & 134217728 /* ModuleExports */) {
                var fileSymbol = getSymbolOfNode(ts.getSourceFileOfNode(symbol.valueDeclaration));
                var members = ts.createSymbolTable();
                members.set("exports", fileSymbol);
                return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, undefined, undefined);
            }
            // Handle catch clause variables
            var declaration = symbol.valueDeclaration;
            if (ts.isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
                return anyType;
            }
            // Handle export default expressions
            if (ts.isSourceFile(declaration) && ts.isJsonSourceFile(declaration)) {
                if (!declaration.statements.length) {
                    return emptyObjectType;
                }
                return getWidenedType(getWidenedLiteralType(checkExpression(declaration.statements[0].expression)));
            }
            // Handle variable, parameter or property
            if (!pushTypeResolution(symbol, 0 /* Type */)) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & 512 /* ValueModule */ && !(symbol.flags & 67108864 /* Assignment */)) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                return reportCircularityError(symbol);
            }
            var type;
            if (declaration.kind === 259 /* ExportAssignment */) {
                type = widenTypeForVariableLikeDeclaration(checkExpressionCached(declaration.expression), declaration);
            }
            else if (ts.isBinaryExpression(declaration) ||
                (ts.isInJSFile(declaration) &&
                    (ts.isCallExpression(declaration) || (ts.isPropertyAccessExpression(declaration) || ts.isBindableStaticElementAccessExpression(declaration)) && ts.isBinaryExpression(declaration.parent)))) {
                type = getWidenedTypeForAssignmentDeclaration(symbol);
            }
            else if (ts.isJSDocPropertyLikeTag(declaration)
                || ts.isPropertyAccessExpression(declaration)
                || ts.isElementAccessExpression(declaration)
                || ts.isIdentifier(declaration)
                || ts.isStringLiteralLike(declaration)
                || ts.isNumericLiteral(declaration)
                || ts.isClassDeclaration(declaration)
                || ts.isFunctionDeclaration(declaration)
                || (ts.isMethodDeclaration(declaration) && !ts.isObjectLiteralMethod(declaration))
                || ts.isMethodSignature(declaration)
                || ts.isSourceFile(declaration)) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                type = ts.isBinaryExpression(declaration.parent) ?
                    getWidenedTypeForAssignmentDeclaration(symbol) :
                    tryGetTypeFromEffectiveTypeNode(declaration) || anyType;
            }
            else if (ts.isPropertyAssignment(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkPropertyAssignment(declaration);
            }
            else if (ts.isJsxAttribute(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkJsxAttribute(declaration);
            }
            else if (ts.isShorthandPropertyAssignment(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkExpressionForMutableLocation(declaration.name, 0 /* Normal */);
            }
            else if (ts.isObjectLiteralMethod(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkObjectLiteralMethod(declaration, 0 /* Normal */);
            }
            else if (ts.isParameter(declaration)
                || ts.isPropertyDeclaration(declaration)
                || ts.isPropertySignature(declaration)
                || ts.isVariableDeclaration(declaration)
                || ts.isBindingElement(declaration)) {
                type = getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true);
            }
            // getTypeOfSymbol dispatches some JS merges incorrectly because their symbol flags are not mutually exclusive.
            // Re-dispatch based on valueDeclaration.kind instead.
            else if (ts.isEnumDeclaration(declaration)) {
                type = getTypeOfFuncClassEnumModule(symbol);
            }
            else if (ts.isEnumMember(declaration)) {
                type = getTypeOfEnumMember(symbol);
            }
            else if (ts.isAccessor(declaration)) {
                type = resolveTypeOfAccessors(symbol);
            }
            else {
                return ts.Debug.fail("Unhandled declaration kind! " + ts.Debug.formatSyntaxKind(declaration.kind) + " for " + ts.Debug.formatSymbol(symbol));
            }
            if (!popTypeResolution()) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & 512 /* ValueModule */ && !(symbol.flags & 67108864 /* Assignment */)) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                return reportCircularityError(symbol);
            }
            return type;
        }
        function getAnnotatedAccessorTypeNode(accessor) {
            if (accessor) {
                if (accessor.kind === 163 /* GetAccessor */) {
                    var getterTypeAnnotation = ts.getEffectiveReturnTypeNode(accessor);
                    return getterTypeAnnotation;
                }
                else {
                    var setterTypeAnnotation = ts.getEffectiveSetAccessorTypeAnnotationNode(accessor);
                    return setterTypeAnnotation;
                }
            }
            return undefined;
        }
        function getAnnotatedAccessorType(accessor) {
            var node = getAnnotatedAccessorTypeNode(accessor);
            return node && getTypeFromTypeNode(node);
        }
        function getAnnotatedAccessorThisParameter(accessor) {
            var parameter = getAccessorThisParameter(accessor);
            return parameter && parameter.symbol;
        }
        function getThisTypeOfDeclaration(declaration) {
            return getThisTypeOfSignature(getSignatureFromDeclaration(declaration));
        }
        function getTypeOfAccessors(symbol) {
            var links = getSymbolLinks(symbol);
            return links.type || (links.type = getTypeOfAccessorsWorker(symbol));
        }
        function getTypeOfAccessorsWorker(symbol) {
            if (!pushTypeResolution(symbol, 0 /* Type */)) {
                return errorType;
            }
            var type = resolveTypeOfAccessors(symbol);
            if (!popTypeResolution()) {
                type = anyType;
                if (noImplicitAny) {
                    var getter = ts.getDeclarationOfKind(symbol, 163 /* GetAccessor */);
                    error(getter, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
                }
            }
            return type;
        }
        function resolveTypeOfAccessors(symbol) {
            var getter = ts.getDeclarationOfKind(symbol, 163 /* GetAccessor */);
            var setter = ts.getDeclarationOfKind(symbol, 164 /* SetAccessor */);
            if (getter && ts.isInJSFile(getter)) {
                var jsDocType = getTypeForDeclarationFromJSDocComment(getter);
                if (jsDocType) {
                    return jsDocType;
                }
            }
            // First try to see if the user specified a return type on the get-accessor.
            var getterReturnType = getAnnotatedAccessorType(getter);
            if (getterReturnType) {
                return getterReturnType;
            }
            else {
                // If the user didn't specify a return type, try to use the set-accessor's parameter type.
                var setterParameterType = getAnnotatedAccessorType(setter);
                if (setterParameterType) {
                    return setterParameterType;
                }
                else {
                    // If there are no specified types, try to infer it from the body of the get accessor if it exists.
                    if (getter && getter.body) {
                        return getReturnTypeFromBody(getter);
                    }
                    // Otherwise, fall back to 'any'.
                    else {
                        if (setter) {
                            if (!isPrivateWithinAmbient(setter)) {
                                errorOrSuggestion(noImplicitAny, setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
                            }
                        }
                        else {
                            ts.Debug.assert(!!getter, "there must exist a getter as we are current checking either setter or getter in this function");
                            if (!isPrivateWithinAmbient(getter)) {
                                errorOrSuggestion(noImplicitAny, getter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
                            }
                        }
                        return anyType;
                    }
                }
            }
        }
        function getBaseTypeVariableOfClass(symbol) {
            var baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol));
            return baseConstructorType.flags & 8650752 /* TypeVariable */ ? baseConstructorType :
                baseConstructorType.flags & 2097152 /* Intersection */ ? ts.find(baseConstructorType.types, function (t) { return !!(t.flags & 8650752 /* TypeVariable */); }) :
                    undefined;
        }
        function getTypeOfFuncClassEnumModule(symbol) {
            var links = getSymbolLinks(symbol);
            var originalLinks = links;
            if (!links.type) {
                var jsDeclaration = symbol.valueDeclaration && ts.getDeclarationOfExpando(symbol.valueDeclaration);
                if (jsDeclaration) {
                    var merged = mergeJSSymbols(symbol, getSymbolOfNode(jsDeclaration));
                    if (merged) {
                        // note:we overwrite links because we just cloned the symbol
                        symbol = links = merged;
                    }
                }
                originalLinks.type = links.type = getTypeOfFuncClassEnumModuleWorker(symbol);
            }
            return links.type;
        }
        function getTypeOfFuncClassEnumModuleWorker(symbol) {
            var declaration = symbol.valueDeclaration;
            if (symbol.flags & 1536 /* Module */ && ts.isShorthandAmbientModuleSymbol(symbol)) {
                return anyType;
            }
            else if (declaration && (declaration.kind === 209 /* BinaryExpression */ ||
                ts.isAccessExpression(declaration) &&
                    declaration.parent.kind === 209 /* BinaryExpression */)) {
                return getWidenedTypeForAssignmentDeclaration(symbol);
            }
            else if (symbol.flags & 512 /* ValueModule */ && declaration && ts.isSourceFile(declaration) && declaration.commonJsModuleIndicator) {
                var resolvedModule = resolveExternalModuleSymbol(symbol);
                if (resolvedModule !== symbol) {
                    if (!pushTypeResolution(symbol, 0 /* Type */)) {
                        return errorType;
                    }
                    var exportEquals = getMergedSymbol(symbol.exports.get("export=" /* ExportEquals */));
                    var type_1 = getWidenedTypeForAssignmentDeclaration(exportEquals, exportEquals === resolvedModule ? undefined : resolvedModule);
                    if (!popTypeResolution()) {
                        return reportCircularityError(symbol);
                    }
                    return type_1;
                }
            }
            var type = createObjectType(16 /* Anonymous */, symbol);
            if (symbol.flags & 32 /* Class */) {
                var baseTypeVariable = getBaseTypeVariableOfClass(symbol);
                return baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type;
            }
            else {
                return strictNullChecks && symbol.flags & 16777216 /* Optional */ ? getOptionalType(type) : type;
            }
        }
        function getTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            return links.type || (links.type = getDeclaredTypeOfEnumMember(symbol));
        }
        function getTypeOfAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                var targetSymbol = resolveAlias(symbol);
                // It only makes sense to get the type of a value symbol. If the result of resolving
                // the alias is not a value, then it has no type. To get the type associated with a
                // type symbol, call getDeclaredTypeOfSymbol.
                // This check is important because without it, a call to getTypeOfSymbol could end
                // up recursively calling getTypeOfAlias, causing a stack overflow.
                links.type = targetSymbol.flags & 111551 /* Value */
                    ? getTypeOfSymbol(targetSymbol)
                    : errorType;
            }
            return links.type;
        }
        function getTypeOfInstantiatedSymbol(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                if (!pushTypeResolution(symbol, 0 /* Type */)) {
                    return links.type = errorType;
                }
                var type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
                if (!popTypeResolution()) {
                    type = reportCircularityError(symbol);
                }
                links.type = type;
            }
            return links.type;
        }
        function reportCircularityError(symbol) {
            var declaration = symbol.valueDeclaration;
            // Check if variable has type annotation that circularly references the variable itself
            if (ts.getEffectiveTypeAnnotationNode(declaration)) {
                error(symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol));
                return errorType;
            }
            // Check if variable has initializer that circularly references the variable itself
            if (noImplicitAny && (declaration.kind !== 156 /* Parameter */ || declaration.initializer)) {
                error(symbol.valueDeclaration, ts.Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol));
            }
            // Circularities could also result from parameters in function expressions that end up
            // having themselves as contextual types following type argument inference. In those cases
            // we have already reported an implicit any error so we don't report anything here.
            return anyType;
        }
        function getTypeOfSymbolWithDeferredType(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                ts.Debug.assertIsDefined(links.deferralParent);
                ts.Debug.assertIsDefined(links.deferralConstituents);
                links.type = links.deferralParent.flags & 1048576 /* Union */ ? getUnionType(links.deferralConstituents) : getIntersectionType(links.deferralConstituents);
            }
            return links.type;
        }
        function getTypeOfSymbol(symbol) {
            var checkFlags = ts.getCheckFlags(symbol);
            if (checkFlags & 65536 /* DeferredType */) {
                return getTypeOfSymbolWithDeferredType(symbol);
            }
            if (checkFlags & 1 /* Instantiated */) {
                return getTypeOfInstantiatedSymbol(symbol);
            }
            if (checkFlags & 262144 /* Mapped */) {
                return getTypeOfMappedSymbol(symbol);
            }
            if (checkFlags & 8192 /* ReverseMapped */) {
                return getTypeOfReverseMappedSymbol(symbol);
            }
            if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) {
                return getTypeOfVariableOrParameterOrProperty(symbol);
            }
            if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                return getTypeOfFuncClassEnumModule(symbol);
            }
            if (symbol.flags & 8 /* EnumMember */) {
                return getTypeOfEnumMember(symbol);
            }
            if (symbol.flags & 98304 /* Accessor */) {
                return getTypeOfAccessors(symbol);
            }
            if (symbol.flags & 2097152 /* Alias */) {
                return getTypeOfAlias(symbol);
            }
            return errorType;
        }
        function isReferenceToType(type, target) {
            return type !== undefined
                && target !== undefined
                && (ts.getObjectFlags(type) & 4 /* Reference */) !== 0
                && type.target === target;
        }
        function getTargetType(type) {
            return ts.getObjectFlags(type) & 4 /* Reference */ ? type.target : type;
        }
        // TODO: GH#18217 If `checkBase` is undefined, we should not call this because this will always return false.
        function hasBaseType(type, checkBase) {
            return check(type);
            function check(type) {
                if (ts.getObjectFlags(type) & (3 /* ClassOrInterface */ | 4 /* Reference */)) {
                    var target = getTargetType(type);
                    return target === checkBase || ts.some(getBaseTypes(target), check);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    return ts.some(type.types, check);
                }
                return false;
            }
        }
        // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set.
        // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set
        // in-place and returns the same array.
        function appendTypeParameters(typeParameters, declarations) {
            for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) {
                var declaration = declarations_2[_i];
                typeParameters = ts.appendIfUnique(typeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)));
            }
            return typeParameters;
        }
        // Return the outer type parameters of a node or undefined if the node has no outer type parameters.
        function getOuterTypeParameters(node, includeThisTypes) {
            while (true) {
                node = node.parent; // TODO: GH#18217 Use SourceFile kind check instead
                if (node && ts.isBinaryExpression(node)) {
                    // prototype assignments get the outer type parameters of their constructor function
                    var assignmentKind = ts.getAssignmentDeclarationKind(node);
                    if (assignmentKind === 6 /* Prototype */ || assignmentKind === 3 /* PrototypeProperty */) {
                        var symbol = getSymbolOfNode(node.left);
                        if (symbol && symbol.parent && !ts.findAncestor(symbol.parent.valueDeclaration, function (d) { return node === d; })) {
                            node = symbol.parent.valueDeclaration;
                        }
                    }
                }
                if (!node) {
                    return undefined;
                }
                switch (node.kind) {
                    case 225 /* VariableStatement */:
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                    case 165 /* CallSignature */:
                    case 166 /* ConstructSignature */:
                    case 160 /* MethodSignature */:
                    case 170 /* FunctionType */:
                    case 171 /* ConstructorType */:
                    case 300 /* JSDocFunctionType */:
                    case 244 /* FunctionDeclaration */:
                    case 161 /* MethodDeclaration */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                    case 247 /* TypeAliasDeclaration */:
                    case 321 /* JSDocTemplateTag */:
                    case 322 /* JSDocTypedefTag */:
                    case 316 /* JSDocEnumTag */:
                    case 315 /* JSDocCallbackTag */:
                    case 186 /* MappedType */:
                    case 180 /* ConditionalType */:
                        var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
                        if (node.kind === 186 /* MappedType */) {
                            return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)));
                        }
                        else if (node.kind === 180 /* ConditionalType */) {
                            return ts.concatenate(outerTypeParameters, getInferTypeParameters(node));
                        }
                        else if (node.kind === 225 /* VariableStatement */ && !ts.isInJSFile(node)) {
                            break;
                        }
                        var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node));
                        var thisType = includeThisTypes &&
                            (node.kind === 245 /* ClassDeclaration */ || node.kind === 214 /* ClassExpression */ || node.kind === 246 /* InterfaceDeclaration */ || isJSConstructor(node)) &&
                            getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType;
                        return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters;
                }
            }
        }
        // The outer type parameters are those defined by enclosing generic classes, methods, or functions.
        function getOuterTypeParametersOfClassOrInterface(symbol) {
            var declaration = symbol.flags & 32 /* Class */ ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 246 /* InterfaceDeclaration */);
            ts.Debug.assert(!!declaration, "Class was missing valueDeclaration -OR- non-class had no interface declarations");
            return getOuterTypeParameters(declaration);
        }
        // The local type parameters are the combined set of type parameters from all declarations of the class,
        // interface, or type alias.
        function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) {
            var result;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var node = _a[_i];
                if (node.kind === 246 /* InterfaceDeclaration */ ||
                    node.kind === 245 /* ClassDeclaration */ ||
                    node.kind === 214 /* ClassExpression */ ||
                    isJSConstructor(node) ||
                    ts.isTypeAlias(node)) {
                    var declaration = node;
                    result = appendTypeParameters(result, ts.getEffectiveTypeParameterDeclarations(declaration));
                }
            }
            return result;
        }
        // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus
        // its locally declared type parameters.
        function getTypeParametersOfClassOrInterface(symbol) {
            return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol));
        }
        // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single
        // rest parameter of type any[].
        function isMixinConstructorType(type) {
            var signatures = getSignaturesOfType(type, 1 /* Construct */);
            if (signatures.length === 1) {
                var s = signatures[0];
                return !s.typeParameters && s.parameters.length === 1 && signatureHasRestParameter(s) && getElementTypeOfArrayType(getTypeOfParameter(s.parameters[0])) === anyType;
            }
            return false;
        }
        function isConstructorType(type) {
            if (getSignaturesOfType(type, 1 /* Construct */).length > 0) {
                return true;
            }
            if (type.flags & 8650752 /* TypeVariable */) {
                var constraint = getBaseConstraintOfType(type);
                return !!constraint && isMixinConstructorType(constraint);
            }
            return false;
        }
        function getBaseTypeNodeOfClass(type) {
            return ts.getEffectiveBaseTypeNode(type.symbol.valueDeclaration);
        }
        function getConstructorsForTypeArguments(type, typeArgumentNodes, location) {
            var typeArgCount = ts.length(typeArgumentNodes);
            var isJavascript = ts.isInJSFile(location);
            return ts.filter(getSignaturesOfType(type, 1 /* Construct */), function (sig) { return (isJavascript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= ts.length(sig.typeParameters); });
        }
        function getInstantiatedConstructorsForTypeArguments(type, typeArgumentNodes, location) {
            var signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location);
            var typeArguments = ts.map(typeArgumentNodes, getTypeFromTypeNode);
            return ts.sameMap(signatures, function (sig) { return ts.some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, ts.isInJSFile(location)) : sig; });
        }
        /**
         * The base constructor of a class can resolve to
         * * undefinedType if the class has no extends clause,
         * * unknownType if an error occurred during resolution of the extends expression,
         * * nullType if the extends expression is the null value,
         * * anyType if the extends expression has type any, or
         * * an object type with at least one construct signature.
         */
        function getBaseConstructorTypeOfClass(type) {
            if (!type.resolvedBaseConstructorType) {
                var decl = type.symbol.valueDeclaration;
                var extended = ts.getEffectiveBaseTypeNode(decl);
                var baseTypeNode = getBaseTypeNodeOfClass(type);
                if (!baseTypeNode) {
                    return type.resolvedBaseConstructorType = undefinedType;
                }
                if (!pushTypeResolution(type, 1 /* ResolvedBaseConstructorType */)) {
                    return errorType;
                }
                var baseConstructorType = checkExpression(baseTypeNode.expression);
                if (extended && baseTypeNode !== extended) {
                    ts.Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag
                    checkExpression(extended.expression);
                }
                if (baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */)) {
                    // Resolving the members of a class requires us to resolve the base class of that class.
                    // We force resolution here such that we catch circularities now.
                    resolveStructuredTypeMembers(baseConstructorType);
                }
                if (!popTypeResolution()) {
                    error(type.symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
                    return type.resolvedBaseConstructorType = errorType;
                }
                if (!(baseConstructorType.flags & 1 /* Any */) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) {
                    var err = error(baseTypeNode.expression, ts.Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
                    if (baseConstructorType.flags & 262144 /* TypeParameter */) {
                        var constraint = getConstraintFromTypeParameter(baseConstructorType);
                        var ctorReturn = unknownType;
                        if (constraint) {
                            var ctorSig = getSignaturesOfType(constraint, 1 /* Construct */);
                            if (ctorSig[0]) {
                                ctorReturn = getReturnTypeOfSignature(ctorSig[0]);
                            }
                        }
                        ts.addRelatedInfo(err, ts.createDiagnosticForNode(baseConstructorType.symbol.declarations[0], ts.Diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, symbolToString(baseConstructorType.symbol), typeToString(ctorReturn)));
                    }
                    return type.resolvedBaseConstructorType = errorType;
                }
                type.resolvedBaseConstructorType = baseConstructorType;
            }
            return type.resolvedBaseConstructorType;
        }
        function getImplementsTypes(type) {
            var resolvedImplementsTypes = ts.emptyArray;
            for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                var implementsTypeNodes = ts.getEffectiveImplementsTypeNodes(declaration);
                if (!implementsTypeNodes)
                    continue;
                for (var _b = 0, implementsTypeNodes_1 = implementsTypeNodes; _b < implementsTypeNodes_1.length; _b++) {
                    var node = implementsTypeNodes_1[_b];
                    var implementsType = getTypeFromTypeNode(node);
                    if (implementsType !== errorType) {
                        if (resolvedImplementsTypes === ts.emptyArray) {
                            resolvedImplementsTypes = [implementsType];
                        }
                        else {
                            resolvedImplementsTypes.push(implementsType);
                        }
                    }
                }
            }
            return resolvedImplementsTypes;
        }
        function getBaseTypes(type) {
            if (!type.resolvedBaseTypes) {
                if (type.objectFlags & 8 /* Tuple */) {
                    type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters || ts.emptyArray), type.readonly)];
                }
                else if (type.symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                    if (type.symbol.flags & 32 /* Class */) {
                        resolveBaseTypesOfClass(type);
                    }
                    if (type.symbol.flags & 64 /* Interface */) {
                        resolveBaseTypesOfInterface(type);
                    }
                }
                else {
                    ts.Debug.fail("type must be class or interface");
                }
            }
            return type.resolvedBaseTypes;
        }
        function resolveBaseTypesOfClass(type) {
            type.resolvedBaseTypes = ts.resolvingEmptyArray;
            var baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
            if (!(baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */ | 1 /* Any */))) {
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            var baseTypeNode = getBaseTypeNodeOfClass(type);
            var baseType;
            var originalBaseType = baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
            if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 /* Class */ &&
                areAllOuterTypeParametersApplied(originalBaseType)) {
                // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
                // class and all return the instance type of the class. There is no need for further checks and we can apply the
                // type arguments in the same manner as a type reference to get the same error reporting experience.
                baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
            }
            else if (baseConstructorType.flags & 1 /* Any */) {
                baseType = baseConstructorType;
            }
            else {
                // The class derives from a "class-like" constructor function, check that we have at least one construct signature
                // with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
                // we check that all instantiated signatures return the same type.
                var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode);
                if (!constructors.length) {
                    error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
                    return type.resolvedBaseTypes = ts.emptyArray;
                }
                baseType = getReturnTypeOfSignature(constructors[0]);
            }
            if (baseType === errorType) {
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            var reducedBaseType = getReducedType(baseType);
            if (!isValidBaseType(reducedBaseType)) {
                var elaboration = elaborateNeverIntersection(/*errorInfo*/ undefined, baseType);
                var diagnostic = ts.chainDiagnosticMessages(elaboration, ts.Diagnostics.Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members, typeToString(reducedBaseType));
                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(baseTypeNode.expression, diagnostic));
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            if (type === reducedBaseType || hasBaseType(reducedBaseType, type)) {
                error(type.symbol.valueDeclaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */));
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            if (type.resolvedBaseTypes === ts.resolvingEmptyArray) {
                // Circular reference, likely through instantiation of default parameters
                // (otherwise there'd be an error from hasBaseType) - this is fine, but `.members` should be reset
                // as `getIndexedAccessType` via `instantiateType` via `getTypeFromClassOrInterfaceReference` forces a
                // partial instantiation of the members without the base types fully resolved
                type.members = undefined;
            }
            return type.resolvedBaseTypes = [reducedBaseType];
        }
        function areAllOuterTypeParametersApplied(type) {
            // An unapplied type parameter has its symbol still the same as the matching argument symbol.
            // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
            var outerTypeParameters = type.outerTypeParameters;
            if (outerTypeParameters) {
                var last_1 = outerTypeParameters.length - 1;
                var typeArguments = getTypeArguments(type);
                return outerTypeParameters[last_1].symbol !== typeArguments[last_1].symbol;
            }
            return true;
        }
        // A valid base type is `any`, an object type or intersection of object types.
        function isValidBaseType(type) {
            if (type.flags & 262144 /* TypeParameter */) {
                var constraint = getBaseConstraintOfType(type);
                if (constraint) {
                    return isValidBaseType(constraint);
                }
            }
            // TODO: Given that we allow type parmeters here now, is this `!isGenericMappedType(type)` check really needed?
            // There's no reason a `T` should be allowed while a `Readonly<T>` should not.
            return !!(type.flags & (524288 /* Object */ | 67108864 /* NonPrimitive */ | 1 /* Any */) && !isGenericMappedType(type) ||
                type.flags & 2097152 /* Intersection */ && ts.every(type.types, isValidBaseType));
        }
        function resolveBaseTypesOfInterface(type) {
            type.resolvedBaseTypes = type.resolvedBaseTypes || ts.emptyArray;
            for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 246 /* InterfaceDeclaration */ && ts.getInterfaceBaseTypeNodes(declaration)) {
                    for (var _b = 0, _c = ts.getInterfaceBaseTypeNodes(declaration); _b < _c.length; _b++) {
                        var node = _c[_b];
                        var baseType = getReducedType(getTypeFromTypeNode(node));
                        if (baseType !== errorType) {
                            if (isValidBaseType(baseType)) {
                                if (type !== baseType && !hasBaseType(baseType, type)) {
                                    if (type.resolvedBaseTypes === ts.emptyArray) {
                                        type.resolvedBaseTypes = [baseType];
                                    }
                                    else {
                                        type.resolvedBaseTypes.push(baseType);
                                    }
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */));
                                }
                            }
                            else {
                                error(node, ts.Diagnostics.An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members);
                            }
                        }
                    }
                }
            }
        }
        /**
         * Returns true if the interface given by the symbol is free of "this" references.
         *
         * Specifically, the result is true if the interface itself contains no references
         * to "this" in its body, if all base types are interfaces,
         * and if none of the base interfaces have a "this" type.
         */
        function isThislessInterface(symbol) {
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 246 /* InterfaceDeclaration */) {
                    if (declaration.flags & 128 /* ContainsThis */) {
                        return false;
                    }
                    var baseTypeNodes = ts.getInterfaceBaseTypeNodes(declaration);
                    if (baseTypeNodes) {
                        for (var _b = 0, baseTypeNodes_1 = baseTypeNodes; _b < baseTypeNodes_1.length; _b++) {
                            var node = baseTypeNodes_1[_b];
                            if (ts.isEntityNameExpression(node.expression)) {
                                var baseSymbol = resolveEntityName(node.expression, 788968 /* Type */, /*ignoreErrors*/ true);
                                if (!baseSymbol || !(baseSymbol.flags & 64 /* Interface */) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }
        function getDeclaredTypeOfClassOrInterface(symbol) {
            var links = getSymbolLinks(symbol);
            var originalLinks = links;
            if (!links.declaredType) {
                var kind = symbol.flags & 32 /* Class */ ? 1 /* Class */ : 2 /* Interface */;
                var merged = mergeJSSymbols(symbol, getAssignedClassSymbol(symbol.valueDeclaration));
                if (merged) {
                    // note:we overwrite links because we just cloned the symbol
                    symbol = links = merged;
                }
                var type = originalLinks.declaredType = links.declaredType = createObjectType(kind, symbol);
                var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol);
                var localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                // A class or interface is generic if it has type parameters or a "this" type. We always give classes a "this" type
                // because it is not feasible to analyze all members to determine if the "this" type escapes the class (in particular,
                // property types inferred from initializers and method return types inferred from return statements are very hard
                // to exhaustively analyze). We give interfaces a "this" type if we can't definitely determine that they are free of
                // "this" references.
                if (outerTypeParameters || localTypeParameters || kind === 1 /* Class */ || !isThislessInterface(symbol)) {
                    type.objectFlags |= 4 /* Reference */;
                    type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters);
                    type.outerTypeParameters = outerTypeParameters;
                    type.localTypeParameters = localTypeParameters;
                    type.instantiations = ts.createMap();
                    type.instantiations.set(getTypeListId(type.typeParameters), type);
                    type.target = type;
                    type.resolvedTypeArguments = type.typeParameters;
                    type.thisType = createTypeParameter(symbol);
                    type.thisType.isThisType = true;
                    type.thisType.constraint = type;
                }
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                // Note that we use the links object as the target here because the symbol object is used as the unique
                // identity for resolution of the 'type' property in SymbolLinks.
                if (!pushTypeResolution(symbol, 2 /* DeclaredType */)) {
                    return errorType;
                }
                var declaration = ts.Debug.checkDefined(ts.find(symbol.declarations, ts.isTypeAlias), "Type alias symbol with no valid declaration found");
                var typeNode = ts.isJSDocTypeAlias(declaration) ? declaration.typeExpression : declaration.type;
                // If typeNode is missing, we will error in checkJSDocTypedefTag.
                var type = typeNode ? getTypeFromTypeNode(typeNode) : errorType;
                if (popTypeResolution()) {
                    var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    if (typeParameters) {
                        // Initialize the instantiation cache for generic type aliases. The declared type corresponds to
                        // an instantiation of the type alias with the type parameters supplied as type arguments.
                        links.typeParameters = typeParameters;
                        links.instantiations = ts.createMap();
                        links.instantiations.set(getTypeListId(typeParameters), type);
                    }
                }
                else {
                    type = errorType;
                    error(ts.isNamedDeclaration(declaration) ? declaration.name : declaration || declaration, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol));
                }
                links.declaredType = type;
            }
            return links.declaredType;
        }
        function isStringConcatExpression(expr) {
            if (ts.isStringLiteralLike(expr)) {
                return true;
            }
            else if (expr.kind === 209 /* BinaryExpression */) {
                return isStringConcatExpression(expr.left) && isStringConcatExpression(expr.right);
            }
            return false;
        }
        function isLiteralEnumMember(member) {
            var expr = member.initializer;
            if (!expr) {
                return !(member.flags & 8388608 /* Ambient */);
            }
            switch (expr.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    return true;
                case 207 /* PrefixUnaryExpression */:
                    return expr.operator === 40 /* MinusToken */ &&
                        expr.operand.kind === 8 /* NumericLiteral */;
                case 75 /* Identifier */:
                    return ts.nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports.get(expr.escapedText);
                case 209 /* BinaryExpression */:
                    return isStringConcatExpression(expr);
                default:
                    return false;
            }
        }
        function getEnumKind(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.enumKind !== undefined) {
                return links.enumKind;
            }
            var hasNonLiteralMember = false;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 248 /* EnumDeclaration */) {
                    for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
                        var member = _c[_b];
                        if (member.initializer && ts.isStringLiteralLike(member.initializer)) {
                            return links.enumKind = 1 /* Literal */;
                        }
                        if (!isLiteralEnumMember(member)) {
                            hasNonLiteralMember = true;
                        }
                    }
                }
            }
            return links.enumKind = hasNonLiteralMember ? 0 /* Numeric */ : 1 /* Literal */;
        }
        function getBaseTypeOfEnumLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ && !(type.flags & 1048576 /* Union */) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)) : type;
        }
        function getDeclaredTypeOfEnum(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.declaredType) {
                return links.declaredType;
            }
            if (getEnumKind(symbol) === 1 /* Literal */) {
                enumCount++;
                var memberTypeList = [];
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (declaration.kind === 248 /* EnumDeclaration */) {
                        for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
                            var member = _c[_b];
                            var value = getEnumMemberValue(member);
                            var memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member)));
                            getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType;
                            memberTypeList.push(getRegularTypeOfLiteralType(memberType));
                        }
                    }
                }
                if (memberTypeList.length) {
                    var enumType_1 = getUnionType(memberTypeList, 1 /* Literal */, symbol, /*aliasTypeArguments*/ undefined);
                    if (enumType_1.flags & 1048576 /* Union */) {
                        enumType_1.flags |= 1024 /* EnumLiteral */;
                        enumType_1.symbol = symbol;
                    }
                    return links.declaredType = enumType_1;
                }
            }
            var enumType = createType(32 /* Enum */);
            enumType.symbol = symbol;
            return links.declaredType = enumType;
        }
        function getDeclaredTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
                if (!links.declaredType) {
                    links.declaredType = enumType;
                }
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeParameter(symbol) {
            var links = getSymbolLinks(symbol);
            return links.declaredType || (links.declaredType = createTypeParameter(symbol));
        }
        function getDeclaredTypeOfAlias(symbol) {
            var links = getSymbolLinks(symbol);
            return links.declaredType || (links.declaredType = getDeclaredTypeOfSymbol(resolveAlias(symbol)));
        }
        function getDeclaredTypeOfSymbol(symbol) {
            return tryGetDeclaredTypeOfSymbol(symbol) || errorType;
        }
        function tryGetDeclaredTypeOfSymbol(symbol) {
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getDeclaredTypeOfClassOrInterface(symbol);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getDeclaredTypeOfTypeAlias(symbol);
            }
            if (symbol.flags & 262144 /* TypeParameter */) {
                return getDeclaredTypeOfTypeParameter(symbol);
            }
            if (symbol.flags & 384 /* Enum */) {
                return getDeclaredTypeOfEnum(symbol);
            }
            if (symbol.flags & 8 /* EnumMember */) {
                return getDeclaredTypeOfEnumMember(symbol);
            }
            if (symbol.flags & 2097152 /* Alias */) {
                return getDeclaredTypeOfAlias(symbol);
            }
            return undefined;
        }
        /**
         * A type is free of this references if it's the any, string, number, boolean, symbol, or void keyword, a string
         * literal type, an array with an element type that is free of this references, or a type reference that is
         * free of this references.
         */
        function isThislessType(node) {
            switch (node.kind) {
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 143 /* StringKeyword */:
                case 140 /* NumberKeyword */:
                case 151 /* BigIntKeyword */:
                case 128 /* BooleanKeyword */:
                case 144 /* SymbolKeyword */:
                case 141 /* ObjectKeyword */:
                case 110 /* VoidKeyword */:
                case 146 /* UndefinedKeyword */:
                case 100 /* NullKeyword */:
                case 137 /* NeverKeyword */:
                case 187 /* LiteralType */:
                    return true;
                case 174 /* ArrayType */:
                    return isThislessType(node.elementType);
                case 169 /* TypeReference */:
                    return !node.typeArguments || node.typeArguments.every(isThislessType);
            }
            return false;
        }
        /** A type parameter is thisless if its constraint is thisless, or if it has no constraint. */
        function isThislessTypeParameter(node) {
            var constraint = ts.getEffectiveConstraintOfTypeParameter(node);
            return !constraint || isThislessType(constraint);
        }
        /**
         * A variable-like declaration is free of this references if it has a type annotation
         * that is thisless, or if it has no type annotation and no initializer (and is thus of type any).
         */
        function isThislessVariableLikeDeclaration(node) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
            return typeNode ? isThislessType(typeNode) : !ts.hasInitializer(node);
        }
        /**
         * A function-like declaration is considered free of `this` references if it has a return type
         * annotation that is free of this references and if each parameter is thisless and if
         * each type parameter (if present) is thisless.
         */
        function isThislessFunctionLikeDeclaration(node) {
            var returnType = ts.getEffectiveReturnTypeNode(node);
            var typeParameters = ts.getEffectiveTypeParameterDeclarations(node);
            return (node.kind === 162 /* Constructor */ || (!!returnType && isThislessType(returnType))) &&
                node.parameters.every(isThislessVariableLikeDeclaration) &&
                typeParameters.every(isThislessTypeParameter);
        }
        /**
         * Returns true if the class or interface member given by the symbol is free of "this" references. The
         * function may return false for symbols that are actually free of "this" references because it is not
         * feasible to perform a complete analysis in all cases. In particular, property members with types
         * inferred from their initializers and function members with inferred return types are conservatively
         * assumed not to be free of "this" references.
         */
        function isThisless(symbol) {
            if (symbol.declarations && symbol.declarations.length === 1) {
                var declaration = symbol.declarations[0];
                if (declaration) {
                    switch (declaration.kind) {
                        case 159 /* PropertyDeclaration */:
                        case 158 /* PropertySignature */:
                            return isThislessVariableLikeDeclaration(declaration);
                        case 161 /* MethodDeclaration */:
                        case 160 /* MethodSignature */:
                        case 162 /* Constructor */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                            return isThislessFunctionLikeDeclaration(declaration);
                    }
                }
            }
            return false;
        }
        // The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true,
        // we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation.
        function createInstantiatedSymbolTable(symbols, mapper, mappingThisOnly) {
            var result = ts.createSymbolTable();
            for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
                var symbol = symbols_2[_i];
                result.set(symbol.escapedName, mappingThisOnly && isThisless(symbol) ? symbol : instantiateSymbol(symbol, mapper));
            }
            return result;
        }
        function addInheritedMembers(symbols, baseSymbols) {
            for (var _i = 0, baseSymbols_1 = baseSymbols; _i < baseSymbols_1.length; _i++) {
                var s = baseSymbols_1[_i];
                if (!symbols.has(s.escapedName) && !isStaticPrivateIdentifierProperty(s)) {
                    symbols.set(s.escapedName, s);
                }
            }
        }
        function isStaticPrivateIdentifierProperty(s) {
            return !!s.valueDeclaration && ts.isPrivateIdentifierPropertyDeclaration(s.valueDeclaration) && ts.hasModifier(s.valueDeclaration, 32 /* Static */);
        }
        function resolveDeclaredMembers(type) {
            if (!type.declaredProperties) {
                var symbol = type.symbol;
                var members = getMembersOfSymbol(symbol);
                type.declaredProperties = getNamedMembers(members);
                // Start with signatures at empty array in case of recursive types
                type.declaredCallSignatures = ts.emptyArray;
                type.declaredConstructSignatures = ts.emptyArray;
                type.declaredCallSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */));
                type.declaredConstructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */));
                type.declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                type.declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
            }
            return type;
        }
        /**
         * Indicates whether a type can be used as a property name.
         */
        function isTypeUsableAsPropertyName(type) {
            return !!(type.flags & 8576 /* StringOrNumberLiteralOrUnique */);
        }
        /**
         * Indicates whether a declaration name is definitely late-bindable.
         * A declaration name is only late-bindable if:
         * - It is a `ComputedPropertyName`.
         * - Its expression is an `Identifier` or either a `PropertyAccessExpression` an
         * `ElementAccessExpression` consisting only of these same three types of nodes.
         * - The type of its expression is a string or numeric literal type, or is a `unique symbol` type.
         */
        function isLateBindableName(node) {
            if (!ts.isComputedPropertyName(node) && !ts.isElementAccessExpression(node)) {
                return false;
            }
            var expr = ts.isComputedPropertyName(node) ? node.expression : node.argumentExpression;
            return ts.isEntityNameExpression(expr)
                && isTypeUsableAsPropertyName(ts.isComputedPropertyName(node) ? checkComputedPropertyName(node) : checkExpressionCached(expr));
        }
        function isLateBoundName(name) {
            return name.charCodeAt(0) === 95 /* _ */ &&
                name.charCodeAt(1) === 95 /* _ */ &&
                name.charCodeAt(2) === 64 /* at */;
        }
        /**
         * Indicates whether a declaration has a late-bindable dynamic name.
         */
        function hasLateBindableName(node) {
            var name = ts.getNameOfDeclaration(node);
            return !!name && isLateBindableName(name);
        }
        /**
         * Indicates whether a declaration has a dynamic name that cannot be late-bound.
         */
        function hasNonBindableDynamicName(node) {
            return ts.hasDynamicName(node) && !hasLateBindableName(node);
        }
        /**
         * Indicates whether a declaration name is a dynamic name that cannot be late-bound.
         */
        function isNonBindableDynamicName(node) {
            return ts.isDynamicName(node) && !isLateBindableName(node);
        }
        /**
         * Gets the symbolic name for a member from its type.
         */
        function getPropertyNameFromType(type) {
            if (type.flags & 8192 /* UniqueESSymbol */) {
                return type.escapedName;
            }
            if (type.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */)) {
                return ts.escapeLeadingUnderscores("" + type.value);
            }
            return ts.Debug.fail();
        }
        /**
         * Adds a declaration to a late-bound dynamic member. This performs the same function for
         * late-bound members that `addDeclarationToSymbol` in binder.ts performs for early-bound
         * members.
         */
        function addDeclarationToLateBoundSymbol(symbol, member, symbolFlags) {
            ts.Debug.assert(!!(ts.getCheckFlags(symbol) & 4096 /* Late */), "Expected a late-bound symbol.");
            symbol.flags |= symbolFlags;
            getSymbolLinks(member.symbol).lateSymbol = symbol;
            if (!symbol.declarations) {
                symbol.declarations = [member];
            }
            else {
                symbol.declarations.push(member);
            }
            if (symbolFlags & 111551 /* Value */) {
                if (!symbol.valueDeclaration || symbol.valueDeclaration.kind !== member.kind) {
                    symbol.valueDeclaration = member;
                }
            }
        }
        /**
         * Performs late-binding of a dynamic member. This performs the same function for
         * late-bound members that `declareSymbol` in binder.ts performs for early-bound
         * members.
         *
         * If a symbol is a dynamic name from a computed property, we perform an additional "late"
         * binding phase to attempt to resolve the name for the symbol from the type of the computed
         * property's expression. If the type of the expression is a string-literal, numeric-literal,
         * or unique symbol type, we can use that type as the name of the symbol.
         *
         * For example, given:
         *
         *   const x = Symbol();
         *
         *   interface I {
         *     [x]: number;
         *   }
         *
         * The binder gives the property `[x]: number` a special symbol with the name "__computed".
         * In the late-binding phase we can type-check the expression `x` and see that it has a
         * unique symbol type which we can then use as the name of the member. This allows users
         * to define custom symbols that can be used in the members of an object type.
         *
         * @param parent The containing symbol for the member.
         * @param earlySymbols The early-bound symbols of the parent.
         * @param lateSymbols The late-bound symbols of the parent.
         * @param decl The member to bind.
         */
        function lateBindMember(parent, earlySymbols, lateSymbols, decl) {
            ts.Debug.assert(!!decl.symbol, "The member is expected to have a symbol.");
            var links = getNodeLinks(decl);
            if (!links.resolvedSymbol) {
                // In the event we attempt to resolve the late-bound name of this member recursively,
                // fall back to the early-bound name of this member.
                links.resolvedSymbol = decl.symbol;
                var declName = ts.isBinaryExpression(decl) ? decl.left : decl.name;
                var type = ts.isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : checkComputedPropertyName(declName);
                if (isTypeUsableAsPropertyName(type)) {
                    var memberName = getPropertyNameFromType(type);
                    var symbolFlags = decl.symbol.flags;
                    // Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations.
                    var lateSymbol = lateSymbols.get(memberName);
                    if (!lateSymbol)
                        lateSymbols.set(memberName, lateSymbol = createSymbol(0 /* None */, memberName, 4096 /* Late */));
                    // Report an error if a late-bound member has the same name as an early-bound member,
                    // or if we have another early-bound symbol declaration with the same name and
                    // conflicting flags.
                    var earlySymbol = earlySymbols && earlySymbols.get(memberName);
                    if (lateSymbol.flags & getExcludedSymbolFlags(symbolFlags) || earlySymbol) {
                        // If we have an existing early-bound member, combine its declarations so that we can
                        // report an error at each declaration.
                        var declarations = earlySymbol ? ts.concatenate(earlySymbol.declarations, lateSymbol.declarations) : lateSymbol.declarations;
                        var name_3 = !(type.flags & 8192 /* UniqueESSymbol */) && ts.unescapeLeadingUnderscores(memberName) || ts.declarationNameToString(declName);
                        ts.forEach(declarations, function (declaration) { return error(ts.getNameOfDeclaration(declaration) || declaration, ts.Diagnostics.Property_0_was_also_declared_here, name_3); });
                        error(declName || decl, ts.Diagnostics.Duplicate_property_0, name_3);
                        lateSymbol = createSymbol(0 /* None */, memberName, 4096 /* Late */);
                    }
                    lateSymbol.nameType = type;
                    addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags);
                    if (lateSymbol.parent) {
                        ts.Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one");
                    }
                    else {
                        lateSymbol.parent = parent;
                    }
                    return links.resolvedSymbol = lateSymbol;
                }
            }
            return links.resolvedSymbol;
        }
        function getResolvedMembersOrExportsOfSymbol(symbol, resolutionKind) {
            var links = getSymbolLinks(symbol);
            if (!links[resolutionKind]) {
                var isStatic = resolutionKind === "resolvedExports" /* resolvedExports */;
                var earlySymbols = !isStatic ? symbol.members :
                    symbol.flags & 1536 /* Module */ ? getExportsOfModuleWorker(symbol) :
                        symbol.exports;
                // In the event we recursively resolve the members/exports of the symbol, we
                // set the initial value of resolvedMembers/resolvedExports to the early-bound
                // members/exports of the symbol.
                links[resolutionKind] = earlySymbols || emptySymbols;
                // fill in any as-yet-unresolved late-bound members.
                var lateSymbols = ts.createSymbolTable();
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var members = ts.getMembersOfDeclaration(decl);
                    if (members) {
                        for (var _b = 0, members_5 = members; _b < members_5.length; _b++) {
                            var member = members_5[_b];
                            if (isStatic === ts.hasStaticModifier(member) && hasLateBindableName(member)) {
                                lateBindMember(symbol, earlySymbols, lateSymbols, member);
                            }
                        }
                    }
                }
                var assignments = symbol.assignmentDeclarationMembers;
                if (assignments) {
                    var decls = ts.arrayFrom(assignments.values());
                    for (var _c = 0, decls_1 = decls; _c < decls_1.length; _c++) {
                        var member = decls_1[_c];
                        var assignmentKind = ts.getAssignmentDeclarationKind(member);
                        var isInstanceMember = assignmentKind === 3 /* PrototypeProperty */
                            || assignmentKind === 4 /* ThisProperty */
                            || assignmentKind === 9 /* ObjectDefinePrototypeProperty */
                            || assignmentKind === 6 /* Prototype */; // A straight `Prototype` assignment probably can never have a computed name
                        if (isStatic === !isInstanceMember && hasLateBindableName(member)) {
                            lateBindMember(symbol, earlySymbols, lateSymbols, member);
                        }
                    }
                }
                links[resolutionKind] = combineSymbolTables(earlySymbols, lateSymbols) || emptySymbols;
            }
            return links[resolutionKind];
        }
        /**
         * Gets a SymbolTable containing both the early- and late-bound members of a symbol.
         *
         * For a description of late-binding, see `lateBindMember`.
         */
        function getMembersOfSymbol(symbol) {
            return symbol.flags & 6256 /* LateBindingContainer */
                ? getResolvedMembersOrExportsOfSymbol(symbol, "resolvedMembers" /* resolvedMembers */)
                : symbol.members || emptySymbols;
        }
        /**
         * If a symbol is the dynamic name of the member of an object type, get the late-bound
         * symbol of the member.
         *
         * For a description of late-binding, see `lateBindMember`.
         */
        function getLateBoundSymbol(symbol) {
            if (symbol.flags & 106500 /* ClassMember */ && symbol.escapedName === "__computed" /* Computed */) {
                var links = getSymbolLinks(symbol);
                if (!links.lateSymbol && ts.some(symbol.declarations, hasLateBindableName)) {
                    // force late binding of members/exports. This will set the late-bound symbol
                    var parent = getMergedSymbol(symbol.parent);
                    if (ts.some(symbol.declarations, ts.hasStaticModifier)) {
                        getExportsOfSymbol(parent);
                    }
                    else {
                        getMembersOfSymbol(parent);
                    }
                }
                return links.lateSymbol || (links.lateSymbol = symbol);
            }
            return symbol;
        }
        function getTypeWithThisArgument(type, thisArgument, needApparentType) {
            if (ts.getObjectFlags(type) & 4 /* Reference */) {
                var target = type.target;
                var typeArguments = getTypeArguments(type);
                if (ts.length(target.typeParameters) === ts.length(typeArguments)) {
                    var ref = createTypeReference(target, ts.concatenate(typeArguments, [thisArgument || target.thisType]));
                    return needApparentType ? getApparentType(ref) : ref;
                }
            }
            else if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, function (t) { return getTypeWithThisArgument(t, thisArgument, needApparentType); }));
            }
            return needApparentType ? getApparentType(type) : type;
        }
        function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) {
            var mapper;
            var members;
            var callSignatures;
            var constructSignatures;
            var stringIndexInfo;
            var numberIndexInfo;
            if (ts.rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) {
                members = source.symbol ? getMembersOfSymbol(source.symbol) : ts.createSymbolTable(source.declaredProperties);
                callSignatures = source.declaredCallSignatures;
                constructSignatures = source.declaredConstructSignatures;
                stringIndexInfo = source.declaredStringIndexInfo;
                numberIndexInfo = source.declaredNumberIndexInfo;
            }
            else {
                mapper = createTypeMapper(typeParameters, typeArguments);
                members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
                callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper);
                constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper);
                stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper);
                numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper);
            }
            var baseTypes = getBaseTypes(source);
            if (baseTypes.length) {
                if (source.symbol && members === getMembersOfSymbol(source.symbol)) {
                    members = ts.createSymbolTable(source.declaredProperties);
                }
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
                var thisArgument = ts.lastOrUndefined(typeArguments);
                for (var _i = 0, baseTypes_1 = baseTypes; _i < baseTypes_1.length; _i++) {
                    var baseType = baseTypes_1[_i];
                    var instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType;
                    addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType));
                    callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, 0 /* Call */));
                    constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, 1 /* Construct */));
                    if (!stringIndexInfo) {
                        stringIndexInfo = instantiatedBaseType === anyType ?
                            createIndexInfo(anyType, /*isReadonly*/ false) :
                            getIndexInfoOfType(instantiatedBaseType, 0 /* String */);
                    }
                    numberIndexInfo = numberIndexInfo || getIndexInfoOfType(instantiatedBaseType, 1 /* Number */);
                }
            }
            setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function resolveClassOrInterfaceMembers(type) {
            resolveObjectTypeMembers(type, resolveDeclaredMembers(type), ts.emptyArray, ts.emptyArray);
        }
        function resolveTypeReferenceMembers(type) {
            var source = resolveDeclaredMembers(type.target);
            var typeParameters = ts.concatenate(source.typeParameters, [source.thisType]);
            var typeArguments = getTypeArguments(type);
            var paddedTypeArguments = typeArguments.length === typeParameters.length ? typeArguments : ts.concatenate(typeArguments, [type]);
            resolveObjectTypeMembers(type, source, typeParameters, paddedTypeArguments);
        }
        function createSignature(declaration, typeParameters, thisParameter, parameters, resolvedReturnType, resolvedTypePredicate, minArgumentCount, flags) {
            var sig = new Signature(checker, flags);
            sig.declaration = declaration;
            sig.typeParameters = typeParameters;
            sig.parameters = parameters;
            sig.thisParameter = thisParameter;
            sig.resolvedReturnType = resolvedReturnType;
            sig.resolvedTypePredicate = resolvedTypePredicate;
            sig.minArgumentCount = minArgumentCount;
            sig.target = undefined;
            sig.mapper = undefined;
            sig.unionSignatures = undefined;
            return sig;
        }
        function cloneSignature(sig) {
            var result = createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & 3 /* PropagatingFlags */);
            result.target = sig.target;
            result.mapper = sig.mapper;
            result.unionSignatures = sig.unionSignatures;
            return result;
        }
        function createUnionSignature(signature, unionSignatures) {
            var result = cloneSignature(signature);
            result.unionSignatures = unionSignatures;
            result.target = undefined;
            result.mapper = undefined;
            return result;
        }
        function getOptionalCallSignature(signature, callChainFlags) {
            if ((signature.flags & 12 /* CallChainFlags */) === callChainFlags) {
                return signature;
            }
            if (!signature.optionalCallSignatureCache) {
                signature.optionalCallSignatureCache = {};
            }
            var key = callChainFlags === 4 /* IsInnerCallChain */ ? "inner" : "outer";
            return signature.optionalCallSignatureCache[key]
                || (signature.optionalCallSignatureCache[key] = createOptionalCallSignature(signature, callChainFlags));
        }
        function createOptionalCallSignature(signature, callChainFlags) {
            ts.Debug.assert(callChainFlags === 4 /* IsInnerCallChain */ || callChainFlags === 8 /* IsOuterCallChain */, "An optional call signature can either be for an inner call chain or an outer call chain, but not both.");
            var result = cloneSignature(signature);
            result.flags |= callChainFlags;
            return result;
        }
        function getExpandedParameters(sig) {
            if (signatureHasRestParameter(sig)) {
                var restIndex_1 = sig.parameters.length - 1;
                var restParameter = sig.parameters[restIndex_1];
                var restType = getTypeOfSymbol(restParameter);
                if (isTupleType(restType)) {
                    var elementTypes = getTypeArguments(restType);
                    var minLength_1 = restType.target.minLength;
                    var tupleRestIndex_1 = restType.target.hasRestElement ? elementTypes.length - 1 : -1;
                    var restParams = ts.map(elementTypes, function (t, i) {
                        var name = getParameterNameAtPosition(sig, restIndex_1 + i);
                        var checkFlags = i === tupleRestIndex_1 ? 32768 /* RestParameter */ :
                            i >= minLength_1 ? 16384 /* OptionalParameter */ : 0;
                        var symbol = createSymbol(1 /* FunctionScopedVariable */, name, checkFlags);
                        symbol.type = i === tupleRestIndex_1 ? createArrayType(t) : t;
                        return symbol;
                    });
                    return ts.concatenate(sig.parameters.slice(0, restIndex_1), restParams);
                }
            }
            return sig.parameters;
        }
        function getDefaultConstructSignatures(classType) {
            var baseConstructorType = getBaseConstructorTypeOfClass(classType);
            var baseSignatures = getSignaturesOfType(baseConstructorType, 1 /* Construct */);
            if (baseSignatures.length === 0) {
                return [createSignature(undefined, classType.localTypeParameters, undefined, ts.emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */)];
            }
            var baseTypeNode = getBaseTypeNodeOfClass(classType);
            var isJavaScript = ts.isInJSFile(baseTypeNode);
            var typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode);
            var typeArgCount = ts.length(typeArguments);
            var result = [];
            for (var _i = 0, baseSignatures_1 = baseSignatures; _i < baseSignatures_1.length; _i++) {
                var baseSig = baseSignatures_1[_i];
                var minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters);
                var typeParamCount = ts.length(baseSig.typeParameters);
                if (isJavaScript || typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) {
                    var sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
                    sig.typeParameters = classType.localTypeParameters;
                    sig.resolvedReturnType = classType;
                    result.push(sig);
                }
            }
            return result;
        }
        function findMatchingSignature(signatureList, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes) {
            for (var _i = 0, signatureList_1 = signatureList; _i < signatureList_1.length; _i++) {
                var s = signatureList_1[_i];
                if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, partialMatch ? compareTypesSubtypeOf : compareTypesIdentical)) {
                    return s;
                }
            }
        }
        function findMatchingSignatures(signatureLists, signature, listIndex) {
            if (signature.typeParameters) {
                // We require an exact match for generic signatures, so we only return signatures from the first
                // signature list and only if they have exact matches in the other signature lists.
                if (listIndex > 0) {
                    return undefined;
                }
                for (var i = 1; i < signatureLists.length; i++) {
                    if (!findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false)) {
                        return undefined;
                    }
                }
                return [signature];
            }
            var result;
            for (var i = 0; i < signatureLists.length; i++) {
                // Allow matching non-generic signatures to have excess parameters and different return types.
                // Prefer matching this types if possible.
                var match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true);
                if (!match) {
                    return undefined;
                }
                result = ts.appendIfUnique(result, match);
            }
            return result;
        }
        // The signatures of a union type are those signatures that are present in each of the constituent types.
        // Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional
        // parameters and may differ in return types. When signatures differ in return types, the resulting return
        // type is the union of the constituent return types.
        function getUnionSignatures(signatureLists) {
            var result;
            var indexWithLengthOverOne;
            for (var i = 0; i < signatureLists.length; i++) {
                if (signatureLists[i].length === 0)
                    return ts.emptyArray;
                if (signatureLists[i].length > 1) {
                    indexWithLengthOverOne = indexWithLengthOverOne === undefined ? i : -1; // -1 is a signal there are multiple overload sets
                }
                for (var _i = 0, _a = signatureLists[i]; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    // Only process signatures with parameter lists that aren't already in the result list
                    if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true)) {
                        var unionSignatures = findMatchingSignatures(signatureLists, signature, i);
                        if (unionSignatures) {
                            var s = signature;
                            // Union the result types when more than one signature matches
                            if (unionSignatures.length > 1) {
                                var thisParameter = signature.thisParameter;
                                var firstThisParameterOfUnionSignatures = ts.forEach(unionSignatures, function (sig) { return sig.thisParameter; });
                                if (firstThisParameterOfUnionSignatures) {
                                    var thisType = getIntersectionType(ts.mapDefined(unionSignatures, function (sig) { return sig.thisParameter && getTypeOfSymbol(sig.thisParameter); }));
                                    thisParameter = createSymbolWithType(firstThisParameterOfUnionSignatures, thisType);
                                }
                                s = createUnionSignature(signature, unionSignatures);
                                s.thisParameter = thisParameter;
                            }
                            (result || (result = [])).push(s);
                        }
                    }
                }
            }
            if (!ts.length(result) && indexWithLengthOverOne !== -1) {
                // No sufficiently similar signature existed to subsume all the other signatures in the union - time to see if we can make a single
                // signature that handles all over them. We only do this when there are overloads in only one constituent.
                // (Overloads are conditional in nature and having overloads in multiple constituents would necessitate making a power set of
                // signatures from the type, whose ordering would be non-obvious)
                var masterList = signatureLists[indexWithLengthOverOne !== undefined ? indexWithLengthOverOne : 0];
                var results = masterList.slice();
                var _loop_9 = function (signatures) {
                    if (signatures !== masterList) {
                        var signature_1 = signatures[0];
                        ts.Debug.assert(!!signature_1, "getUnionSignatures bails early on empty signature lists and should not have empty lists on second pass");
                        results = signature_1.typeParameters && ts.some(results, function (s) { return !!s.typeParameters; }) ? undefined : ts.map(results, function (sig) { return combineSignaturesOfUnionMembers(sig, signature_1); });
                        if (!results) {
                            return "break";
                        }
                    }
                };
                for (var _b = 0, signatureLists_1 = signatureLists; _b < signatureLists_1.length; _b++) {
                    var signatures = signatureLists_1[_b];
                    var state_3 = _loop_9(signatures);
                    if (state_3 === "break")
                        break;
                }
                result = results;
            }
            return result || ts.emptyArray;
        }
        function combineUnionThisParam(left, right) {
            if (!left || !right) {
                return left || right;
            }
            // A signature `this` type might be a read or a write position... It's very possible that it should be invariant
            // and we should refuse to merge signatures if there are `this` types and they do not match. However, so as to be
            // permissive when calling, for now, we'll intersect the `this` types just like we do for param types in union signatures.
            var thisType = getIntersectionType([getTypeOfSymbol(left), getTypeOfSymbol(right)]);
            return createSymbolWithType(left, thisType);
        }
        function combineUnionParameters(left, right) {
            var leftCount = getParameterCount(left);
            var rightCount = getParameterCount(right);
            var longest = leftCount >= rightCount ? left : right;
            var shorter = longest === left ? right : left;
            var longestCount = longest === left ? leftCount : rightCount;
            var eitherHasEffectiveRest = (hasEffectiveRestParameter(left) || hasEffectiveRestParameter(right));
            var needsExtraRestElement = eitherHasEffectiveRest && !hasEffectiveRestParameter(longest);
            var params = new Array(longestCount + (needsExtraRestElement ? 1 : 0));
            for (var i = 0; i < longestCount; i++) {
                var longestParamType = tryGetTypeAtPosition(longest, i);
                var shorterParamType = tryGetTypeAtPosition(shorter, i) || unknownType;
                var unionParamType = getIntersectionType([longestParamType, shorterParamType]);
                var isRestParam = eitherHasEffectiveRest && !needsExtraRestElement && i === (longestCount - 1);
                var isOptional = i >= getMinArgumentCount(longest) && i >= getMinArgumentCount(shorter);
                var leftName = i >= leftCount ? undefined : getParameterNameAtPosition(left, i);
                var rightName = i >= rightCount ? undefined : getParameterNameAtPosition(right, i);
                var paramName = leftName === rightName ? leftName :
                    !leftName ? rightName :
                        !rightName ? leftName :
                            undefined;
                var paramSymbol = createSymbol(1 /* FunctionScopedVariable */ | (isOptional && !isRestParam ? 16777216 /* Optional */ : 0), paramName || "arg" + i);
                paramSymbol.type = isRestParam ? createArrayType(unionParamType) : unionParamType;
                params[i] = paramSymbol;
            }
            if (needsExtraRestElement) {
                var restParamSymbol = createSymbol(1 /* FunctionScopedVariable */, "args");
                restParamSymbol.type = createArrayType(getTypeAtPosition(shorter, longestCount));
                params[longestCount] = restParamSymbol;
            }
            return params;
        }
        function combineSignaturesOfUnionMembers(left, right) {
            var declaration = left.declaration;
            var params = combineUnionParameters(left, right);
            var thisParam = combineUnionThisParam(left.thisParameter, right.thisParameter);
            var minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount);
            var result = createSignature(declaration, left.typeParameters || right.typeParameters, thisParam, params, 
            /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, minArgCount, (left.flags | right.flags) & 3 /* PropagatingFlags */);
            result.unionSignatures = ts.concatenate(left.unionSignatures || [left], [right]);
            return result;
        }
        function getUnionIndexInfo(types, kind) {
            var indexTypes = [];
            var isAnyReadonly = false;
            for (var _i = 0, types_3 = types; _i < types_3.length; _i++) {
                var type = types_3[_i];
                var indexInfo = getIndexInfoOfType(getApparentType(type), kind);
                if (!indexInfo) {
                    return undefined;
                }
                indexTypes.push(indexInfo.type);
                isAnyReadonly = isAnyReadonly || indexInfo.isReadonly;
            }
            return createIndexInfo(getUnionType(indexTypes, 2 /* Subtype */), isAnyReadonly);
        }
        function resolveUnionTypeMembers(type) {
            // The members and properties collections are empty for union types. To get all properties of a union
            // type use getPropertiesOfType (only the language service uses this).
            var callSignatures = getUnionSignatures(ts.map(type.types, function (t) { return t === globalFunctionType ? [unknownSignature] : getSignaturesOfType(t, 0 /* Call */); }));
            var constructSignatures = getUnionSignatures(ts.map(type.types, function (t) { return getSignaturesOfType(t, 1 /* Construct */); }));
            var stringIndexInfo = getUnionIndexInfo(type.types, 0 /* String */);
            var numberIndexInfo = getUnionIndexInfo(type.types, 1 /* Number */);
            setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function intersectTypes(type1, type2) {
            return !type1 ? type2 : !type2 ? type1 : getIntersectionType([type1, type2]);
        }
        function intersectIndexInfos(info1, info2) {
            return !info1 ? info2 : !info2 ? info1 : createIndexInfo(getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly);
        }
        function unionSpreadIndexInfos(info1, info2) {
            return info1 && info2 && createIndexInfo(getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
        }
        function findMixins(types) {
            var constructorTypeCount = ts.countWhere(types, function (t) { return getSignaturesOfType(t, 1 /* Construct */).length > 0; });
            var mixinFlags = ts.map(types, isMixinConstructorType);
            if (constructorTypeCount > 0 && constructorTypeCount === ts.countWhere(mixinFlags, function (b) { return b; })) {
                var firstMixinIndex = mixinFlags.indexOf(/*searchElement*/ true);
                mixinFlags[firstMixinIndex] = false;
            }
            return mixinFlags;
        }
        function includeMixinType(type, types, mixinFlags, index) {
            var mixedTypes = [];
            for (var i = 0; i < types.length; i++) {
                if (i === index) {
                    mixedTypes.push(type);
                }
                else if (mixinFlags[i]) {
                    mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], 1 /* Construct */)[0]));
                }
            }
            return getIntersectionType(mixedTypes);
        }
        function resolveIntersectionTypeMembers(type) {
            // The members and properties collections are empty for intersection types. To get all properties of an
            // intersection type use getPropertiesOfType (only the language service uses this).
            var callSignatures;
            var constructSignatures;
            var stringIndexInfo;
            var numberIndexInfo;
            var types = type.types;
            var mixinFlags = findMixins(types);
            var mixinCount = ts.countWhere(mixinFlags, function (b) { return b; });
            var _loop_10 = function (i) {
                var t = type.types[i];
                // When an intersection type contains mixin constructor types, the construct signatures from
                // those types are discarded and their return types are mixed into the return types of all
                // other construct signatures in the intersection type. For example, the intersection type
                // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature
                // 'new(s: string) => A & B'.
                if (!mixinFlags[i]) {
                    var signatures = getSignaturesOfType(t, 1 /* Construct */);
                    if (signatures.length && mixinCount > 0) {
                        signatures = ts.map(signatures, function (s) {
                            var clone = cloneSignature(s);
                            clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, mixinFlags, i);
                            return clone;
                        });
                    }
                    constructSignatures = appendSignatures(constructSignatures, signatures);
                }
                callSignatures = appendSignatures(callSignatures, getSignaturesOfType(t, 0 /* Call */));
                stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, 0 /* String */));
                numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, 1 /* Number */));
            };
            for (var i = 0; i < types.length; i++) {
                _loop_10(i);
            }
            setStructuredTypeMembers(type, emptySymbols, callSignatures || ts.emptyArray, constructSignatures || ts.emptyArray, stringIndexInfo, numberIndexInfo);
        }
        function appendSignatures(signatures, newSignatures) {
            var _loop_11 = function (sig) {
                if (!signatures || ts.every(signatures, function (s) { return !compareSignaturesIdentical(s, sig, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, compareTypesIdentical); })) {
                    signatures = ts.append(signatures, sig);
                }
            };
            for (var _i = 0, newSignatures_1 = newSignatures; _i < newSignatures_1.length; _i++) {
                var sig = newSignatures_1[_i];
                _loop_11(sig);
            }
            return signatures;
        }
        /**
         * Converts an AnonymousType to a ResolvedType.
         */
        function resolveAnonymousTypeMembers(type) {
            var symbol = getMergedSymbol(type.symbol);
            if (type.target) {
                setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
                var members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
                var callSignatures = instantiateSignatures(getSignaturesOfType(type.target, 0 /* Call */), type.mapper);
                var constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, 1 /* Construct */), type.mapper);
                var stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 0 /* String */), type.mapper);
                var numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 1 /* Number */), type.mapper);
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else if (symbol.flags & 2048 /* TypeLiteral */) {
                setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
                var members = getMembersOfSymbol(symbol);
                var callSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */));
                var constructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */));
                var stringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                var numberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else {
                // Combinations of function, class, enum and module
                var members = emptySymbols;
                var stringIndexInfo = void 0;
                if (symbol.exports) {
                    members = getExportsOfSymbol(symbol);
                    if (symbol === globalThisSymbol) {
                        var varsOnly_1 = ts.createMap();
                        members.forEach(function (p) {
                            if (!(p.flags & 418 /* BlockScoped */)) {
                                varsOnly_1.set(p.escapedName, p);
                            }
                        });
                        members = varsOnly_1;
                    }
                }
                setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, undefined, undefined);
                if (symbol.flags & 32 /* Class */) {
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    var baseConstructorType = getBaseConstructorTypeOfClass(classType);
                    if (baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */ | 8650752 /* TypeVariable */)) {
                        members = ts.createSymbolTable(getNamedMembers(members));
                        addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
                    }
                    else if (baseConstructorType === anyType) {
                        stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
                    }
                }
                var numberIndexInfo = symbol.flags & 384 /* Enum */ && (getDeclaredTypeOfSymbol(symbol).flags & 32 /* Enum */ ||
                    ts.some(type.properties, function (prop) { return !!(getTypeOfSymbol(prop).flags & 296 /* NumberLike */); })) ? enumNumberIndexInfo : undefined;
                setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
                // We resolve the members before computing the signatures because a signature may use
                // typeof with a qualified name expression that circularly references the type we are
                // in the process of resolving (see issue #6072). The temporarily empty signature list
                // will never be observed because a qualified name can't reference signatures.
                if (symbol.flags & (16 /* Function */ | 8192 /* Method */)) {
                    type.callSignatures = getSignaturesOfSymbol(symbol);
                }
                // And likewise for construct signatures for classes
                if (symbol.flags & 32 /* Class */) {
                    var classType_1 = getDeclaredTypeOfClassOrInterface(symbol);
                    var constructSignatures = symbol.members ? getSignaturesOfSymbol(symbol.members.get("__constructor" /* Constructor */)) : ts.emptyArray;
                    if (symbol.flags & 16 /* Function */) {
                        constructSignatures = ts.addRange(constructSignatures.slice(), ts.mapDefined(type.callSignatures, function (sig) { return isJSConstructor(sig.declaration) ?
                            createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType_1, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & 3 /* PropagatingFlags */) :
                            undefined; }));
                    }
                    if (!constructSignatures.length) {
                        constructSignatures = getDefaultConstructSignatures(classType_1);
                    }
                    type.constructSignatures = constructSignatures;
                }
            }
        }
        function resolveReverseMappedTypeMembers(type) {
            var indexInfo = getIndexInfoOfType(type.source, 0 /* String */);
            var modifiers = getMappedTypeModifiers(type.mappedType);
            var readonlyMask = modifiers & 1 /* IncludeReadonly */ ? false : true;
            var optionalMask = modifiers & 4 /* IncludeOptional */ ? 0 : 16777216 /* Optional */;
            var stringIndexInfo = indexInfo && createIndexInfo(inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly);
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfType(type.source); _i < _a.length; _i++) {
                var prop = _a[_i];
                var checkFlags = 8192 /* ReverseMapped */ | (readonlyMask && isReadonlySymbol(prop) ? 8 /* Readonly */ : 0);
                var inferredProp = createSymbol(4 /* Property */ | prop.flags & optionalMask, prop.escapedName, checkFlags);
                inferredProp.declarations = prop.declarations;
                inferredProp.nameType = getSymbolLinks(prop).nameType;
                inferredProp.propertyType = getTypeOfSymbol(prop);
                inferredProp.mappedType = type.mappedType;
                inferredProp.constraintType = type.constraintType;
                members.set(prop.escapedName, inferredProp);
            }
            setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
        }
        // Return the lower bound of the key type in a mapped type. Intuitively, the lower
        // bound includes those keys that are known to always be present, for example because
        // because of constraints on type parameters (e.g. 'keyof T' for a constrained T).
        function getLowerBoundOfKeyType(type) {
            if (type.flags & (1 /* Any */ | 131068 /* Primitive */)) {
                return type;
            }
            if (type.flags & 4194304 /* Index */) {
                return getIndexType(getApparentType(type.type));
            }
            if (type.flags & 16777216 /* Conditional */) {
                if (type.root.isDistributive) {
                    var checkType = type.checkType;
                    var constraint = getLowerBoundOfKeyType(checkType);
                    if (constraint !== checkType) {
                        return getConditionalTypeInstantiation(type, prependTypeMapping(type.root.checkType, constraint, type.mapper));
                    }
                }
                return type;
            }
            if (type.flags & 1048576 /* Union */) {
                return getUnionType(ts.sameMap(type.types, getLowerBoundOfKeyType));
            }
            if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.sameMap(type.types, getLowerBoundOfKeyType));
            }
            return neverType;
        }
        /** Resolve the members of a mapped type { [P in K]: T } */
        function resolveMappedTypeMembers(type) {
            var members = ts.createSymbolTable();
            var stringIndexInfo;
            var numberIndexInfo;
            // Resolve upfront such that recursive references see an empty object type.
            setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
            // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
            // and T as the template type.
            var typeParameter = getTypeParameterFromMappedType(type);
            var constraintType = getConstraintTypeFromMappedType(type);
            var templateType = getTemplateTypeFromMappedType(type.target || type);
            var modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
            var templateModifiers = getMappedTypeModifiers(type);
            var include = keyofStringsOnly ? 128 /* StringLiteral */ : 8576 /* StringOrNumberLiteralOrUnique */;
            if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                // We have a { [P in keyof T]: X }
                for (var _i = 0, _a = getPropertiesOfType(modifiersType); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    addMemberForKeyType(getLiteralTypeFromProperty(prop, include));
                }
                if (modifiersType.flags & 1 /* Any */ || getIndexInfoOfType(modifiersType, 0 /* String */)) {
                    addMemberForKeyType(stringType);
                }
                if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, 1 /* Number */)) {
                    addMemberForKeyType(numberType);
                }
            }
            else {
                forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType);
            }
            setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
            function addMemberForKeyType(t) {
                // Create a mapper from T to the current iteration type constituent. Then, if the
                // mapped type is itself an instantiated type, combine the iteration mapper with the
                // instantiation mapper.
                var templateMapper = appendTypeMapping(type.mapper, typeParameter, t);
                // If the current iteration type constituent is a string literal type, create a property.
                // Otherwise, for type string create a string index signature.
                if (isTypeUsableAsPropertyName(t)) {
                    var propName = getPropertyNameFromType(t);
                    var modifiersProp = getPropertyOfType(modifiersType, propName);
                    var isOptional = !!(templateModifiers & 4 /* IncludeOptional */ ||
                        !(templateModifiers & 8 /* ExcludeOptional */) && modifiersProp && modifiersProp.flags & 16777216 /* Optional */);
                    var isReadonly = !!(templateModifiers & 1 /* IncludeReadonly */ ||
                        !(templateModifiers & 2 /* ExcludeReadonly */) && modifiersProp && isReadonlySymbol(modifiersProp));
                    var stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & 16777216 /* Optional */;
                    var prop = createSymbol(4 /* Property */ | (isOptional ? 16777216 /* Optional */ : 0), propName, 262144 /* Mapped */ | (isReadonly ? 8 /* Readonly */ : 0) | (stripOptional ? 524288 /* StripOptional */ : 0));
                    prop.mappedType = type;
                    prop.mapper = templateMapper;
                    if (modifiersProp) {
                        prop.syntheticOrigin = modifiersProp;
                        prop.declarations = modifiersProp.declarations;
                    }
                    prop.nameType = t;
                    members.set(propName, prop);
                }
                else if (t.flags & (1 /* Any */ | 4 /* String */ | 8 /* Number */ | 32 /* Enum */)) {
                    var propType = instantiateType(templateType, templateMapper);
                    if (t.flags & (1 /* Any */ | 4 /* String */)) {
                        stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & 1 /* IncludeReadonly */));
                    }
                    else {
                        numberIndexInfo = createIndexInfo(numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType, !!(templateModifiers & 1 /* IncludeReadonly */));
                    }
                }
            }
        }
        function getTypeOfMappedSymbol(symbol) {
            if (!symbol.type) {
                if (!pushTypeResolution(symbol, 0 /* Type */)) {
                    return errorType;
                }
                var templateType = getTemplateTypeFromMappedType(symbol.mappedType.target || symbol.mappedType);
                var propType = instantiateType(templateType, symbol.mapper);
                // When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the
                // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks
                // mode, if the underlying property is optional we remove 'undefined' from the type.
                var type = strictNullChecks && symbol.flags & 16777216 /* Optional */ && !maybeTypeOfKind(propType, 32768 /* Undefined */ | 16384 /* Void */) ? getOptionalType(propType) :
                    symbol.checkFlags & 524288 /* StripOptional */ ? getTypeWithFacts(propType, 524288 /* NEUndefined */) :
                        propType;
                if (!popTypeResolution()) {
                    error(currentNode, ts.Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(symbol.mappedType));
                    type = errorType;
                }
                symbol.type = type;
                symbol.mapper = undefined;
            }
            return symbol.type;
        }
        function getTypeParameterFromMappedType(type) {
            return type.typeParameter ||
                (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter)));
        }
        function getConstraintTypeFromMappedType(type) {
            return type.constraintType ||
                (type.constraintType = getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)) || errorType);
        }
        function getTemplateTypeFromMappedType(type) {
            return type.templateType ||
                (type.templateType = type.declaration.type ?
                    instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!(getMappedTypeModifiers(type) & 4 /* IncludeOptional */)), type.mapper) :
                    errorType);
        }
        function getConstraintDeclarationForMappedType(type) {
            return ts.getEffectiveConstraintOfTypeParameter(type.declaration.typeParameter);
        }
        function isMappedTypeWithKeyofConstraintDeclaration(type) {
            var constraintDeclaration = getConstraintDeclarationForMappedType(type); // TODO: GH#18217
            return constraintDeclaration.kind === 184 /* TypeOperator */ &&
                constraintDeclaration.operator === 134 /* KeyOfKeyword */;
        }
        function getModifiersTypeFromMappedType(type) {
            if (!type.modifiersType) {
                if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                    // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check
                    // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves
                    // 'keyof T' to a literal union type and we can't recover T from that type.
                    type.modifiersType = instantiateType(getTypeFromTypeNode(getConstraintDeclarationForMappedType(type).type), type.mapper);
                }
                else {
                    // Otherwise, get the declared constraint type, and if the constraint type is a type parameter,
                    // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T',
                    // the modifiers type is T. Otherwise, the modifiers type is unknown.
                    var declaredType = getTypeFromMappedTypeNode(type.declaration);
                    var constraint = getConstraintTypeFromMappedType(declaredType);
                    var extendedConstraint = constraint && constraint.flags & 262144 /* TypeParameter */ ? getConstraintOfTypeParameter(constraint) : constraint;
                    type.modifiersType = extendedConstraint && extendedConstraint.flags & 4194304 /* Index */ ? instantiateType(extendedConstraint.type, type.mapper) : unknownType;
                }
            }
            return type.modifiersType;
        }
        function getMappedTypeModifiers(type) {
            var declaration = type.declaration;
            return (declaration.readonlyToken ? declaration.readonlyToken.kind === 40 /* MinusToken */ ? 2 /* ExcludeReadonly */ : 1 /* IncludeReadonly */ : 0) |
                (declaration.questionToken ? declaration.questionToken.kind === 40 /* MinusToken */ ? 8 /* ExcludeOptional */ : 4 /* IncludeOptional */ : 0);
        }
        function getMappedTypeOptionality(type) {
            var modifiers = getMappedTypeModifiers(type);
            return modifiers & 8 /* ExcludeOptional */ ? -1 : modifiers & 4 /* IncludeOptional */ ? 1 : 0;
        }
        function getCombinedMappedTypeOptionality(type) {
            var optionality = getMappedTypeOptionality(type);
            var modifiersType = getModifiersTypeFromMappedType(type);
            return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(modifiersType) : 0);
        }
        function isPartialMappedType(type) {
            return !!(ts.getObjectFlags(type) & 32 /* Mapped */ && getMappedTypeModifiers(type) & 4 /* IncludeOptional */);
        }
        function isGenericMappedType(type) {
            return !!(ts.getObjectFlags(type) & 32 /* Mapped */) && isGenericIndexType(getConstraintTypeFromMappedType(type));
        }
        function resolveStructuredTypeMembers(type) {
            if (!type.members) {
                if (type.flags & 524288 /* Object */) {
                    if (type.objectFlags & 4 /* Reference */) {
                        resolveTypeReferenceMembers(type);
                    }
                    else if (type.objectFlags & 3 /* ClassOrInterface */) {
                        resolveClassOrInterfaceMembers(type);
                    }
                    else if (type.objectFlags & 2048 /* ReverseMapped */) {
                        resolveReverseMappedTypeMembers(type);
                    }
                    else if (type.objectFlags & 16 /* Anonymous */) {
                        resolveAnonymousTypeMembers(type);
                    }
                    else if (type.objectFlags & 32 /* Mapped */) {
                        resolveMappedTypeMembers(type);
                    }
                }
                else if (type.flags & 1048576 /* Union */) {
                    resolveUnionTypeMembers(type);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    resolveIntersectionTypeMembers(type);
                }
            }
            return type;
        }
        /** Return properties of an object type or an empty array for other types */
        function getPropertiesOfObjectType(type) {
            if (type.flags & 524288 /* Object */) {
                return resolveStructuredTypeMembers(type).properties;
            }
            return ts.emptyArray;
        }
        /** If the given type is an object type and that type has a property by the given name,
         * return the symbol for that property. Otherwise return undefined.
         */
        function getPropertyOfObjectType(type, name) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                var symbol = resolved.members.get(name);
                if (symbol && symbolIsValue(symbol)) {
                    return symbol;
                }
            }
        }
        function getPropertiesOfUnionOrIntersectionType(type) {
            if (!type.resolvedProperties) {
                var members = ts.createSymbolTable();
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var current = _a[_i];
                    for (var _b = 0, _c = getPropertiesOfType(current); _b < _c.length; _b++) {
                        var prop = _c[_b];
                        if (!members.has(prop.escapedName)) {
                            var combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.escapedName);
                            if (combinedProp) {
                                members.set(prop.escapedName, combinedProp);
                            }
                        }
                    }
                    // The properties of a union type are those that are present in all constituent types, so
                    // we only need to check the properties of the first type without index signature
                    if (type.flags & 1048576 /* Union */ && !getIndexInfoOfType(current, 0 /* String */) && !getIndexInfoOfType(current, 1 /* Number */)) {
                        break;
                    }
                }
                type.resolvedProperties = getNamedMembers(members);
            }
            return type.resolvedProperties;
        }
        function getPropertiesOfType(type) {
            type = getReducedApparentType(type);
            return type.flags & 3145728 /* UnionOrIntersection */ ?
                getPropertiesOfUnionOrIntersectionType(type) :
                getPropertiesOfObjectType(type);
        }
        function isTypeInvalidDueToUnionDiscriminant(contextualType, obj) {
            var list = obj.properties;
            return list.some(function (property) {
                var nameType = property.name && getLiteralTypeFromPropertyName(property.name);
                var name = nameType && isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined;
                var expected = name === undefined ? undefined : getTypeOfPropertyOfType(contextualType, name);
                return !!expected && isLiteralType(expected) && !isTypeAssignableTo(getTypeOfNode(property), expected);
            });
        }
        function getAllPossiblePropertiesOfTypes(types) {
            var unionType = getUnionType(types);
            if (!(unionType.flags & 1048576 /* Union */)) {
                return getAugmentedPropertiesOfType(unionType);
            }
            var props = ts.createSymbolTable();
            for (var _i = 0, types_4 = types; _i < types_4.length; _i++) {
                var memberType = types_4[_i];
                for (var _a = 0, _b = getAugmentedPropertiesOfType(memberType); _a < _b.length; _a++) {
                    var escapedName = _b[_a].escapedName;
                    if (!props.has(escapedName)) {
                        var prop = createUnionOrIntersectionProperty(unionType, escapedName);
                        // May be undefined if the property is private
                        if (prop)
                            props.set(escapedName, prop);
                    }
                }
            }
            return ts.arrayFrom(props.values());
        }
        function getConstraintOfType(type) {
            return type.flags & 262144 /* TypeParameter */ ? getConstraintOfTypeParameter(type) :
                type.flags & 8388608 /* IndexedAccess */ ? getConstraintOfIndexedAccess(type) :
                    type.flags & 16777216 /* Conditional */ ? getConstraintOfConditionalType(type) :
                        getBaseConstraintOfType(type);
        }
        function getConstraintOfTypeParameter(typeParameter) {
            return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
        }
        function getConstraintOfIndexedAccess(type) {
            return hasNonCircularBaseConstraint(type) ? getConstraintFromIndexedAccess(type) : undefined;
        }
        function getSimplifiedTypeOrConstraint(type) {
            var simplified = getSimplifiedType(type, /*writing*/ false);
            return simplified !== type ? simplified : getConstraintOfType(type);
        }
        function getConstraintFromIndexedAccess(type) {
            var indexConstraint = getSimplifiedTypeOrConstraint(type.indexType);
            if (indexConstraint && indexConstraint !== type.indexType) {
                var indexedAccess = getIndexedAccessTypeOrUndefined(type.objectType, indexConstraint);
                if (indexedAccess) {
                    return indexedAccess;
                }
            }
            var objectConstraint = getSimplifiedTypeOrConstraint(type.objectType);
            if (objectConstraint && objectConstraint !== type.objectType) {
                return getIndexedAccessTypeOrUndefined(objectConstraint, type.indexType);
            }
            return undefined;
        }
        function getDefaultConstraintOfConditionalType(type) {
            if (!type.resolvedDefaultConstraint) {
                // An `any` branch of a conditional type would normally be viral - specifically, without special handling here,
                // a conditional type with a single branch of type `any` would be assignable to anything, since it's constraint would simplify to
                // just `any`. This result is _usually_ unwanted - so instead here we elide an `any` branch from the constraint type,
                // in effect treating `any` like `never` rather than `unknown` in this location.
                var trueConstraint = getInferredTrueTypeFromConditionalType(type);
                var falseConstraint = getFalseTypeFromConditionalType(type);
                type.resolvedDefaultConstraint = isTypeAny(trueConstraint) ? falseConstraint : isTypeAny(falseConstraint) ? trueConstraint : getUnionType([trueConstraint, falseConstraint]);
            }
            return type.resolvedDefaultConstraint;
        }
        function getConstraintOfDistributiveConditionalType(type) {
            // Check if we have a conditional type of the form 'T extends U ? X : Y', where T is a constrained
            // type parameter. If so, create an instantiation of the conditional type where T is replaced
            // with its constraint. We do this because if the constraint is a union type it will be distributed
            // over the conditional type and possibly reduced. For example, 'T extends undefined ? never : T'
            // removes 'undefined' from T.
            // We skip returning a distributive constraint for a restrictive instantiation of a conditional type
            // as the constraint for all type params (check type included) have been replace with `unknown`, which
            // is going to produce even more false positive/negative results than the distribute constraint already does.
            // Please note: the distributive constraint is a kludge for emulating what a negated type could to do filter
            // a union - once negated types exist and are applied to the conditional false branch, this "constraint"
            // likely doesn't need to exist.
            if (type.root.isDistributive && type.restrictiveInstantiation !== type) {
                var simplified = getSimplifiedType(type.checkType, /*writing*/ false);
                var constraint = simplified === type.checkType ? getConstraintOfType(simplified) : simplified;
                if (constraint && constraint !== type.checkType) {
                    var instantiated = getConditionalTypeInstantiation(type, prependTypeMapping(type.root.checkType, constraint, type.mapper));
                    if (!(instantiated.flags & 131072 /* Never */)) {
                        return instantiated;
                    }
                }
            }
            return undefined;
        }
        function getConstraintFromConditionalType(type) {
            return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type);
        }
        function getConstraintOfConditionalType(type) {
            return hasNonCircularBaseConstraint(type) ? getConstraintFromConditionalType(type) : undefined;
        }
        function getEffectiveConstraintOfIntersection(types, targetIsUnion) {
            var constraints;
            var hasDisjointDomainType = false;
            for (var _i = 0, types_5 = types; _i < types_5.length; _i++) {
                var t = types_5[_i];
                if (t.flags & 63176704 /* Instantiable */) {
                    // We keep following constraints as long as we have an instantiable type that is known
                    // not to be circular or infinite (hence we stop on index access types).
                    var constraint = getConstraintOfType(t);
                    while (constraint && constraint.flags & (262144 /* TypeParameter */ | 4194304 /* Index */ | 16777216 /* Conditional */)) {
                        constraint = getConstraintOfType(constraint);
                    }
                    if (constraint) {
                        constraints = ts.append(constraints, constraint);
                        if (targetIsUnion) {
                            constraints = ts.append(constraints, t);
                        }
                    }
                }
                else if (t.flags & 67238908 /* DisjointDomains */) {
                    hasDisjointDomainType = true;
                }
            }
            // If the target is a union type or if we are intersecting with types belonging to one of the
            // disjoint domains, we may end up producing a constraint that hasn't been examined before.
            if (constraints && (targetIsUnion || hasDisjointDomainType)) {
                if (hasDisjointDomainType) {
                    // We add any types belong to one of the disjoint domains because they might cause the final
                    // intersection operation to reduce the union constraints.
                    for (var _a = 0, types_6 = types; _a < types_6.length; _a++) {
                        var t = types_6[_a];
                        if (t.flags & 67238908 /* DisjointDomains */) {
                            constraints = ts.append(constraints, t);
                        }
                    }
                }
                return getIntersectionType(constraints);
            }
            return undefined;
        }
        function getBaseConstraintOfType(type) {
            if (type.flags & (58982400 /* InstantiableNonPrimitive */ | 3145728 /* UnionOrIntersection */)) {
                var constraint = getResolvedBaseConstraint(type);
                return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
            }
            return type.flags & 4194304 /* Index */ ? keyofConstraintType : undefined;
        }
        /**
         * This is similar to `getBaseConstraintOfType` except it returns the input type if there's no base constraint, instead of `undefined`
         * It also doesn't map indexes to `string`, as where this is used this would be unneeded (and likely undesirable)
         */
        function getBaseConstraintOrType(type) {
            return getBaseConstraintOfType(type) || type;
        }
        function hasNonCircularBaseConstraint(type) {
            return getResolvedBaseConstraint(type) !== circularConstraintType;
        }
        /**
         * Return the resolved base constraint of a type variable. The noConstraintType singleton is returned if the
         * type variable has no constraint, and the circularConstraintType singleton is returned if the constraint
         * circularly references the type variable.
         */
        function getResolvedBaseConstraint(type) {
            var nonTerminating = false;
            return type.resolvedBaseConstraint ||
                (type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type));
            function getImmediateBaseConstraint(t) {
                if (!t.immediateBaseConstraint) {
                    if (!pushTypeResolution(t, 4 /* ImmediateBaseConstraint */)) {
                        return circularConstraintType;
                    }
                    if (constraintDepth >= 50) {
                        // We have reached 50 recursive invocations of getImmediateBaseConstraint and there is a
                        // very high likelihood we're dealing with an infinite generic type that perpetually generates
                        // new type identities as we descend into it. We stop the recursion here and mark this type
                        // and the outer types as having circular constraints.
                        error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
                        nonTerminating = true;
                        return t.immediateBaseConstraint = noConstraintType;
                    }
                    constraintDepth++;
                    var result = computeBaseConstraint(getSimplifiedType(t, /*writing*/ false));
                    constraintDepth--;
                    if (!popTypeResolution()) {
                        if (t.flags & 262144 /* TypeParameter */) {
                            var errorNode = getConstraintDeclaration(t);
                            if (errorNode) {
                                var diagnostic = error(errorNode, ts.Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(t));
                                if (currentNode && !ts.isNodeDescendantOf(errorNode, currentNode) && !ts.isNodeDescendantOf(currentNode, errorNode)) {
                                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(currentNode, ts.Diagnostics.Circularity_originates_in_type_at_this_location));
                                }
                            }
                        }
                        result = circularConstraintType;
                    }
                    if (nonTerminating) {
                        result = circularConstraintType;
                    }
                    t.immediateBaseConstraint = result || noConstraintType;
                }
                return t.immediateBaseConstraint;
            }
            function getBaseConstraint(t) {
                var c = getImmediateBaseConstraint(t);
                return c !== noConstraintType && c !== circularConstraintType ? c : undefined;
            }
            function computeBaseConstraint(t) {
                if (t.flags & 262144 /* TypeParameter */) {
                    var constraint = getConstraintFromTypeParameter(t);
                    return t.isThisType || !constraint ?
                        constraint :
                        getBaseConstraint(constraint);
                }
                if (t.flags & 3145728 /* UnionOrIntersection */) {
                    var types = t.types;
                    var baseTypes = [];
                    for (var _i = 0, types_7 = types; _i < types_7.length; _i++) {
                        var type_2 = types_7[_i];
                        var baseType = getBaseConstraint(type_2);
                        if (baseType) {
                            baseTypes.push(baseType);
                        }
                    }
                    return t.flags & 1048576 /* Union */ && baseTypes.length === types.length ? getUnionType(baseTypes) :
                        t.flags & 2097152 /* Intersection */ && baseTypes.length ? getIntersectionType(baseTypes) :
                            undefined;
                }
                if (t.flags & 4194304 /* Index */) {
                    return keyofConstraintType;
                }
                if (t.flags & 8388608 /* IndexedAccess */) {
                    var baseObjectType = getBaseConstraint(t.objectType);
                    var baseIndexType = getBaseConstraint(t.indexType);
                    var baseIndexedAccess = baseObjectType && baseIndexType && getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType);
                    return baseIndexedAccess && getBaseConstraint(baseIndexedAccess);
                }
                if (t.flags & 16777216 /* Conditional */) {
                    var constraint = getConstraintFromConditionalType(t);
                    constraintDepth++; // Penalize repeating conditional types (this captures the recursion within getConstraintFromConditionalType and carries it forward)
                    var result = constraint && getBaseConstraint(constraint);
                    constraintDepth--;
                    return result;
                }
                if (t.flags & 33554432 /* Substitution */) {
                    return getBaseConstraint(t.substitute);
                }
                return t;
            }
        }
        function getApparentTypeOfIntersectionType(type) {
            return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type, /*apparentType*/ true));
        }
        function getResolvedTypeParameterDefault(typeParameter) {
            if (!typeParameter.default) {
                if (typeParameter.target) {
                    var targetDefault = getResolvedTypeParameterDefault(typeParameter.target);
                    typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType;
                }
                else {
                    // To block recursion, set the initial value to the resolvingDefaultType.
                    typeParameter.default = resolvingDefaultType;
                    var defaultDeclaration = typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; });
                    var defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType;
                    if (typeParameter.default === resolvingDefaultType) {
                        // If we have not been called recursively, set the correct default type.
                        typeParameter.default = defaultType;
                    }
                }
            }
            else if (typeParameter.default === resolvingDefaultType) {
                // If we are called recursively for this type parameter, mark the default as circular.
                typeParameter.default = circularConstraintType;
            }
            return typeParameter.default;
        }
        /**
         * Gets the default type for a type parameter.
         *
         * If the type parameter is the result of an instantiation, this gets the instantiated
         * default type of its target. If the type parameter has no default type or the default is
         * circular, `undefined` is returned.
         */
        function getDefaultFromTypeParameter(typeParameter) {
            var defaultType = getResolvedTypeParameterDefault(typeParameter);
            return defaultType !== noConstraintType && defaultType !== circularConstraintType ? defaultType : undefined;
        }
        function hasNonCircularTypeParameterDefault(typeParameter) {
            return getResolvedTypeParameterDefault(typeParameter) !== circularConstraintType;
        }
        /**
         * Indicates whether the declaration of a typeParameter has a default type.
         */
        function hasTypeParameterDefault(typeParameter) {
            return !!(typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; }));
        }
        function getApparentTypeOfMappedType(type) {
            return type.resolvedApparentType || (type.resolvedApparentType = getResolvedApparentTypeOfMappedType(type));
        }
        function getResolvedApparentTypeOfMappedType(type) {
            var typeVariable = getHomomorphicTypeVariable(type);
            if (typeVariable) {
                var constraint = getConstraintOfTypeParameter(typeVariable);
                if (constraint && (isArrayType(constraint) || isTupleType(constraint))) {
                    return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
                }
            }
            return type;
        }
        /**
         * For a type parameter, return the base constraint of the type parameter. For the string, number,
         * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
         * type itself.
         */
        function getApparentType(type) {
            var t = type.flags & 63176704 /* Instantiable */ ? getBaseConstraintOfType(type) || unknownType : type;
            return ts.getObjectFlags(t) & 32 /* Mapped */ ? getApparentTypeOfMappedType(t) :
                t.flags & 2097152 /* Intersection */ ? getApparentTypeOfIntersectionType(t) :
                    t.flags & 132 /* StringLike */ ? globalStringType :
                        t.flags & 296 /* NumberLike */ ? globalNumberType :
                            t.flags & 2112 /* BigIntLike */ ? getGlobalBigIntType(/*reportErrors*/ languageVersion >= 7 /* ES2020 */) :
                                t.flags & 528 /* BooleanLike */ ? globalBooleanType :
                                    t.flags & 12288 /* ESSymbolLike */ ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= 2 /* ES2015 */) :
                                        t.flags & 67108864 /* NonPrimitive */ ? emptyObjectType :
                                            t.flags & 4194304 /* Index */ ? keyofConstraintType :
                                                t.flags & 2 /* Unknown */ && !strictNullChecks ? emptyObjectType :
                                                    t;
        }
        function getReducedApparentType(type) {
            // Since getApparentType may return a non-reduced union or intersection type, we need to perform
            // type reduction both before and after obtaining the apparent type. For example, given a type parameter
            // 'T extends A | B', the type 'T & X' becomes 'A & X | B & X' after obtaining the apparent type, and
            // that type may need futher reduction to remove empty intersections.
            return getReducedType(getApparentType(getReducedType(type)));
        }
        function createUnionOrIntersectionProperty(containingType, name) {
            var singleProp;
            var propSet;
            var indexTypes;
            var isUnion = containingType.flags & 1048576 /* Union */;
            // Flags we want to propagate to the result if they exist in all source symbols
            var optionalFlag = isUnion ? 0 /* None */ : 16777216 /* Optional */;
            var syntheticFlag = 4 /* SyntheticMethod */;
            var checkFlags = 0;
            for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) {
                var current = _a[_i];
                var type = getApparentType(current);
                if (!(type === errorType || type.flags & 131072 /* Never */)) {
                    var prop = getPropertyOfType(type, name);
                    var modifiers = prop ? ts.getDeclarationModifierFlagsFromSymbol(prop) : 0;
                    if (prop) {
                        if (isUnion) {
                            optionalFlag |= (prop.flags & 16777216 /* Optional */);
                        }
                        else {
                            optionalFlag &= prop.flags;
                        }
                        if (!singleProp) {
                            singleProp = prop;
                        }
                        else if (prop !== singleProp) {
                            if (!propSet) {
                                propSet = ts.createMap();
                                propSet.set("" + getSymbolId(singleProp), singleProp);
                            }
                            var id = "" + getSymbolId(prop);
                            if (!propSet.has(id)) {
                                propSet.set(id, prop);
                            }
                        }
                        checkFlags |= (isReadonlySymbol(prop) ? 8 /* Readonly */ : 0) |
                            (!(modifiers & 24 /* NonPublicAccessibilityModifier */) ? 256 /* ContainsPublic */ : 0) |
                            (modifiers & 16 /* Protected */ ? 512 /* ContainsProtected */ : 0) |
                            (modifiers & 8 /* Private */ ? 1024 /* ContainsPrivate */ : 0) |
                            (modifiers & 32 /* Static */ ? 2048 /* ContainsStatic */ : 0);
                        if (!isPrototypeProperty(prop)) {
                            syntheticFlag = 2 /* SyntheticProperty */;
                        }
                    }
                    else if (isUnion) {
                        var indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, 1 /* Number */) || getIndexInfoOfType(type, 0 /* String */));
                        if (indexInfo) {
                            checkFlags |= 32 /* WritePartial */ | (indexInfo.isReadonly ? 8 /* Readonly */ : 0);
                            indexTypes = ts.append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type);
                        }
                        else if (isObjectLiteralType(type)) {
                            checkFlags |= 32 /* WritePartial */;
                            indexTypes = ts.append(indexTypes, undefinedType);
                        }
                        else {
                            checkFlags |= 16 /* ReadPartial */;
                        }
                    }
                }
            }
            if (!singleProp || isUnion && (propSet || checkFlags & 48 /* Partial */) && checkFlags & (1024 /* ContainsPrivate */ | 512 /* ContainsProtected */)) {
                // No property was found, or, in a union, a property has a private or protected declaration in one
                // constituent, but is missing or has a different declaration in another constituent.
                return undefined;
            }
            if (!propSet && !(checkFlags & 16 /* ReadPartial */) && !indexTypes) {
                return singleProp;
            }
            var props = propSet ? ts.arrayFrom(propSet.values()) : [singleProp];
            var declarations;
            var firstType;
            var nameType;
            var propTypes = [];
            var firstValueDeclaration;
            var hasNonUniformValueDeclaration = false;
            for (var _b = 0, props_1 = props; _b < props_1.length; _b++) {
                var prop = props_1[_b];
                if (!firstValueDeclaration) {
                    firstValueDeclaration = prop.valueDeclaration;
                }
                else if (prop.valueDeclaration && prop.valueDeclaration !== firstValueDeclaration) {
                    hasNonUniformValueDeclaration = true;
                }
                declarations = ts.addRange(declarations, prop.declarations);
                var type = getTypeOfSymbol(prop);
                if (!firstType) {
                    firstType = type;
                    nameType = getSymbolLinks(prop).nameType;
                }
                else if (type !== firstType) {
                    checkFlags |= 64 /* HasNonUniformType */;
                }
                if (isLiteralType(type)) {
                    checkFlags |= 128 /* HasLiteralType */;
                }
                if (type.flags & 131072 /* Never */) {
                    checkFlags |= 131072 /* HasNeverType */;
                }
                propTypes.push(type);
            }
            ts.addRange(propTypes, indexTypes);
            var result = createSymbol(4 /* Property */ | optionalFlag, name, syntheticFlag | checkFlags);
            result.containingType = containingType;
            if (!hasNonUniformValueDeclaration && firstValueDeclaration) {
                result.valueDeclaration = firstValueDeclaration;
                // Inherit information about parent type.
                if (firstValueDeclaration.symbol.parent) {
                    result.parent = firstValueDeclaration.symbol.parent;
                }
            }
            result.declarations = declarations;
            result.nameType = nameType;
            if (propTypes.length > 2) {
                // When `propTypes` has the potential to explode in size when normalized, defer normalization until absolutely needed
                result.checkFlags |= 65536 /* DeferredType */;
                result.deferralParent = containingType;
                result.deferralConstituents = propTypes;
            }
            else {
                result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
            }
            return result;
        }
        // Return the symbol for a given property in a union or intersection type, or undefined if the property
        // does not exist in any constituent type. Note that the returned property may only be present in some
        // constituents, in which case the isPartial flag is set when the containing type is union type. We need
        // these partial properties when identifying discriminant properties, but otherwise they are filtered out
        // and do not appear to be present in the union type.
        function getUnionOrIntersectionProperty(type, name) {
            var properties = type.propertyCache || (type.propertyCache = ts.createSymbolTable());
            var property = properties.get(name);
            if (!property) {
                property = createUnionOrIntersectionProperty(type, name);
                if (property) {
                    properties.set(name, property);
                }
            }
            return property;
        }
        function getPropertyOfUnionOrIntersectionType(type, name) {
            var property = getUnionOrIntersectionProperty(type, name);
            // We need to filter out partial properties in union types
            return property && !(ts.getCheckFlags(property) & 16 /* ReadPartial */) ? property : undefined;
        }
        /**
         * Return the reduced form of the given type. For a union type, it is a union of the normalized constituent types.
         * For an intersection of types containing one or more mututally exclusive discriminant properties, it is 'never'.
         * For all other types, it is simply the type itself. Discriminant properties are considered mutually exclusive when
         * no constituent property has type 'never', but the intersection of the constituent property types is 'never'.
         */
        function getReducedType(type) {
            if (type.flags & 1048576 /* Union */ && type.objectFlags & 268435456 /* ContainsIntersections */) {
                return type.resolvedReducedType || (type.resolvedReducedType = getReducedUnionType(type));
            }
            else if (type.flags & 2097152 /* Intersection */) {
                if (!(type.objectFlags & 268435456 /* IsNeverIntersectionComputed */)) {
                    type.objectFlags |= 268435456 /* IsNeverIntersectionComputed */ |
                        (ts.some(getPropertiesOfUnionOrIntersectionType(type), isNeverReducedProperty) ? 536870912 /* IsNeverIntersection */ : 0);
                }
                return type.objectFlags & 536870912 /* IsNeverIntersection */ ? neverType : type;
            }
            return type;
        }
        function getReducedUnionType(unionType) {
            var reducedTypes = ts.sameMap(unionType.types, getReducedType);
            if (reducedTypes === unionType.types) {
                return unionType;
            }
            var reduced = getUnionType(reducedTypes);
            if (reduced.flags & 1048576 /* Union */) {
                reduced.resolvedReducedType = reduced;
            }
            return reduced;
        }
        function isNeverReducedProperty(prop) {
            return isDiscriminantWithNeverType(prop) || isConflictingPrivateProperty(prop);
        }
        function isDiscriminantWithNeverType(prop) {
            // Return true for a synthetic non-optional property with non-uniform types, where at least one is
            // a literal type and none is never, that reduces to never.
            return !(prop.flags & 16777216 /* Optional */) &&
                (ts.getCheckFlags(prop) & (192 /* Discriminant */ | 131072 /* HasNeverType */)) === 192 /* Discriminant */ &&
                !!(getTypeOfSymbol(prop).flags & 131072 /* Never */);
        }
        function isConflictingPrivateProperty(prop) {
            // Return true for a synthetic property with multiple declarations, at least one of which is private.
            return !prop.valueDeclaration && !!(ts.getCheckFlags(prop) & 1024 /* ContainsPrivate */);
        }
        function elaborateNeverIntersection(errorInfo, type) {
            if (ts.getObjectFlags(type) & 536870912 /* IsNeverIntersection */) {
                var neverProp = ts.find(getPropertiesOfUnionOrIntersectionType(type), isDiscriminantWithNeverType);
                if (neverProp) {
                    return ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents, typeToString(type, /*enclosingDeclaration*/ undefined, 536870912 /* NoTypeReduction */), symbolToString(neverProp));
                }
                var privateProp = ts.find(getPropertiesOfUnionOrIntersectionType(type), isConflictingPrivateProperty);
                if (privateProp) {
                    return ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some, typeToString(type, /*enclosingDeclaration*/ undefined, 536870912 /* NoTypeReduction */), symbolToString(privateProp));
                }
            }
            return errorInfo;
        }
        /**
         * Return the symbol for the property with the given name in the given type. Creates synthetic union properties when
         * necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from
         * Object and Function as appropriate.
         *
         * @param type a type to look up property from
         * @param name a name of property to look up in a given type
         */
        function getPropertyOfType(type, name) {
            type = getReducedApparentType(type);
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                var symbol = resolved.members.get(name);
                if (symbol && symbolIsValue(symbol)) {
                    return symbol;
                }
                var functionType = resolved === anyFunctionType ? globalFunctionType :
                    resolved.callSignatures.length ? globalCallableFunctionType :
                        resolved.constructSignatures.length ? globalNewableFunctionType :
                            undefined;
                if (functionType) {
                    var symbol_1 = getPropertyOfObjectType(functionType, name);
                    if (symbol_1) {
                        return symbol_1;
                    }
                }
                return getPropertyOfObjectType(globalObjectType, name);
            }
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                return getPropertyOfUnionOrIntersectionType(type, name);
            }
            return undefined;
        }
        function getSignaturesOfStructuredType(type, kind) {
            if (type.flags & 3670016 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* Call */ ? resolved.callSignatures : resolved.constructSignatures;
            }
            return ts.emptyArray;
        }
        /**
         * Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and
         * maps primitive types and type parameters are to their apparent types.
         */
        function getSignaturesOfType(type, kind) {
            return getSignaturesOfStructuredType(getReducedApparentType(type), kind);
        }
        function getIndexInfoOfStructuredType(type, kind) {
            if (type.flags & 3670016 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* String */ ? resolved.stringIndexInfo : resolved.numberIndexInfo;
            }
        }
        function getIndexTypeOfStructuredType(type, kind) {
            var info = getIndexInfoOfStructuredType(type, kind);
            return info && info.type;
        }
        // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and
        // maps primitive types and type parameters are to their apparent types.
        function getIndexInfoOfType(type, kind) {
            return getIndexInfoOfStructuredType(getReducedApparentType(type), kind);
        }
        // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and
        // maps primitive types and type parameters are to their apparent types.
        function getIndexTypeOfType(type, kind) {
            return getIndexTypeOfStructuredType(getReducedApparentType(type), kind);
        }
        function getImplicitIndexTypeOfType(type, kind) {
            if (isObjectTypeWithInferableIndex(type)) {
                var propTypes = [];
                for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
                        propTypes.push(getTypeOfSymbol(prop));
                    }
                }
                if (kind === 0 /* String */) {
                    ts.append(propTypes, getIndexTypeOfType(type, 1 /* Number */));
                }
                if (propTypes.length) {
                    return getUnionType(propTypes);
                }
            }
            return undefined;
        }
        // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
        // type checking functions).
        function getTypeParametersFromDeclaration(declaration) {
            var result;
            for (var _i = 0, _a = ts.getEffectiveTypeParameterDeclarations(declaration); _i < _a.length; _i++) {
                var node = _a[_i];
                result = ts.appendIfUnique(result, getDeclaredTypeOfTypeParameter(node.symbol));
            }
            return result;
        }
        function symbolsToArray(symbols) {
            var result = [];
            symbols.forEach(function (symbol, id) {
                if (!isReservedMemberName(id)) {
                    result.push(symbol);
                }
            });
            return result;
        }
        function isJSDocOptionalParameter(node) {
            return ts.isInJSFile(node) && (
            // node.type should only be a JSDocOptionalType when node is a parameter of a JSDocFunctionType
            node.type && node.type.kind === 299 /* JSDocOptionalType */
                || ts.getJSDocParameterTags(node).some(function (_a) {
                    var isBracketed = _a.isBracketed, typeExpression = _a.typeExpression;
                    return isBracketed || !!typeExpression && typeExpression.type.kind === 299 /* JSDocOptionalType */;
                }));
        }
        function tryFindAmbientModule(moduleName, withAugmentations) {
            if (ts.isExternalModuleNameRelative(moduleName)) {
                return undefined;
            }
            var symbol = getSymbol(globals, '"' + moduleName + '"', 512 /* ValueModule */);
            // merged symbol is module declaration symbol combined with all augmentations
            return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol;
        }
        function isOptionalParameter(node) {
            if (ts.hasQuestionToken(node) || isOptionalJSDocParameterTag(node) || isJSDocOptionalParameter(node)) {
                return true;
            }
            if (node.initializer) {
                var signature = getSignatureFromDeclaration(node.parent);
                var parameterIndex = node.parent.parameters.indexOf(node);
                ts.Debug.assert(parameterIndex >= 0);
                return parameterIndex >= getMinArgumentCount(signature, /*strongArityForUntypedJS*/ true);
            }
            var iife = ts.getImmediatelyInvokedFunctionExpression(node.parent);
            if (iife) {
                return !node.type &&
                    !node.dotDotDotToken &&
                    node.parent.parameters.indexOf(node) >= iife.arguments.length;
            }
            return false;
        }
        function isOptionalJSDocParameterTag(node) {
            if (!ts.isJSDocParameterTag(node)) {
                return false;
            }
            var isBracketed = node.isBracketed, typeExpression = node.typeExpression;
            return isBracketed || !!typeExpression && typeExpression.type.kind === 299 /* JSDocOptionalType */;
        }
        function createTypePredicate(kind, parameterName, parameterIndex, type) {
            return { kind: kind, parameterName: parameterName, parameterIndex: parameterIndex, type: type };
        }
        /**
         * Gets the minimum number of type arguments needed to satisfy all non-optional type
         * parameters.
         */
        function getMinTypeArgumentCount(typeParameters) {
            var minTypeArgumentCount = 0;
            if (typeParameters) {
                for (var i = 0; i < typeParameters.length; i++) {
                    if (!hasTypeParameterDefault(typeParameters[i])) {
                        minTypeArgumentCount = i + 1;
                    }
                }
            }
            return minTypeArgumentCount;
        }
        function fillMissingTypeArguments(typeArguments, typeParameters, minTypeArgumentCount, isJavaScriptImplicitAny) {
            var numTypeParameters = ts.length(typeParameters);
            if (!numTypeParameters) {
                return [];
            }
            var numTypeArguments = ts.length(typeArguments);
            if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
                var result = typeArguments ? typeArguments.slice() : [];
                // Map invalid forward references in default types to the error type
                for (var i = numTypeArguments; i < numTypeParameters; i++) {
                    result[i] = errorType;
                }
                var baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
                for (var i = numTypeArguments; i < numTypeParameters; i++) {
                    var defaultType = getDefaultFromTypeParameter(typeParameters[i]);
                    if (isJavaScriptImplicitAny && defaultType && (isTypeIdenticalTo(defaultType, unknownType) || isTypeIdenticalTo(defaultType, emptyObjectType))) {
                        defaultType = anyType;
                    }
                    result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters, result)) : baseDefaultType;
                }
                result.length = typeParameters.length;
                return result;
            }
            return typeArguments && typeArguments.slice();
        }
        function getSignatureFromDeclaration(declaration) {
            var links = getNodeLinks(declaration);
            if (!links.resolvedSignature) {
                var parameters = [];
                var flags = 0 /* None */;
                var minArgumentCount = 0;
                var thisParameter = void 0;
                var hasThisParameter = false;
                var iife = ts.getImmediatelyInvokedFunctionExpression(declaration);
                var isJSConstructSignature = ts.isJSDocConstructSignature(declaration);
                var isUntypedSignatureInJSFile = !iife &&
                    ts.isInJSFile(declaration) &&
                    ts.isValueSignatureDeclaration(declaration) &&
                    !ts.hasJSDocParameterTags(declaration) &&
                    !ts.getJSDocType(declaration);
                if (isUntypedSignatureInJSFile) {
                    flags |= 16 /* IsUntypedSignatureInJSFile */;
                }
                // If this is a JSDoc construct signature, then skip the first parameter in the
                // parameter list.  The first parameter represents the return type of the construct
                // signature.
                for (var i = isJSConstructSignature ? 1 : 0; i < declaration.parameters.length; i++) {
                    var param = declaration.parameters[i];
                    var paramSymbol = param.symbol;
                    var type = ts.isJSDocParameterTag(param) ? (param.typeExpression && param.typeExpression.type) : param.type;
                    // Include parameter symbol instead of property symbol in the signature
                    if (paramSymbol && !!(paramSymbol.flags & 4 /* Property */) && !ts.isBindingPattern(param.name)) {
                        var resolvedSymbol = resolveName(param, paramSymbol.escapedName, 111551 /* Value */, undefined, undefined, /*isUse*/ false);
                        paramSymbol = resolvedSymbol;
                    }
                    if (i === 0 && paramSymbol.escapedName === "this" /* This */) {
                        hasThisParameter = true;
                        thisParameter = param.symbol;
                    }
                    else {
                        parameters.push(paramSymbol);
                    }
                    if (type && type.kind === 187 /* LiteralType */) {
                        flags |= 2 /* HasLiteralTypes */;
                    }
                    // Record a new minimum argument count if this is not an optional parameter
                    var isOptionalParameter_1 = isOptionalJSDocParameterTag(param) ||
                        param.initializer || param.questionToken || param.dotDotDotToken ||
                        iife && parameters.length > iife.arguments.length && !type ||
                        isJSDocOptionalParameter(param);
                    if (!isOptionalParameter_1) {
                        minArgumentCount = parameters.length;
                    }
                }
                // If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation
                if ((declaration.kind === 163 /* GetAccessor */ || declaration.kind === 164 /* SetAccessor */) &&
                    !hasNonBindableDynamicName(declaration) &&
                    (!hasThisParameter || !thisParameter)) {
                    var otherKind = declaration.kind === 163 /* GetAccessor */ ? 164 /* SetAccessor */ : 163 /* GetAccessor */;
                    var other = ts.getDeclarationOfKind(getSymbolOfNode(declaration), otherKind);
                    if (other) {
                        thisParameter = getAnnotatedAccessorThisParameter(other);
                    }
                }
                var classType = declaration.kind === 162 /* Constructor */ ?
                    getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol))
                    : undefined;
                var typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
                if (ts.hasRestParameter(declaration) || ts.isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) {
                    flags |= 1 /* HasRestParameter */;
                }
                links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, 
                /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, minArgumentCount, flags);
            }
            return links.resolvedSignature;
        }
        /**
         * A JS function gets a synthetic rest parameter if it references `arguments` AND:
         * 1. It has no parameters but at least one `@param` with a type that starts with `...`
         * OR
         * 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...`
         */
        function maybeAddJsSyntheticRestParameter(declaration, parameters) {
            if (ts.isJSDocSignature(declaration) || !containsArgumentsReference(declaration)) {
                return false;
            }
            var lastParam = ts.lastOrUndefined(declaration.parameters);
            var lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag);
            var lastParamVariadicType = ts.firstDefined(lastParamTags, function (p) {
                return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined;
            });
            var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args", 32768 /* RestParameter */);
            syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType;
            if (lastParamVariadicType) {
                // Replace the last parameter with a rest parameter.
                parameters.pop();
            }
            parameters.push(syntheticArgsSymbol);
            return true;
        }
        function getSignatureOfTypeTag(node) {
            // should be attached to a function declaration or expression
            if (!(ts.isInJSFile(node) && ts.isFunctionLikeDeclaration(node)))
                return undefined;
            var typeTag = ts.getJSDocTypeTag(node);
            var signature = typeTag && typeTag.typeExpression && getSingleCallSignature(getTypeFromTypeNode(typeTag.typeExpression));
            return signature && getErasedSignature(signature);
        }
        function getReturnTypeOfTypeTag(node) {
            var signature = getSignatureOfTypeTag(node);
            return signature && getReturnTypeOfSignature(signature);
        }
        function containsArgumentsReference(declaration) {
            var links = getNodeLinks(declaration);
            if (links.containsArgumentsReference === undefined) {
                if (links.flags & 8192 /* CaptureArguments */) {
                    links.containsArgumentsReference = true;
                }
                else {
                    links.containsArgumentsReference = traverse(declaration.body);
                }
            }
            return links.containsArgumentsReference;
            function traverse(node) {
                if (!node)
                    return false;
                switch (node.kind) {
                    case 75 /* Identifier */:
                        return node.escapedText === "arguments" && ts.isExpressionNode(node);
                    case 159 /* PropertyDeclaration */:
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        return node.name.kind === 154 /* ComputedPropertyName */
                            && traverse(node.name);
                    default:
                        return !ts.nodeStartsNewLexicalEnvironment(node) && !ts.isPartOfTypeNode(node) && !!ts.forEachChild(node, traverse);
                }
            }
        }
        function getSignaturesOfSymbol(symbol) {
            if (!symbol)
                return ts.emptyArray;
            var result = [];
            for (var i = 0; i < symbol.declarations.length; i++) {
                var decl = symbol.declarations[i];
                if (!ts.isFunctionLike(decl))
                    continue;
                // Don't include signature if node is the implementation of an overloaded function. A node is considered
                // an implementation node if it has a body and the previous node is of the same kind and immediately
                // precedes the implementation node (i.e. has the same parent and ends where the implementation starts).
                if (i > 0 && decl.body) {
                    var previous = symbol.declarations[i - 1];
                    if (decl.parent === previous.parent && decl.kind === previous.kind && decl.pos === previous.end) {
                        continue;
                    }
                }
                result.push(getSignatureFromDeclaration(decl));
            }
            return result;
        }
        function resolveExternalModuleTypeByLiteral(name) {
            var moduleSym = resolveExternalModuleName(name, name);
            if (moduleSym) {
                var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
                if (resolvedModuleSymbol) {
                    return getTypeOfSymbol(resolvedModuleSymbol);
                }
            }
            return anyType;
        }
        function getThisTypeOfSignature(signature) {
            if (signature.thisParameter) {
                return getTypeOfSymbol(signature.thisParameter);
            }
        }
        function getTypePredicateOfSignature(signature) {
            if (!signature.resolvedTypePredicate) {
                if (signature.target) {
                    var targetTypePredicate = getTypePredicateOfSignature(signature.target);
                    signature.resolvedTypePredicate = targetTypePredicate ? instantiateTypePredicate(targetTypePredicate, signature.mapper) : noTypePredicate;
                }
                else if (signature.unionSignatures) {
                    signature.resolvedTypePredicate = getUnionTypePredicate(signature.unionSignatures) || noTypePredicate;
                }
                else {
                    var type = signature.declaration && ts.getEffectiveReturnTypeNode(signature.declaration);
                    var jsdocPredicate = void 0;
                    if (!type && ts.isInJSFile(signature.declaration)) {
                        var jsdocSignature = getSignatureOfTypeTag(signature.declaration);
                        if (jsdocSignature && signature !== jsdocSignature) {
                            jsdocPredicate = getTypePredicateOfSignature(jsdocSignature);
                        }
                    }
                    signature.resolvedTypePredicate = type && ts.isTypePredicateNode(type) ?
                        createTypePredicateFromTypePredicateNode(type, signature) :
                        jsdocPredicate || noTypePredicate;
                }
                ts.Debug.assert(!!signature.resolvedTypePredicate);
            }
            return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate;
        }
        function createTypePredicateFromTypePredicateNode(node, signature) {
            var parameterName = node.parameterName;
            var type = node.type && getTypeFromTypeNode(node.type);
            return parameterName.kind === 183 /* ThisType */ ?
                createTypePredicate(node.assertsModifier ? 2 /* AssertsThis */ : 0 /* This */, /*parameterName*/ undefined, /*parameterIndex*/ undefined, type) :
                createTypePredicate(node.assertsModifier ? 3 /* AssertsIdentifier */ : 1 /* Identifier */, parameterName.escapedText, ts.findIndex(signature.parameters, function (p) { return p.escapedName === parameterName.escapedText; }), type);
        }
        function getReturnTypeOfSignature(signature) {
            if (!signature.resolvedReturnType) {
                if (!pushTypeResolution(signature, 3 /* ResolvedReturnType */)) {
                    return errorType;
                }
                var type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper) :
                    signature.unionSignatures ? getUnionType(ts.map(signature.unionSignatures, getReturnTypeOfSignature), 2 /* Subtype */) :
                        getReturnTypeFromAnnotation(signature.declaration) ||
                            (ts.nodeIsMissing(signature.declaration.body) ? anyType : getReturnTypeFromBody(signature.declaration));
                if (signature.flags & 4 /* IsInnerCallChain */) {
                    type = addOptionalTypeMarker(type);
                }
                else if (signature.flags & 8 /* IsOuterCallChain */) {
                    type = getOptionalType(type);
                }
                if (!popTypeResolution()) {
                    if (signature.declaration) {
                        var typeNode = ts.getEffectiveReturnTypeNode(signature.declaration);
                        if (typeNode) {
                            error(typeNode, ts.Diagnostics.Return_type_annotation_circularly_references_itself);
                        }
                        else if (noImplicitAny) {
                            var declaration = signature.declaration;
                            var name = ts.getNameOfDeclaration(declaration);
                            if (name) {
                                error(name, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, ts.declarationNameToString(name));
                            }
                            else {
                                error(declaration, ts.Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions);
                            }
                        }
                    }
                    type = anyType;
                }
                signature.resolvedReturnType = type;
            }
            return signature.resolvedReturnType;
        }
        function getReturnTypeFromAnnotation(declaration) {
            if (declaration.kind === 162 /* Constructor */) {
                return getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol));
            }
            if (ts.isJSDocConstructSignature(declaration)) {
                return getTypeFromTypeNode(declaration.parameters[0].type); // TODO: GH#18217
            }
            var typeNode = ts.getEffectiveReturnTypeNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
            if (declaration.kind === 163 /* GetAccessor */ && !hasNonBindableDynamicName(declaration)) {
                var jsDocType = ts.isInJSFile(declaration) && getTypeForDeclarationFromJSDocComment(declaration);
                if (jsDocType) {
                    return jsDocType;
                }
                var setter = ts.getDeclarationOfKind(getSymbolOfNode(declaration), 164 /* SetAccessor */);
                var setterType = getAnnotatedAccessorType(setter);
                if (setterType) {
                    return setterType;
                }
            }
            return getReturnTypeOfTypeTag(declaration);
        }
        function isResolvingReturnTypeOfSignature(signature) {
            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0;
        }
        function getRestTypeOfSignature(signature) {
            return tryGetRestTypeOfSignature(signature) || anyType;
        }
        function tryGetRestTypeOfSignature(signature) {
            if (signatureHasRestParameter(signature)) {
                var sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                var restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType;
                return restType && getIndexTypeOfType(restType, 1 /* Number */);
            }
            return undefined;
        }
        function getSignatureInstantiation(signature, typeArguments, isJavascript, inferredTypeParameters) {
            var instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
            if (inferredTypeParameters) {
                var returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature));
                if (returnSignature) {
                    var newReturnSignature = cloneSignature(returnSignature);
                    newReturnSignature.typeParameters = inferredTypeParameters;
                    var newInstantiatedSignature = cloneSignature(instantiatedSignature);
                    newInstantiatedSignature.resolvedReturnType = getOrCreateTypeFromSignature(newReturnSignature);
                    return newInstantiatedSignature;
                }
            }
            return instantiatedSignature;
        }
        function getSignatureInstantiationWithoutFillingInTypeArguments(signature, typeArguments) {
            var instantiations = signature.instantiations || (signature.instantiations = ts.createMap());
            var id = getTypeListId(typeArguments);
            var instantiation = instantiations.get(id);
            if (!instantiation) {
                instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments));
            }
            return instantiation;
        }
        function createSignatureInstantiation(signature, typeArguments) {
            return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true);
        }
        function createSignatureTypeMapper(signature, typeArguments) {
            return createTypeMapper(signature.typeParameters, typeArguments);
        }
        function getErasedSignature(signature) {
            return signature.typeParameters ?
                signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) :
                signature;
        }
        function createErasedSignature(signature) {
            // Create an instantiation of the signature where all type arguments are the any type.
            return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
        }
        function getCanonicalSignature(signature) {
            return signature.typeParameters ?
                signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) :
                signature;
        }
        function createCanonicalSignature(signature) {
            // Create an instantiation of the signature where each unconstrained type parameter is replaced with
            // its original. When a generic class or interface is instantiated, each generic method in the class or
            // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios
            // where different generations of the same type parameter are in scope). This leads to a lot of new type
            // identities, and potentially a lot of work comparing those identities, so here we create an instantiation
            // that uses the original type identities for all unconstrained type parameters.
            return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; }), ts.isInJSFile(signature.declaration));
        }
        function getBaseSignature(signature) {
            var typeParameters = signature.typeParameters;
            if (typeParameters) {
                var typeEraser_1 = createTypeEraser(typeParameters);
                var baseConstraints = ts.map(typeParameters, function (tp) { return instantiateType(getBaseConstraintOfType(tp), typeEraser_1) || unknownType; });
                return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true);
            }
            return signature;
        }
        function getOrCreateTypeFromSignature(signature) {
            // There are two ways to declare a construct signature, one is by declaring a class constructor
            // using the constructor keyword, and the other is declaring a bare construct signature in an
            // object type literal or interface (using the new keyword). Each way of declaring a constructor
            // will result in a different declaration kind.
            if (!signature.isolatedSignatureType) {
                var kind = signature.declaration ? signature.declaration.kind : 0 /* Unknown */;
                var isConstructor = kind === 162 /* Constructor */ || kind === 166 /* ConstructSignature */ || kind === 171 /* ConstructorType */;
                var type = createObjectType(16 /* Anonymous */);
                type.members = emptySymbols;
                type.properties = ts.emptyArray;
                type.callSignatures = !isConstructor ? [signature] : ts.emptyArray;
                type.constructSignatures = isConstructor ? [signature] : ts.emptyArray;
                signature.isolatedSignatureType = type;
            }
            return signature.isolatedSignatureType;
        }
        function getIndexSymbol(symbol) {
            return symbol.members.get("__index" /* Index */);
        }
        function getIndexDeclarationOfSymbol(symbol, kind) {
            var syntaxKind = kind === 1 /* Number */ ? 140 /* NumberKeyword */ : 143 /* StringKeyword */;
            var indexSymbol = getIndexSymbol(symbol);
            if (indexSymbol) {
                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var node = ts.cast(decl, ts.isIndexSignatureDeclaration);
                    if (node.parameters.length === 1) {
                        var parameter = node.parameters[0];
                        if (parameter.type && parameter.type.kind === syntaxKind) {
                            return node;
                        }
                    }
                }
            }
            return undefined;
        }
        function createIndexInfo(type, isReadonly, declaration) {
            return { type: type, isReadonly: isReadonly, declaration: declaration };
        }
        function getIndexInfoOfSymbol(symbol, kind) {
            var declaration = getIndexDeclarationOfSymbol(symbol, kind);
            if (declaration) {
                return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64 /* Readonly */), declaration);
            }
            return undefined;
        }
        function getConstraintDeclaration(type) {
            return ts.mapDefined(ts.filter(type.symbol && type.symbol.declarations, ts.isTypeParameterDeclaration), ts.getEffectiveConstraintOfTypeParameter)[0];
        }
        function getInferredTypeParameterConstraint(typeParameter) {
            var inferences;
            if (typeParameter.symbol) {
                for (var _i = 0, _a = typeParameter.symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (declaration.parent.kind === 181 /* InferType */) {
                        // When an 'infer T' declaration is immediately contained in a type reference node
                        // (such as 'Foo<infer T>'), T's constraint is inferred from the constraint of the
                        // corresponding type parameter in 'Foo'. When multiple 'infer T' declarations are
                        // present, we form an intersection of the inferred constraint types.
                        var grandParent = declaration.parent.parent;
                        if (grandParent.kind === 169 /* TypeReference */) {
                            var typeReference = grandParent;
                            var typeParameters = getTypeParametersForTypeReference(typeReference);
                            if (typeParameters) {
                                var index = typeReference.typeArguments.indexOf(declaration.parent);
                                if (index < typeParameters.length) {
                                    var declaredConstraint = getConstraintOfTypeParameter(typeParameters[index]);
                                    if (declaredConstraint) {
                                        // Type parameter constraints can reference other type parameters so
                                        // constraints need to be instantiated. If instantiation produces the
                                        // type parameter itself, we discard that inference. For example, in
                                        //   type Foo<T extends string, U extends T> = [T, U];
                                        //   type Bar<T> = T extends Foo<infer X, infer X> ? Foo<X, X> : T;
                                        // the instantiated constraint for U is X, so we discard that inference.
                                        var mapper = createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReference, typeParameters));
                                        var constraint = instantiateType(declaredConstraint, mapper);
                                        if (constraint !== typeParameter) {
                                            inferences = ts.append(inferences, constraint);
                                        }
                                    }
                                }
                            }
                        }
                        // When an 'infer T' declaration is immediately contained in a rest parameter
                        // declaration, we infer an 'unknown[]' constraint.
                        else if (grandParent.kind === 156 /* Parameter */ && grandParent.dotDotDotToken) {
                            inferences = ts.append(inferences, createArrayType(unknownType));
                        }
                    }
                }
            }
            return inferences && getIntersectionType(inferences);
        }
        /** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */
        function getConstraintFromTypeParameter(typeParameter) {
            if (!typeParameter.constraint) {
                if (typeParameter.target) {
                    var targetConstraint = getConstraintOfTypeParameter(typeParameter.target);
                    typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper) : noConstraintType;
                }
                else {
                    var constraintDeclaration = getConstraintDeclaration(typeParameter);
                    if (!constraintDeclaration) {
                        typeParameter.constraint = getInferredTypeParameterConstraint(typeParameter) || noConstraintType;
                    }
                    else {
                        var type = getTypeFromTypeNode(constraintDeclaration);
                        if (type.flags & 1 /* Any */ && type !== errorType) { // Allow errorType to propegate to keep downstream errors suppressed
                            // use keyofConstraintType as the base constraint for mapped type key constraints (unknown isn;t assignable to that, but `any` was),
                            // use unknown otherwise
                            type = constraintDeclaration.parent.parent.kind === 186 /* MappedType */ ? keyofConstraintType : unknownType;
                        }
                        typeParameter.constraint = type;
                    }
                }
            }
            return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint;
        }
        function getParentSymbolOfTypeParameter(typeParameter) {
            var tp = ts.getDeclarationOfKind(typeParameter.symbol, 155 /* TypeParameter */);
            var host = ts.isJSDocTemplateTag(tp.parent) ? ts.getHostSignatureFromJSDoc(tp.parent) : tp.parent;
            return host && getSymbolOfNode(host);
        }
        function getTypeListId(types) {
            var result = "";
            if (types) {
                var length_4 = types.length;
                var i = 0;
                while (i < length_4) {
                    var startId = types[i].id;
                    var count = 1;
                    while (i + count < length_4 && types[i + count].id === startId + count) {
                        count++;
                    }
                    if (result.length) {
                        result += ",";
                    }
                    result += startId;
                    if (count > 1) {
                        result += ":" + count;
                    }
                    i += count;
                }
            }
            return result;
        }
        // This function is used to propagate certain flags when creating new object type references and union types.
        // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
        // of an object literal or the anyFunctionType. This is because there are operations in the type checker
        // that care about the presence of such types at arbitrary depth in a containing type.
        function getPropagatingFlagsOfTypes(types, excludeKinds) {
            var result = 0;
            for (var _i = 0, types_8 = types; _i < types_8.length; _i++) {
                var type = types_8[_i];
                if (!(type.flags & excludeKinds)) {
                    result |= ts.getObjectFlags(type);
                }
            }
            return result & 3670016 /* PropagatingFlags */;
        }
        function createTypeReference(target, typeArguments) {
            var id = getTypeListId(typeArguments);
            var type = target.instantiations.get(id);
            if (!type) {
                type = createObjectType(4 /* Reference */, target.symbol);
                target.instantiations.set(id, type);
                type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
                type.target = target;
                type.resolvedTypeArguments = typeArguments;
            }
            return type;
        }
        function cloneTypeReference(source) {
            var type = createType(source.flags);
            type.symbol = source.symbol;
            type.objectFlags = source.objectFlags;
            type.target = source.target;
            type.resolvedTypeArguments = source.resolvedTypeArguments;
            return type;
        }
        function createDeferredTypeReference(target, node, mapper) {
            var aliasSymbol = getAliasSymbolForTypeNode(node);
            var aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
            var type = createObjectType(4 /* Reference */, target.symbol);
            type.target = target;
            type.node = node;
            type.mapper = mapper;
            type.aliasSymbol = aliasSymbol;
            type.aliasTypeArguments = mapper ? instantiateTypes(aliasTypeArguments, mapper) : aliasTypeArguments;
            return type;
        }
        function getTypeArguments(type) {
            var _a, _b;
            if (!type.resolvedTypeArguments) {
                if (!pushTypeResolution(type, 6 /* ResolvedTypeArguments */)) {
                    return ((_a = type.target.localTypeParameters) === null || _a === void 0 ? void 0 : _a.map(function () { return errorType; })) || ts.emptyArray;
                }
                var node = type.node;
                var typeArguments = !node ? ts.emptyArray :
                    node.kind === 169 /* TypeReference */ ? ts.concatenate(type.target.outerTypeParameters, getEffectiveTypeArguments(node, type.target.localTypeParameters)) :
                        node.kind === 174 /* ArrayType */ ? [getTypeFromTypeNode(node.elementType)] :
                            ts.map(node.elementTypes, getTypeFromTypeNode);
                if (popTypeResolution()) {
                    type.resolvedTypeArguments = type.mapper ? instantiateTypes(typeArguments, type.mapper) : typeArguments;
                }
                else {
                    type.resolvedTypeArguments = ((_b = type.target.localTypeParameters) === null || _b === void 0 ? void 0 : _b.map(function () { return errorType; })) || ts.emptyArray;
                    error(type.node || currentNode, type.target.symbol
                        ? ts.Diagnostics.Type_arguments_for_0_circularly_reference_themselves
                        : ts.Diagnostics.Tuple_type_arguments_circularly_reference_themselves, type.target.symbol && symbolToString(type.target.symbol));
                }
            }
            return type.resolvedTypeArguments;
        }
        function getTypeReferenceArity(type) {
            return ts.length(type.target.typeParameters);
        }
        /**
         * Get type from type-reference that reference to class or interface
         */
        function getTypeFromClassOrInterfaceReference(node, symbol) {
            var type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
            var typeParameters = type.localTypeParameters;
            if (typeParameters) {
                var numTypeArguments = ts.length(node.typeArguments);
                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                var isJs = ts.isInJSFile(node);
                var isJsImplicitAny = !noImplicitAny && isJs;
                if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) {
                    var missingAugmentsTag = isJs && ts.isExpressionWithTypeArguments(node) && !ts.isJSDocAugmentsTag(node.parent);
                    var diag = minTypeArgumentCount === typeParameters.length ?
                        missingAugmentsTag ?
                            ts.Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag :
                            ts.Diagnostics.Generic_type_0_requires_1_type_argument_s :
                        missingAugmentsTag ?
                            ts.Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag :
                            ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments;
                    var typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */);
                    error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length);
                    if (!isJs) {
                        // TODO: Adopt same permissive behavior in TS as in JS to reduce follow-on editing experience failures (requires editing fillMissingTypeArguments)
                        return errorType;
                    }
                }
                if (node.kind === 169 /* TypeReference */ && isDeferredTypeReferenceNode(node, ts.length(node.typeArguments) !== typeParameters.length)) {
                    return createDeferredTypeReference(type, node, /*mapper*/ undefined);
                }
                // In a type reference, the outer type parameters of the referenced class or interface are automatically
                // supplied as type arguments and the type reference only specifies arguments for the local type parameters
                // of the class or interface.
                var typeArguments = ts.concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgumentsFromTypeReferenceNode(node), typeParameters, minTypeArgumentCount, isJs));
                return createTypeReference(type, typeArguments);
            }
            return checkNoTypeArguments(node, symbol) ? type : errorType;
        }
        function getTypeAliasInstantiation(symbol, typeArguments) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var links = getSymbolLinks(symbol);
            var typeParameters = links.typeParameters;
            var id = getTypeListId(typeArguments);
            var instantiation = links.instantiations.get(id);
            if (!instantiation) {
                links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJSFile(symbol.valueDeclaration)))));
            }
            return instantiation;
        }
        /**
         * Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
         * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
         * declared type. Instantiations are cached using the type identities of the type arguments as the key.
         */
        function getTypeFromTypeAliasReference(node, symbol) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeParameters = getSymbolLinks(symbol).typeParameters;
            if (typeParameters) {
                var numTypeArguments = ts.length(node.typeArguments);
                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) {
                    error(node, minTypeArgumentCount === typeParameters.length ?
                        ts.Diagnostics.Generic_type_0_requires_1_type_argument_s :
                        ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, symbolToString(symbol), minTypeArgumentCount, typeParameters.length);
                    return errorType;
                }
                return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node));
            }
            return checkNoTypeArguments(node, symbol) ? type : errorType;
        }
        function getTypeReferenceName(node) {
            switch (node.kind) {
                case 169 /* TypeReference */:
                    return node.typeName;
                case 216 /* ExpressionWithTypeArguments */:
                    // We only support expressions that are simple qualified names. For other
                    // expressions this produces undefined.
                    var expr = node.expression;
                    if (ts.isEntityNameExpression(expr)) {
                        return expr;
                    }
                // fall through;
            }
            return undefined;
        }
        function resolveTypeReferenceName(typeReferenceName, meaning, ignoreErrors) {
            if (!typeReferenceName) {
                return unknownSymbol;
            }
            return resolveEntityName(typeReferenceName, meaning, ignoreErrors) || unknownSymbol;
        }
        function getTypeReferenceType(node, symbol) {
            if (symbol === unknownSymbol) {
                return errorType;
            }
            symbol = getExpandoSymbol(symbol) || symbol;
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getTypeFromClassOrInterfaceReference(node, symbol);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getTypeFromTypeAliasReference(node, symbol);
            }
            // Get type from reference to named type that cannot be generic (enum or type parameter)
            var res = tryGetDeclaredTypeOfSymbol(symbol);
            if (res) {
                return checkNoTypeArguments(node, symbol) ? getRegularTypeOfLiteralType(res) : errorType;
            }
            if (symbol.flags & 111551 /* Value */ && isJSDocTypeReference(node)) {
                var jsdocType = getTypeFromJSDocValueReference(node, symbol);
                if (jsdocType) {
                    return jsdocType;
                }
                else {
                    // Resolve the type reference as a Type for the purpose of reporting errors.
                    resolveTypeReferenceName(getTypeReferenceName(node), 788968 /* Type */);
                    return getTypeOfSymbol(symbol);
                }
            }
            return errorType;
        }
        /**
         * A JSdoc TypeReference may be to a value, but resolve it as a type anyway.
         * Note: If the value is imported from commonjs, it should really be an alias,
         * but this function's special-case code fakes alias resolution as well.
         */
        function getTypeFromJSDocValueReference(node, symbol) {
            var links = getNodeLinks(node);
            if (!links.resolvedJSDocType) {
                var valueType = getTypeOfSymbol(symbol);
                var typeType = valueType;
                if (symbol.valueDeclaration) {
                    var decl = ts.getRootDeclaration(symbol.valueDeclaration);
                    var isRequireAlias = false;
                    if (ts.isVariableDeclaration(decl) && decl.initializer) {
                        var expr = decl.initializer;
                        // skip past entity names, eg `require("x").a.b.c`
                        while (ts.isPropertyAccessExpression(expr)) {
                            expr = expr.expression;
                        }
                        isRequireAlias = ts.isCallExpression(expr) && ts.isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !!valueType.symbol;
                    }
                    var isImportTypeWithQualifier = node.kind === 188 /* ImportType */ && node.qualifier;
                    // valueType might not have a symbol, eg, {import('./b').STRING_LITERAL}
                    if (valueType.symbol && (isRequireAlias || isImportTypeWithQualifier)) {
                        typeType = getTypeReferenceType(node, valueType.symbol);
                    }
                }
                links.resolvedJSDocType = typeType;
            }
            return links.resolvedJSDocType;
        }
        function getSubstitutionType(baseType, substitute) {
            if (substitute.flags & 3 /* AnyOrUnknown */ || substitute === baseType) {
                return baseType;
            }
            var id = getTypeId(baseType) + ">" + getTypeId(substitute);
            var cached = substitutionTypes.get(id);
            if (cached) {
                return cached;
            }
            var result = createType(33554432 /* Substitution */);
            result.baseType = baseType;
            result.substitute = substitute;
            substitutionTypes.set(id, result);
            return result;
        }
        function isUnaryTupleTypeNode(node) {
            return node.kind === 175 /* TupleType */ && node.elementTypes.length === 1;
        }
        function getImpliedConstraint(type, checkNode, extendsNode) {
            return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(type, checkNode.elementTypes[0], extendsNode.elementTypes[0]) :
                getActualTypeVariable(getTypeFromTypeNode(checkNode)) === type ? getTypeFromTypeNode(extendsNode) :
                    undefined;
        }
        function getConditionalFlowTypeOfType(type, node) {
            var constraints;
            while (node && !ts.isStatement(node) && node.kind !== 303 /* JSDocComment */) {
                var parent = node.parent;
                if (parent.kind === 180 /* ConditionalType */ && node === parent.trueType) {
                    var constraint = getImpliedConstraint(type, parent.checkType, parent.extendsType);
                    if (constraint) {
                        constraints = ts.append(constraints, constraint);
                    }
                }
                node = parent;
            }
            return constraints ? getSubstitutionType(type, getIntersectionType(ts.append(constraints, type))) : type;
        }
        function isJSDocTypeReference(node) {
            return !!(node.flags & 4194304 /* JSDoc */) && (node.kind === 169 /* TypeReference */ || node.kind === 188 /* ImportType */);
        }
        function checkNoTypeArguments(node, symbol) {
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, symbol ? symbolToString(symbol) : node.typeName ? ts.declarationNameToString(node.typeName) : anon);
                return false;
            }
            return true;
        }
        function getIntendedTypeFromJSDocTypeReference(node) {
            if (ts.isIdentifier(node.typeName)) {
                var typeArgs = node.typeArguments;
                switch (node.typeName.escapedText) {
                    case "String":
                        checkNoTypeArguments(node);
                        return stringType;
                    case "Number":
                        checkNoTypeArguments(node);
                        return numberType;
                    case "Boolean":
                        checkNoTypeArguments(node);
                        return booleanType;
                    case "Void":
                        checkNoTypeArguments(node);
                        return voidType;
                    case "Undefined":
                        checkNoTypeArguments(node);
                        return undefinedType;
                    case "Null":
                        checkNoTypeArguments(node);
                        return nullType;
                    case "Function":
                    case "function":
                        checkNoTypeArguments(node);
                        return globalFunctionType;
                    case "array":
                        return (!typeArgs || !typeArgs.length) && !noImplicitAny ? anyArrayType : undefined;
                    case "promise":
                        return (!typeArgs || !typeArgs.length) && !noImplicitAny ? createPromiseType(anyType) : undefined;
                    case "Object":
                        if (typeArgs && typeArgs.length === 2) {
                            if (ts.isJSDocIndexSignature(node)) {
                                var indexed = getTypeFromTypeNode(typeArgs[0]);
                                var target = getTypeFromTypeNode(typeArgs[1]);
                                var index = createIndexInfo(target, /*isReadonly*/ false);
                                return createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, indexed === stringType ? index : undefined, indexed === numberType ? index : undefined);
                            }
                            return anyType;
                        }
                        checkNoTypeArguments(node);
                        return !noImplicitAny ? anyType : undefined;
                }
            }
        }
        function getTypeFromJSDocNullableTypeNode(node) {
            var type = getTypeFromTypeNode(node.type);
            return strictNullChecks ? getNullableType(type, 65536 /* Null */) : type;
        }
        function getTypeFromTypeReference(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // handle LS queries on the `const` in `x as const` by resolving to the type of `x`
                if (ts.isConstTypeReference(node) && ts.isAssertionExpression(node.parent)) {
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = checkExpressionCached(node.parent.expression);
                }
                var symbol = void 0;
                var type = void 0;
                var meaning = 788968 /* Type */;
                if (isJSDocTypeReference(node)) {
                    type = getIntendedTypeFromJSDocTypeReference(node);
                    if (!type) {
                        symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning, /*ignoreErrors*/ true);
                        if (symbol === unknownSymbol) {
                            symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning | 111551 /* Value */);
                        }
                        else {
                            resolveTypeReferenceName(getTypeReferenceName(node), meaning); // Resolve again to mark errors, if any
                        }
                        type = getTypeReferenceType(node, symbol);
                    }
                }
                if (!type) {
                    symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
                    type = getTypeReferenceType(node, symbol);
                }
                // Cache both the resolved symbol and the resolved type. The resolved symbol is needed when we check the
                // type reference in checkTypeReferenceNode.
                links.resolvedSymbol = symbol;
                links.resolvedType = type;
            }
            return links.resolvedType;
        }
        function typeArgumentsFromTypeReferenceNode(node) {
            return ts.map(node.typeArguments, getTypeFromTypeNode);
        }
        function getTypeFromTypeQueryNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // TypeScript 1.0 spec (April 2014): 3.6.3
                // The expression is processed as an identifier expression (section 4.3)
                // or property access expression(section 4.10),
                // the widened type(section 3.9) of which becomes the result.
                links.resolvedType = getRegularTypeOfLiteralType(getWidenedType(checkExpression(node.exprName)));
            }
            return links.resolvedType;
        }
        function getTypeOfGlobalSymbol(symbol, arity) {
            function getTypeDeclaration(symbol) {
                var declarations = symbol.declarations;
                for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) {
                    var declaration = declarations_3[_i];
                    switch (declaration.kind) {
                        case 245 /* ClassDeclaration */:
                        case 246 /* InterfaceDeclaration */:
                        case 248 /* EnumDeclaration */:
                            return declaration;
                    }
                }
            }
            if (!symbol) {
                return arity ? emptyGenericType : emptyObjectType;
            }
            var type = getDeclaredTypeOfSymbol(symbol);
            if (!(type.flags & 524288 /* Object */)) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, ts.symbolName(symbol));
                return arity ? emptyGenericType : emptyObjectType;
            }
            if (ts.length(type.typeParameters) !== arity) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, ts.symbolName(symbol), arity);
                return arity ? emptyGenericType : emptyObjectType;
            }
            return type;
        }
        function getGlobalValueSymbol(name, reportErrors) {
            return getGlobalSymbol(name, 111551 /* Value */, reportErrors ? ts.Diagnostics.Cannot_find_global_value_0 : undefined);
        }
        function getGlobalTypeSymbol(name, reportErrors) {
            return getGlobalSymbol(name, 788968 /* Type */, reportErrors ? ts.Diagnostics.Cannot_find_global_type_0 : undefined);
        }
        function getGlobalSymbol(name, meaning, diagnostic) {
            // Don't track references for global symbols anyway, so value if `isReference` is arbitrary
            return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false);
        }
        function getGlobalType(name, arity, reportErrors) {
            var symbol = getGlobalTypeSymbol(name, reportErrors);
            return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined;
        }
        function getGlobalTypedPropertyDescriptorType() {
            return deferredGlobalTypedPropertyDescriptorType || (deferredGlobalTypedPropertyDescriptorType = getGlobalType("TypedPropertyDescriptor", /*arity*/ 1, /*reportErrors*/ true)) || emptyGenericType;
        }
        function getGlobalTemplateStringsArrayType() {
            return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
        }
        function getGlobalImportMetaType() {
            return deferredGlobalImportMetaType || (deferredGlobalImportMetaType = getGlobalType("ImportMeta", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
        }
        function getGlobalESSymbolConstructorSymbol(reportErrors) {
            return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol", reportErrors));
        }
        function getGlobalESSymbolType(reportErrors) {
            return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        function getGlobalPromiseType(reportErrors) {
            return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalPromiseLikeType(reportErrors) {
            return deferredGlobalPromiseLikeType || (deferredGlobalPromiseLikeType = getGlobalType("PromiseLike", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalPromiseConstructorSymbol(reportErrors) {
            return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise", reportErrors));
        }
        function getGlobalPromiseConstructorLikeType(reportErrors) {
            return deferredGlobalPromiseConstructorLikeType || (deferredGlobalPromiseConstructorLikeType = getGlobalType("PromiseConstructorLike", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        function getGlobalAsyncIterableType(reportErrors) {
            return deferredGlobalAsyncIterableType || (deferredGlobalAsyncIterableType = getGlobalType("AsyncIterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncIteratorType(reportErrors) {
            return deferredGlobalAsyncIteratorType || (deferredGlobalAsyncIteratorType = getGlobalType("AsyncIterator", /*arity*/ 3, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncIterableIteratorType(reportErrors) {
            return deferredGlobalAsyncIterableIteratorType || (deferredGlobalAsyncIterableIteratorType = getGlobalType("AsyncIterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncGeneratorType(reportErrors) {
            return deferredGlobalAsyncGeneratorType || (deferredGlobalAsyncGeneratorType = getGlobalType("AsyncGenerator", /*arity*/ 3, reportErrors)) || emptyGenericType;
        }
        function getGlobalIterableType(reportErrors) {
            return deferredGlobalIterableType || (deferredGlobalIterableType = getGlobalType("Iterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIteratorType(reportErrors) {
            return deferredGlobalIteratorType || (deferredGlobalIteratorType = getGlobalType("Iterator", /*arity*/ 3, reportErrors)) || emptyGenericType;
        }
        function getGlobalIterableIteratorType(reportErrors) {
            return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalGeneratorType(reportErrors) {
            return deferredGlobalGeneratorType || (deferredGlobalGeneratorType = getGlobalType("Generator", /*arity*/ 3, reportErrors)) || emptyGenericType;
        }
        function getGlobalIteratorYieldResultType(reportErrors) {
            return deferredGlobalIteratorYieldResultType || (deferredGlobalIteratorYieldResultType = getGlobalType("IteratorYieldResult", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIteratorReturnResultType(reportErrors) {
            return deferredGlobalIteratorReturnResultType || (deferredGlobalIteratorReturnResultType = getGlobalType("IteratorReturnResult", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalTypeOrUndefined(name, arity) {
            if (arity === void 0) { arity = 0; }
            var symbol = getGlobalSymbol(name, 788968 /* Type */, /*diagnostic*/ undefined);
            return symbol && getTypeOfGlobalSymbol(symbol, arity);
        }
        function getGlobalExtractSymbol() {
            return deferredGlobalExtractSymbol || (deferredGlobalExtractSymbol = getGlobalSymbol("Extract", 524288 /* TypeAlias */, ts.Diagnostics.Cannot_find_global_type_0)); // TODO: GH#18217
        }
        function getGlobalOmitSymbol() {
            return deferredGlobalOmitSymbol || (deferredGlobalOmitSymbol = getGlobalSymbol("Omit", 524288 /* TypeAlias */, ts.Diagnostics.Cannot_find_global_type_0)); // TODO: GH#18217
        }
        function getGlobalBigIntType(reportErrors) {
            return deferredGlobalBigIntType || (deferredGlobalBigIntType = getGlobalType("BigInt", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        /**
         * Instantiates a global type that is generic with some element type, and returns that instantiation.
         */
        function createTypeFromGenericGlobalType(genericGlobalType, typeArguments) {
            return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, typeArguments) : emptyObjectType;
        }
        function createTypedPropertyDescriptorType(propertyType) {
            return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]);
        }
        function createIterableType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]);
        }
        function createArrayType(elementType, readonly) {
            return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]);
        }
        function getArrayOrTupleTargetType(node) {
            var readonly = isReadonlyTypeOperator(node.parent);
            if (node.kind === 174 /* ArrayType */ || node.elementTypes.length === 1 && node.elementTypes[0].kind === 177 /* RestType */) {
                return readonly ? globalReadonlyArrayType : globalArrayType;
            }
            var lastElement = ts.lastOrUndefined(node.elementTypes);
            var restElement = lastElement && lastElement.kind === 177 /* RestType */ ? lastElement : undefined;
            var minLength = ts.findLastIndex(node.elementTypes, function (n) { return n.kind !== 176 /* OptionalType */ && n !== restElement; }) + 1;
            return getTupleTypeOfArity(node.elementTypes.length, minLength, !!restElement, readonly, /*associatedNames*/ undefined);
        }
        // Return true if the given type reference node is directly aliased or if it needs to be deferred
        // because it is possibly contained in a circular chain of eagerly resolved types.
        function isDeferredTypeReferenceNode(node, hasDefaultTypeArguments) {
            return !!getAliasSymbolForTypeNode(node) || isResolvedByTypeAlias(node) && (node.kind === 174 /* ArrayType */ ? mayResolveTypeAlias(node.elementType) :
                node.kind === 175 /* TupleType */ ? ts.some(node.elementTypes, mayResolveTypeAlias) :
                    hasDefaultTypeArguments || ts.some(node.typeArguments, mayResolveTypeAlias));
        }
        // Return true when the given node is transitively contained in type constructs that eagerly
        // resolve their constituent types. We include SyntaxKind.TypeReference because type arguments
        // of type aliases are eagerly resolved.
        function isResolvedByTypeAlias(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 182 /* ParenthesizedType */:
                case 169 /* TypeReference */:
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                case 185 /* IndexedAccessType */:
                case 180 /* ConditionalType */:
                case 184 /* TypeOperator */:
                case 174 /* ArrayType */:
                case 175 /* TupleType */:
                    return isResolvedByTypeAlias(parent);
                case 247 /* TypeAliasDeclaration */:
                    return true;
            }
            return false;
        }
        // Return true if resolving the given node (i.e. getTypeFromTypeNode) possibly causes resolution
        // of a type alias.
        function mayResolveTypeAlias(node) {
            switch (node.kind) {
                case 169 /* TypeReference */:
                    return isJSDocTypeReference(node) || !!(resolveTypeReferenceName(node.typeName, 788968 /* Type */).flags & 524288 /* TypeAlias */);
                case 172 /* TypeQuery */:
                    return true;
                case 184 /* TypeOperator */:
                    return node.operator !== 147 /* UniqueKeyword */ && mayResolveTypeAlias(node.type);
                case 182 /* ParenthesizedType */:
                case 176 /* OptionalType */:
                case 299 /* JSDocOptionalType */:
                case 297 /* JSDocNullableType */:
                case 298 /* JSDocNonNullableType */:
                case 294 /* JSDocTypeExpression */:
                    return mayResolveTypeAlias(node.type);
                case 177 /* RestType */:
                    return node.type.kind !== 174 /* ArrayType */ || mayResolveTypeAlias(node.type.elementType);
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                    return ts.some(node.types, mayResolveTypeAlias);
                case 185 /* IndexedAccessType */:
                    return mayResolveTypeAlias(node.objectType) || mayResolveTypeAlias(node.indexType);
                case 180 /* ConditionalType */:
                    return mayResolveTypeAlias(node.checkType) || mayResolveTypeAlias(node.extendsType) ||
                        mayResolveTypeAlias(node.trueType) || mayResolveTypeAlias(node.falseType);
            }
            return false;
        }
        function getTypeFromArrayOrTupleTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var target = getArrayOrTupleTargetType(node);
                if (target === emptyGenericType) {
                    links.resolvedType = emptyObjectType;
                }
                else if (isDeferredTypeReferenceNode(node)) {
                    links.resolvedType = node.kind === 175 /* TupleType */ && node.elementTypes.length === 0 ? target :
                        createDeferredTypeReference(target, node, /*mapper*/ undefined);
                }
                else {
                    var elementTypes = node.kind === 174 /* ArrayType */ ? [getTypeFromTypeNode(node.elementType)] : ts.map(node.elementTypes, getTypeFromTypeNode);
                    links.resolvedType = createTypeReference(target, elementTypes);
                }
            }
            return links.resolvedType;
        }
        function isReadonlyTypeOperator(node) {
            return ts.isTypeOperatorNode(node) && node.operator === 138 /* ReadonlyKeyword */;
        }
        // We represent tuple types as type references to synthesized generic interface types created by
        // this function. The types are of the form:
        //
        //   interface Tuple<T0, T1, T2, ...> extends Array<T0 | T1 | T2 | ...> { 0: T0, 1: T1, 2: T2, ... }
        //
        // Note that the generic type created by this function has no symbol associated with it. The same
        // is true for each of the synthesized type parameters.
        function createTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames) {
            var typeParameters;
            var properties = [];
            var maxLength = hasRestElement ? arity - 1 : arity;
            if (arity) {
                typeParameters = new Array(arity);
                for (var i = 0; i < arity; i++) {
                    var typeParameter = typeParameters[i] = createTypeParameter();
                    if (i < maxLength) {
                        var property = createSymbol(4 /* Property */ | (i >= minLength ? 16777216 /* Optional */ : 0), "" + i, readonly ? 8 /* Readonly */ : 0);
                        property.type = typeParameter;
                        properties.push(property);
                    }
                }
            }
            var literalTypes = [];
            for (var i = minLength; i <= maxLength; i++)
                literalTypes.push(getLiteralType(i));
            var lengthSymbol = createSymbol(4 /* Property */, "length");
            lengthSymbol.type = hasRestElement ? numberType : getUnionType(literalTypes);
            properties.push(lengthSymbol);
            var type = createObjectType(8 /* Tuple */ | 4 /* Reference */);
            type.typeParameters = typeParameters;
            type.outerTypeParameters = undefined;
            type.localTypeParameters = typeParameters;
            type.instantiations = ts.createMap();
            type.instantiations.set(getTypeListId(type.typeParameters), type);
            type.target = type;
            type.resolvedTypeArguments = type.typeParameters;
            type.thisType = createTypeParameter();
            type.thisType.isThisType = true;
            type.thisType.constraint = type;
            type.declaredProperties = properties;
            type.declaredCallSignatures = ts.emptyArray;
            type.declaredConstructSignatures = ts.emptyArray;
            type.declaredStringIndexInfo = undefined;
            type.declaredNumberIndexInfo = undefined;
            type.minLength = minLength;
            type.hasRestElement = hasRestElement;
            type.readonly = readonly;
            type.associatedNames = associatedNames;
            return type;
        }
        function getTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames) {
            var key = arity + (hasRestElement ? "+" : ",") + minLength + (readonly ? "R" : "") + (associatedNames && associatedNames.length ? "," + associatedNames.join(",") : "");
            var type = tupleTypes.get(key);
            if (!type) {
                tupleTypes.set(key, type = createTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames));
            }
            return type;
        }
        function createTupleType(elementTypes, minLength, hasRestElement, readonly, associatedNames) {
            if (minLength === void 0) { minLength = elementTypes.length; }
            if (hasRestElement === void 0) { hasRestElement = false; }
            if (readonly === void 0) { readonly = false; }
            var arity = elementTypes.length;
            if (arity === 1 && hasRestElement) {
                return createArrayType(elementTypes[0], readonly);
            }
            var tupleType = getTupleTypeOfArity(arity, minLength, arity > 0 && hasRestElement, readonly, associatedNames);
            return elementTypes.length ? createTypeReference(tupleType, elementTypes) : tupleType;
        }
        function sliceTupleType(type, index) {
            var tuple = type.target;
            if (tuple.hasRestElement) {
                // don't slice off rest element
                index = Math.min(index, getTypeReferenceArity(type) - 1);
            }
            return createTupleType(getTypeArguments(type).slice(index), Math.max(0, tuple.minLength - index), tuple.hasRestElement, tuple.readonly, tuple.associatedNames && tuple.associatedNames.slice(index));
        }
        function getTypeFromOptionalTypeNode(node) {
            var type = getTypeFromTypeNode(node.type);
            return strictNullChecks ? getOptionalType(type) : type;
        }
        function getTypeId(type) {
            return type.id;
        }
        function containsType(types, type) {
            return ts.binarySearch(types, type, getTypeId, ts.compareValues) >= 0;
        }
        function insertType(types, type) {
            var index = ts.binarySearch(types, type, getTypeId, ts.compareValues);
            if (index < 0) {
                types.splice(~index, 0, type);
                return true;
            }
            return false;
        }
        function addTypeToUnion(typeSet, includes, type) {
            var flags = type.flags;
            if (flags & 1048576 /* Union */) {
                return addTypesToUnion(typeSet, includes, type.types);
            }
            // We ignore 'never' types in unions
            if (!(flags & 131072 /* Never */)) {
                includes |= flags & 71041023 /* IncludesMask */;
                if (flags & 66846720 /* StructuredOrInstantiable */)
                    includes |= 262144 /* IncludesStructuredOrInstantiable */;
                if (type === wildcardType)
                    includes |= 8388608 /* IncludesWildcard */;
                if (!strictNullChecks && flags & 98304 /* Nullable */) {
                    if (!(ts.getObjectFlags(type) & 524288 /* ContainsWideningType */))
                        includes |= 4194304 /* IncludesNonWideningType */;
                }
                else {
                    var len = typeSet.length;
                    var index = len && type.id > typeSet[len - 1].id ? ~len : ts.binarySearch(typeSet, type, getTypeId, ts.compareValues);
                    if (index < 0) {
                        typeSet.splice(~index, 0, type);
                    }
                }
            }
            return includes;
        }
        // Add the given types to the given type set. Order is preserved, duplicates are removed,
        // and nested types of the given kind are flattened into the set.
        function addTypesToUnion(typeSet, includes, types) {
            for (var _i = 0, types_9 = types; _i < types_9.length; _i++) {
                var type = types_9[_i];
                includes = addTypeToUnion(typeSet, includes, type);
            }
            return includes;
        }
        function isSetOfLiteralsFromSameEnum(types) {
            var first = types[0];
            if (first.flags & 1024 /* EnumLiteral */) {
                var firstEnum = getParentOfSymbol(first.symbol);
                for (var i = 1; i < types.length; i++) {
                    var other = types[i];
                    if (!(other.flags & 1024 /* EnumLiteral */) || (firstEnum !== getParentOfSymbol(other.symbol))) {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
        function removeSubtypes(types, primitivesOnly) {
            var len = types.length;
            if (len === 0 || isSetOfLiteralsFromSameEnum(types)) {
                return true;
            }
            var i = len;
            var count = 0;
            while (i > 0) {
                i--;
                var source = types[i];
                for (var _i = 0, types_10 = types; _i < types_10.length; _i++) {
                    var target = types_10[_i];
                    if (source !== target) {
                        if (count === 100000) {
                            // After 100000 subtype checks we estimate the remaining amount of work by assuming the
                            // same ratio of checks per element. If the estimated number of remaining type checks is
                            // greater than an upper limit we deem the union type too complex to represent. The
                            // upper limit is 25M for unions of primitives only, and 1M otherwise. This for example
                            // caps union types at 5000 unique literal types and 1000 unique object types.
                            var estimatedCount = (count / (len - i)) * len;
                            if (estimatedCount > (primitivesOnly ? 25000000 : 1000000)) {
                                error(currentNode, ts.Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
                                return false;
                            }
                        }
                        count++;
                        if (isTypeRelatedTo(source, target, strictSubtypeRelation) && (!(ts.getObjectFlags(getTargetType(source)) & 1 /* Class */) ||
                            !(ts.getObjectFlags(getTargetType(target)) & 1 /* Class */) ||
                            isTypeDerivedFrom(source, target))) {
                            ts.orderedRemoveItemAt(types, i);
                            break;
                        }
                    }
                }
            }
            return true;
        }
        function removeRedundantLiteralTypes(types, includes) {
            var i = types.length;
            while (i > 0) {
                i--;
                var t = types[i];
                var remove = t.flags & 128 /* StringLiteral */ && includes & 4 /* String */ ||
                    t.flags & 256 /* NumberLiteral */ && includes & 8 /* Number */ ||
                    t.flags & 2048 /* BigIntLiteral */ && includes & 64 /* BigInt */ ||
                    t.flags & 8192 /* UniqueESSymbol */ && includes & 4096 /* ESSymbol */ ||
                    isFreshLiteralType(t) && containsType(types, t.regularType);
                if (remove) {
                    ts.orderedRemoveItemAt(types, i);
                }
            }
        }
        // We sort and deduplicate the constituent types based on object identity. If the subtypeReduction
        // flag is specified we also reduce the constituent type set to only include types that aren't subtypes
        // of other types. Subtype reduction is expensive for large union types and is possible only when union
        // types are known not to circularly reference themselves (as is the case with union types created by
        // expression constructs such as array literals and the || and ?: operators). Named types can
        // circularly reference themselves and therefore cannot be subtype reduced during their declaration.
        // For example, "type Item = string | (() => Item" is a named type that circularly references itself.
        function getUnionType(types, unionReduction, aliasSymbol, aliasTypeArguments) {
            if (unionReduction === void 0) { unionReduction = 1 /* Literal */; }
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var typeSet = [];
            var includes = addTypesToUnion(typeSet, 0, types);
            if (unionReduction !== 0 /* None */) {
                if (includes & 3 /* AnyOrUnknown */) {
                    return includes & 1 /* Any */ ? includes & 8388608 /* IncludesWildcard */ ? wildcardType : anyType : unknownType;
                }
                switch (unionReduction) {
                    case 1 /* Literal */:
                        if (includes & (2944 /* Literal */ | 8192 /* UniqueESSymbol */)) {
                            removeRedundantLiteralTypes(typeSet, includes);
                        }
                        break;
                    case 2 /* Subtype */:
                        if (!removeSubtypes(typeSet, !(includes & 262144 /* IncludesStructuredOrInstantiable */))) {
                            return errorType;
                        }
                        break;
                }
                if (typeSet.length === 0) {
                    return includes & 65536 /* Null */ ? includes & 4194304 /* IncludesNonWideningType */ ? nullType : nullWideningType :
                        includes & 32768 /* Undefined */ ? includes & 4194304 /* IncludesNonWideningType */ ? undefinedType : undefinedWideningType :
                            neverType;
                }
            }
            var objectFlags = (includes & 66994211 /* NotPrimitiveUnion */ ? 0 : 262144 /* PrimitiveUnion */) |
                (includes & 2097152 /* Intersection */ ? 268435456 /* ContainsIntersections */ : 0);
            return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments);
        }
        function getUnionTypePredicate(signatures) {
            var first;
            var types = [];
            for (var _i = 0, signatures_6 = signatures; _i < signatures_6.length; _i++) {
                var sig = signatures_6[_i];
                var pred = getTypePredicateOfSignature(sig);
                if (!pred || pred.kind === 2 /* AssertsThis */ || pred.kind === 3 /* AssertsIdentifier */) {
                    continue;
                }
                if (first) {
                    if (!typePredicateKindsMatch(first, pred)) {
                        // No common type predicate.
                        return undefined;
                    }
                }
                else {
                    first = pred;
                }
                types.push(pred.type);
            }
            if (!first) {
                // No union signatures had a type predicate.
                return undefined;
            }
            var unionType = getUnionType(types);
            return createTypePredicate(first.kind, first.parameterName, first.parameterIndex, unionType);
        }
        function typePredicateKindsMatch(a, b) {
            return a.kind === b.kind && a.parameterIndex === b.parameterIndex;
        }
        // This function assumes the constituent type list is sorted and deduplicated.
        function getUnionTypeFromSortedList(types, objectFlags, aliasSymbol, aliasTypeArguments) {
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var id = getTypeListId(types);
            var type = unionTypes.get(id);
            if (!type) {
                type = createType(1048576 /* Union */);
                unionTypes.set(id, type);
                type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 98304 /* Nullable */);
                type.types = types;
                /*
                Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type.
                For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol.
                (In the language service, the order may depend on the order in which a user takes actions, such as hovering over symbols.)
                It's important that we create equivalent union types only once, so that's an unfortunate side effect.
                */
                type.aliasSymbol = aliasSymbol;
                type.aliasTypeArguments = aliasTypeArguments;
            }
            return type;
        }
        function getTypeFromUnionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), 1 /* Literal */, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
            }
            return links.resolvedType;
        }
        function addTypeToIntersection(typeSet, includes, type) {
            var flags = type.flags;
            if (flags & 2097152 /* Intersection */) {
                return addTypesToIntersection(typeSet, includes, type.types);
            }
            if (isEmptyAnonymousObjectType(type)) {
                if (!(includes & 16777216 /* IncludesEmptyObject */)) {
                    includes |= 16777216 /* IncludesEmptyObject */;
                    typeSet.set(type.id.toString(), type);
                }
            }
            else {
                if (flags & 3 /* AnyOrUnknown */) {
                    if (type === wildcardType)
                        includes |= 8388608 /* IncludesWildcard */;
                }
                else if ((strictNullChecks || !(flags & 98304 /* Nullable */)) && !typeSet.has(type.id.toString())) {
                    if (type.flags & 109440 /* Unit */ && includes & 109440 /* Unit */) {
                        // We have seen two distinct unit types which means we should reduce to an
                        // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen.
                        includes |= 67108864 /* NonPrimitive */;
                    }
                    typeSet.set(type.id.toString(), type);
                }
                includes |= flags & 71041023 /* IncludesMask */;
            }
            return includes;
        }
        // Add the given types to the given type set. Order is preserved, freshness is removed from literal
        // types, duplicates are removed, and nested types of the given kind are flattened into the set.
        function addTypesToIntersection(typeSet, includes, types) {
            for (var _i = 0, types_11 = types; _i < types_11.length; _i++) {
                var type = types_11[_i];
                includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type));
            }
            return includes;
        }
        function removeRedundantPrimitiveTypes(types, includes) {
            var i = types.length;
            while (i > 0) {
                i--;
                var t = types[i];
                var remove = t.flags & 4 /* String */ && includes & 128 /* StringLiteral */ ||
                    t.flags & 8 /* Number */ && includes & 256 /* NumberLiteral */ ||
                    t.flags & 64 /* BigInt */ && includes & 2048 /* BigIntLiteral */ ||
                    t.flags & 4096 /* ESSymbol */ && includes & 8192 /* UniqueESSymbol */;
                if (remove) {
                    ts.orderedRemoveItemAt(types, i);
                }
            }
        }
        // Check that the given type has a match in every union. A given type is matched by
        // an identical type, and a literal type is additionally matched by its corresponding
        // primitive type.
        function eachUnionContains(unionTypes, type) {
            for (var _i = 0, unionTypes_1 = unionTypes; _i < unionTypes_1.length; _i++) {
                var u = unionTypes_1[_i];
                if (!containsType(u.types, type)) {
                    var primitive = type.flags & 128 /* StringLiteral */ ? stringType :
                        type.flags & 256 /* NumberLiteral */ ? numberType :
                            type.flags & 2048 /* BigIntLiteral */ ? bigintType :
                                type.flags & 8192 /* UniqueESSymbol */ ? esSymbolType :
                                    undefined;
                    if (!primitive || !containsType(u.types, primitive)) {
                        return false;
                    }
                }
            }
            return true;
        }
        function extractIrreducible(types, flag) {
            if (ts.every(types, function (t) { return !!(t.flags & 1048576 /* Union */) && ts.some(t.types, function (tt) { return !!(tt.flags & flag); }); })) {
                for (var i = 0; i < types.length; i++) {
                    types[i] = filterType(types[i], function (t) { return !(t.flags & flag); });
                }
                return true;
            }
            return false;
        }
        // If the given list of types contains more than one union of primitive types, replace the
        // first with a union containing an intersection of those primitive types, then remove the
        // other unions and return true. Otherwise, do nothing and return false.
        function intersectUnionsOfPrimitiveTypes(types) {
            var unionTypes;
            var index = ts.findIndex(types, function (t) { return !!(ts.getObjectFlags(t) & 262144 /* PrimitiveUnion */); });
            if (index < 0) {
                return false;
            }
            var i = index + 1;
            // Remove all but the first union of primitive types and collect them in
            // the unionTypes array.
            while (i < types.length) {
                var t = types[i];
                if (ts.getObjectFlags(t) & 262144 /* PrimitiveUnion */) {
                    (unionTypes || (unionTypes = [types[index]])).push(t);
                    ts.orderedRemoveItemAt(types, i);
                }
                else {
                    i++;
                }
            }
            // Return false if there was only one union of primitive types
            if (!unionTypes) {
                return false;
            }
            // We have more than one union of primitive types, now intersect them. For each
            // type in each union we check if the type is matched in every union and if so
            // we include it in the result.
            var checked = [];
            var result = [];
            for (var _i = 0, unionTypes_2 = unionTypes; _i < unionTypes_2.length; _i++) {
                var u = unionTypes_2[_i];
                for (var _a = 0, _b = u.types; _a < _b.length; _a++) {
                    var t = _b[_a];
                    if (insertType(checked, t)) {
                        if (eachUnionContains(unionTypes, t)) {
                            insertType(result, t);
                        }
                    }
                }
            }
            // Finally replace the first union with the result
            types[index] = getUnionTypeFromSortedList(result, 262144 /* PrimitiveUnion */);
            return true;
        }
        function createIntersectionType(types, aliasSymbol, aliasTypeArguments) {
            var result = createType(2097152 /* Intersection */);
            result.objectFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 98304 /* Nullable */);
            result.types = types;
            result.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
            result.aliasTypeArguments = aliasTypeArguments;
            return result;
        }
        // We normalize combinations of intersection and union types based on the distributive property of the '&'
        // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
        // types with union type constituents into equivalent union types with intersection type constituents and
        // effectively ensure that union types are always at the top level in type representations.
        //
        // We do not perform structural deduplication on intersection types. Intersection types are created only by the &
        // type operator and we can't reduce those because we want to support recursive intersection types. For example,
        // a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
        // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
        // for intersections of types with signatures can be deterministic.
        function getIntersectionType(types, aliasSymbol, aliasTypeArguments) {
            var typeMembershipMap = ts.createMap();
            var includes = addTypesToIntersection(typeMembershipMap, 0, types);
            var typeSet = ts.arrayFrom(typeMembershipMap.values());
            // An intersection type is considered empty if it contains
            // the type never, or
            // more than one unit type or,
            // an object type and a nullable type (null or undefined), or
            // a string-like type and a type known to be non-string-like, or
            // a number-like type and a type known to be non-number-like, or
            // a symbol-like type and a type known to be non-symbol-like, or
            // a void-like type and a type known to be non-void-like, or
            // a non-primitive type and a type known to be primitive.
            if (includes & 131072 /* Never */ ||
                strictNullChecks && includes & 98304 /* Nullable */ && includes & (524288 /* Object */ | 67108864 /* NonPrimitive */ | 16777216 /* IncludesEmptyObject */) ||
                includes & 67108864 /* NonPrimitive */ && includes & (67238908 /* DisjointDomains */ & ~67108864 /* NonPrimitive */) ||
                includes & 132 /* StringLike */ && includes & (67238908 /* DisjointDomains */ & ~132 /* StringLike */) ||
                includes & 296 /* NumberLike */ && includes & (67238908 /* DisjointDomains */ & ~296 /* NumberLike */) ||
                includes & 2112 /* BigIntLike */ && includes & (67238908 /* DisjointDomains */ & ~2112 /* BigIntLike */) ||
                includes & 12288 /* ESSymbolLike */ && includes & (67238908 /* DisjointDomains */ & ~12288 /* ESSymbolLike */) ||
                includes & 49152 /* VoidLike */ && includes & (67238908 /* DisjointDomains */ & ~49152 /* VoidLike */)) {
                return neverType;
            }
            if (includes & 1 /* Any */) {
                return includes & 8388608 /* IncludesWildcard */ ? wildcardType : anyType;
            }
            if (!strictNullChecks && includes & 98304 /* Nullable */) {
                return includes & 32768 /* Undefined */ ? undefinedType : nullType;
            }
            if (includes & 4 /* String */ && includes & 128 /* StringLiteral */ ||
                includes & 8 /* Number */ && includes & 256 /* NumberLiteral */ ||
                includes & 64 /* BigInt */ && includes & 2048 /* BigIntLiteral */ ||
                includes & 4096 /* ESSymbol */ && includes & 8192 /* UniqueESSymbol */) {
                removeRedundantPrimitiveTypes(typeSet, includes);
            }
            if (includes & 16777216 /* IncludesEmptyObject */ && includes & 524288 /* Object */) {
                ts.orderedRemoveItemAt(typeSet, ts.findIndex(typeSet, isEmptyAnonymousObjectType));
            }
            if (typeSet.length === 0) {
                return unknownType;
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var result = intersectionTypes.get(id);
            if (!result) {
                if (includes & 1048576 /* Union */) {
                    if (intersectUnionsOfPrimitiveTypes(typeSet)) {
                        // When the intersection creates a reduced set (which might mean that *all* union types have
                        // disappeared), we restart the operation to get a new set of combined flags. Once we have
                        // reduced we'll never reduce again, so this occurs at most once.
                        result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
                    }
                    else if (extractIrreducible(typeSet, 32768 /* Undefined */)) {
                        result = getUnionType([getIntersectionType(typeSet), undefinedType], 1 /* Literal */, aliasSymbol, aliasTypeArguments);
                    }
                    else if (extractIrreducible(typeSet, 65536 /* Null */)) {
                        result = getUnionType([getIntersectionType(typeSet), nullType], 1 /* Literal */, aliasSymbol, aliasTypeArguments);
                    }
                    else {
                        // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
                        // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
                        // If the estimated size of the resulting union type exceeds 100000 constituents, report an error.
                        var size = ts.reduceLeft(typeSet, function (n, t) { return n * (t.flags & 1048576 /* Union */ ? t.types.length : 1); }, 1);
                        if (size >= 100000) {
                            error(currentNode, ts.Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
                            return errorType;
                        }
                        var unionIndex_1 = ts.findIndex(typeSet, function (t) { return (t.flags & 1048576 /* Union */) !== 0; });
                        var unionType = typeSet[unionIndex_1];
                        result = getUnionType(ts.map(unionType.types, function (t) { return getIntersectionType(ts.replaceElement(typeSet, unionIndex_1, t)); }), 1 /* Literal */, aliasSymbol, aliasTypeArguments);
                    }
                }
                else {
                    result = createIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
                }
                intersectionTypes.set(id, result);
            }
            return result;
        }
        function getTypeFromIntersectionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                links.resolvedType = getIntersectionType(ts.map(node.types, getTypeFromTypeNode), aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
            }
            return links.resolvedType;
        }
        function createIndexType(type, stringsOnly) {
            var result = createType(4194304 /* Index */);
            result.type = type;
            result.stringsOnly = stringsOnly;
            return result;
        }
        function getIndexTypeForGenericType(type, stringsOnly) {
            return stringsOnly ?
                type.resolvedStringIndexType || (type.resolvedStringIndexType = createIndexType(type, /*stringsOnly*/ true)) :
                type.resolvedIndexType || (type.resolvedIndexType = createIndexType(type, /*stringsOnly*/ false));
        }
        function getLiteralTypeFromPropertyName(name) {
            if (ts.isPrivateIdentifier(name)) {
                return neverType;
            }
            return ts.isIdentifier(name) ? getLiteralType(ts.unescapeLeadingUnderscores(name.escapedText)) :
                getRegularTypeOfLiteralType(ts.isComputedPropertyName(name) ? checkComputedPropertyName(name) : checkExpression(name));
        }
        function getBigIntLiteralType(node) {
            return getLiteralType({
                negative: false,
                base10Value: ts.parsePseudoBigInt(node.text)
            });
        }
        function getLiteralTypeFromProperty(prop, include) {
            if (!(ts.getDeclarationModifierFlagsFromSymbol(prop) & 24 /* NonPublicAccessibilityModifier */)) {
                var type = getSymbolLinks(getLateBoundSymbol(prop)).nameType;
                if (!type && !ts.isKnownSymbol(prop)) {
                    if (prop.escapedName === "default" /* Default */) {
                        type = getLiteralType("default");
                    }
                    else {
                        var name = prop.valueDeclaration && ts.getNameOfDeclaration(prop.valueDeclaration);
                        type = name && getLiteralTypeFromPropertyName(name) || getLiteralType(ts.symbolName(prop));
                    }
                }
                if (type && type.flags & include) {
                    return type;
                }
            }
            return neverType;
        }
        function getLiteralTypeFromProperties(type, include) {
            return getUnionType(ts.map(getPropertiesOfType(type), function (p) { return getLiteralTypeFromProperty(p, include); }));
        }
        function getNonEnumNumberIndexInfo(type) {
            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
            return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined;
        }
        function getIndexType(type, stringsOnly, noIndexSignatures) {
            if (stringsOnly === void 0) { stringsOnly = keyofStringsOnly; }
            type = getReducedType(type);
            return type.flags & 1048576 /* Union */ ? getIntersectionType(ts.map(type.types, function (t) { return getIndexType(t, stringsOnly, noIndexSignatures); })) :
                type.flags & 2097152 /* Intersection */ ? getUnionType(ts.map(type.types, function (t) { return getIndexType(t, stringsOnly, noIndexSignatures); })) :
                    maybeTypeOfKind(type, 58982400 /* InstantiableNonPrimitive */) ? getIndexTypeForGenericType(type, stringsOnly) :
                        ts.getObjectFlags(type) & 32 /* Mapped */ ? filterType(getConstraintTypeFromMappedType(type), function (t) { return !(noIndexSignatures && t.flags & (1 /* Any */ | 4 /* String */)); }) :
                            type === wildcardType ? wildcardType :
                                type.flags & 2 /* Unknown */ ? neverType :
                                    type.flags & (1 /* Any */ | 131072 /* Never */) ? keyofConstraintType :
                                        stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, 0 /* String */) ? stringType : getLiteralTypeFromProperties(type, 128 /* StringLiteral */) :
                                            !noIndexSignatures && getIndexInfoOfType(type, 0 /* String */) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, 8192 /* UniqueESSymbol */)]) :
                                                getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, 128 /* StringLiteral */ | 8192 /* UniqueESSymbol */)]) :
                                                    getLiteralTypeFromProperties(type, 8576 /* StringOrNumberLiteralOrUnique */);
        }
        function getExtractStringType(type) {
            if (keyofStringsOnly) {
                return type;
            }
            var extractTypeAlias = getGlobalExtractSymbol();
            return extractTypeAlias ? getTypeAliasInstantiation(extractTypeAlias, [type, stringType]) : stringType;
        }
        function getIndexTypeOrString(type) {
            var indexType = getExtractStringType(getIndexType(type));
            return indexType.flags & 131072 /* Never */ ? stringType : indexType;
        }
        function getTypeFromTypeOperatorNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                switch (node.operator) {
                    case 134 /* KeyOfKeyword */:
                        links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
                        break;
                    case 147 /* UniqueKeyword */:
                        links.resolvedType = node.type.kind === 144 /* SymbolKeyword */
                            ? getESSymbolLikeTypeForNode(ts.walkUpParenthesizedTypes(node.parent))
                            : errorType;
                        break;
                    case 138 /* ReadonlyKeyword */:
                        links.resolvedType = getTypeFromTypeNode(node.type);
                        break;
                    default:
                        throw ts.Debug.assertNever(node.operator);
                }
            }
            return links.resolvedType;
        }
        function createIndexedAccessType(objectType, indexType, aliasSymbol, aliasTypeArguments) {
            var type = createType(8388608 /* IndexedAccess */);
            type.objectType = objectType;
            type.indexType = indexType;
            type.aliasSymbol = aliasSymbol;
            type.aliasTypeArguments = aliasTypeArguments;
            return type;
        }
        /**
         * Returns if a type is or consists of a JSLiteral object type
         * In addition to objects which are directly literals,
         * * unions where every element is a jsliteral
         * * intersections where at least one element is a jsliteral
         * * and instantiable types constrained to a jsliteral
         * Should all count as literals and not print errors on access or assignment of possibly existing properties.
         * This mirrors the behavior of the index signature propagation, to which this behaves similarly (but doesn't affect assignability or inference).
         */
        function isJSLiteralType(type) {
            if (noImplicitAny) {
                return false; // Flag is meaningless under `noImplicitAny` mode
            }
            if (ts.getObjectFlags(type) & 16384 /* JSLiteral */) {
                return true;
            }
            if (type.flags & 1048576 /* Union */) {
                return ts.every(type.types, isJSLiteralType);
            }
            if (type.flags & 2097152 /* Intersection */) {
                return ts.some(type.types, isJSLiteralType);
            }
            if (type.flags & 63176704 /* Instantiable */) {
                return isJSLiteralType(getResolvedBaseConstraint(type));
            }
            return false;
        }
        function getPropertyNameFromIndex(indexType, accessNode) {
            var accessExpression = accessNode && accessNode.kind === 195 /* ElementAccessExpression */ ? accessNode : undefined;
            return isTypeUsableAsPropertyName(indexType) ?
                getPropertyNameFromType(indexType) :
                accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
                    ts.getPropertyNameForKnownSymbolName(ts.idText(accessExpression.argumentExpression.name)) :
                    accessNode && ts.isPropertyName(accessNode) ?
                        // late bound names are handled in the first branch, so here we only need to handle normal names
                        ts.getPropertyNameForPropertyNameNode(accessNode) :
                        undefined;
        }
        function getPropertyTypeForIndexType(originalObjectType, objectType, indexType, fullIndexType, suppressNoImplicitAnyError, accessNode, accessFlags) {
            var accessExpression = accessNode && accessNode.kind === 195 /* ElementAccessExpression */ ? accessNode : undefined;
            var propName = accessNode && ts.isPrivateIdentifier(accessNode) ? undefined : getPropertyNameFromIndex(indexType, accessNode);
            if (propName !== undefined) {
                var prop = getPropertyOfType(objectType, propName);
                if (prop) {
                    if (accessExpression) {
                        markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === 104 /* ThisKeyword */);
                        if (isAssignmentToReadonlyEntity(accessExpression, prop, ts.getAssignmentTargetKind(accessExpression))) {
                            error(accessExpression.argumentExpression, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(prop));
                            return undefined;
                        }
                        if (accessFlags & 4 /* CacheSymbol */) {
                            getNodeLinks(accessNode).resolvedSymbol = prop;
                        }
                    }
                    var propType = getTypeOfSymbol(prop);
                    return accessExpression && ts.getAssignmentTargetKind(accessExpression) !== 1 /* Definite */ ?
                        getFlowTypeOfReference(accessExpression, propType) :
                        propType;
                }
                if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) {
                    if (accessNode && everyType(objectType, function (t) { return !t.target.hasRestElement; }) && !(accessFlags & 8 /* NoTupleBoundsCheck */)) {
                        var indexNode = getIndexNodeForAccessExpression(accessNode);
                        if (isTupleType(objectType)) {
                            error(indexNode, ts.Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2, typeToString(objectType), getTypeReferenceArity(objectType), ts.unescapeLeadingUnderscores(propName));
                        }
                        else {
                            error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(propName), typeToString(objectType));
                        }
                    }
                    errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, 1 /* Number */));
                    return mapType(objectType, function (t) { return getRestTypeOfTupleType(t) || undefinedType; });
                }
            }
            if (!(indexType.flags & 98304 /* Nullable */) && isTypeAssignableToKind(indexType, 132 /* StringLike */ | 296 /* NumberLike */ | 12288 /* ESSymbolLike */)) {
                if (objectType.flags & (1 /* Any */ | 131072 /* Never */)) {
                    return objectType;
                }
                var stringIndexInfo = getIndexInfoOfType(objectType, 0 /* String */);
                var indexInfo = isTypeAssignableToKind(indexType, 296 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) || stringIndexInfo;
                if (indexInfo) {
                    if (accessFlags & 1 /* NoIndexSignatures */ && indexInfo === stringIndexInfo) {
                        if (accessExpression) {
                            error(accessExpression, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType));
                        }
                        return undefined;
                    }
                    if (accessNode && !isTypeAssignableToKind(indexType, 4 /* String */ | 8 /* Number */)) {
                        var indexNode = getIndexNodeForAccessExpression(accessNode);
                        error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
                        return indexInfo.type;
                    }
                    errorIfWritingToReadonlyIndex(indexInfo);
                    return indexInfo.type;
                }
                if (indexType.flags & 131072 /* Never */) {
                    return neverType;
                }
                if (isJSLiteralType(objectType)) {
                    return anyType;
                }
                if (accessExpression && !isConstEnumObjectType(objectType)) {
                    if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports.has(propName) && (globalThisSymbol.exports.get(propName).flags & 418 /* BlockScoped */)) {
                        error(accessExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(propName), typeToString(objectType));
                    }
                    else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !suppressNoImplicitAnyError) {
                        if (propName !== undefined && typeHasStaticProperty(propName, objectType)) {
                            error(accessExpression, ts.Diagnostics.Property_0_is_a_static_member_of_type_1, propName, typeToString(objectType));
                        }
                        else if (getIndexTypeOfType(objectType, 1 /* Number */)) {
                            error(accessExpression.argumentExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number);
                        }
                        else {
                            var suggestion = void 0;
                            if (propName !== undefined && (suggestion = getSuggestionForNonexistentProperty(propName, objectType))) {
                                if (suggestion !== undefined) {
                                    error(accessExpression.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, propName, typeToString(objectType), suggestion);
                                }
                            }
                            else {
                                var suggestion_1 = getSuggestionForNonexistentIndexSignature(objectType, accessExpression, indexType);
                                if (suggestion_1 !== undefined) {
                                    error(accessExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion_1);
                                }
                                else {
                                    var errorInfo = void 0;
                                    if (indexType.flags & 1024 /* EnumLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "[" + typeToString(indexType) + "]", typeToString(objectType));
                                    }
                                    else if (indexType.flags & 8192 /* UniqueESSymbol */) {
                                        var symbolName_2 = getFullyQualifiedName(indexType.symbol, accessExpression);
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "[" + symbolName_2 + "]", typeToString(objectType));
                                    }
                                    else if (indexType.flags & 128 /* StringLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, indexType.value, typeToString(objectType));
                                    }
                                    else if (indexType.flags & 256 /* NumberLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, indexType.value, typeToString(objectType));
                                    }
                                    else if (indexType.flags & (8 /* Number */ | 4 /* String */)) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1, typeToString(indexType), typeToString(objectType));
                                    }
                                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1, typeToString(fullIndexType), typeToString(objectType));
                                    diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(accessExpression, errorInfo));
                                }
                            }
                        }
                    }
                    return undefined;
                }
            }
            if (isJSLiteralType(objectType)) {
                return anyType;
            }
            if (accessNode) {
                var indexNode = getIndexNodeForAccessExpression(accessNode);
                if (indexType.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */)) {
                    error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "" + indexType.value, typeToString(objectType));
                }
                else if (indexType.flags & (4 /* String */ | 8 /* Number */)) {
                    error(indexNode, ts.Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType));
                }
                else {
                    error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
                }
            }
            if (isTypeAny(indexType)) {
                return indexType;
            }
            return undefined;
            function errorIfWritingToReadonlyIndex(indexInfo) {
                if (indexInfo && indexInfo.isReadonly && accessExpression && (ts.isAssignmentTarget(accessExpression) || ts.isDeleteTarget(accessExpression))) {
                    error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
                }
            }
        }
        function getIndexNodeForAccessExpression(accessNode) {
            return accessNode.kind === 195 /* ElementAccessExpression */ ? accessNode.argumentExpression :
                accessNode.kind === 185 /* IndexedAccessType */ ? accessNode.indexType :
                    accessNode.kind === 154 /* ComputedPropertyName */ ? accessNode.expression :
                        accessNode;
        }
        function isGenericObjectType(type) {
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                if (!(type.objectFlags & 4194304 /* IsGenericObjectTypeComputed */)) {
                    type.objectFlags |= 4194304 /* IsGenericObjectTypeComputed */ |
                        (ts.some(type.types, isGenericObjectType) ? 8388608 /* IsGenericObjectType */ : 0);
                }
                return !!(type.objectFlags & 8388608 /* IsGenericObjectType */);
            }
            return !!(type.flags & 58982400 /* InstantiableNonPrimitive */) || isGenericMappedType(type);
        }
        function isGenericIndexType(type) {
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                if (!(type.objectFlags & 16777216 /* IsGenericIndexTypeComputed */)) {
                    type.objectFlags |= 16777216 /* IsGenericIndexTypeComputed */ |
                        (ts.some(type.types, isGenericIndexType) ? 33554432 /* IsGenericIndexType */ : 0);
                }
                return !!(type.objectFlags & 33554432 /* IsGenericIndexType */);
            }
            return !!(type.flags & (58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */));
        }
        function isThisTypeParameter(type) {
            return !!(type.flags & 262144 /* TypeParameter */ && type.isThisType);
        }
        function getSimplifiedType(type, writing) {
            return type.flags & 8388608 /* IndexedAccess */ ? getSimplifiedIndexedAccessType(type, writing) :
                type.flags & 16777216 /* Conditional */ ? getSimplifiedConditionalType(type, writing) :
                    type;
        }
        function distributeIndexOverObjectType(objectType, indexType, writing) {
            // (T | U)[K] -> T[K] | U[K] (reading)
            // (T | U)[K] -> T[K] & U[K] (writing)
            // (T & U)[K] -> T[K] & U[K]
            if (objectType.flags & 3145728 /* UnionOrIntersection */) {
                var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); });
                return objectType.flags & 2097152 /* Intersection */ || writing ? getIntersectionType(types) : getUnionType(types);
            }
        }
        function distributeObjectOverIndexType(objectType, indexType, writing) {
            // T[A | B] -> T[A] | T[B] (reading)
            // T[A | B] -> T[A] & T[B] (writing)
            if (indexType.flags & 1048576 /* Union */) {
                var types = ts.map(indexType.types, function (t) { return getSimplifiedType(getIndexedAccessType(objectType, t), writing); });
                return writing ? getIntersectionType(types) : getUnionType(types);
            }
        }
        function unwrapSubstitution(type) {
            if (type.flags & 33554432 /* Substitution */) {
                return type.substitute;
            }
            return type;
        }
        // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return
        // the type itself if no transformation is possible. The writing flag indicates that the type is
        // the target of an assignment.
        function getSimplifiedIndexedAccessType(type, writing) {
            var cache = writing ? "simplifiedForWriting" : "simplifiedForReading";
            if (type[cache]) {
                return type[cache] === circularConstraintType ? type : type[cache];
            }
            type[cache] = circularConstraintType;
            // We recursively simplify the object type as it may in turn be an indexed access type. For example, with
            // '{ [P in T]: { [Q in U]: number } }[T][U]' we want to first simplify the inner indexed access type.
            var objectType = unwrapSubstitution(getSimplifiedType(type.objectType, writing));
            var indexType = getSimplifiedType(type.indexType, writing);
            // T[A | B] -> T[A] | T[B] (reading)
            // T[A | B] -> T[A] & T[B] (writing)
            var distributedOverIndex = distributeObjectOverIndexType(objectType, indexType, writing);
            if (distributedOverIndex) {
                return type[cache] = distributedOverIndex;
            }
            // Only do the inner distributions if the index can no longer be instantiated to cause index distribution again
            if (!(indexType.flags & 63176704 /* Instantiable */)) {
                // (T | U)[K] -> T[K] | U[K] (reading)
                // (T | U)[K] -> T[K] & U[K] (writing)
                // (T & U)[K] -> T[K] & U[K]
                var distributedOverObject = distributeIndexOverObjectType(objectType, indexType, writing);
                if (distributedOverObject) {
                    return type[cache] = distributedOverObject;
                }
            }
            // So ultimately (reading):
            // ((A & B) | C)[K1 | K2] -> ((A & B) | C)[K1] | ((A & B) | C)[K2] -> (A & B)[K1] | C[K1] | (A & B)[K2] | C[K2] -> (A[K1] & B[K1]) | C[K1] | (A[K2] & B[K2]) | C[K2]
            // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper
            // that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
            // construct the type Box<T[X]>.
            if (isGenericMappedType(objectType)) {
                return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), function (t) { return getSimplifiedType(t, writing); });
            }
            return type[cache] = type;
        }
        function getSimplifiedConditionalType(type, writing) {
            var checkType = type.checkType;
            var extendsType = type.extendsType;
            var trueType = getTrueTypeFromConditionalType(type);
            var falseType = getFalseTypeFromConditionalType(type);
            // Simplifications for types of the form `T extends U ? T : never` and `T extends U ? never : T`.
            if (falseType.flags & 131072 /* Never */ && getActualTypeVariable(trueType) === getActualTypeVariable(checkType)) {
                if (checkType.flags & 1 /* Any */ || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
                    return getSimplifiedType(trueType, writing);
                }
                else if (isIntersectionEmpty(checkType, extendsType)) { // Always false
                    return neverType;
                }
            }
            else if (trueType.flags & 131072 /* Never */ && getActualTypeVariable(falseType) === getActualTypeVariable(checkType)) {
                if (!(checkType.flags & 1 /* Any */) && isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
                    return neverType;
                }
                else if (checkType.flags & 1 /* Any */ || isIntersectionEmpty(checkType, extendsType)) { // Always false
                    return getSimplifiedType(falseType, writing);
                }
            }
            return type;
        }
        /**
         * Invokes union simplification logic to determine if an intersection is considered empty as a union constituent
         */
        function isIntersectionEmpty(type1, type2) {
            return !!(getUnionType([intersectTypes(type1, type2), neverType]).flags & 131072 /* Never */);
        }
        function substituteIndexedMappedType(objectType, index) {
            var mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [index]);
            var templateMapper = combineTypeMappers(objectType.mapper, mapper);
            return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
        }
        function getIndexedAccessType(objectType, indexType, accessNode, aliasSymbol, aliasTypeArguments) {
            return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, 0 /* None */, aliasSymbol, aliasTypeArguments) || (accessNode ? errorType : unknownType);
        }
        function getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, accessFlags, aliasSymbol, aliasTypeArguments) {
            if (accessFlags === void 0) { accessFlags = 0 /* None */; }
            if (objectType === wildcardType || indexType === wildcardType) {
                return wildcardType;
            }
            // If the object type has a string index signature and no other members we know that the result will
            // always be the type of that index signature and we can simplify accordingly.
            if (isStringIndexSignatureOnlyType(objectType) && !(indexType.flags & 98304 /* Nullable */) && isTypeAssignableToKind(indexType, 4 /* String */ | 8 /* Number */)) {
                indexType = stringType;
            }
            // If the index type is generic, or if the object type is generic and doesn't originate in an expression,
            // we are performing a higher-order index access where we cannot meaningfully access the properties of the
            // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in
            // an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]'
            // has always been resolved eagerly using the constraint type of 'this' at the given location.
            if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind !== 185 /* IndexedAccessType */) && isGenericObjectType(objectType)) {
                if (objectType.flags & 3 /* AnyOrUnknown */) {
                    return objectType;
                }
                // Defer the operation by creating an indexed access type.
                var id = objectType.id + "," + indexType.id;
                var type = indexedAccessTypes.get(id);
                if (!type) {
                    indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType, aliasSymbol, aliasTypeArguments));
                }
                return type;
            }
            // In the following we resolve T[K] to the type of the property in T selected by K.
            // We treat boolean as different from other unions to improve errors;
            // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'.
            var apparentObjectType = getReducedApparentType(objectType);
            if (indexType.flags & 1048576 /* Union */ && !(indexType.flags & 16 /* Boolean */)) {
                var propTypes = [];
                var wasMissingProp = false;
                for (var _i = 0, _a = indexType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    var propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, indexType, wasMissingProp, accessNode, accessFlags);
                    if (propType) {
                        propTypes.push(propType);
                    }
                    else if (!accessNode) {
                        // If there's no error node, we can immeditely stop, since error reporting is off
                        return undefined;
                    }
                    else {
                        // Otherwise we set a flag and return at the end of the loop so we still mark all errors
                        wasMissingProp = true;
                    }
                }
                if (wasMissingProp) {
                    return undefined;
                }
                return accessFlags & 2 /* Writing */ ? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments) : getUnionType(propTypes, 1 /* Literal */, aliasSymbol, aliasTypeArguments);
            }
            return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | 4 /* CacheSymbol */);
        }
        function getTypeFromIndexedAccessTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var objectType = getTypeFromTypeNode(node.objectType);
                var indexType = getTypeFromTypeNode(node.indexType);
                var potentialAlias = getAliasSymbolForTypeNode(node);
                var resolved = getIndexedAccessType(objectType, indexType, node, potentialAlias, getTypeArgumentsForAliasSymbol(potentialAlias));
                links.resolvedType = resolved.flags & 8388608 /* IndexedAccess */ &&
                    resolved.objectType === objectType &&
                    resolved.indexType === indexType ?
                    getConditionalFlowTypeOfType(resolved, node) : resolved;
            }
            return links.resolvedType;
        }
        function getTypeFromMappedTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var type = createObjectType(32 /* Mapped */, node.symbol);
                type.declaration = node;
                type.aliasSymbol = getAliasSymbolForTypeNode(node);
                type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(type.aliasSymbol);
                links.resolvedType = type;
                // Eagerly resolve the constraint type which forces an error if the constraint type circularly
                // references itself through one or more type aliases.
                getConstraintTypeFromMappedType(type);
            }
            return links.resolvedType;
        }
        function getActualTypeVariable(type) {
            if (type.flags & 33554432 /* Substitution */) {
                return type.baseType;
            }
            if (type.flags & 8388608 /* IndexedAccess */ && (type.objectType.flags & 33554432 /* Substitution */ ||
                type.indexType.flags & 33554432 /* Substitution */)) {
                return getIndexedAccessType(getActualTypeVariable(type.objectType), getActualTypeVariable(type.indexType));
            }
            return type;
        }
        function getConditionalType(root, mapper) {
            var result;
            var extraTypes;
            var _loop_12 = function () {
                var checkType = instantiateType(root.checkType, mapper);
                var checkTypeInstantiable = isGenericObjectType(checkType) || isGenericIndexType(checkType);
                var extendsType = instantiateType(root.extendsType, mapper);
                if (checkType === wildcardType || extendsType === wildcardType) {
                    return { value: wildcardType };
                }
                var combinedMapper = void 0;
                if (root.inferTypeParameters) {
                    var context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, 0 /* None */);
                    // We skip inference of the possible `infer` types unles the `extendsType` _is_ an infer type
                    // if it was, it's trivial to say that extendsType = checkType, however such a pattern is used to
                    // "reset" the type being build up during constraint calculation and avoid making an apparently "infinite" constraint
                    // so in those cases we refain from performing inference and retain the uninfered type parameter
                    if (!checkTypeInstantiable || !ts.some(root.inferTypeParameters, function (t) { return t === extendsType; })) {
                        // We don't want inferences from constraints as they may cause us to eagerly resolve the
                        // conditional type instead of deferring resolution. Also, we always want strict function
                        // types rules (i.e. proper contravariance) for inferences.
                        inferTypes(context.inferences, checkType, extendsType, 128 /* NoConstraints */ | 256 /* AlwaysStrict */);
                    }
                    combinedMapper = mergeTypeMappers(mapper, context.mapper);
                }
                // Instantiate the extends type including inferences for 'infer T' type parameters
                var inferredExtendsType = combinedMapper ? instantiateType(root.extendsType, combinedMapper) : extendsType;
                // We attempt to resolve the conditional type only when the check and extends types are non-generic
                if (!checkTypeInstantiable && !isGenericObjectType(inferredExtendsType) && !isGenericIndexType(inferredExtendsType)) {
                    // Return falseType for a definitely false extends check. We check an instantiations of the two
                    // types with type parameters mapped to the wildcard type, the most permissive instantiations
                    // possible (the wildcard type is assignable to and from all types). If those are not related,
                    // then no instantiations will be and we can just return the false branch type.
                    if (!(inferredExtendsType.flags & 3 /* AnyOrUnknown */) && (checkType.flags & 1 /* Any */ || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) {
                        // Return union of trueType and falseType for 'any' since it matches anything
                        if (checkType.flags & 1 /* Any */) {
                            (extraTypes || (extraTypes = [])).push(instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper));
                        }
                        // If falseType is an immediately nested conditional type that isn't distributive or has an
                        // identical checkType, switch to that type and loop.
                        var falseType_1 = root.falseType;
                        if (falseType_1.flags & 16777216 /* Conditional */) {
                            var newRoot = falseType_1.root;
                            if (newRoot.node.parent === root.node && (!newRoot.isDistributive || newRoot.checkType === root.checkType)) {
                                root = newRoot;
                                return "continue";
                            }
                        }
                        result = instantiateTypeWithoutDepthIncrease(falseType_1, mapper);
                        return "break";
                    }
                    // Return trueType for a definitely true extends check. We check instantiations of the two
                    // types with type parameters mapped to their restrictive form, i.e. a form of the type parameter
                    // that has no constraint. This ensures that, for example, the type
                    //   type Foo<T extends { x: any }> = T extends { x: string } ? string : number
                    // doesn't immediately resolve to 'string' instead of being deferred.
                    if (inferredExtendsType.flags & 3 /* AnyOrUnknown */ || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
                        result = instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper);
                        return "break";
                    }
                }
                // Return a deferred type for a check that is neither definitely true nor definitely false
                var erasedCheckType = getActualTypeVariable(checkType);
                result = createType(16777216 /* Conditional */);
                result.root = root;
                result.checkType = erasedCheckType;
                result.extendsType = extendsType;
                result.mapper = mapper;
                result.combinedMapper = combinedMapper;
                result.aliasSymbol = root.aliasSymbol;
                result.aliasTypeArguments = instantiateTypes(root.aliasTypeArguments, mapper); // TODO: GH#18217
                return "break";
            };
            // We loop here for an immediately nested conditional type in the false position, effectively treating
            // types of the form 'A extends B ? X : C extends D ? Y : E extends F ? Z : ...' as a single construct for
            // purposes of resolution. This means such types aren't subject to the instatiation depth limiter.
            while (true) {
                var state_4 = _loop_12();
                if (typeof state_4 === "object")
                    return state_4.value;
                if (state_4 === "break")
                    break;
            }
            return extraTypes ? getUnionType(ts.append(extraTypes, result)) : result;
        }
        function getTrueTypeFromConditionalType(type) {
            return type.resolvedTrueType || (type.resolvedTrueType = instantiateType(type.root.trueType, type.mapper));
        }
        function getFalseTypeFromConditionalType(type) {
            return type.resolvedFalseType || (type.resolvedFalseType = instantiateType(type.root.falseType, type.mapper));
        }
        function getInferredTrueTypeFromConditionalType(type) {
            return type.resolvedInferredTrueType || (type.resolvedInferredTrueType = type.combinedMapper ? instantiateType(type.root.trueType, type.combinedMapper) : getTrueTypeFromConditionalType(type));
        }
        function getInferTypeParameters(node) {
            var result;
            if (node.locals) {
                node.locals.forEach(function (symbol) {
                    if (symbol.flags & 262144 /* TypeParameter */) {
                        result = ts.append(result, getDeclaredTypeOfSymbol(symbol));
                    }
                });
            }
            return result;
        }
        function getTypeFromConditionalTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var checkType = getTypeFromTypeNode(node.checkType);
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                var aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
                var allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true);
                var outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : ts.filter(allOuterTypeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, node); });
                var root = {
                    node: node,
                    checkType: checkType,
                    extendsType: getTypeFromTypeNode(node.extendsType),
                    trueType: getTypeFromTypeNode(node.trueType),
                    falseType: getTypeFromTypeNode(node.falseType),
                    isDistributive: !!(checkType.flags & 262144 /* TypeParameter */),
                    inferTypeParameters: getInferTypeParameters(node),
                    outerTypeParameters: outerTypeParameters,
                    instantiations: undefined,
                    aliasSymbol: aliasSymbol,
                    aliasTypeArguments: aliasTypeArguments
                };
                links.resolvedType = getConditionalType(root, /*mapper*/ undefined);
                if (outerTypeParameters) {
                    root.instantiations = ts.createMap();
                    root.instantiations.set(getTypeListId(outerTypeParameters), links.resolvedType);
                }
            }
            return links.resolvedType;
        }
        function getTypeFromInferTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter));
            }
            return links.resolvedType;
        }
        function getIdentifierChain(node) {
            if (ts.isIdentifier(node)) {
                return [node];
            }
            else {
                return ts.append(getIdentifierChain(node.left), node.right);
            }
        }
        function getTypeFromImportTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                if (node.isTypeOf && node.typeArguments) { // Only the non-typeof form can make use of type arguments
                    error(node, ts.Diagnostics.Type_arguments_cannot_be_used_here);
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                if (!ts.isLiteralImportTypeNode(node)) {
                    error(node.argument, ts.Diagnostics.String_literal_expected);
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                var targetMeaning = node.isTypeOf ? 111551 /* Value */ : node.flags & 4194304 /* JSDoc */ ? 111551 /* Value */ | 788968 /* Type */ : 788968 /* Type */;
                // TODO: Future work: support unions/generics/whatever via a deferred import-type
                var innerModuleSymbol = resolveExternalModuleName(node, node.argument.literal);
                if (!innerModuleSymbol) {
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                var moduleSymbol = resolveExternalModuleSymbol(innerModuleSymbol, /*dontResolveAlias*/ false);
                if (!ts.nodeIsMissing(node.qualifier)) {
                    var nameStack = getIdentifierChain(node.qualifier);
                    var currentNamespace = moduleSymbol;
                    var current = void 0;
                    while (current = nameStack.shift()) {
                        var meaning = nameStack.length ? 1920 /* Namespace */ : targetMeaning;
                        var next = getSymbol(getExportsOfSymbol(getMergedSymbol(resolveSymbol(currentNamespace))), current.escapedText, meaning);
                        if (!next) {
                            error(current, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(currentNamespace), ts.declarationNameToString(current));
                            return links.resolvedType = errorType;
                        }
                        getNodeLinks(current).resolvedSymbol = next;
                        getNodeLinks(current.parent).resolvedSymbol = next;
                        currentNamespace = next;
                    }
                    links.resolvedType = resolveImportSymbolType(node, links, currentNamespace, targetMeaning);
                }
                else {
                    if (moduleSymbol.flags & targetMeaning) {
                        links.resolvedType = resolveImportSymbolType(node, links, moduleSymbol, targetMeaning);
                    }
                    else {
                        var errorMessage = targetMeaning === 111551 /* Value */
                            ? ts.Diagnostics.Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here
                            : ts.Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0;
                        error(node, errorMessage, node.argument.literal.text);
                        links.resolvedSymbol = unknownSymbol;
                        links.resolvedType = errorType;
                    }
                }
            }
            return links.resolvedType;
        }
        function resolveImportSymbolType(node, links, symbol, meaning) {
            var resolvedSymbol = resolveSymbol(symbol);
            links.resolvedSymbol = resolvedSymbol;
            if (meaning === 111551 /* Value */) {
                return getTypeOfSymbol(symbol); // intentionally doesn't use resolved symbol so type is cached as expected on the alias
            }
            else {
                return getTypeReferenceType(node, resolvedSymbol); // getTypeReferenceType doesn't handle aliases - it must get the resolved symbol
            }
        }
        function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // Deferred resolution of members is handled by resolveObjectTypeMembers
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                if (getMembersOfSymbol(node.symbol).size === 0 && !aliasSymbol) {
                    links.resolvedType = emptyTypeLiteralType;
                }
                else {
                    var type = createObjectType(16 /* Anonymous */, node.symbol);
                    type.aliasSymbol = aliasSymbol;
                    type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
                    if (ts.isJSDocTypeLiteral(node) && node.isArrayType) {
                        type = createArrayType(type);
                    }
                    links.resolvedType = type;
                }
            }
            return links.resolvedType;
        }
        function getAliasSymbolForTypeNode(node) {
            var host = node.parent;
            while (ts.isParenthesizedTypeNode(host) || ts.isTypeOperatorNode(host) && host.operator === 138 /* ReadonlyKeyword */) {
                host = host.parent;
            }
            return ts.isTypeAlias(host) ? getSymbolOfNode(host) : undefined;
        }
        function getTypeArgumentsForAliasSymbol(symbol) {
            return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined;
        }
        function isNonGenericObjectType(type) {
            return !!(type.flags & 524288 /* Object */) && !isGenericMappedType(type);
        }
        function isEmptyObjectTypeOrSpreadsIntoEmptyObject(type) {
            return isEmptyObjectType(type) || !!(type.flags & (65536 /* Null */ | 32768 /* Undefined */ | 528 /* BooleanLike */ | 296 /* NumberLike */ | 2112 /* BigIntLike */ | 132 /* StringLike */ | 1056 /* EnumLike */ | 67108864 /* NonPrimitive */ | 4194304 /* Index */));
        }
        function isSinglePropertyAnonymousObjectType(type) {
            return !!(type.flags & 524288 /* Object */) &&
                !!(ts.getObjectFlags(type) & 16 /* Anonymous */) &&
                (ts.length(getPropertiesOfType(type)) === 1 || ts.every(getPropertiesOfType(type), function (p) { return !!(p.flags & 16777216 /* Optional */); }));
        }
        function tryMergeUnionOfObjectTypeAndEmptyObject(type, readonly) {
            if (type.types.length === 2) {
                var firstType = type.types[0];
                var secondType = type.types[1];
                if (ts.every(type.types, isEmptyObjectTypeOrSpreadsIntoEmptyObject)) {
                    return isEmptyObjectType(firstType) ? firstType : isEmptyObjectType(secondType) ? secondType : emptyObjectType;
                }
                if (isEmptyObjectTypeOrSpreadsIntoEmptyObject(firstType) && isSinglePropertyAnonymousObjectType(secondType)) {
                    return getAnonymousPartialType(secondType);
                }
                if (isEmptyObjectTypeOrSpreadsIntoEmptyObject(secondType) && isSinglePropertyAnonymousObjectType(firstType)) {
                    return getAnonymousPartialType(firstType);
                }
            }
            function getAnonymousPartialType(type) {
                // gets the type as if it had been spread, but where everything in the spread is made optional
                var members = ts.createSymbolTable();
                for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (ts.getDeclarationModifierFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */)) {
                        // do nothing, skip privates
                    }
                    else if (isSpreadableProperty(prop)) {
                        var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */);
                        var flags = 4 /* Property */ | 16777216 /* Optional */;
                        var result = createSymbol(flags, prop.escapedName, readonly ? 8 /* Readonly */ : 0);
                        result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
                        result.declarations = prop.declarations;
                        result.nameType = getSymbolLinks(prop).nameType;
                        result.syntheticOrigin = prop;
                        members.set(prop.escapedName, result);
                    }
                }
                var spread = createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, getIndexInfoOfType(type, 0 /* String */), getIndexInfoOfType(type, 1 /* Number */));
                spread.objectFlags |= 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
                return spread;
            }
        }
        /**
         * Since the source of spread types are object literals, which are not binary,
         * this function should be called in a left folding style, with left = previous result of getSpreadType
         * and right = the new element to be spread.
         */
        function getSpreadType(left, right, symbol, objectFlags, readonly) {
            if (left.flags & 1 /* Any */ || right.flags & 1 /* Any */) {
                return anyType;
            }
            if (left.flags & 2 /* Unknown */ || right.flags & 2 /* Unknown */) {
                return unknownType;
            }
            if (left.flags & 131072 /* Never */) {
                return right;
            }
            if (right.flags & 131072 /* Never */) {
                return left;
            }
            if (left.flags & 1048576 /* Union */) {
                var merged = tryMergeUnionOfObjectTypeAndEmptyObject(left, readonly);
                if (merged) {
                    return getSpreadType(merged, right, symbol, objectFlags, readonly);
                }
                return mapType(left, function (t) { return getSpreadType(t, right, symbol, objectFlags, readonly); });
            }
            if (right.flags & 1048576 /* Union */) {
                var merged = tryMergeUnionOfObjectTypeAndEmptyObject(right, readonly);
                if (merged) {
                    return getSpreadType(left, merged, symbol, objectFlags, readonly);
                }
                return mapType(right, function (t) { return getSpreadType(left, t, symbol, objectFlags, readonly); });
            }
            if (right.flags & (528 /* BooleanLike */ | 296 /* NumberLike */ | 2112 /* BigIntLike */ | 132 /* StringLike */ | 1056 /* EnumLike */ | 67108864 /* NonPrimitive */ | 4194304 /* Index */)) {
                return left;
            }
            if (isGenericObjectType(left) || isGenericObjectType(right)) {
                if (isEmptyObjectType(left)) {
                    return right;
                }
                // When the left type is an intersection, we may need to merge the last constituent of the
                // intersection with the right type. For example when the left type is 'T & { a: string }'
                // and the right type is '{ b: string }' we produce 'T & { a: string, b: string }'.
                if (left.flags & 2097152 /* Intersection */) {
                    var types = left.types;
                    var lastLeft = types[types.length - 1];
                    if (isNonGenericObjectType(lastLeft) && isNonGenericObjectType(right)) {
                        return getIntersectionType(ts.concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, objectFlags, readonly)]));
                    }
                }
                return getIntersectionType([left, right]);
            }
            var members = ts.createSymbolTable();
            var skippedPrivateMembers = ts.createUnderscoreEscapedMap();
            var stringIndexInfo;
            var numberIndexInfo;
            if (left === emptyObjectType) {
                // for the first spread element, left === emptyObjectType, so take the right's string indexer
                stringIndexInfo = getIndexInfoOfType(right, 0 /* String */);
                numberIndexInfo = getIndexInfoOfType(right, 1 /* Number */);
            }
            else {
                stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 0 /* String */), getIndexInfoOfType(right, 0 /* String */));
                numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 1 /* Number */), getIndexInfoOfType(right, 1 /* Number */));
            }
            for (var _i = 0, _a = getPropertiesOfType(right); _i < _a.length; _i++) {
                var rightProp = _a[_i];
                if (ts.getDeclarationModifierFlagsFromSymbol(rightProp) & (8 /* Private */ | 16 /* Protected */)) {
                    skippedPrivateMembers.set(rightProp.escapedName, true);
                }
                else if (isSpreadableProperty(rightProp)) {
                    members.set(rightProp.escapedName, getSpreadSymbol(rightProp, readonly));
                }
            }
            for (var _b = 0, _c = getPropertiesOfType(left); _b < _c.length; _b++) {
                var leftProp = _c[_b];
                if (skippedPrivateMembers.has(leftProp.escapedName) || !isSpreadableProperty(leftProp)) {
                    continue;
                }
                if (members.has(leftProp.escapedName)) {
                    var rightProp = members.get(leftProp.escapedName);
                    var rightType = getTypeOfSymbol(rightProp);
                    if (rightProp.flags & 16777216 /* Optional */) {
                        var declarations = ts.concatenate(leftProp.declarations, rightProp.declarations);
                        var flags = 4 /* Property */ | (leftProp.flags & 16777216 /* Optional */);
                        var result = createSymbol(flags, leftProp.escapedName);
                        result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, 524288 /* NEUndefined */)]);
                        result.leftSpread = leftProp;
                        result.rightSpread = rightProp;
                        result.declarations = declarations;
                        result.nameType = getSymbolLinks(leftProp).nameType;
                        members.set(leftProp.escapedName, result);
                    }
                }
                else {
                    members.set(leftProp.escapedName, getSpreadSymbol(leftProp, readonly));
                }
            }
            var spread = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, getIndexInfoWithReadonly(stringIndexInfo, readonly), getIndexInfoWithReadonly(numberIndexInfo, readonly));
            spread.objectFlags |= 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */ | 1024 /* ContainsSpread */ | objectFlags;
            return spread;
        }
        /** We approximate own properties as non-methods plus methods that are inside the object literal */
        function isSpreadableProperty(prop) {
            return !ts.some(prop.declarations, ts.isPrivateIdentifierPropertyDeclaration) &&
                (!(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) ||
                    !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); }));
        }
        function getSpreadSymbol(prop, readonly) {
            var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */);
            if (!isSetonlyAccessor && readonly === isReadonlySymbol(prop)) {
                return prop;
            }
            var flags = 4 /* Property */ | (prop.flags & 16777216 /* Optional */);
            var result = createSymbol(flags, prop.escapedName, readonly ? 8 /* Readonly */ : 0);
            result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
            result.declarations = prop.declarations;
            result.nameType = getSymbolLinks(prop).nameType;
            result.syntheticOrigin = prop;
            return result;
        }
        function getIndexInfoWithReadonly(info, readonly) {
            return info && info.isReadonly !== readonly ? createIndexInfo(info.type, readonly, info.declaration) : info;
        }
        function createLiteralType(flags, value, symbol) {
            var type = createType(flags);
            type.symbol = symbol;
            type.value = value;
            return type;
        }
        function getFreshTypeOfLiteralType(type) {
            if (type.flags & 2944 /* Literal */) {
                if (!type.freshType) {
                    var freshType = createLiteralType(type.flags, type.value, type.symbol);
                    freshType.regularType = type;
                    freshType.freshType = freshType;
                    type.freshType = freshType;
                }
                return type.freshType;
            }
            return type;
        }
        function getRegularTypeOfLiteralType(type) {
            return type.flags & 2944 /* Literal */ ? type.regularType :
                type.flags & 1048576 /* Union */ ? (type.regularType || (type.regularType = getUnionType(ts.sameMap(type.types, getRegularTypeOfLiteralType)))) :
                    type;
        }
        function isFreshLiteralType(type) {
            return !!(type.flags & 2944 /* Literal */) && type.freshType === type;
        }
        function getLiteralType(value, enumId, symbol) {
            // We store all literal types in a single map with keys of the form '#NNN' and '@SSS',
            // where NNN is the text representation of a numeric literal and SSS are the characters
            // of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where
            // EEE is a unique id for the containing enum type.
            var qualifier = typeof value === "number" ? "#" : typeof value === "string" ? "@" : "n";
            var key = (enumId ? enumId : "") + qualifier + (typeof value === "object" ? ts.pseudoBigIntToString(value) : value);
            var type = literalTypes.get(key);
            if (!type) {
                var flags = (typeof value === "number" ? 256 /* NumberLiteral */ :
                    typeof value === "string" ? 128 /* StringLiteral */ : 2048 /* BigIntLiteral */) |
                    (enumId ? 1024 /* EnumLiteral */ : 0);
                literalTypes.set(key, type = createLiteralType(flags, value, symbol));
                type.regularType = type;
            }
            return type;
        }
        function getTypeFromLiteralTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal));
            }
            return links.resolvedType;
        }
        function createUniqueESSymbolType(symbol) {
            var type = createType(8192 /* UniqueESSymbol */);
            type.symbol = symbol;
            type.escapedName = "__@" + type.symbol.escapedName + "@" + getSymbolId(type.symbol);
            return type;
        }
        function getESSymbolLikeTypeForNode(node) {
            if (ts.isValidESSymbolDeclaration(node)) {
                var symbol = getSymbolOfNode(node);
                var links = getSymbolLinks(symbol);
                return links.uniqueESSymbolType || (links.uniqueESSymbolType = createUniqueESSymbolType(symbol));
            }
            return esSymbolType;
        }
        function getThisType(node) {
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            var parent = container && container.parent;
            if (parent && (ts.isClassLike(parent) || parent.kind === 246 /* InterfaceDeclaration */)) {
                if (!ts.hasModifier(container, 32 /* Static */) &&
                    (!ts.isConstructorDeclaration(container) || ts.isNodeDescendantOf(node, container.body))) {
                    return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType;
                }
            }
            // inside x.prototype = { ... }
            if (parent && ts.isObjectLiteralExpression(parent) && ts.isBinaryExpression(parent.parent) && ts.getAssignmentDeclarationKind(parent.parent) === 6 /* Prototype */) {
                return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent.parent.left).parent).thisType;
            }
            // /** @return {this} */
            // x.prototype.m = function() { ... }
            var host = node.flags & 4194304 /* JSDoc */ ? ts.getHostSignatureFromJSDoc(node) : undefined;
            if (host && ts.isFunctionExpression(host) && ts.isBinaryExpression(host.parent) && ts.getAssignmentDeclarationKind(host.parent) === 3 /* PrototypeProperty */) {
                return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(host.parent.left).parent).thisType;
            }
            // inside constructor function C() { ... }
            if (isJSConstructor(container) && ts.isNodeDescendantOf(node, container.body)) {
                return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(container)).thisType;
            }
            error(node, ts.Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface);
            return errorType;
        }
        function getTypeFromThisTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getThisType(node);
            }
            return links.resolvedType;
        }
        function getTypeFromTypeNode(node) {
            return getConditionalFlowTypeOfType(getTypeFromTypeNodeWorker(node), node);
        }
        function getTypeFromTypeNodeWorker(node) {
            switch (node.kind) {
                case 125 /* AnyKeyword */:
                case 295 /* JSDocAllType */:
                case 296 /* JSDocUnknownType */:
                    return anyType;
                case 148 /* UnknownKeyword */:
                    return unknownType;
                case 143 /* StringKeyword */:
                    return stringType;
                case 140 /* NumberKeyword */:
                    return numberType;
                case 151 /* BigIntKeyword */:
                    return bigintType;
                case 128 /* BooleanKeyword */:
                    return booleanType;
                case 144 /* SymbolKeyword */:
                    return esSymbolType;
                case 110 /* VoidKeyword */:
                    return voidType;
                case 146 /* UndefinedKeyword */:
                    return undefinedType;
                case 100 /* NullKeyword */:
                    return nullType;
                case 137 /* NeverKeyword */:
                    return neverType;
                case 141 /* ObjectKeyword */:
                    return node.flags & 131072 /* JavaScriptFile */ && !noImplicitAny ? anyType : nonPrimitiveType;
                case 183 /* ThisType */:
                case 104 /* ThisKeyword */:
                    return getTypeFromThisTypeNode(node);
                case 187 /* LiteralType */:
                    return getTypeFromLiteralTypeNode(node);
                case 169 /* TypeReference */:
                    return getTypeFromTypeReference(node);
                case 168 /* TypePredicate */:
                    return node.assertsModifier ? voidType : booleanType;
                case 216 /* ExpressionWithTypeArguments */:
                    return getTypeFromTypeReference(node);
                case 172 /* TypeQuery */:
                    return getTypeFromTypeQueryNode(node);
                case 174 /* ArrayType */:
                case 175 /* TupleType */:
                    return getTypeFromArrayOrTupleTypeNode(node);
                case 176 /* OptionalType */:
                    return getTypeFromOptionalTypeNode(node);
                case 178 /* UnionType */:
                    return getTypeFromUnionTypeNode(node);
                case 179 /* IntersectionType */:
                    return getTypeFromIntersectionTypeNode(node);
                case 297 /* JSDocNullableType */:
                    return getTypeFromJSDocNullableTypeNode(node);
                case 299 /* JSDocOptionalType */:
                    return addOptionality(getTypeFromTypeNode(node.type));
                case 182 /* ParenthesizedType */:
                case 298 /* JSDocNonNullableType */:
                case 294 /* JSDocTypeExpression */:
                    return getTypeFromTypeNode(node.type);
                case 177 /* RestType */:
                    return getElementTypeOfArrayType(getTypeFromTypeNode(node.type)) || errorType;
                case 301 /* JSDocVariadicType */:
                    return getTypeFromJSDocVariadicType(node);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */:
                case 173 /* TypeLiteral */:
                case 304 /* JSDocTypeLiteral */:
                case 300 /* JSDocFunctionType */:
                case 305 /* JSDocSignature */:
                    return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                case 184 /* TypeOperator */:
                    return getTypeFromTypeOperatorNode(node);
                case 185 /* IndexedAccessType */:
                    return getTypeFromIndexedAccessTypeNode(node);
                case 186 /* MappedType */:
                    return getTypeFromMappedTypeNode(node);
                case 180 /* ConditionalType */:
                    return getTypeFromConditionalTypeNode(node);
                case 181 /* InferType */:
                    return getTypeFromInferTypeNode(node);
                case 188 /* ImportType */:
                    return getTypeFromImportTypeNode(node);
                // This function assumes that an identifier or qualified name is a type expression
                // Callers should first ensure this by calling isTypeNode
                case 75 /* Identifier */:
                case 153 /* QualifiedName */:
                    var symbol = getSymbolAtLocation(node);
                    return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
                default:
                    return errorType;
            }
        }
        function instantiateList(items, mapper, instantiator) {
            if (items && items.length) {
                for (var i = 0; i < items.length; i++) {
                    var item = items[i];
                    var mapped = instantiator(item, mapper);
                    if (item !== mapped) {
                        var result = i === 0 ? [] : items.slice(0, i);
                        result.push(mapped);
                        for (i++; i < items.length; i++) {
                            result.push(instantiator(items[i], mapper));
                        }
                        return result;
                    }
                }
            }
            return items;
        }
        function instantiateTypes(types, mapper) {
            return instantiateList(types, mapper, instantiateType);
        }
        function instantiateSignatures(signatures, mapper) {
            return instantiateList(signatures, mapper, instantiateSignature);
        }
        function createTypeMapper(sources, targets) {
            return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : makeArrayTypeMapper(sources, targets);
        }
        function getMappedType(type, mapper) {
            switch (mapper.kind) {
                case 0 /* Simple */:
                    return type === mapper.source ? mapper.target : type;
                case 1 /* Array */:
                    var sources = mapper.sources;
                    var targets = mapper.targets;
                    for (var i = 0; i < sources.length; i++) {
                        if (type === sources[i]) {
                            return targets ? targets[i] : anyType;
                        }
                    }
                    return type;
                case 2 /* Function */:
                    return mapper.func(type);
                case 3 /* Composite */:
                case 4 /* Merged */:
                    var t1 = getMappedType(type, mapper.mapper1);
                    return t1 !== type && mapper.kind === 3 /* Composite */ ? instantiateType(t1, mapper.mapper2) : getMappedType(t1, mapper.mapper2);
            }
        }
        function makeUnaryTypeMapper(source, target) {
            return { kind: 0 /* Simple */, source: source, target: target };
        }
        function makeArrayTypeMapper(sources, targets) {
            return { kind: 1 /* Array */, sources: sources, targets: targets };
        }
        function makeFunctionTypeMapper(func) {
            return { kind: 2 /* Function */, func: func };
        }
        function makeCompositeTypeMapper(kind, mapper1, mapper2) {
            return { kind: kind, mapper1: mapper1, mapper2: mapper2 };
        }
        function createTypeEraser(sources) {
            return createTypeMapper(sources, /*targets*/ undefined);
        }
        /**
         * Maps forward-references to later types parameters to the empty object type.
         * This is used during inference when instantiating type parameter defaults.
         */
        function createBackreferenceMapper(context, index) {
            return makeFunctionTypeMapper(function (t) { return ts.findIndex(context.inferences, function (info) { return info.typeParameter === t; }) >= index ? unknownType : t; });
        }
        function combineTypeMappers(mapper1, mapper2) {
            return mapper1 ? makeCompositeTypeMapper(3 /* Composite */, mapper1, mapper2) : mapper2;
        }
        function mergeTypeMappers(mapper1, mapper2) {
            return mapper1 ? makeCompositeTypeMapper(4 /* Merged */, mapper1, mapper2) : mapper2;
        }
        function prependTypeMapping(source, target, mapper) {
            return !mapper ? makeUnaryTypeMapper(source, target) : makeCompositeTypeMapper(4 /* Merged */, makeUnaryTypeMapper(source, target), mapper);
        }
        function appendTypeMapping(mapper, source, target) {
            return !mapper ? makeUnaryTypeMapper(source, target) : makeCompositeTypeMapper(4 /* Merged */, mapper, makeUnaryTypeMapper(source, target));
        }
        function getRestrictiveTypeParameter(tp) {
            return tp.constraint === unknownType ? tp : tp.restrictiveInstantiation || (tp.restrictiveInstantiation = createTypeParameter(tp.symbol),
                tp.restrictiveInstantiation.constraint = unknownType,
                tp.restrictiveInstantiation);
        }
        function cloneTypeParameter(typeParameter) {
            var result = createTypeParameter(typeParameter.symbol);
            result.target = typeParameter;
            return result;
        }
        function instantiateTypePredicate(predicate, mapper) {
            return createTypePredicate(predicate.kind, predicate.parameterName, predicate.parameterIndex, instantiateType(predicate.type, mapper));
        }
        function instantiateSignature(signature, mapper, eraseTypeParameters) {
            var freshTypeParameters;
            if (signature.typeParameters && !eraseTypeParameters) {
                // First create a fresh set of type parameters, then include a mapping from the old to the
                // new type parameters in the mapper function. Finally store this mapper in the new type
                // parameters such that we can use it when instantiating constraints.
                freshTypeParameters = ts.map(signature.typeParameters, cloneTypeParameter);
                mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
                for (var _i = 0, freshTypeParameters_1 = freshTypeParameters; _i < freshTypeParameters_1.length; _i++) {
                    var tp = freshTypeParameters_1[_i];
                    tp.mapper = mapper;
                }
            }
            // Don't compute resolvedReturnType and resolvedTypePredicate now,
            // because using `mapper` now could trigger inferences to become fixed. (See `createInferenceContext`.)
            // See GH#17600.
            var result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), 
            /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, signature.minArgumentCount, signature.flags & 3 /* PropagatingFlags */);
            result.target = signature;
            result.mapper = mapper;
            return result;
        }
        function instantiateSymbol(symbol, mapper) {
            var links = getSymbolLinks(symbol);
            if (links.type && !couldContainTypeVariables(links.type)) {
                // If the type of the symbol is already resolved, and if that type could not possibly
                // be affected by instantiation, simply return the symbol itself.
                return symbol;
            }
            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
                // If symbol being instantiated is itself a instantiation, fetch the original target and combine the
                // type mappers. This ensures that original type identities are properly preserved and that aliases
                // always reference a non-aliases.
                symbol = links.target;
                mapper = combineTypeMappers(links.mapper, mapper);
            }
            // Keep the flags from the symbol we're instantiating.  Mark that is instantiated, and
            // also transient so that we can just store data on it directly.
            var result = createSymbol(symbol.flags, symbol.escapedName, 1 /* Instantiated */ | ts.getCheckFlags(symbol) & (8 /* Readonly */ | 4096 /* Late */ | 16384 /* OptionalParameter */ | 32768 /* RestParameter */));
            result.declarations = symbol.declarations;
            result.parent = symbol.parent;
            result.target = symbol;
            result.mapper = mapper;
            if (symbol.valueDeclaration) {
                result.valueDeclaration = symbol.valueDeclaration;
            }
            if (links.nameType) {
                result.nameType = links.nameType;
            }
            return result;
        }
        function getObjectTypeInstantiation(type, mapper) {
            var target = type.objectFlags & 64 /* Instantiated */ ? type.target : type;
            var node = type.objectFlags & 4 /* Reference */ ? type.node : type.symbol.declarations[0];
            var links = getNodeLinks(node);
            var typeParameters = links.outerTypeParameters;
            if (!typeParameters) {
                // The first time an anonymous type is instantiated we compute and store a list of the type
                // parameters that are in scope (and therefore potentially referenced). For type literals that
                // aren't the right hand side of a generic type alias declaration we optimize by reducing the
                // set of type parameters to those that are possibly referenced in the literal.
                var declaration_1 = node;
                if (ts.isInJSFile(declaration_1)) {
                    var paramTag = ts.findAncestor(declaration_1, ts.isJSDocParameterTag);
                    if (paramTag) {
                        var paramSymbol = ts.getParameterSymbolFromJSDoc(paramTag);
                        if (paramSymbol) {
                            declaration_1 = paramSymbol.valueDeclaration;
                        }
                    }
                }
                var outerTypeParameters = getOuterTypeParameters(declaration_1, /*includeThisTypes*/ true);
                if (isJSConstructor(declaration_1)) {
                    var templateTagParameters = getTypeParametersFromDeclaration(declaration_1);
                    outerTypeParameters = ts.addRange(outerTypeParameters, templateTagParameters);
                }
                typeParameters = outerTypeParameters || ts.emptyArray;
                typeParameters = (target.objectFlags & 4 /* Reference */ || target.symbol.flags & 2048 /* TypeLiteral */) && !target.aliasTypeArguments ?
                    ts.filter(typeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, declaration_1); }) :
                    typeParameters;
                links.outerTypeParameters = typeParameters;
                if (typeParameters.length) {
                    links.instantiations = ts.createMap();
                    links.instantiations.set(getTypeListId(typeParameters), target);
                }
            }
            if (typeParameters.length) {
                // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the
                // mapper to the type parameters to produce the effective list of type arguments, and compute the
                // instantiation cache key from the type IDs of the type arguments.
                var combinedMapper_1 = combineTypeMappers(type.mapper, mapper);
                var typeArguments = ts.map(typeParameters, function (t) { return getMappedType(t, combinedMapper_1); });
                var id = getTypeListId(typeArguments);
                var result = links.instantiations.get(id);
                if (!result) {
                    var newMapper = createTypeMapper(typeParameters, typeArguments);
                    result = target.objectFlags & 4 /* Reference */ ? createDeferredTypeReference(type.target, type.node, newMapper) :
                        target.objectFlags & 32 /* Mapped */ ? instantiateMappedType(target, newMapper) :
                            instantiateAnonymousType(target, newMapper);
                    links.instantiations.set(id, result);
                }
                return result;
            }
            return type;
        }
        function maybeTypeParameterReference(node) {
            return !(node.kind === 153 /* QualifiedName */ ||
                node.parent.kind === 169 /* TypeReference */ && node.parent.typeArguments && node === node.parent.typeName ||
                node.parent.kind === 188 /* ImportType */ && node.parent.typeArguments && node === node.parent.qualifier);
        }
        function isTypeParameterPossiblyReferenced(tp, node) {
            // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks
            // between the node and the type parameter declaration, if the node contains actual references to the
            // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced.
            if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) {
                var container = tp.symbol.declarations[0].parent;
                for (var n = node; n !== container; n = n.parent) {
                    if (!n || n.kind === 223 /* Block */ || n.kind === 180 /* ConditionalType */ && ts.forEachChild(n.extendsType, containsReference)) {
                        return true;
                    }
                }
                return !!ts.forEachChild(node, containsReference);
            }
            return true;
            function containsReference(node) {
                switch (node.kind) {
                    case 183 /* ThisType */:
                        return !!tp.isThisType;
                    case 75 /* Identifier */:
                        return !tp.isThisType && ts.isPartOfTypeNode(node) && maybeTypeParameterReference(node) &&
                            getTypeFromTypeNodeWorker(node) === tp; // use worker because we're looking for === equality
                    case 172 /* TypeQuery */:
                        return true;
                }
                return !!ts.forEachChild(node, containsReference);
            }
        }
        function getHomomorphicTypeVariable(type) {
            var constraintType = getConstraintTypeFromMappedType(type);
            if (constraintType.flags & 4194304 /* Index */) {
                var typeVariable = getActualTypeVariable(constraintType.type);
                if (typeVariable.flags & 262144 /* TypeParameter */) {
                    return typeVariable;
                }
            }
            return undefined;
        }
        function instantiateMappedType(type, mapper) {
            // For a homomorphic mapped type { [P in keyof T]: X }, where T is some type variable, the mapping
            // operation depends on T as follows:
            // * If T is a primitive type no mapping is performed and the result is simply T.
            // * If T is a union type we distribute the mapped type over the union.
            // * If T is an array we map to an array where the element type has been transformed.
            // * If T is a tuple we map to a tuple where the element types have been transformed.
            // * Otherwise we map to an object type where the type of each property has been transformed.
            // For example, when T is instantiated to a union type A | B, we produce { [P in keyof A]: X } |
            // { [P in keyof B]: X }, and when when T is instantiated to a union type A | undefined, we produce
            // { [P in keyof A]: X } | undefined.
            var typeVariable = getHomomorphicTypeVariable(type);
            if (typeVariable) {
                var mappedTypeVariable = instantiateType(typeVariable, mapper);
                if (typeVariable !== mappedTypeVariable) {
                    return mapType(getReducedType(mappedTypeVariable), function (t) {
                        if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && t !== errorType) {
                            var replacementMapper = prependTypeMapping(typeVariable, t, mapper);
                            return isArrayType(t) ? instantiateMappedArrayType(t, type, replacementMapper) :
                                isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) :
                                    instantiateAnonymousType(type, replacementMapper);
                        }
                        return t;
                    });
                }
            }
            return instantiateAnonymousType(type, mapper);
        }
        function getModifiedReadonlyState(state, modifiers) {
            return modifiers & 1 /* IncludeReadonly */ ? true : modifiers & 2 /* ExcludeReadonly */ ? false : state;
        }
        function instantiateMappedArrayType(arrayType, mappedType, mapper) {
            var elementType = instantiateMappedTypeTemplate(mappedType, numberType, /*isOptional*/ true, mapper);
            return elementType === errorType ? errorType :
                createArrayType(elementType, getModifiedReadonlyState(isReadonlyArrayType(arrayType), getMappedTypeModifiers(mappedType)));
        }
        function instantiateMappedTupleType(tupleType, mappedType, mapper) {
            var minLength = tupleType.target.minLength;
            var elementTypes = ts.map(getTypeArguments(tupleType), function (_, i) {
                return instantiateMappedTypeTemplate(mappedType, getLiteralType("" + i), i >= minLength, mapper);
            });
            var modifiers = getMappedTypeModifiers(mappedType);
            var newMinLength = modifiers & 4 /* IncludeOptional */ ? 0 :
                modifiers & 8 /* ExcludeOptional */ ? getTypeReferenceArity(tupleType) - (tupleType.target.hasRestElement ? 1 : 0) :
                    minLength;
            var newReadonly = getModifiedReadonlyState(tupleType.target.readonly, modifiers);
            return ts.contains(elementTypes, errorType) ? errorType :
                createTupleType(elementTypes, newMinLength, tupleType.target.hasRestElement, newReadonly, tupleType.target.associatedNames);
        }
        function instantiateMappedTypeTemplate(type, key, isOptional, mapper) {
            var templateMapper = appendTypeMapping(mapper, getTypeParameterFromMappedType(type), key);
            var propType = instantiateType(getTemplateTypeFromMappedType(type.target || type), templateMapper);
            var modifiers = getMappedTypeModifiers(type);
            return strictNullChecks && modifiers & 4 /* IncludeOptional */ && !maybeTypeOfKind(propType, 32768 /* Undefined */ | 16384 /* Void */) ? getOptionalType(propType) :
                strictNullChecks && modifiers & 8 /* ExcludeOptional */ && isOptional ? getTypeWithFacts(propType, 524288 /* NEUndefined */) :
                    propType;
        }
        function instantiateAnonymousType(type, mapper) {
            var result = createObjectType(type.objectFlags | 64 /* Instantiated */, type.symbol);
            if (type.objectFlags & 32 /* Mapped */) {
                result.declaration = type.declaration;
                // C.f. instantiateSignature
                var origTypeParameter = getTypeParameterFromMappedType(type);
                var freshTypeParameter = cloneTypeParameter(origTypeParameter);
                result.typeParameter = freshTypeParameter;
                mapper = combineTypeMappers(makeUnaryTypeMapper(origTypeParameter, freshTypeParameter), mapper);
                freshTypeParameter.mapper = mapper;
            }
            result.target = type;
            result.mapper = mapper;
            result.aliasSymbol = type.aliasSymbol;
            result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
            return result;
        }
        function getConditionalTypeInstantiation(type, mapper) {
            var root = type.root;
            if (root.outerTypeParameters) {
                // We are instantiating a conditional type that has one or more type parameters in scope. Apply the
                // mapper to the type parameters to produce the effective list of type arguments, and compute the
                // instantiation cache key from the type IDs of the type arguments.
                var typeArguments = ts.map(root.outerTypeParameters, function (t) { return getMappedType(t, mapper); });
                var id = getTypeListId(typeArguments);
                var result = root.instantiations.get(id);
                if (!result) {
                    var newMapper = createTypeMapper(root.outerTypeParameters, typeArguments);
                    result = instantiateConditionalType(root, newMapper);
                    root.instantiations.set(id, result);
                }
                return result;
            }
            return type;
        }
        function instantiateConditionalType(root, mapper) {
            // Check if we have a conditional type where the check type is a naked type parameter. If so,
            // the conditional type is distributive over union types and when T is instantiated to a union
            // type A | B, we produce (A extends U ? X : Y) | (B extends U ? X : Y).
            if (root.isDistributive) {
                var checkType_1 = root.checkType;
                var instantiatedType = getMappedType(checkType_1, mapper);
                if (checkType_1 !== instantiatedType && instantiatedType.flags & (1048576 /* Union */ | 131072 /* Never */)) {
                    return mapType(instantiatedType, function (t) { return getConditionalType(root, prependTypeMapping(checkType_1, t, mapper)); });
                }
            }
            return getConditionalType(root, mapper);
        }
        function instantiateType(type, mapper) {
            if (!type || !mapper) {
                return type;
            }
            if (instantiationDepth === 50 || instantiationCount >= 5000000) {
                // We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing
                // with a combination of infinite generic types that perpetually generate new type identities. We stop
                // the recursion here by yielding the error type.
                error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
                return errorType;
            }
            totalInstantiationCount++;
            instantiationCount++;
            instantiationDepth++;
            var result = instantiateTypeWorker(type, mapper);
            instantiationDepth--;
            return result;
        }
        /**
         * This can be used to avoid the penalty on instantiation depth for types which result from immediate
         * simplification. It essentially removes the depth increase done in `instantiateType`.
         */
        function instantiateTypeWithoutDepthIncrease(type, mapper) {
            instantiationDepth--;
            var result = instantiateType(type, mapper);
            instantiationDepth++;
            return result;
        }
        function instantiateTypeWorker(type, mapper) {
            var flags = type.flags;
            if (flags & 262144 /* TypeParameter */) {
                return getMappedType(type, mapper);
            }
            if (flags & 524288 /* Object */) {
                var objectFlags = type.objectFlags;
                if (objectFlags & 16 /* Anonymous */) {
                    // If the anonymous type originates in a declaration of a function, method, class, or
                    // interface, in an object type literal, or in an object literal expression, we may need
                    // to instantiate the type because it might reference a type parameter.
                    return couldContainTypeVariables(type) ?
                        getObjectTypeInstantiation(type, mapper) : type;
                }
                if (objectFlags & 32 /* Mapped */) {
                    return getObjectTypeInstantiation(type, mapper);
                }
                if (objectFlags & 4 /* Reference */) {
                    if (type.node) {
                        return getObjectTypeInstantiation(type, mapper);
                    }
                    var resolvedTypeArguments = type.resolvedTypeArguments;
                    var newTypeArguments = instantiateTypes(resolvedTypeArguments, mapper);
                    return newTypeArguments !== resolvedTypeArguments ? createTypeReference(type.target, newTypeArguments) : type;
                }
                return type;
            }
            if ((flags & 2097152 /* Intersection */) || (flags & 1048576 /* Union */ && !(flags & 131068 /* Primitive */))) {
                if (!couldContainTypeVariables(type)) {
                    return type;
                }
                var types = type.types;
                var newTypes = instantiateTypes(types, mapper);
                return newTypes === types
                    ? type
                    : (flags & 2097152 /* Intersection */)
                        ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper))
                        : getUnionType(newTypes, 1 /* Literal */, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
            }
            if (flags & 4194304 /* Index */) {
                return getIndexType(instantiateType(type.type, mapper));
            }
            if (flags & 8388608 /* IndexedAccess */) {
                return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper), /*accessNode*/ undefined, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
            }
            if (flags & 16777216 /* Conditional */) {
                return getConditionalTypeInstantiation(type, combineTypeMappers(type.mapper, mapper));
            }
            if (flags & 33554432 /* Substitution */) {
                var maybeVariable = instantiateType(type.baseType, mapper);
                if (maybeVariable.flags & 8650752 /* TypeVariable */) {
                    return getSubstitutionType(maybeVariable, instantiateType(type.substitute, mapper));
                }
                else {
                    var sub = instantiateType(type.substitute, mapper);
                    if (sub.flags & 3 /* AnyOrUnknown */ || isTypeAssignableTo(getRestrictiveInstantiation(maybeVariable), getRestrictiveInstantiation(sub))) {
                        return maybeVariable;
                    }
                    return sub;
                }
            }
            return type;
        }
        function getPermissiveInstantiation(type) {
            return type.flags & (131068 /* Primitive */ | 3 /* AnyOrUnknown */ | 131072 /* Never */) ? type :
                type.permissiveInstantiation || (type.permissiveInstantiation = instantiateType(type, permissiveMapper));
        }
        function getRestrictiveInstantiation(type) {
            if (type.flags & (131068 /* Primitive */ | 3 /* AnyOrUnknown */ | 131072 /* Never */)) {
                return type;
            }
            if (type.restrictiveInstantiation) {
                return type.restrictiveInstantiation;
            }
            type.restrictiveInstantiation = instantiateType(type, restrictiveMapper);
            // We set the following so we don't attempt to set the restrictive instance of a restrictive instance
            // which is redundant - we'll produce new type identities, but all type params have already been mapped.
            // This also gives us a way to detect restrictive instances upon comparisons and _disable_ the "distributeive constraint"
            // assignability check for them, which is distinctly unsafe, as once you have a restrctive instance, all the type parameters
            // are constrained to `unknown` and produce tons of false positives/negatives!
            type.restrictiveInstantiation.restrictiveInstantiation = type.restrictiveInstantiation;
            return type.restrictiveInstantiation;
        }
        function instantiateIndexInfo(info, mapper) {
            return info && createIndexInfo(instantiateType(info.type, mapper), info.isReadonly, info.declaration);
        }
        // Returns true if the given expression contains (at any level of nesting) a function or arrow expression
        // that is subject to contextual typing.
        function isContextSensitive(node) {
            ts.Debug.assert(node.kind !== 161 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            switch (node.kind) {
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 161 /* MethodDeclaration */:
                case 244 /* FunctionDeclaration */: // Function declarations can have context when annotated with a jsdoc @type
                    return isContextSensitiveFunctionLikeDeclaration(node);
                case 193 /* ObjectLiteralExpression */:
                    return ts.some(node.properties, isContextSensitive);
                case 192 /* ArrayLiteralExpression */:
                    return ts.some(node.elements, isContextSensitive);
                case 210 /* ConditionalExpression */:
                    return isContextSensitive(node.whenTrue) ||
                        isContextSensitive(node.whenFalse);
                case 209 /* BinaryExpression */:
                    return (node.operatorToken.kind === 56 /* BarBarToken */ || node.operatorToken.kind === 60 /* QuestionQuestionToken */) &&
                        (isContextSensitive(node.left) || isContextSensitive(node.right));
                case 281 /* PropertyAssignment */:
                    return isContextSensitive(node.initializer);
                case 200 /* ParenthesizedExpression */:
                    return isContextSensitive(node.expression);
                case 274 /* JsxAttributes */:
                    return ts.some(node.properties, isContextSensitive) || ts.isJsxOpeningElement(node.parent) && ts.some(node.parent.parent.children, isContextSensitive);
                case 273 /* JsxAttribute */: {
                    // If there is no initializer, JSX attribute has a boolean value of true which is not context sensitive.
                    var initializer = node.initializer;
                    return !!initializer && isContextSensitive(initializer);
                }
                case 276 /* JsxExpression */: {
                    // It is possible to that node.expression is undefined (e.g <div x={} />)
                    var expression = node.expression;
                    return !!expression && isContextSensitive(expression);
                }
            }
            return false;
        }
        function isContextSensitiveFunctionLikeDeclaration(node) {
            return (!ts.isFunctionDeclaration(node) || ts.isInJSFile(node) && !!getTypeForDeclarationFromJSDocComment(node)) &&
                (hasContextSensitiveParameters(node) || hasContextSensitiveReturnExpression(node));
        }
        function hasContextSensitiveParameters(node) {
            // Functions with type parameters are not context sensitive.
            if (!node.typeParameters) {
                // Functions with any parameters that lack type annotations are context sensitive.
                if (ts.some(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) {
                    return true;
                }
                if (node.kind !== 202 /* ArrowFunction */) {
                    // If the first parameter is not an explicit 'this' parameter, then the function has
                    // an implicit 'this' parameter which is subject to contextual typing.
                    var parameter = ts.firstOrUndefined(node.parameters);
                    if (!(parameter && ts.parameterIsThisKeyword(parameter))) {
                        return true;
                    }
                }
            }
            return false;
        }
        function hasContextSensitiveReturnExpression(node) {
            // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
            return !node.typeParameters && !ts.getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== 223 /* Block */ && isContextSensitive(node.body);
        }
        function isContextSensitiveFunctionOrObjectLiteralMethod(func) {
            return (ts.isInJSFile(func) && ts.isFunctionDeclaration(func) || isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) &&
                isContextSensitiveFunctionLikeDeclaration(func);
        }
        function getTypeWithoutSignatures(type) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (resolved.constructSignatures.length || resolved.callSignatures.length) {
                    var result = createObjectType(16 /* Anonymous */, type.symbol);
                    result.members = resolved.members;
                    result.properties = resolved.properties;
                    result.callSignatures = ts.emptyArray;
                    result.constructSignatures = ts.emptyArray;
                    return result;
                }
            }
            else if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, getTypeWithoutSignatures));
            }
            return type;
        }
        // TYPE CHECKING
        function isTypeIdenticalTo(source, target) {
            return isTypeRelatedTo(source, target, identityRelation);
        }
        function compareTypesIdentical(source, target) {
            return isTypeRelatedTo(source, target, identityRelation) ? -1 /* True */ : 0 /* False */;
        }
        function compareTypesAssignable(source, target) {
            return isTypeRelatedTo(source, target, assignableRelation) ? -1 /* True */ : 0 /* False */;
        }
        function compareTypesSubtypeOf(source, target) {
            return isTypeRelatedTo(source, target, subtypeRelation) ? -1 /* True */ : 0 /* False */;
        }
        function isTypeSubtypeOf(source, target) {
            return isTypeRelatedTo(source, target, subtypeRelation);
        }
        function isTypeAssignableTo(source, target) {
            return isTypeRelatedTo(source, target, assignableRelation);
        }
        // An object type S is considered to be derived from an object type T if
        // S is a union type and every constituent of S is derived from T,
        // T is a union type and S is derived from at least one constituent of T, or
        // S is a type variable with a base constraint that is derived from T,
        // T is one of the global types Object and Function and S is a subtype of T, or
        // T occurs directly or indirectly in an 'extends' clause of S.
        // Note that this check ignores type parameters and only considers the
        // inheritance hierarchy.
        function isTypeDerivedFrom(source, target) {
            return source.flags & 1048576 /* Union */ ? ts.every(source.types, function (t) { return isTypeDerivedFrom(t, target); }) :
                target.flags & 1048576 /* Union */ ? ts.some(target.types, function (t) { return isTypeDerivedFrom(source, t); }) :
                    source.flags & 58982400 /* InstantiableNonPrimitive */ ? isTypeDerivedFrom(getBaseConstraintOfType(source) || unknownType, target) :
                        target === globalObjectType ? !!(source.flags & (524288 /* Object */ | 67108864 /* NonPrimitive */)) :
                            target === globalFunctionType ? !!(source.flags & 524288 /* Object */) && isFunctionObjectType(source) :
                                hasBaseType(source, getTargetType(target));
        }
        /**
         * This is *not* a bi-directional relationship.
         * If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
         *
         * A type S is comparable to a type T if some (but not necessarily all) of the possible values of S are also possible values of T.
         * It is used to check following cases:
         *   - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`).
         *   - the types of `case` clause expressions and their respective `switch` expressions.
         *   - the type of an expression in a type assertion with the type being asserted.
         */
        function isTypeComparableTo(source, target) {
            return isTypeRelatedTo(source, target, comparableRelation);
        }
        function areTypesComparable(type1, type2) {
            return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1);
        }
        function checkTypeAssignableTo(source, target, errorNode, headMessage, containingMessageChain, errorOutputObject) {
            return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain, errorOutputObject);
        }
        /**
         * Like `checkTypeAssignableTo`, but if it would issue an error, instead performs structural comparisons of the types using the given expression node to
         * attempt to issue more specific errors on, for example, specific object literal properties or tuple members.
         */
        function checkTypeAssignableToAndOptionallyElaborate(source, target, errorNode, expr, headMessage, containingMessageChain) {
            return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain, /*errorOutputContainer*/ undefined);
        }
        function checkTypeRelatedToAndOptionallyElaborate(source, target, relation, errorNode, expr, headMessage, containingMessageChain, errorOutputContainer) {
            if (isTypeRelatedTo(source, target, relation))
                return true;
            if (!errorNode || !elaborateError(expr, source, target, relation, headMessage, containingMessageChain, errorOutputContainer)) {
                return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer);
            }
            return false;
        }
        function isOrHasGenericConditional(type) {
            return !!(type.flags & 16777216 /* Conditional */ || (type.flags & 2097152 /* Intersection */ && ts.some(type.types, isOrHasGenericConditional)));
        }
        function elaborateError(node, source, target, relation, headMessage, containingMessageChain, errorOutputContainer) {
            if (!node || isOrHasGenericConditional(target))
                return false;
            if (!checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined)
                && elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage, containingMessageChain, errorOutputContainer)) {
                return true;
            }
            switch (node.kind) {
                case 276 /* JsxExpression */:
                case 200 /* ParenthesizedExpression */:
                    return elaborateError(node.expression, source, target, relation, headMessage, containingMessageChain, errorOutputContainer);
                case 209 /* BinaryExpression */:
                    switch (node.operatorToken.kind) {
                        case 62 /* EqualsToken */:
                        case 27 /* CommaToken */:
                            return elaborateError(node.right, source, target, relation, headMessage, containingMessageChain, errorOutputContainer);
                    }
                    break;
                case 193 /* ObjectLiteralExpression */:
                    return elaborateObjectLiteral(node, source, target, relation, containingMessageChain, errorOutputContainer);
                case 192 /* ArrayLiteralExpression */:
                    return elaborateArrayLiteral(node, source, target, relation, containingMessageChain, errorOutputContainer);
                case 274 /* JsxAttributes */:
                    return elaborateJsxComponents(node, source, target, relation, containingMessageChain, errorOutputContainer);
                case 202 /* ArrowFunction */:
                    return elaborateArrowFunction(node, source, target, relation, containingMessageChain, errorOutputContainer);
            }
            return false;
        }
        function elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage, containingMessageChain, errorOutputContainer) {
            var callSignatures = getSignaturesOfType(source, 0 /* Call */);
            var constructSignatures = getSignaturesOfType(source, 1 /* Construct */);
            for (var _i = 0, _a = [constructSignatures, callSignatures]; _i < _a.length; _i++) {
                var signatures = _a[_i];
                if (ts.some(signatures, function (s) {
                    var returnType = getReturnTypeOfSignature(s);
                    return !(returnType.flags & (1 /* Any */ | 131072 /* Never */)) && checkTypeRelatedTo(returnType, target, relation, /*errorNode*/ undefined);
                })) {
                    var resultObj = errorOutputContainer || {};
                    checkTypeAssignableTo(source, target, node, headMessage, containingMessageChain, resultObj);
                    var diagnostic = resultObj.errors[resultObj.errors.length - 1];
                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(node, signatures === constructSignatures ? ts.Diagnostics.Did_you_mean_to_use_new_with_this_expression : ts.Diagnostics.Did_you_mean_to_call_this_expression));
                    return true;
                }
            }
            return false;
        }
        function elaborateArrowFunction(node, source, target, relation, containingMessageChain, errorOutputContainer) {
            // Don't elaborate blocks
            if (ts.isBlock(node.body)) {
                return false;
            }
            // Or functions with annotated parameter types
            if (ts.some(node.parameters, ts.hasType)) {
                return false;
            }
            var sourceSig = getSingleCallSignature(source);
            if (!sourceSig) {
                return false;
            }
            var targetSignatures = getSignaturesOfType(target, 0 /* Call */);
            if (!ts.length(targetSignatures)) {
                return false;
            }
            var returnExpression = node.body;
            var sourceReturn = getReturnTypeOfSignature(sourceSig);
            var targetReturn = getUnionType(ts.map(targetSignatures, getReturnTypeOfSignature));
            if (!checkTypeRelatedTo(sourceReturn, targetReturn, relation, /*errorNode*/ undefined)) {
                var elaborated = returnExpression && elaborateError(returnExpression, sourceReturn, targetReturn, relation, /*headMessage*/ undefined, containingMessageChain, errorOutputContainer);
                if (elaborated) {
                    return elaborated;
                }
                var resultObj = errorOutputContainer || {};
                checkTypeRelatedTo(sourceReturn, targetReturn, relation, returnExpression, /*message*/ undefined, containingMessageChain, resultObj);
                if (resultObj.errors) {
                    if (target.symbol && ts.length(target.symbol.declarations)) {
                        ts.addRelatedInfo(resultObj.errors[resultObj.errors.length - 1], ts.createDiagnosticForNode(target.symbol.declarations[0], ts.Diagnostics.The_expected_type_comes_from_the_return_type_of_this_signature));
                    }
                    if ((ts.getFunctionFlags(node) & 2 /* Async */) === 0
                        // exclude cases where source itself is promisy - this way we don't make a suggestion when relating
                        // an IPromise and a Promise that are slightly different
                        && !getTypeOfPropertyOfType(sourceReturn, "then")
                        && checkTypeRelatedTo(createPromiseType(sourceReturn), targetReturn, relation, /*errorNode*/ undefined)) {
                        ts.addRelatedInfo(resultObj.errors[resultObj.errors.length - 1], ts.createDiagnosticForNode(node, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async));
                    }
                    return true;
                }
            }
            return false;
        }
        function getBestMatchIndexedAccessTypeOrUndefined(source, target, nameType) {
            var idx = getIndexedAccessTypeOrUndefined(target, nameType);
            if (idx) {
                return idx;
            }
            if (target.flags & 1048576 /* Union */) {
                var best = getBestMatchingType(source, target);
                if (best) {
                    return getIndexedAccessTypeOrUndefined(best, nameType);
                }
            }
        }
        function checkExpressionForMutableLocationWithContextualType(next, sourcePropType) {
            next.contextualType = sourcePropType;
            try {
                return checkExpressionForMutableLocation(next, 1 /* Contextual */, sourcePropType);
            }
            finally {
                next.contextualType = undefined;
            }
        }
        /**
         * For every element returned from the iterator, checks that element to issue an error on a property of that element's type
         * If that element would issue an error, we first attempt to dive into that element's inner expression and issue a more specific error by recuring into `elaborateError`
         * Otherwise, we issue an error on _every_ element which fail the assignability check
         */
        function elaborateElementwise(iterator, source, target, relation, containingMessageChain, errorOutputContainer) {
            // Assignability failure - check each prop individually, and if that fails, fall back on the bad error span
            var reportedError = false;
            for (var status = iterator.next(); !status.done; status = iterator.next()) {
                var _a = status.value, prop = _a.errorNode, next = _a.innerExpression, nameType = _a.nameType, errorMessage = _a.errorMessage;
                var targetPropType = getBestMatchIndexedAccessTypeOrUndefined(source, target, nameType);
                if (!targetPropType || targetPropType.flags & 8388608 /* IndexedAccess */)
                    continue; // Don't elaborate on indexes on generic variables
                var sourcePropType = getIndexedAccessTypeOrUndefined(source, nameType);
                if (sourcePropType && !checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) {
                    var elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined, containingMessageChain, errorOutputContainer);
                    if (elaborated) {
                        reportedError = true;
                    }
                    else {
                        // Issue error on the prop itself, since the prop couldn't elaborate the error
                        var resultObj = errorOutputContainer || {};
                        // Use the expression type, if available
                        var specificSource = next ? checkExpressionForMutableLocationWithContextualType(next, sourcePropType) : sourcePropType;
                        var result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage, containingMessageChain, resultObj);
                        if (result && specificSource !== sourcePropType) {
                            // If for whatever reason the expression type doesn't yield an error, make sure we still issue an error on the sourcePropType
                            checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage, containingMessageChain, resultObj);
                        }
                        if (resultObj.errors) {
                            var reportedDiag = resultObj.errors[resultObj.errors.length - 1];
                            var propertyName = isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined;
                            var targetProp = propertyName !== undefined ? getPropertyOfType(target, propertyName) : undefined;
                            var issuedElaboration = false;
                            if (!targetProp) {
                                var indexInfo = isTypeAssignableToKind(nameType, 296 /* NumberLike */) && getIndexInfoOfType(target, 1 /* Number */) ||
                                    getIndexInfoOfType(target, 0 /* String */) ||
                                    undefined;
                                if (indexInfo && indexInfo.declaration && !ts.getSourceFileOfNode(indexInfo.declaration).hasNoDefaultLib) {
                                    issuedElaboration = true;
                                    ts.addRelatedInfo(reportedDiag, ts.createDiagnosticForNode(indexInfo.declaration, ts.Diagnostics.The_expected_type_comes_from_this_index_signature));
                                }
                            }
                            if (!issuedElaboration && (targetProp && ts.length(targetProp.declarations) || target.symbol && ts.length(target.symbol.declarations))) {
                                var targetNode = targetProp && ts.length(targetProp.declarations) ? targetProp.declarations[0] : target.symbol.declarations[0];
                                if (!ts.getSourceFileOfNode(targetNode).hasNoDefaultLib) {
                                    ts.addRelatedInfo(reportedDiag, ts.createDiagnosticForNode(targetNode, ts.Diagnostics.The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1, propertyName && !(nameType.flags & 8192 /* UniqueESSymbol */) ? ts.unescapeLeadingUnderscores(propertyName) : typeToString(nameType), typeToString(target)));
                                }
                            }
                        }
                        reportedError = true;
                    }
                }
            }
            return reportedError;
        }
        function generateJsxAttributes(node) {
            var _i, _a, prop;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!ts.length(node.properties))
                            return [2 /*return*/];
                        _i = 0, _a = node.properties;
                        _b.label = 1;
                    case 1:
                        if (!(_i < _a.length)) return [3 /*break*/, 4];
                        prop = _a[_i];
                        if (ts.isJsxSpreadAttribute(prop))
                            return [3 /*break*/, 3];
                        return [4 /*yield*/, { errorNode: prop.name, innerExpression: prop.initializer, nameType: getLiteralType(ts.idText(prop.name)) }];
                    case 2:
                        _b.sent();
                        _b.label = 3;
                    case 3:
                        _i++;
                        return [3 /*break*/, 1];
                    case 4: return [2 /*return*/];
                }
            });
        }
        function generateJsxChildren(node, getInvalidTextDiagnostic) {
            var memberOffset, i, child, nameType, elem;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!ts.length(node.children))
                            return [2 /*return*/];
                        memberOffset = 0;
                        i = 0;
                        _a.label = 1;
                    case 1:
                        if (!(i < node.children.length)) return [3 /*break*/, 5];
                        child = node.children[i];
                        nameType = getLiteralType(i - memberOffset);
                        elem = getElaborationElementForJsxChild(child, nameType, getInvalidTextDiagnostic);
                        if (!elem) return [3 /*break*/, 3];
                        return [4 /*yield*/, elem];
                    case 2:
                        _a.sent();
                        return [3 /*break*/, 4];
                    case 3:
                        memberOffset++;
                        _a.label = 4;
                    case 4:
                        i++;
                        return [3 /*break*/, 1];
                    case 5: return [2 /*return*/];
                }
            });
        }
        function getElaborationElementForJsxChild(child, nameType, getInvalidTextDiagnostic) {
            switch (child.kind) {
                case 276 /* JsxExpression */:
                    // child is of the type of the expression
                    return { errorNode: child, innerExpression: child.expression, nameType: nameType };
                case 11 /* JsxText */:
                    if (child.containsOnlyTriviaWhiteSpaces) {
                        break; // Whitespace only jsx text isn't real jsx text
                    }
                    // child is a string
                    return { errorNode: child, innerExpression: undefined, nameType: nameType, errorMessage: getInvalidTextDiagnostic() };
                case 266 /* JsxElement */:
                case 267 /* JsxSelfClosingElement */:
                case 270 /* JsxFragment */:
                    // child is of type JSX.Element
                    return { errorNode: child, innerExpression: child, nameType: nameType };
                default:
                    return ts.Debug.assertNever(child, "Found invalid jsx child");
            }
        }
        function getSemanticJsxChildren(children) {
            return ts.filter(children, function (i) { return !ts.isJsxText(i) || !i.containsOnlyTriviaWhiteSpaces; });
        }
        function elaborateJsxComponents(node, source, target, relation, containingMessageChain, errorOutputContainer) {
            var result = elaborateElementwise(generateJsxAttributes(node), source, target, relation, containingMessageChain, errorOutputContainer);
            var invalidTextDiagnostic;
            if (ts.isJsxOpeningElement(node.parent) && ts.isJsxElement(node.parent.parent)) {
                var containingElement = node.parent.parent;
                var childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
                var childrenPropName = childPropName === undefined ? "children" : ts.unescapeLeadingUnderscores(childPropName);
                var childrenNameType = getLiteralType(childrenPropName);
                var childrenTargetType = getIndexedAccessType(target, childrenNameType);
                var validChildren = getSemanticJsxChildren(containingElement.children);
                if (!ts.length(validChildren)) {
                    return result;
                }
                var moreThanOneRealChildren = ts.length(validChildren) > 1;
                var arrayLikeTargetParts = filterType(childrenTargetType, isArrayOrTupleLikeType);
                var nonArrayLikeTargetParts = filterType(childrenTargetType, function (t) { return !isArrayOrTupleLikeType(t); });
                if (moreThanOneRealChildren) {
                    if (arrayLikeTargetParts !== neverType) {
                        var realSource = createTupleType(checkJsxChildren(containingElement, 0 /* Normal */));
                        var children = generateJsxChildren(containingElement, getInvalidTextualChildDiagnostic);
                        result = elaborateElementwise(children, realSource, arrayLikeTargetParts, relation, containingMessageChain, errorOutputContainer) || result;
                    }
                    else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) {
                        // arity mismatch
                        result = true;
                        var diag = error(containingElement.openingElement.tagName, ts.Diagnostics.This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided, childrenPropName, typeToString(childrenTargetType));
                        if (errorOutputContainer && errorOutputContainer.skipLogging) {
                            (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                        }
                    }
                }
                else {
                    if (nonArrayLikeTargetParts !== neverType) {
                        var child = validChildren[0];
                        var elem_1 = getElaborationElementForJsxChild(child, childrenNameType, getInvalidTextualChildDiagnostic);
                        if (elem_1) {
                            result = elaborateElementwise((function () { return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0: return [4 /*yield*/, elem_1];
                                    case 1:
                                        _a.sent();
                                        return [2 /*return*/];
                                }
                            }); })(), source, target, relation, containingMessageChain, errorOutputContainer) || result;
                        }
                    }
                    else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) {
                        // arity mismatch
                        result = true;
                        var diag = error(containingElement.openingElement.tagName, ts.Diagnostics.This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided, childrenPropName, typeToString(childrenTargetType));
                        if (errorOutputContainer && errorOutputContainer.skipLogging) {
                            (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                        }
                    }
                }
            }
            return result;
            function getInvalidTextualChildDiagnostic() {
                if (!invalidTextDiagnostic) {
                    var tagNameText = ts.getTextOfNode(node.parent.tagName);
                    var childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
                    var childrenPropName = childPropName === undefined ? "children" : ts.unescapeLeadingUnderscores(childPropName);
                    var childrenTargetType = getIndexedAccessType(target, getLiteralType(childrenPropName));
                    var diagnostic = ts.Diagnostics._0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2;
                    invalidTextDiagnostic = __assign(__assign({}, diagnostic), { key: "!!ALREADY FORMATTED!!", message: ts.formatMessage(/*_dummy*/ undefined, diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) });
                }
                return invalidTextDiagnostic;
            }
        }
        function generateLimitedTupleElements(node, target) {
            var len, i, elem, nameType;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        len = ts.length(node.elements);
                        if (!len)
                            return [2 /*return*/];
                        i = 0;
                        _a.label = 1;
                    case 1:
                        if (!(i < len)) return [3 /*break*/, 4];
                        // Skip elements which do not exist in the target - a length error on the tuple overall is likely better than an error on a mismatched index signature
                        if (isTupleLikeType(target) && !getPropertyOfType(target, ("" + i)))
                            return [3 /*break*/, 3];
                        elem = node.elements[i];
                        if (ts.isOmittedExpression(elem))
                            return [3 /*break*/, 3];
                        nameType = getLiteralType(i);
                        return [4 /*yield*/, { errorNode: elem, innerExpression: elem, nameType: nameType }];
                    case 2:
                        _a.sent();
                        _a.label = 3;
                    case 3:
                        i++;
                        return [3 /*break*/, 1];
                    case 4: return [2 /*return*/];
                }
            });
        }
        function elaborateArrayLiteral(node, source, target, relation, containingMessageChain, errorOutputContainer) {
            if (target.flags & 131068 /* Primitive */)
                return false;
            if (isTupleLikeType(source)) {
                return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation, containingMessageChain, errorOutputContainer);
            }
            // recreate a tuple from the elements, if possible
            // Since we're re-doing the expression type, we need to reapply the contextual type
            var oldContext = node.contextualType;
            node.contextualType = target;
            try {
                var tupleizedType = checkArrayLiteral(node, 1 /* Contextual */, /*forceTuple*/ true);
                node.contextualType = oldContext;
                if (isTupleLikeType(tupleizedType)) {
                    return elaborateElementwise(generateLimitedTupleElements(node, target), tupleizedType, target, relation, containingMessageChain, errorOutputContainer);
                }
                return false;
            }
            finally {
                node.contextualType = oldContext;
            }
        }
        function generateObjectLiteralElements(node) {
            var _i, _a, prop, type, _b;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        if (!ts.length(node.properties))
                            return [2 /*return*/];
                        _i = 0, _a = node.properties;
                        _c.label = 1;
                    case 1:
                        if (!(_i < _a.length)) return [3 /*break*/, 8];
                        prop = _a[_i];
                        if (ts.isSpreadAssignment(prop))
                            return [3 /*break*/, 7];
                        type = getLiteralTypeFromProperty(getSymbolOfNode(prop), 8576 /* StringOrNumberLiteralOrUnique */);
                        if (!type || (type.flags & 131072 /* Never */)) {
                            return [3 /*break*/, 7];
                        }
                        _b = prop.kind;
                        switch (_b) {
                            case 164 /* SetAccessor */: return [3 /*break*/, 2];
                            case 163 /* GetAccessor */: return [3 /*break*/, 2];
                            case 161 /* MethodDeclaration */: return [3 /*break*/, 2];
                            case 282 /* ShorthandPropertyAssignment */: return [3 /*break*/, 2];
                            case 281 /* PropertyAssignment */: return [3 /*break*/, 4];
                        }
                        return [3 /*break*/, 6];
                    case 2: return [4 /*yield*/, { errorNode: prop.name, innerExpression: undefined, nameType: type }];
                    case 3:
                        _c.sent();
                        return [3 /*break*/, 7];
                    case 4: return [4 /*yield*/, { errorNode: prop.name, innerExpression: prop.initializer, nameType: type, errorMessage: ts.isComputedNonLiteralName(prop.name) ? ts.Diagnostics.Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1 : undefined }];
                    case 5:
                        _c.sent();
                        return [3 /*break*/, 7];
                    case 6:
                        ts.Debug.assertNever(prop);
                        _c.label = 7;
                    case 7:
                        _i++;
                        return [3 /*break*/, 1];
                    case 8: return [2 /*return*/];
                }
            });
        }
        function elaborateObjectLiteral(node, source, target, relation, containingMessageChain, errorOutputContainer) {
            if (target.flags & 131068 /* Primitive */)
                return false;
            return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation, containingMessageChain, errorOutputContainer);
        }
        /**
         * This is *not* a bi-directional relationship.
         * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'.
         */
        function checkTypeComparableTo(source, target, errorNode, headMessage, containingMessageChain) {
            return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain);
        }
        function isSignatureAssignableTo(source, target, ignoreReturnTypes) {
            return compareSignaturesRelated(source, target, ignoreReturnTypes ? 4 /* IgnoreReturnTypes */ : 0, /*reportErrors*/ false, 
            /*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== 0 /* False */;
        }
        /**
         * Returns true if `s` is `(...args: any[]) => any` or `(this: any, ...args: any[]) => any`
         */
        function isAnySignature(s) {
            return !s.typeParameters && (!s.thisParameter || isTypeAny(getTypeOfParameter(s.thisParameter))) && s.parameters.length === 1 &&
                signatureHasRestParameter(s) && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) &&
                isTypeAny(getReturnTypeOfSignature(s));
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesRelated(source, target, checkMode, reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) {
            // TODO (drosen): De-duplicate code between related functions.
            if (source === target) {
                return -1 /* True */;
            }
            if (isAnySignature(target)) {
                return -1 /* True */;
            }
            var targetCount = getParameterCount(target);
            var sourceHasMoreParameters = !hasEffectiveRestParameter(target) &&
                (checkMode & 8 /* StrictArity */ ? hasEffectiveRestParameter(source) || getParameterCount(source) > targetCount : getMinArgumentCount(source) > targetCount);
            if (sourceHasMoreParameters) {
                return 0 /* False */;
            }
            if (source.typeParameters && source.typeParameters !== target.typeParameters) {
                target = getCanonicalSignature(target);
                source = instantiateSignatureInContextOf(source, target, /*inferenceContext*/ undefined, compareTypes);
            }
            var sourceCount = getParameterCount(source);
            var sourceRestType = getNonArrayRestType(source);
            var targetRestType = getNonArrayRestType(target);
            if (sourceRestType || targetRestType) {
                void instantiateType(sourceRestType || targetRestType, reportUnreliableMarkers);
            }
            if (sourceRestType && targetRestType && sourceCount !== targetCount) {
                // We're not able to relate misaligned complex rest parameters
                return 0 /* False */;
            }
            var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */;
            var strictVariance = !(checkMode & 3 /* Callback */) && strictFunctionTypes && kind !== 161 /* MethodDeclaration */ &&
                kind !== 160 /* MethodSignature */ && kind !== 162 /* Constructor */;
            var result = -1 /* True */;
            var sourceThisType = getThisTypeOfSignature(source);
            if (sourceThisType && sourceThisType !== voidType) {
                var targetThisType = getThisTypeOfSignature(target);
                if (targetThisType) {
                    // void sources are assignable to anything.
                    var related = !strictVariance && compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false)
                        || compareTypes(targetThisType, sourceThisType, reportErrors);
                    if (!related) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.The_this_types_of_each_signature_are_incompatible);
                        }
                        return 0 /* False */;
                    }
                    result &= related;
                }
            }
            var paramCount = sourceRestType || targetRestType ? Math.min(sourceCount, targetCount) : Math.max(sourceCount, targetCount);
            var restIndex = sourceRestType || targetRestType ? paramCount - 1 : -1;
            for (var i = 0; i < paramCount; i++) {
                var sourceType = i === restIndex ? getRestTypeAtPosition(source, i) : getTypeAtPosition(source, i);
                var targetType = i === restIndex ? getRestTypeAtPosition(target, i) : getTypeAtPosition(target, i);
                // In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
                // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
                // they naturally relate only contra-variantly). However, if the source and target parameters both have
                // function types with a single call signature, we know we are relating two callback parameters. In
                // that case it is sufficient to only relate the parameters of the signatures co-variantly because,
                // similar to return values, callback parameters are output positions. This means that a Promise<T>,
                // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant)
                // with respect to T.
                var sourceSig = checkMode & 3 /* Callback */ ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
                var targetSig = checkMode & 3 /* Callback */ ? undefined : getSingleCallSignature(getNonNullableType(targetType));
                var callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) &&
                    (getFalsyFlags(sourceType) & 98304 /* Nullable */) === (getFalsyFlags(targetType) & 98304 /* Nullable */);
                var related = callbacks ?
                    compareSignaturesRelated(targetSig, sourceSig, (checkMode & 8 /* StrictArity */) | (strictVariance ? 2 /* StrictCallback */ : 1 /* BivariantCallback */), reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) :
                    !(checkMode & 3 /* Callback */) && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
                // With strict arity, (x: number | undefined) => void is a subtype of (x?: number | undefined) => void
                if (related && checkMode & 8 /* StrictArity */ && i >= getMinArgumentCount(source) && i < getMinArgumentCount(target) && compareTypes(sourceType, targetType, /*reportErrors*/ false)) {
                    related = 0 /* False */;
                }
                if (!related) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, ts.unescapeLeadingUnderscores(getParameterNameAtPosition(source, i)), ts.unescapeLeadingUnderscores(getParameterNameAtPosition(target, i)));
                    }
                    return 0 /* False */;
                }
                result &= related;
            }
            if (!(checkMode & 4 /* IgnoreReturnTypes */)) {
                // If a signature resolution is already in-flight, skip issuing a circularity error
                // here and just use the `any` type directly
                var targetReturnType = isResolvingReturnTypeOfSignature(target) ? anyType
                    : target.declaration && isJSConstructor(target.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(target.declaration.symbol))
                        : getReturnTypeOfSignature(target);
                if (targetReturnType === voidType) {
                    return result;
                }
                var sourceReturnType = isResolvingReturnTypeOfSignature(source) ? anyType
                    : source.declaration && isJSConstructor(source.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(source.declaration.symbol))
                        : getReturnTypeOfSignature(source);
                // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
                var targetTypePredicate = getTypePredicateOfSignature(target);
                if (targetTypePredicate) {
                    var sourceTypePredicate = getTypePredicateOfSignature(source);
                    if (sourceTypePredicate) {
                        result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, reportErrors, errorReporter, compareTypes);
                    }
                    else if (ts.isIdentifierTypePredicate(targetTypePredicate)) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source));
                        }
                        return 0 /* False */;
                    }
                }
                else {
                    // When relating callback signatures, we still need to relate return types bi-variantly as otherwise
                    // the containing type wouldn't be co-variant. For example, interface Foo<T> { add(cb: () => T): void }
                    // wouldn't be co-variant for T without this rule.
                    result &= checkMode & 1 /* BivariantCallback */ && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
                        compareTypes(sourceReturnType, targetReturnType, reportErrors);
                    if (!result && reportErrors && incompatibleErrorReporter) {
                        incompatibleErrorReporter(sourceReturnType, targetReturnType);
                    }
                }
            }
            return result;
        }
        function compareTypePredicateRelatedTo(source, target, reportErrors, errorReporter, compareTypes) {
            if (source.kind !== target.kind) {
                if (reportErrors) {
                    errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard);
                    errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
                }
                return 0 /* False */;
            }
            if (source.kind === 1 /* Identifier */ || source.kind === 3 /* AssertsIdentifier */) {
                if (source.parameterIndex !== target.parameterIndex) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, target.parameterName);
                        errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
                    }
                    return 0 /* False */;
                }
            }
            var related = source.type === target.type ? -1 /* True */ :
                source.type && target.type ? compareTypes(source.type, target.type, reportErrors) :
                    0 /* False */;
            if (related === 0 /* False */ && reportErrors) {
                errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
            }
            return related;
        }
        function isImplementationCompatibleWithOverload(implementation, overload) {
            var erasedSource = getErasedSignature(implementation);
            var erasedTarget = getErasedSignature(overload);
            // First see if the return types are compatible in either direction.
            var sourceReturnType = getReturnTypeOfSignature(erasedSource);
            var targetReturnType = getReturnTypeOfSignature(erasedTarget);
            if (targetReturnType === voidType
                || isTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation)
                || isTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation)) {
                return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true);
            }
            return false;
        }
        function isEmptyResolvedType(t) {
            return t !== anyFunctionType &&
                t.properties.length === 0 &&
                t.callSignatures.length === 0 &&
                t.constructSignatures.length === 0 &&
                !t.stringIndexInfo &&
                !t.numberIndexInfo;
        }
        function isEmptyObjectType(type) {
            return type.flags & 524288 /* Object */ ? !isGenericMappedType(type) && isEmptyResolvedType(resolveStructuredTypeMembers(type)) :
                type.flags & 67108864 /* NonPrimitive */ ? true :
                    type.flags & 1048576 /* Union */ ? ts.some(type.types, isEmptyObjectType) :
                        type.flags & 2097152 /* Intersection */ ? ts.every(type.types, isEmptyObjectType) :
                            false;
        }
        function isEmptyAnonymousObjectType(type) {
            return !!(ts.getObjectFlags(type) & 16 /* Anonymous */) && isEmptyObjectType(type);
        }
        function isStringIndexSignatureOnlyType(type) {
            return type.flags & 524288 /* Object */ && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfoOfType(type, 0 /* String */) && !getIndexInfoOfType(type, 1 /* Number */) ||
                type.flags & 3145728 /* UnionOrIntersection */ && ts.every(type.types, isStringIndexSignatureOnlyType) ||
                false;
        }
        function isEnumTypeRelatedTo(sourceSymbol, targetSymbol, errorReporter) {
            if (sourceSymbol === targetSymbol) {
                return true;
            }
            var id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol);
            var entry = enumRelation.get(id);
            if (entry !== undefined && !(!(entry & 4 /* Reported */) && entry & 2 /* Failed */ && errorReporter)) {
                return !!(entry & 1 /* Succeeded */);
            }
            if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & 256 /* RegularEnum */) || !(targetSymbol.flags & 256 /* RegularEnum */)) {
                enumRelation.set(id, 2 /* Failed */ | 4 /* Reported */);
                return false;
            }
            var targetEnumType = getTypeOfSymbol(targetSymbol);
            for (var _i = 0, _a = getPropertiesOfType(getTypeOfSymbol(sourceSymbol)); _i < _a.length; _i++) {
                var property = _a[_i];
                if (property.flags & 8 /* EnumMember */) {
                    var targetProperty = getPropertyOfType(targetEnumType, property.escapedName);
                    if (!targetProperty || !(targetProperty.flags & 8 /* EnumMember */)) {
                        if (errorReporter) {
                            errorReporter(ts.Diagnostics.Property_0_is_missing_in_type_1, ts.symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */));
                            enumRelation.set(id, 2 /* Failed */ | 4 /* Reported */);
                        }
                        else {
                            enumRelation.set(id, 2 /* Failed */);
                        }
                        return false;
                    }
                }
            }
            enumRelation.set(id, 1 /* Succeeded */);
            return true;
        }
        function isSimpleTypeRelatedTo(source, target, relation, errorReporter) {
            var s = source.flags;
            var t = target.flags;
            if (t & 3 /* AnyOrUnknown */ || s & 131072 /* Never */ || source === wildcardType)
                return true;
            if (t & 131072 /* Never */)
                return false;
            if (s & 132 /* StringLike */ && t & 4 /* String */)
                return true;
            if (s & 128 /* StringLiteral */ && s & 1024 /* EnumLiteral */ &&
                t & 128 /* StringLiteral */ && !(t & 1024 /* EnumLiteral */) &&
                source.value === target.value)
                return true;
            if (s & 296 /* NumberLike */ && t & 8 /* Number */)
                return true;
            if (s & 256 /* NumberLiteral */ && s & 1024 /* EnumLiteral */ &&
                t & 256 /* NumberLiteral */ && !(t & 1024 /* EnumLiteral */) &&
                source.value === target.value)
                return true;
            if (s & 2112 /* BigIntLike */ && t & 64 /* BigInt */)
                return true;
            if (s & 528 /* BooleanLike */ && t & 16 /* Boolean */)
                return true;
            if (s & 12288 /* ESSymbolLike */ && t & 4096 /* ESSymbol */)
                return true;
            if (s & 32 /* Enum */ && t & 32 /* Enum */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
                return true;
            if (s & 1024 /* EnumLiteral */ && t & 1024 /* EnumLiteral */) {
                if (s & 1048576 /* Union */ && t & 1048576 /* Union */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
                    return true;
                if (s & 2944 /* Literal */ && t & 2944 /* Literal */ &&
                    source.value === target.value &&
                    isEnumTypeRelatedTo(getParentOfSymbol(source.symbol), getParentOfSymbol(target.symbol), errorReporter))
                    return true;
            }
            if (s & 32768 /* Undefined */ && (!strictNullChecks || t & (32768 /* Undefined */ | 16384 /* Void */)))
                return true;
            if (s & 65536 /* Null */ && (!strictNullChecks || t & 65536 /* Null */))
                return true;
            if (s & 524288 /* Object */ && t & 67108864 /* NonPrimitive */)
                return true;
            if (relation === assignableRelation || relation === comparableRelation) {
                if (s & 1 /* Any */)
                    return true;
                // Type number or any numeric literal type is assignable to any numeric enum type or any
                // numeric enum literal type. This rule exists for backwards compatibility reasons because
                // bit-flag enum types sometimes look like literal enum types with numeric literal values.
                if (s & (8 /* Number */ | 256 /* NumberLiteral */) && !(s & 1024 /* EnumLiteral */) && (t & 32 /* Enum */ || t & 256 /* NumberLiteral */ && t & 1024 /* EnumLiteral */))
                    return true;
            }
            return false;
        }
        function isTypeRelatedTo(source, target, relation) {
            if (isFreshLiteralType(source)) {
                source = source.regularType;
            }
            if (isFreshLiteralType(target)) {
                target = target.regularType;
            }
            if (source === target) {
                return true;
            }
            if (relation !== identityRelation) {
                if (relation === comparableRelation && !(target.flags & 131072 /* Never */) && isSimpleTypeRelatedTo(target, source, relation) || isSimpleTypeRelatedTo(source, target, relation)) {
                    return true;
                }
            }
            else {
                if (!(source.flags & 3145728 /* UnionOrIntersection */) && !(target.flags & 3145728 /* UnionOrIntersection */) &&
                    source.flags !== target.flags && !(source.flags & 66584576 /* Substructure */))
                    return false;
            }
            if (source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */) {
                var related = relation.get(getRelationKey(source, target, 0 /* None */, relation));
                if (related !== undefined) {
                    return !!(related & 1 /* Succeeded */);
                }
            }
            if (source.flags & 66846720 /* StructuredOrInstantiable */ || target.flags & 66846720 /* StructuredOrInstantiable */) {
                return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined);
            }
            return false;
        }
        function isIgnoredJsxProperty(source, sourceProp) {
            return ts.getObjectFlags(source) & 4096 /* JsxAttributes */ && !isUnhyphenatedJsxName(sourceProp.escapedName);
        }
        function getNormalizedType(type, writing) {
            while (true) {
                var t = isFreshLiteralType(type) ? type.regularType :
                    ts.getObjectFlags(type) & 4 /* Reference */ && type.node ? createTypeReference(type.target, getTypeArguments(type)) :
                        type.flags & 3145728 /* UnionOrIntersection */ ? getReducedType(type) :
                            type.flags & 33554432 /* Substitution */ ? writing ? type.baseType : type.substitute :
                                type.flags & 25165824 /* Simplifiable */ ? getSimplifiedType(type, writing) :
                                    type;
                if (t === type)
                    break;
                type = t;
            }
            return type;
        }
        /**
         * Checks if 'source' is related to 'target' (e.g.: is a assignable to).
         * @param source The left-hand-side of the relation.
         * @param target The right-hand-side of the relation.
         * @param relation The relation considered. One of 'identityRelation', 'subtypeRelation', 'assignableRelation', or 'comparableRelation'.
         * Used as both to determine which checks are performed and as a cache of previously computed results.
         * @param errorNode The suggested node upon which all errors will be reported, if defined. This may or may not be the actual node used.
         * @param headMessage If the error chain should be prepended by a head message, then headMessage will be used.
         * @param containingMessageChain A chain of errors to prepend any new errors found.
         * @param errorOutputContainer Return the diagnostic. Do not log if 'skipLogging' is truthy.
         */
        function checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer) {
            var errorInfo;
            var relatedInfo;
            var maybeKeys;
            var sourceStack;
            var targetStack;
            var maybeCount = 0;
            var depth = 0;
            var expandingFlags = 0 /* None */;
            var overflow = false;
            var overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid
            var lastSkippedInfo;
            var incompatibleStack = [];
            var inPropertyCheck = false;
            ts.Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
            var result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage);
            if (incompatibleStack.length) {
                reportIncompatibleStack();
            }
            if (overflow) {
                var diag = error(errorNode || currentNode, ts.Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
                if (errorOutputContainer) {
                    (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                }
            }
            else if (errorInfo) {
                if (containingMessageChain) {
                    var chain = containingMessageChain();
                    if (chain) {
                        ts.concatenateDiagnosticMessageChains(chain, errorInfo);
                        errorInfo = chain;
                    }
                }
                var relatedInformation = void 0;
                // Check if we should issue an extra diagnostic to produce a quickfix for a slightly incorrect import statement
                if (headMessage && errorNode && !result && source.symbol) {
                    var links = getSymbolLinks(source.symbol);
                    if (links.originatingImport && !ts.isImportCall(links.originatingImport)) {
                        var helpfulRetry = checkTypeRelatedTo(getTypeOfSymbol(links.target), target, relation, /*errorNode*/ undefined);
                        if (helpfulRetry) {
                            // Likely an incorrect import. Issue a helpful diagnostic to produce a quickfix to change the import
                            var diag_1 = ts.createDiagnosticForNode(links.originatingImport, ts.Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead);
                            relatedInformation = ts.append(relatedInformation, diag_1); // Cause the error to appear with the error that triggered it
                        }
                    }
                }
                var diag = ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo, relatedInformation);
                if (relatedInfo) {
                    ts.addRelatedInfo.apply(void 0, __spreadArrays([diag], relatedInfo));
                }
                if (errorOutputContainer) {
                    (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                }
                if (!errorOutputContainer || !errorOutputContainer.skipLogging) {
                    diagnostics.add(diag);
                }
            }
            if (errorNode && errorOutputContainer && errorOutputContainer.skipLogging && result === 0 /* False */) {
                ts.Debug.assert(!!errorOutputContainer.errors, "missed opportunity to interact with error.");
            }
            return result !== 0 /* False */;
            function resetErrorInfo(saved) {
                errorInfo = saved.errorInfo;
                lastSkippedInfo = saved.lastSkippedInfo;
                incompatibleStack = saved.incompatibleStack;
                overrideNextErrorInfo = saved.overrideNextErrorInfo;
                relatedInfo = saved.relatedInfo;
            }
            function captureErrorCalculationState() {
                return {
                    errorInfo: errorInfo,
                    lastSkippedInfo: lastSkippedInfo,
                    incompatibleStack: incompatibleStack.slice(),
                    overrideNextErrorInfo: overrideNextErrorInfo,
                    relatedInfo: !relatedInfo ? undefined : relatedInfo.slice()
                };
            }
            function reportIncompatibleError(message, arg0, arg1, arg2, arg3) {
                overrideNextErrorInfo++; // Suppress the next relation error
                lastSkippedInfo = undefined; // Reset skipped info cache
                incompatibleStack.push([message, arg0, arg1, arg2, arg3]);
            }
            function reportIncompatibleStack() {
                var stack = incompatibleStack;
                incompatibleStack = [];
                var info = lastSkippedInfo;
                lastSkippedInfo = undefined;
                if (stack.length === 1) {
                    reportError.apply(void 0, stack[0]);
                    if (info) {
                        // Actually do the last relation error
                        reportRelationError.apply(void 0, __spreadArrays([/*headMessage*/ undefined], info));
                    }
                    return;
                }
                // The first error will be the innermost, while the last will be the outermost - so by popping off the end,
                // we can build from left to right
                var path = "";
                var secondaryRootErrors = [];
                while (stack.length) {
                    var _a = stack.pop(), msg = _a[0], args = _a.slice(1);
                    switch (msg.code) {
                        case ts.Diagnostics.Types_of_property_0_are_incompatible.code: {
                            // Parenthesize a `new` if there is one
                            if (path.indexOf("new ") === 0) {
                                path = "(" + path + ")";
                            }
                            var str = "" + args[0];
                            // If leading, just print back the arg (irrespective of if it's a valid identifier)
                            if (path.length === 0) {
                                path = "" + str;
                            }
                            // Otherwise write a dotted name if possible
                            else if (ts.isIdentifierText(str, compilerOptions.target)) {
                                path = path + "." + str;
                            }
                            // Failing that, check if the name is already a computed name
                            else if (str[0] === "[" && str[str.length - 1] === "]") {
                                path = "" + path + str;
                            }
                            // And finally write out a computed name as a last resort
                            else {
                                path = path + "[" + str + "]";
                            }
                            break;
                        }
                        case ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible.code:
                        case ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code:
                        case ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code:
                        case ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code: {
                            if (path.length === 0) {
                                // Don't flatten signature compatability errors at the start of a chain - instead prefer
                                // to unify (the with no arguments bit is excessive for printback) and print them back
                                var mappedMsg = msg;
                                if (msg.code === ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) {
                                    mappedMsg = ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible;
                                }
                                else if (msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) {
                                    mappedMsg = ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible;
                                }
                                secondaryRootErrors.unshift([mappedMsg, args[0], args[1]]);
                            }
                            else {
                                var prefix = (msg.code === ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code ||
                                    msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code)
                                    ? "new "
                                    : "";
                                var params = (msg.code === ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code ||
                                    msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code)
                                    ? ""
                                    : "...";
                                path = "" + prefix + path + "(" + params + ")";
                            }
                            break;
                        }
                        default:
                            return ts.Debug.fail("Unhandled Diagnostic: " + msg.code);
                    }
                }
                if (path) {
                    reportError(path[path.length - 1] === ")"
                        ? ts.Diagnostics.The_types_returned_by_0_are_incompatible_between_these_types
                        : ts.Diagnostics.The_types_of_0_are_incompatible_between_these_types, path);
                }
                else {
                    // Remove the innermost secondary error as it will duplicate the error already reported by `reportRelationError` on entry
                    secondaryRootErrors.shift();
                }
                for (var _i = 0, secondaryRootErrors_1 = secondaryRootErrors; _i < secondaryRootErrors_1.length; _i++) {
                    var _b = secondaryRootErrors_1[_i], msg = _b[0], args = _b.slice(1);
                    var originalValue = msg.elidedInCompatabilityPyramid;
                    msg.elidedInCompatabilityPyramid = false; // Teporarily override elision to ensure error is reported
                    reportError.apply(void 0, __spreadArrays([msg], args));
                    msg.elidedInCompatabilityPyramid = originalValue;
                }
                if (info) {
                    // Actually do the last relation error
                    reportRelationError.apply(void 0, __spreadArrays([/*headMessage*/ undefined], info));
                }
            }
            function reportError(message, arg0, arg1, arg2, arg3) {
                ts.Debug.assert(!!errorNode);
                if (incompatibleStack.length)
                    reportIncompatibleStack();
                if (message.elidedInCompatabilityPyramid)
                    return;
                errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2, arg3);
            }
            function associateRelatedInfo(info) {
                ts.Debug.assert(!!errorInfo);
                if (!relatedInfo) {
                    relatedInfo = [info];
                }
                else {
                    relatedInfo.push(info);
                }
            }
            function reportRelationError(message, source, target) {
                if (incompatibleStack.length)
                    reportIncompatibleStack();
                var _a = getTypeNamesForErrorDisplay(source, target), sourceType = _a[0], targetType = _a[1];
                if (target.flags & 262144 /* TypeParameter */) {
                    var constraint = getBaseConstraintOfType(target);
                    var constraintElab = constraint && isTypeAssignableTo(source, constraint);
                    if (constraintElab) {
                        reportError(ts.Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2, sourceType, targetType, typeToString(constraint));
                    }
                    else {
                        reportError(ts.Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1, targetType, sourceType);
                    }
                }
                if (!message) {
                    if (relation === comparableRelation) {
                        message = ts.Diagnostics.Type_0_is_not_comparable_to_type_1;
                    }
                    else if (sourceType === targetType) {
                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated;
                    }
                    else {
                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1;
                    }
                }
                reportError(message, sourceType, targetType);
            }
            function tryElaborateErrorsForPrimitivesAndObjects(source, target) {
                var sourceType = symbolValueDeclarationIsContextSensitive(source.symbol) ? typeToString(source, source.symbol.valueDeclaration) : typeToString(source);
                var targetType = symbolValueDeclarationIsContextSensitive(target.symbol) ? typeToString(target, target.symbol.valueDeclaration) : typeToString(target);
                if ((globalStringType === source && stringType === target) ||
                    (globalNumberType === source && numberType === target) ||
                    (globalBooleanType === source && booleanType === target) ||
                    (getGlobalESSymbolType(/*reportErrors*/ false) === source && esSymbolType === target)) {
                    reportError(ts.Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType);
                }
            }
            /**
             * Try and elaborate array and tuple errors. Returns false
             * if we have found an elaboration, or we should ignore
             * any other elaborations when relating the `source` and
             * `target` types.
             */
            function tryElaborateArrayLikeErrors(source, target, reportErrors) {
                /**
                 * The spec for elaboration is:
                 * - If the source is a readonly tuple and the target is a mutable array or tuple, elaborate on mutability and skip property elaborations.
                 * - If the source is a tuple then skip property elaborations if the target is an array or tuple.
                 * - If the source is a readonly array and the target is a mutable array or tuple, elaborate on mutability and skip property elaborations.
                 * - If the source an array then skip property elaborations if the target is a tuple.
                 */
                if (isTupleType(source)) {
                    if (source.target.readonly && isMutableArrayOrTuple(target)) {
                        if (reportErrors) {
                            reportError(ts.Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
                        }
                        return false;
                    }
                    return isTupleType(target) || isArrayType(target);
                }
                if (isReadonlyArrayType(source) && isMutableArrayOrTuple(target)) {
                    if (reportErrors) {
                        reportError(ts.Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
                    }
                    return false;
                }
                if (isTupleType(target)) {
                    return isArrayType(source);
                }
                return true;
            }
            /**
             * Compare two types and return
             * * Ternary.True if they are related with no assumptions,
             * * Ternary.Maybe if they are related with assumptions of other relationships, or
             * * Ternary.False if they are not related.
             */
            function isRelatedTo(originalSource, originalTarget, reportErrors, headMessage, intersectionState) {
                if (reportErrors === void 0) { reportErrors = false; }
                if (intersectionState === void 0) { intersectionState = 0 /* None */; }
                // Before normalization: if `source` is type an object type, and `target` is primitive,
                // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result
                if (originalSource.flags & 524288 /* Object */ && originalTarget.flags & 131068 /* Primitive */) {
                    if (isSimpleTypeRelatedTo(originalSource, originalTarget, relation, reportErrors ? reportError : undefined)) {
                        return -1 /* True */;
                    }
                    reportErrorResults(originalSource, originalTarget, 0 /* False */, !!(ts.getObjectFlags(originalSource) & 4096 /* JsxAttributes */));
                    return 0 /* False */;
                }
                // Normalize the source and target types: Turn fresh literal types into regular literal types,
                // turn deferred type references into regular type references, simplify indexed access and
                // conditional types, and resolve substitution types to either the substitution (on the source
                // side) or the type variable (on the target side).
                var source = getNormalizedType(originalSource, /*writing*/ false);
                var target = getNormalizedType(originalTarget, /*writing*/ true);
                if (source === target)
                    return -1 /* True */;
                if (relation === identityRelation) {
                    return isIdenticalTo(source, target);
                }
                // We fastpath comparing a type parameter to exactly its constraint, as this is _super_ common,
                // and otherwise, for type parameters in large unions, causes us to need to compare the union to itself,
                // as we break down the _target_ union first, _then_ get the source constraint - so for every
                // member of the target, we attempt to find a match in the source. This avoids that in cases where
                // the target is exactly the constraint.
                if (source.flags & 262144 /* TypeParameter */ && getConstraintOfType(source) === target) {
                    return -1 /* True */;
                }
                // Try to see if we're relating something like `Foo` -> `Bar | null | undefined`.
                // If so, reporting the `null` and `undefined` in the type is hardly useful.
                // First, see if we're even relating an object type to a union.
                // Then see if the target is stripped down to a single non-union type.
                // Note
                //  * We actually want to remove null and undefined naively here (rather than using getNonNullableType),
                //    since we don't want to end up with a worse error like "`Foo` is not assignable to `NonNullable<T>`"
                //    when dealing with generics.
                //  * We also don't deal with primitive source types, since we already halt elaboration below.
                if (target.flags & 1048576 /* Union */ && source.flags & 524288 /* Object */ &&
                    target.types.length <= 3 && maybeTypeOfKind(target, 98304 /* Nullable */)) {
                    var nullStrippedTarget = extractTypesOfKind(target, ~98304 /* Nullable */);
                    if (!(nullStrippedTarget.flags & (1048576 /* Union */ | 131072 /* Never */))) {
                        if (source === nullStrippedTarget)
                            return -1 /* True */;
                        target = nullStrippedTarget;
                    }
                }
                if (relation === comparableRelation && !(target.flags & 131072 /* Never */) && isSimpleTypeRelatedTo(target, source, relation) ||
                    isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined))
                    return -1 /* True */;
                var isComparingJsxAttributes = !!(ts.getObjectFlags(source) & 4096 /* JsxAttributes */);
                var isPerformingExcessPropertyChecks = !(intersectionState & 2 /* Target */) && (isObjectLiteralType(source) && ts.getObjectFlags(source) & 32768 /* FreshLiteral */);
                if (isPerformingExcessPropertyChecks) {
                    if (hasExcessProperties(source, target, reportErrors)) {
                        if (reportErrors) {
                            reportRelationError(headMessage, source, target);
                        }
                        return 0 /* False */;
                    }
                }
                var isPerformingCommonPropertyChecks = relation !== comparableRelation && !(intersectionState & 2 /* Target */) &&
                    source.flags & (131068 /* Primitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && source !== globalObjectType &&
                    target.flags & (524288 /* Object */ | 2097152 /* Intersection */) && isWeakType(target) &&
                    (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source));
                if (isPerformingCommonPropertyChecks && !hasCommonProperties(source, target, isComparingJsxAttributes)) {
                    if (reportErrors) {
                        var calls = getSignaturesOfType(source, 0 /* Call */);
                        var constructs = getSignaturesOfType(source, 1 /* Construct */);
                        if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) ||
                            constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) {
                            reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target));
                        }
                        else {
                            reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target));
                        }
                    }
                    return 0 /* False */;
                }
                var result = 0 /* False */;
                var saveErrorInfo = captureErrorCalculationState();
                // Note that these checks are specifically ordered to produce correct results. In particular,
                // we need to deconstruct unions before intersections (because unions are always at the top),
                // and we need to handle "each" relations before "some" relations for the same kind of type.
                if (source.flags & 1048576 /* Union */) {
                    result = relation === comparableRelation ?
                        someTypeRelatedToType(source, target, reportErrors && !(source.flags & 131068 /* Primitive */), intersectionState) :
                        eachTypeRelatedToType(source, target, reportErrors && !(source.flags & 131068 /* Primitive */), intersectionState);
                }
                else {
                    if (target.flags & 1048576 /* Union */) {
                        result = typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target, reportErrors && !(source.flags & 131068 /* Primitive */) && !(target.flags & 131068 /* Primitive */));
                    }
                    else if (target.flags & 2097152 /* Intersection */) {
                        result = typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target, reportErrors, 2 /* Target */);
                    }
                    else if (source.flags & 2097152 /* Intersection */) {
                        // Check to see if any constituents of the intersection are immediately related to the target.
                        //
                        // Don't report errors though. Checking whether a constituent is related to the source is not actually
                        // useful and leads to some confusing error messages. Instead it is better to let the below checks
                        // take care of this, or to not elaborate at all. For instance,
                        //
                        //    - For an object type (such as 'C = A & B'), users are usually more interested in structural errors.
                        //
                        //    - For a union type (such as '(A | B) = (C & D)'), it's better to hold onto the whole intersection
                        //          than to report that 'D' is not assignable to 'A' or 'B'.
                        //
                        //    - For a primitive type or type parameter (such as 'number = A & B') there is no point in
                        //          breaking the intersection apart.
                        result = someTypeRelatedToType(source, target, /*reportErrors*/ false, 1 /* Source */);
                    }
                    if (!result && (source.flags & 66846720 /* StructuredOrInstantiable */ || target.flags & 66846720 /* StructuredOrInstantiable */)) {
                        if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState)) {
                            resetErrorInfo(saveErrorInfo);
                        }
                    }
                }
                if (!result && source.flags & (2097152 /* Intersection */ | 262144 /* TypeParameter */)) {
                    // The combined constraint of an intersection type is the intersection of the constraints of
                    // the constituents. When an intersection type contains instantiable types with union type
                    // constraints, there are situations where we need to examine the combined constraint. One is
                    // when the target is a union type. Another is when the intersection contains types belonging
                    // to one of the disjoint domains. For example, given type variables T and U, each with the
                    // constraint 'string | number', the combined constraint of 'T & U' is 'string | number' and
                    // we need to check this constraint against a union on the target side. Also, given a type
                    // variable V constrained to 'string | number', 'V & number' has a combined constraint of
                    // 'string & number | number & number' which reduces to just 'number'.
                    // This also handles type parameters, as a type parameter with a union constraint compared against a union
                    // needs to have its constraint hoisted into an intersection with said type parameter, this way
                    // the type param can be compared with itself in the target (with the influence of its constraint to match other parts)
                    // For example, if `T extends 1 | 2` and `U extends 2 | 3` and we compare `T & U` to `T & U & (1 | 2 | 3)`
                    var constraint = getEffectiveConstraintOfIntersection(source.flags & 2097152 /* Intersection */ ? source.types : [source], !!(target.flags & 1048576 /* Union */));
                    if (constraint && (source.flags & 2097152 /* Intersection */ || target.flags & 1048576 /* Union */)) {
                        if (everyType(constraint, function (c) { return c !== source; })) { // Skip comparison if expansion contains the source itself
                            // TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this
                            if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
                                resetErrorInfo(saveErrorInfo);
                            }
                        }
                    }
                }
                // For certain combinations involving intersections and optional, excess, or mismatched properties we need
                // an extra property check where the intersection is viewed as a single object. The following are motivating
                // examples that all should be errors, but aren't without this extra property check:
                //
                //   let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 };  // Nested excess property
                //
                //   declare let wrong: { a: { y: string } };
                //   let weak: { a?: { x?: number } } & { c?: string } = wrong;  // Nested weak object type
                //
                //   function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
                //     x = y;  // Mismatched property in source intersection
                //   }
                //
                // We suppress recursive intersection property checks because they can generate lots of work when relating
                // recursive intersections that are structurally similar but not exactly identical. See #37854.
                if (result && !inPropertyCheck && (target.flags & 2097152 /* Intersection */ && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
                    isNonGenericObjectType(target) && !isArrayType(target) && !isTupleType(target) && source.flags & 2097152 /* Intersection */ && getApparentType(source).flags & 3670016 /* StructuredType */ && !ts.some(source.types, function (t) { return !!(ts.getObjectFlags(t) & 2097152 /* NonInferrableType */); }))) {
                    inPropertyCheck = true;
                    result &= recursiveTypeRelatedTo(source, target, reportErrors, 4 /* PropertyCheck */);
                    inPropertyCheck = false;
                }
                reportErrorResults(source, target, result, isComparingJsxAttributes);
                return result;
                function reportErrorResults(source, target, result, isComparingJsxAttributes) {
                    if (!result && reportErrors) {
                        source = originalSource.aliasSymbol ? originalSource : source;
                        target = originalTarget.aliasSymbol ? originalTarget : target;
                        var maybeSuppress = overrideNextErrorInfo > 0;
                        if (maybeSuppress) {
                            overrideNextErrorInfo--;
                        }
                        if (source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */) {
                            var currentError = errorInfo;
                            tryElaborateArrayLikeErrors(source, target, reportErrors);
                            if (errorInfo !== currentError) {
                                maybeSuppress = !!errorInfo;
                            }
                        }
                        if (source.flags & 524288 /* Object */ && target.flags & 131068 /* Primitive */) {
                            tryElaborateErrorsForPrimitivesAndObjects(source, target);
                        }
                        else if (source.symbol && source.flags & 524288 /* Object */ && globalObjectType === source) {
                            reportError(ts.Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead);
                        }
                        else if (isComparingJsxAttributes && target.flags & 2097152 /* Intersection */) {
                            var targetTypes = target.types;
                            var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode);
                            var intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode);
                            if (intrinsicAttributes !== errorType && intrinsicClassAttributes !== errorType &&
                                (ts.contains(targetTypes, intrinsicAttributes) || ts.contains(targetTypes, intrinsicClassAttributes))) {
                                // do not report top error
                                return result;
                            }
                        }
                        else {
                            errorInfo = elaborateNeverIntersection(errorInfo, originalTarget);
                        }
                        if (!headMessage && maybeSuppress) {
                            lastSkippedInfo = [source, target];
                            // Used by, eg, missing property checking to replace the top-level message with a more informative one
                            return result;
                        }
                        reportRelationError(headMessage, source, target);
                    }
                }
            }
            function isIdenticalTo(source, target) {
                var flags = source.flags & target.flags;
                if (!(flags & 66584576 /* Substructure */)) {
                    return 0 /* False */;
                }
                if (flags & 3145728 /* UnionOrIntersection */) {
                    var result_5 = eachTypeRelatedToSomeType(source, target);
                    if (result_5) {
                        result_5 &= eachTypeRelatedToSomeType(target, source);
                    }
                    return result_5;
                }
                return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, 0 /* None */);
            }
            function getTypeOfPropertyInTypes(types, name) {
                var appendPropType = function (propTypes, type) {
                    type = getApparentType(type);
                    var prop = type.flags & 3145728 /* UnionOrIntersection */ ? getPropertyOfUnionOrIntersectionType(type, name) : getPropertyOfObjectType(type, name);
                    var propType = prop && getTypeOfSymbol(prop) || isNumericLiteralName(name) && getIndexTypeOfType(type, 1 /* Number */) || getIndexTypeOfType(type, 0 /* String */) || undefinedType;
                    return ts.append(propTypes, propType);
                };
                return getUnionType(ts.reduceLeft(types, appendPropType, /*initial*/ undefined) || ts.emptyArray);
            }
            function hasExcessProperties(source, target, reportErrors) {
                if (!isExcessPropertyCheckTarget(target) || !noImplicitAny && ts.getObjectFlags(target) & 16384 /* JSLiteral */) {
                    return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny
                }
                var isComparingJsxAttributes = !!(ts.getObjectFlags(source) & 4096 /* JsxAttributes */);
                if ((relation === assignableRelation || relation === comparableRelation) &&
                    (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
                    return false;
                }
                var reducedTarget = target;
                var checkTypes;
                if (target.flags & 1048576 /* Union */) {
                    reducedTarget = findMatchingDiscriminantType(source, target, isRelatedTo) || filterPrimitivesIfContainsNonPrimitive(target);
                    checkTypes = reducedTarget.flags & 1048576 /* Union */ ? reducedTarget.types : [reducedTarget];
                }
                var _loop_13 = function (prop) {
                    if (shouldCheckAsExcessProperty(prop, source.symbol) && !isIgnoredJsxProperty(source, prop)) {
                        if (!isKnownProperty(reducedTarget, prop.escapedName, isComparingJsxAttributes)) {
                            if (reportErrors) {
                                // Report error in terms of object types in the target as those are the only ones
                                // we check in isKnownProperty.
                                var errorTarget = filterType(reducedTarget, isExcessPropertyCheckTarget);
                                // We know *exactly* where things went wrong when comparing the types.
                                // Use this property as the error node as this will be more helpful in
                                // reasoning about what went wrong.
                                if (!errorNode)
                                    return { value: ts.Debug.fail() };
                                if (ts.isJsxAttributes(errorNode) || ts.isJsxOpeningLikeElement(errorNode) || ts.isJsxOpeningLikeElement(errorNode.parent)) {
                                    // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
                                    // However, using an object-literal error message will be very confusing to the users so we give different a message.
                                    // TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages)
                                    if (prop.valueDeclaration && ts.isJsxAttribute(prop.valueDeclaration) && ts.getSourceFileOfNode(errorNode) === ts.getSourceFileOfNode(prop.valueDeclaration.name)) {
                                        // Note that extraneous children (as in `<NoChild>extra</NoChild>`) don't pass this check,
                                        // since `children` is a SyntaxKind.PropertySignature instead of a SyntaxKind.JsxAttribute.
                                        errorNode = prop.valueDeclaration.name;
                                    }
                                    reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget));
                                }
                                else {
                                    // use the property's value declaration if the property is assigned inside the literal itself
                                    var objectLiteralDeclaration_1 = source.symbol && ts.firstOrUndefined(source.symbol.declarations);
                                    var suggestion = void 0;
                                    if (prop.valueDeclaration && ts.findAncestor(prop.valueDeclaration, function (d) { return d === objectLiteralDeclaration_1; }) && ts.getSourceFileOfNode(objectLiteralDeclaration_1) === ts.getSourceFileOfNode(errorNode)) {
                                        var propDeclaration = prop.valueDeclaration;
                                        ts.Debug.assertNode(propDeclaration, ts.isObjectLiteralElementLike);
                                        errorNode = propDeclaration;
                                        var name = propDeclaration.name;
                                        if (ts.isIdentifier(name)) {
                                            suggestion = getSuggestionForNonexistentProperty(name, errorTarget);
                                        }
                                    }
                                    if (suggestion !== undefined) {
                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, symbolToString(prop), typeToString(errorTarget), suggestion);
                                    }
                                    else {
                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(errorTarget));
                                    }
                                }
                            }
                            return { value: true };
                        }
                        if (checkTypes && !isRelatedTo(getTypeOfSymbol(prop), getTypeOfPropertyInTypes(checkTypes, prop.escapedName), reportErrors)) {
                            if (reportErrors) {
                                reportIncompatibleError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(prop));
                            }
                            return { value: true };
                        }
                    }
                };
                for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    var state_5 = _loop_13(prop);
                    if (typeof state_5 === "object")
                        return state_5.value;
                }
                return false;
            }
            function shouldCheckAsExcessProperty(prop, container) {
                return prop.valueDeclaration && container.valueDeclaration && prop.valueDeclaration.parent === container.valueDeclaration;
            }
            function eachTypeRelatedToSomeType(source, target) {
                var result = -1 /* True */;
                var sourceTypes = source.types;
                for (var _i = 0, sourceTypes_1 = sourceTypes; _i < sourceTypes_1.length; _i++) {
                    var sourceType = sourceTypes_1[_i];
                    var related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function typeRelatedToSomeType(source, target, reportErrors) {
                var targetTypes = target.types;
                if (target.flags & 1048576 /* Union */ && containsType(targetTypes, source)) {
                    return -1 /* True */;
                }
                for (var _i = 0, targetTypes_1 = targetTypes; _i < targetTypes_1.length; _i++) {
                    var type = targetTypes_1[_i];
                    var related = isRelatedTo(source, type, /*reportErrors*/ false);
                    if (related) {
                        return related;
                    }
                }
                if (reportErrors) {
                    var bestMatchingType = getBestMatchingType(source, target, isRelatedTo);
                    isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
                }
                return 0 /* False */;
            }
            function typeRelatedToEachType(source, target, reportErrors, intersectionState) {
                var result = -1 /* True */;
                var targetTypes = target.types;
                for (var _i = 0, targetTypes_2 = targetTypes; _i < targetTypes_2.length; _i++) {
                    var targetType = targetTypes_2[_i];
                    var related = isRelatedTo(source, targetType, reportErrors, /*headMessage*/ undefined, intersectionState);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function someTypeRelatedToType(source, target, reportErrors, intersectionState) {
                var sourceTypes = source.types;
                if (source.flags & 1048576 /* Union */ && containsType(sourceTypes, target)) {
                    return -1 /* True */;
                }
                var len = sourceTypes.length;
                for (var i = 0; i < len; i++) {
                    var related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1, /*headMessage*/ undefined, intersectionState);
                    if (related) {
                        return related;
                    }
                }
                return 0 /* False */;
            }
            function eachTypeRelatedToType(source, target, reportErrors, intersectionState) {
                var result = -1 /* True */;
                var sourceTypes = source.types;
                for (var i = 0; i < sourceTypes.length; i++) {
                    var sourceType = sourceTypes[i];
                    if (target.flags & 1048576 /* Union */ && target.types.length === sourceTypes.length) {
                        // many unions are mappings of one another; in such cases, simply comparing members at the same index can shortcut the comparison
                        var related_1 = isRelatedTo(sourceType, target.types[i], /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
                        if (related_1) {
                            result &= related_1;
                            continue;
                        }
                    }
                    var related = isRelatedTo(sourceType, target, reportErrors, /*headMessage*/ undefined, intersectionState);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function typeArgumentsRelatedTo(sources, targets, variances, reportErrors, intersectionState) {
                if (sources === void 0) { sources = ts.emptyArray; }
                if (targets === void 0) { targets = ts.emptyArray; }
                if (variances === void 0) { variances = ts.emptyArray; }
                if (sources.length !== targets.length && relation === identityRelation) {
                    return 0 /* False */;
                }
                var length = sources.length <= targets.length ? sources.length : targets.length;
                var result = -1 /* True */;
                for (var i = 0; i < length; i++) {
                    // When variance information isn't available we default to covariance. This happens
                    // in the process of computing variance information for recursive types and when
                    // comparing 'this' type arguments.
                    var varianceFlags = i < variances.length ? variances[i] : 1 /* Covariant */;
                    var variance = varianceFlags & 7 /* VarianceMask */;
                    // We ignore arguments for independent type parameters (because they're never witnessed).
                    if (variance !== 4 /* Independent */) {
                        var s = sources[i];
                        var t = targets[i];
                        var related = -1 /* True */;
                        if (varianceFlags & 8 /* Unmeasurable */) {
                            // Even an `Unmeasurable` variance works out without a structural check if the source and target are _identical_.
                            // We can't simply assume invariance, because `Unmeasurable` marks nonlinear relations, for example, a relation tained by
                            // the `-?` modifier in a mapped type (where, no matter how the inputs are related, the outputs still might not be)
                            related = relation === identityRelation ? isRelatedTo(s, t, /*reportErrors*/ false) : compareTypesIdentical(s, t);
                        }
                        else if (variance === 1 /* Covariant */) {
                            related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState);
                        }
                        else if (variance === 2 /* Contravariant */) {
                            related = isRelatedTo(t, s, reportErrors, /*headMessage*/ undefined, intersectionState);
                        }
                        else if (variance === 3 /* Bivariant */) {
                            // In the bivariant case we first compare contravariantly without reporting
                            // errors. Then, if that doesn't succeed, we compare covariantly with error
                            // reporting. Thus, error elaboration will be based on the the covariant check,
                            // which is generally easier to reason about.
                            related = isRelatedTo(t, s, /*reportErrors*/ false);
                            if (!related) {
                                related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState);
                            }
                        }
                        else {
                            // In the invariant case we first compare covariantly, and only when that
                            // succeeds do we proceed to compare contravariantly. Thus, error elaboration
                            // will typically be based on the covariant check.
                            related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState);
                            if (related) {
                                related &= isRelatedTo(t, s, reportErrors, /*headMessage*/ undefined, intersectionState);
                            }
                        }
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                return result;
            }
            // Determine if possibly recursive types are related. First, check if the result is already available in the global cache.
            // Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
            // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
            // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
            // and issue an error. Otherwise, actually compare the structure of the two types.
            function recursiveTypeRelatedTo(source, target, reportErrors, intersectionState) {
                if (overflow) {
                    return 0 /* False */;
                }
                var id = getRelationKey(source, target, intersectionState | (inPropertyCheck ? 8 /* InPropertyCheck */ : 0), relation);
                var entry = relation.get(id);
                if (entry !== undefined) {
                    if (reportErrors && entry & 2 /* Failed */ && !(entry & 4 /* Reported */)) {
                        // We are elaborating errors and the cached result is an unreported failure. The result will be reported
                        // as a failure, and should be updated as a reported failure by the bottom of this function.
                    }
                    else {
                        if (outofbandVarianceMarkerHandler) {
                            // We're in the middle of variance checking - integrate any unmeasurable/unreliable flags from this cached component
                            var saved = entry & 24 /* ReportsMask */;
                            if (saved & 8 /* ReportsUnmeasurable */) {
                                instantiateType(source, makeFunctionTypeMapper(reportUnmeasurableMarkers));
                            }
                            if (saved & 16 /* ReportsUnreliable */) {
                                instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers));
                            }
                        }
                        return entry & 1 /* Succeeded */ ? -1 /* True */ : 0 /* False */;
                    }
                }
                if (!maybeKeys) {
                    maybeKeys = [];
                    sourceStack = [];
                    targetStack = [];
                }
                else {
                    for (var i = 0; i < maybeCount; i++) {
                        // If source and target are already being compared, consider them related with assumptions
                        if (id === maybeKeys[i]) {
                            return 1 /* Maybe */;
                        }
                    }
                    if (depth === 100) {
                        overflow = true;
                        return 0 /* False */;
                    }
                }
                var maybeStart = maybeCount;
                maybeKeys[maybeCount] = id;
                maybeCount++;
                sourceStack[depth] = source;
                targetStack[depth] = target;
                depth++;
                var saveExpandingFlags = expandingFlags;
                if (!(expandingFlags & 1 /* Source */) && isDeeplyNestedType(source, sourceStack, depth))
                    expandingFlags |= 1 /* Source */;
                if (!(expandingFlags & 2 /* Target */) && isDeeplyNestedType(target, targetStack, depth))
                    expandingFlags |= 2 /* Target */;
                var originalHandler;
                var propagatingVarianceFlags = 0;
                if (outofbandVarianceMarkerHandler) {
                    originalHandler = outofbandVarianceMarkerHandler;
                    outofbandVarianceMarkerHandler = function (onlyUnreliable) {
                        propagatingVarianceFlags |= onlyUnreliable ? 16 /* ReportsUnreliable */ : 8 /* ReportsUnmeasurable */;
                        return originalHandler(onlyUnreliable);
                    };
                }
                var result = expandingFlags !== 3 /* Both */ ? structuredTypeRelatedTo(source, target, reportErrors, intersectionState) : 1 /* Maybe */;
                if (outofbandVarianceMarkerHandler) {
                    outofbandVarianceMarkerHandler = originalHandler;
                }
                expandingFlags = saveExpandingFlags;
                depth--;
                if (result) {
                    if (result === -1 /* True */ || depth === 0) {
                        // If result is definitely true, record all maybe keys as having succeeded
                        for (var i = maybeStart; i < maybeCount; i++) {
                            relation.set(maybeKeys[i], 1 /* Succeeded */ | propagatingVarianceFlags);
                        }
                        maybeCount = maybeStart;
                    }
                }
                else {
                    // A false result goes straight into global cache (when something is false under
                    // assumptions it will also be false without assumptions)
                    relation.set(id, (reportErrors ? 4 /* Reported */ : 0) | 2 /* Failed */ | propagatingVarianceFlags);
                    maybeCount = maybeStart;
                }
                return result;
            }
            function structuredTypeRelatedTo(source, target, reportErrors, intersectionState) {
                if (intersectionState & 4 /* PropertyCheck */) {
                    return propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, 0 /* None */);
                }
                var flags = source.flags & target.flags;
                if (relation === identityRelation && !(flags & 524288 /* Object */)) {
                    if (flags & 4194304 /* Index */) {
                        return isRelatedTo(source.type, target.type, /*reportErrors*/ false);
                    }
                    var result_6 = 0 /* False */;
                    if (flags & 8388608 /* IndexedAccess */) {
                        if (result_6 = isRelatedTo(source.objectType, target.objectType, /*reportErrors*/ false)) {
                            if (result_6 &= isRelatedTo(source.indexType, target.indexType, /*reportErrors*/ false)) {
                                return result_6;
                            }
                        }
                    }
                    if (flags & 16777216 /* Conditional */) {
                        if (source.root.isDistributive === target.root.isDistributive) {
                            if (result_6 = isRelatedTo(source.checkType, target.checkType, /*reportErrors*/ false)) {
                                if (result_6 &= isRelatedTo(source.extendsType, target.extendsType, /*reportErrors*/ false)) {
                                    if (result_6 &= isRelatedTo(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target), /*reportErrors*/ false)) {
                                        if (result_6 &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), /*reportErrors*/ false)) {
                                            return result_6;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (flags & 33554432 /* Substitution */) {
                        return isRelatedTo(source.substitute, target.substitute, /*reportErrors*/ false);
                    }
                    return 0 /* False */;
                }
                var result;
                var originalErrorInfo;
                var varianceCheckFailed = false;
                var saveErrorInfo = captureErrorCalculationState();
                // We limit alias variance probing to only object and conditional types since their alias behavior
                // is more predictable than other, interned types, which may or may not have an alias depending on
                // the order in which things were checked.
                if (source.flags & (524288 /* Object */ | 16777216 /* Conditional */) && source.aliasSymbol &&
                    source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol &&
                    !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) {
                    var variances = getAliasVariances(source.aliasSymbol);
                    if (variances === ts.emptyArray) {
                        return 1 /* Maybe */;
                    }
                    var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState);
                    if (varianceResult !== undefined) {
                        return varianceResult;
                    }
                }
                if (target.flags & 262144 /* TypeParameter */) {
                    // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q].
                    if (ts.getObjectFlags(source) & 32 /* Mapped */ && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source))) {
                        if (!(getMappedTypeModifiers(source) & 4 /* IncludeOptional */)) {
                            var templateType = getTemplateTypeFromMappedType(source);
                            var indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source));
                            if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) {
                                return result;
                            }
                        }
                    }
                }
                else if (target.flags & 4194304 /* Index */) {
                    // A keyof S is related to a keyof T if T is related to S.
                    if (source.flags & 4194304 /* Index */) {
                        if (result = isRelatedTo(target.type, source.type, /*reportErrors*/ false)) {
                            return result;
                        }
                    }
                    // A type S is assignable to keyof T if S is assignable to keyof C, where C is the
                    // simplified form of T or, if T doesn't simplify, the constraint of T.
                    var constraint = getSimplifiedTypeOrConstraint(target.type);
                    if (constraint) {
                        // We require Ternary.True here such that circular constraints don't cause
                        // false positives. For example, given 'T extends { [K in keyof T]: string }',
                        // 'keyof T' has itself as its constraint and produces a Ternary.Maybe when
                        // related to other types.
                        if (isRelatedTo(source, getIndexType(constraint, target.stringsOnly), reportErrors) === -1 /* True */) {
                            return -1 /* True */;
                        }
                    }
                }
                else if (target.flags & 8388608 /* IndexedAccess */) {
                    // A type S is related to a type T[K] if S is related to C, where C is the base
                    // constraint of T[K] for writing.
                    if (relation !== identityRelation) {
                        var objectType = target.objectType;
                        var indexType = target.indexType;
                        var baseObjectType = getBaseConstraintOfType(objectType) || objectType;
                        var baseIndexType = getBaseConstraintOfType(indexType) || indexType;
                        if (!isGenericObjectType(baseObjectType) && !isGenericIndexType(baseIndexType)) {
                            var accessFlags = 2 /* Writing */ | (baseObjectType !== objectType ? 1 /* NoIndexSignatures */ : 0);
                            var constraint = getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, /*accessNode*/ undefined, accessFlags);
                            if (constraint && (result = isRelatedTo(source, constraint, reportErrors))) {
                                return result;
                            }
                        }
                    }
                }
                else if (isGenericMappedType(target)) {
                    // A source type T is related to a target type { [P in X]: T[P] }
                    var template = getTemplateTypeFromMappedType(target);
                    var modifiers = getMappedTypeModifiers(target);
                    if (!(modifiers & 8 /* ExcludeOptional */)) {
                        if (template.flags & 8388608 /* IndexedAccess */ && template.objectType === source &&
                            template.indexType === getTypeParameterFromMappedType(target)) {
                            return -1 /* True */;
                        }
                        if (!isGenericMappedType(source)) {
                            var targetConstraint = getConstraintTypeFromMappedType(target);
                            var sourceKeys = getIndexType(source, /*stringsOnly*/ undefined, /*noIndexSignatures*/ true);
                            var includeOptional = modifiers & 4 /* IncludeOptional */;
                            var filteredByApplicability = includeOptional ? intersectTypes(targetConstraint, sourceKeys) : undefined;
                            // A source type T is related to a target type { [P in Q]: X } if Q is related to keyof T and T[Q] is related to X.
                            // A source type T is related to a target type { [P in Q]?: X } if some constituent Q' of Q is related to keyof T and T[Q'] is related to X.
                            if (includeOptional
                                ? !(filteredByApplicability.flags & 131072 /* Never */)
                                : isRelatedTo(targetConstraint, sourceKeys)) {
                                var typeParameter = getTypeParameterFromMappedType(target);
                                var indexingType = filteredByApplicability ? getIntersectionType([filteredByApplicability, typeParameter]) : typeParameter;
                                var indexedAccessType = getIndexedAccessType(source, indexingType);
                                var templateType = getTemplateTypeFromMappedType(target);
                                if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
                                    return result;
                                }
                            }
                            originalErrorInfo = errorInfo;
                            resetErrorInfo(saveErrorInfo);
                        }
                    }
                }
                if (source.flags & 8650752 /* TypeVariable */) {
                    if (source.flags & 8388608 /* IndexedAccess */ && target.flags & 8388608 /* IndexedAccess */) {
                        // A type S[K] is related to a type T[J] if S is related to T and K is related to J.
                        if (result = isRelatedTo(source.objectType, target.objectType, reportErrors)) {
                            result &= isRelatedTo(source.indexType, target.indexType, reportErrors);
                        }
                        if (result) {
                            resetErrorInfo(saveErrorInfo);
                            return result;
                        }
                    }
                    else {
                        var constraint = getConstraintOfType(source);
                        if (!constraint || (source.flags & 262144 /* TypeParameter */ && constraint.flags & 1 /* Any */)) {
                            // A type variable with no constraint is not related to the non-primitive object type.
                            if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~67108864 /* NonPrimitive */))) {
                                resetErrorInfo(saveErrorInfo);
                                return result;
                            }
                        }
                        // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
                        else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
                            resetErrorInfo(saveErrorInfo);
                            return result;
                        }
                        // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
                        else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, intersectionState)) {
                            resetErrorInfo(saveErrorInfo);
                            return result;
                        }
                    }
                }
                else if (source.flags & 4194304 /* Index */) {
                    if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) {
                        resetErrorInfo(saveErrorInfo);
                        return result;
                    }
                }
                else if (source.flags & 16777216 /* Conditional */) {
                    if (target.flags & 16777216 /* Conditional */) {
                        // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if
                        // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2,
                        // and Y1 is related to Y2.
                        var sourceParams = source.root.inferTypeParameters;
                        var sourceExtends = source.extendsType;
                        var mapper = void 0;
                        if (sourceParams) {
                            // If the source has infer type parameters, we instantiate them in the context of the target
                            var ctx = createInferenceContext(sourceParams, /*signature*/ undefined, 0 /* None */, isRelatedTo);
                            inferTypes(ctx.inferences, target.extendsType, sourceExtends, 128 /* NoConstraints */ | 256 /* AlwaysStrict */);
                            sourceExtends = instantiateType(sourceExtends, ctx.mapper);
                            mapper = ctx.mapper;
                        }
                        if (isTypeIdenticalTo(sourceExtends, target.extendsType) &&
                            (isRelatedTo(source.checkType, target.checkType) || isRelatedTo(target.checkType, source.checkType))) {
                            if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source), mapper), getTrueTypeFromConditionalType(target), reportErrors)) {
                                result &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), reportErrors);
                            }
                            if (result) {
                                resetErrorInfo(saveErrorInfo);
                                return result;
                            }
                        }
                    }
                    else {
                        // conditionals aren't related to one another via distributive constraint as it is much too inaccurate and allows way
                        // more assignments than are desirable (since it maps the source check type to its constraint, it loses information)
                        var distributiveConstraint = getConstraintOfDistributiveConditionalType(source);
                        if (distributiveConstraint) {
                            if (result = isRelatedTo(distributiveConstraint, target, reportErrors)) {
                                resetErrorInfo(saveErrorInfo);
                                return result;
                            }
                        }
                    }
                    // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O`
                    // when `O` is a conditional (`never` is trivially aissgnable to `O`, as is `O`!).
                    var defaultConstraint = getDefaultConstraintOfConditionalType(source);
                    if (defaultConstraint) {
                        if (result = isRelatedTo(defaultConstraint, target, reportErrors)) {
                            resetErrorInfo(saveErrorInfo);
                            return result;
                        }
                    }
                }
                else {
                    // An empty object type is related to any mapped type that includes a '?' modifier.
                    if (relation !== subtypeRelation && relation !== strictSubtypeRelation && isPartialMappedType(target) && isEmptyObjectType(source)) {
                        return -1 /* True */;
                    }
                    if (isGenericMappedType(target)) {
                        if (isGenericMappedType(source)) {
                            if (result = mappedTypeRelatedTo(source, target, reportErrors)) {
                                resetErrorInfo(saveErrorInfo);
                                return result;
                            }
                        }
                        return 0 /* False */;
                    }
                    var sourceIsPrimitive = !!(source.flags & 131068 /* Primitive */);
                    if (relation !== identityRelation) {
                        source = getApparentType(source);
                    }
                    else if (isGenericMappedType(source)) {
                        return 0 /* False */;
                    }
                    if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && source.target === target.target &&
                        !(ts.getObjectFlags(source) & 8192 /* MarkerType */ || ts.getObjectFlags(target) & 8192 /* MarkerType */)) {
                        // We have type references to the same generic type, and the type references are not marker
                        // type references (which are intended by be compared structurally). Obtain the variance
                        // information for the type parameters and relate the type arguments accordingly.
                        var variances = getVariances(source.target);
                        // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This
                        // effectively means we measure variance only from type parameter occurrences that aren't nested in
                        // recursive instantiations of the generic type.
                        if (variances === ts.emptyArray) {
                            return 1 /* Maybe */;
                        }
                        var varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState);
                        if (varianceResult !== undefined) {
                            return varianceResult;
                        }
                    }
                    else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
                        if (relation !== identityRelation) {
                            return isRelatedTo(getIndexTypeOfType(source, 1 /* Number */) || anyType, getIndexTypeOfType(target, 1 /* Number */) || anyType, reportErrors);
                        }
                        else {
                            // By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple
                            // or `target` is an array and source is a tuple - in both cases the types cannot be identical, by construction
                            return 0 /* False */;
                        }
                    }
                    // Consider a fresh empty object literal type "closed" under the subtype relationship - this way `{} <- {[idx: string]: any} <- fresh({})`
                    // and not `{} <- fresh({}) <- {[idx: string]: any}`
                    else if ((relation === subtypeRelation || relation === strictSubtypeRelation) && isEmptyObjectType(target) && ts.getObjectFlags(target) & 32768 /* FreshLiteral */ && !isEmptyObjectType(source)) {
                        return 0 /* False */;
                    }
                    // Even if relationship doesn't hold for unions, intersections, or generic type references,
                    // it may hold in a structural comparison.
                    // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
                    // to X. Failing both of those we want to check if the aggregation of A and B's members structurally
                    // relates to X. Thus, we include intersection types on the source side here.
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */) && target.flags & 524288 /* Object */) {
                        // Report structural errors only if we haven't reported any errors yet
                        var reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo.errorInfo && !sourceIsPrimitive;
                        result = propertiesRelatedTo(source, target, reportStructuralErrors, /*excludedProperties*/ undefined, intersectionState);
                        if (result) {
                            result &= signaturesRelatedTo(source, target, 0 /* Call */, reportStructuralErrors);
                            if (result) {
                                result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportStructuralErrors);
                                if (result) {
                                    result &= indexTypesRelatedTo(source, target, 0 /* String */, sourceIsPrimitive, reportStructuralErrors, intersectionState);
                                    if (result) {
                                        result &= indexTypesRelatedTo(source, target, 1 /* Number */, sourceIsPrimitive, reportStructuralErrors, intersectionState);
                                    }
                                }
                            }
                        }
                        if (varianceCheckFailed && result) {
                            errorInfo = originalErrorInfo || errorInfo || saveErrorInfo.errorInfo; // Use variance error (there is no structural one) and return false
                        }
                        else if (result) {
                            return result;
                        }
                    }
                    // If S is an object type and T is a discriminated union, S may be related to T if
                    // there exists a constituent of T for every combination of the discriminants of S
                    // with respect to T. We do not report errors here, as we will use the existing
                    // error result from checking each constituent of the union.
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */) && target.flags & 1048576 /* Union */) {
                        var objectOnlyTarget = extractTypesOfKind(target, 524288 /* Object */ | 2097152 /* Intersection */ | 33554432 /* Substitution */);
                        if (objectOnlyTarget.flags & 1048576 /* Union */) {
                            var result_7 = typeRelatedToDiscriminatedType(source, objectOnlyTarget);
                            if (result_7) {
                                return result_7;
                            }
                        }
                    }
                }
                return 0 /* False */;
                function relateVariances(sourceTypeArguments, targetTypeArguments, variances, intersectionState) {
                    if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors, intersectionState)) {
                        return result;
                    }
                    if (ts.some(variances, function (v) { return !!(v & 24 /* AllowsStructuralFallback */); })) {
                        // If some type parameter was `Unmeasurable` or `Unreliable`, and we couldn't pass by assuming it was identical, then we
                        // have to allow a structural fallback check
                        // We elide the variance-based error elaborations, since those might not be too helpful, since we'll potentially
                        // be assuming identity of the type parameter.
                        originalErrorInfo = undefined;
                        resetErrorInfo(saveErrorInfo);
                        return undefined;
                    }
                    var allowStructuralFallback = targetTypeArguments && hasCovariantVoidArgument(targetTypeArguments, variances);
                    varianceCheckFailed = !allowStructuralFallback;
                    // The type arguments did not relate appropriately, but it may be because we have no variance
                    // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type
                    // arguments). It might also be the case that the target type has a 'void' type argument for
                    // a covariant type parameter that is only used in return positions within the generic type
                    // (in which case any type argument is permitted on the source side). In those cases we proceed
                    // with a structural comparison. Otherwise, we know for certain the instantiations aren't
                    // related and we can return here.
                    if (variances !== ts.emptyArray && !allowStructuralFallback) {
                        // In some cases generic types that are covariant in regular type checking mode become
                        // invariant in --strictFunctionTypes mode because one or more type parameters are used in
                        // both co- and contravariant positions. In order to make it easier to diagnose *why* such
                        // types are invariant, if any of the type parameters are invariant we reset the reported
                        // errors and instead force a structural comparison (which will include elaborations that
                        // reveal the reason).
                        // We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`,
                        // we can return `False` early here to skip calculating the structural error message we don't need.
                        if (varianceCheckFailed && !(reportErrors && ts.some(variances, function (v) { return (v & 7 /* VarianceMask */) === 0 /* Invariant */; }))) {
                            return 0 /* False */;
                        }
                        // We remember the original error information so we can restore it in case the structural
                        // comparison unexpectedly succeeds. This can happen when the structural comparison result
                        // is a Ternary.Maybe for example caused by the recursion depth limiter.
                        originalErrorInfo = errorInfo;
                        resetErrorInfo(saveErrorInfo);
                    }
                }
            }
            function reportUnmeasurableMarkers(p) {
                if (outofbandVarianceMarkerHandler && (p === markerSuperType || p === markerSubType || p === markerOtherType)) {
                    outofbandVarianceMarkerHandler(/*onlyUnreliable*/ false);
                }
                return p;
            }
            function reportUnreliableMarkers(p) {
                if (outofbandVarianceMarkerHandler && (p === markerSuperType || p === markerSubType || p === markerOtherType)) {
                    outofbandVarianceMarkerHandler(/*onlyUnreliable*/ true);
                }
                return p;
            }
            // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is
            // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice
            // that S and T are contra-variant whereas X and Y are co-variant.
            function mappedTypeRelatedTo(source, target, reportErrors) {
                var modifiersRelated = relation === comparableRelation || (relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) :
                    getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target));
                if (modifiersRelated) {
                    var result_8;
                    var targetConstraint = getConstraintTypeFromMappedType(target);
                    var sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), makeFunctionTypeMapper(getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers));
                    if (result_8 = isRelatedTo(targetConstraint, sourceConstraint, reportErrors)) {
                        var mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]);
                        return result_8 & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors);
                    }
                }
                return 0 /* False */;
            }
            function typeRelatedToDiscriminatedType(source, target) {
                // 1. Generate the combinations of discriminant properties & types 'source' can satisfy.
                //    a. If the number of combinations is above a set limit, the comparison is too complex.
                // 2. Filter 'target' to the subset of types whose discriminants exist in the matrix.
                //    a. If 'target' does not satisfy all discriminants in the matrix, 'source' is not related.
                // 3. For each type in the filtered 'target', determine if all non-discriminant properties of
                //    'target' are related to a property in 'source'.
                //
                // NOTE: See ~/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts
                //       for examples.
                var sourceProperties = getPropertiesOfType(source);
                var sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
                if (!sourcePropertiesFiltered)
                    return 0 /* False */;
                // Though we could compute the number of combinations as we generate
                // the matrix, this would incur additional memory overhead due to
                // array allocations. To reduce this overhead, we first compute
                // the number of combinations to ensure we will not surpass our
                // fixed limit before incurring the cost of any allocations:
                var numCombinations = 1;
                for (var _i = 0, sourcePropertiesFiltered_1 = sourcePropertiesFiltered; _i < sourcePropertiesFiltered_1.length; _i++) {
                    var sourceProperty = sourcePropertiesFiltered_1[_i];
                    numCombinations *= countTypes(getTypeOfSymbol(sourceProperty));
                    if (numCombinations > 25) {
                        // We've reached the complexity limit.
                        return 0 /* False */;
                    }
                }
                // Compute the set of types for each discriminant property.
                var sourceDiscriminantTypes = new Array(sourcePropertiesFiltered.length);
                var excludedProperties = ts.createUnderscoreEscapedMap();
                for (var i = 0; i < sourcePropertiesFiltered.length; i++) {
                    var sourceProperty = sourcePropertiesFiltered[i];
                    var sourcePropertyType = getTypeOfSymbol(sourceProperty);
                    sourceDiscriminantTypes[i] = sourcePropertyType.flags & 1048576 /* Union */
                        ? sourcePropertyType.types
                        : [sourcePropertyType];
                    excludedProperties.set(sourceProperty.escapedName, true);
                }
                // Match each combination of the cartesian product of discriminant properties to one or more
                // constituents of 'target'. If any combination does not have a match then 'source' is not relatable.
                var discriminantCombinations = ts.cartesianProduct(sourceDiscriminantTypes);
                var matchingTypes = [];
                var _loop_14 = function (combination) {
                    var hasMatch = false;
                    outer: for (var _i = 0, _a = target.types; _i < _a.length; _i++) {
                        var type = _a[_i];
                        var _loop_15 = function (i) {
                            var sourceProperty = sourcePropertiesFiltered[i];
                            var targetProperty = getPropertyOfType(type, sourceProperty.escapedName);
                            if (!targetProperty)
                                return "continue-outer";
                            if (sourceProperty === targetProperty)
                                return "continue";
                            // We compare the source property to the target in the context of a single discriminant type.
                            var related = propertyRelatedTo(source, target, sourceProperty, targetProperty, function (_) { return combination[i]; }, /*reportErrors*/ false, 0 /* None */, /*skipOptional*/ strictNullChecks || relation === comparableRelation);
                            // If the target property could not be found, or if the properties were not related,
                            // then this constituent is not a match.
                            if (!related) {
                                return "continue-outer";
                            }
                        };
                        for (var i = 0; i < sourcePropertiesFiltered.length; i++) {
                            var state_7 = _loop_15(i);
                            switch (state_7) {
                                case "continue-outer": continue outer;
                            }
                        }
                        ts.pushIfUnique(matchingTypes, type, ts.equateValues);
                        hasMatch = true;
                    }
                    if (!hasMatch) {
                        return { value: 0 /* False */ };
                    }
                };
                for (var _a = 0, discriminantCombinations_1 = discriminantCombinations; _a < discriminantCombinations_1.length; _a++) {
                    var combination = discriminantCombinations_1[_a];
                    var state_6 = _loop_14(combination);
                    if (typeof state_6 === "object")
                        return state_6.value;
                }
                // Compare the remaining non-discriminant properties of each match.
                var result = -1 /* True */;
                for (var _b = 0, matchingTypes_1 = matchingTypes; _b < matchingTypes_1.length; _b++) {
                    var type = matchingTypes_1[_b];
                    result &= propertiesRelatedTo(source, type, /*reportErrors*/ false, excludedProperties, 0 /* None */);
                    if (result) {
                        result &= signaturesRelatedTo(source, type, 0 /* Call */, /*reportStructuralErrors*/ false);
                        if (result) {
                            result &= signaturesRelatedTo(source, type, 1 /* Construct */, /*reportStructuralErrors*/ false);
                            if (result) {
                                result &= indexTypesRelatedTo(source, type, 0 /* String */, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, 0 /* None */);
                                if (result) {
                                    result &= indexTypesRelatedTo(source, type, 1 /* Number */, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, 0 /* None */);
                                }
                            }
                        }
                    }
                    if (!result) {
                        return result;
                    }
                }
                return result;
            }
            function excludeProperties(properties, excludedProperties) {
                if (!excludedProperties || properties.length === 0)
                    return properties;
                var result;
                for (var i = 0; i < properties.length; i++) {
                    if (!excludedProperties.has(properties[i].escapedName)) {
                        if (result) {
                            result.push(properties[i]);
                        }
                    }
                    else if (!result) {
                        result = properties.slice(0, i);
                    }
                }
                return result || properties;
            }
            function isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState) {
                var targetIsOptional = strictNullChecks && !!(ts.getCheckFlags(targetProp) & 48 /* Partial */);
                var source = getTypeOfSourceProperty(sourceProp);
                if (ts.getCheckFlags(targetProp) & 65536 /* DeferredType */ && !getSymbolLinks(targetProp).type) {
                    // Rather than resolving (and normalizing) the type, relate constituent-by-constituent without performing normalization or seconadary passes
                    var links = getSymbolLinks(targetProp);
                    ts.Debug.assertIsDefined(links.deferralParent);
                    ts.Debug.assertIsDefined(links.deferralConstituents);
                    var unionParent = !!(links.deferralParent.flags & 1048576 /* Union */);
                    var result_9 = unionParent ? 0 /* False */ : -1 /* True */;
                    var targetTypes = links.deferralConstituents;
                    for (var _i = 0, targetTypes_3 = targetTypes; _i < targetTypes_3.length; _i++) {
                        var targetType = targetTypes_3[_i];
                        var related = isRelatedTo(source, targetType, /*reportErrors*/ false, /*headMessage*/ undefined, unionParent ? 0 : 2 /* Target */);
                        if (!unionParent) {
                            if (!related) {
                                // Can't assign to a target individually - have to fallback to assigning to the _whole_ intersection (which forces normalization)
                                return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
                            }
                            result_9 &= related;
                        }
                        else {
                            if (related) {
                                return related;
                            }
                        }
                    }
                    if (unionParent && !result_9 && targetIsOptional) {
                        result_9 = isRelatedTo(source, undefinedType);
                    }
                    if (unionParent && !result_9 && reportErrors) {
                        // The easiest way to get the right errors here is to un-defer (which may be costly)
                        // If it turns out this is too costly too often, we can replicate the error handling logic within
                        // typeRelatedToSomeType without the discriminatable type branch (as that requires a manifest union
                        // type on which to hand discriminable properties, which we are expressly trying to avoid here)
                        return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
                    }
                    return result_9;
                }
                else {
                    return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors, /*headMessage*/ undefined, intersectionState);
                }
            }
            function propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState, skipOptional) {
                var sourcePropFlags = ts.getDeclarationModifierFlagsFromSymbol(sourceProp);
                var targetPropFlags = ts.getDeclarationModifierFlagsFromSymbol(targetProp);
                if (sourcePropFlags & 8 /* Private */ || targetPropFlags & 8 /* Private */) {
                    if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) {
                        if (reportErrors) {
                            if (sourcePropFlags & 8 /* Private */ && targetPropFlags & 8 /* Private */) {
                                reportError(ts.Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
                            }
                            else {
                                reportError(ts.Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), typeToString(sourcePropFlags & 8 /* Private */ ? source : target), typeToString(sourcePropFlags & 8 /* Private */ ? target : source));
                            }
                        }
                        return 0 /* False */;
                    }
                }
                else if (targetPropFlags & 16 /* Protected */) {
                    if (!isValidOverrideOf(sourceProp, targetProp)) {
                        if (reportErrors) {
                            reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target));
                        }
                        return 0 /* False */;
                    }
                }
                else if (sourcePropFlags & 16 /* Protected */) {
                    if (reportErrors) {
                        reportError(ts.Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                    }
                    return 0 /* False */;
                }
                // If the target comes from a partial union prop, allow `undefined` in the target type
                var related = isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState);
                if (!related) {
                    if (reportErrors) {
                        reportIncompatibleError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
                    }
                    return 0 /* False */;
                }
                // When checking for comparability, be more lenient with optional properties.
                if (!skipOptional && sourceProp.flags & 16777216 /* Optional */ && !(targetProp.flags & 16777216 /* Optional */)) {
                    // TypeScript 1.0 spec (April 2014): 3.8.3
                    // S is a subtype of a type T, and T is a supertype of S if ...
                    // S' and T are object types and, for each member M in T..
                    // M is a property and S' contains a property N where
                    // if M is a required property, N is also a required property
                    // (M - property in T)
                    // (N - property in S)
                    if (reportErrors) {
                        reportError(ts.Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                    }
                    return 0 /* False */;
                }
                return related;
            }
            function reportUnmatchedProperty(source, target, unmatchedProperty, requireOptionalProperties) {
                var shouldSkipElaboration = false;
                // give specific error in case where private names have the same description
                if (unmatchedProperty.valueDeclaration
                    && ts.isNamedDeclaration(unmatchedProperty.valueDeclaration)
                    && ts.isPrivateIdentifier(unmatchedProperty.valueDeclaration.name)
                    && source.symbol
                    && source.symbol.flags & 32 /* Class */) {
                    var privateIdentifierDescription = unmatchedProperty.valueDeclaration.name.escapedText;
                    var symbolTableKey = ts.getSymbolNameForPrivateIdentifier(source.symbol, privateIdentifierDescription);
                    if (symbolTableKey && getPropertyOfType(source, symbolTableKey)) {
                        var sourceName = ts.getDeclarationName(source.symbol.valueDeclaration);
                        var targetName = ts.getDeclarationName(target.symbol.valueDeclaration);
                        reportError(ts.Diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, diagnosticName(privateIdentifierDescription), diagnosticName(sourceName.escapedText === "" ? anon : sourceName), diagnosticName(targetName.escapedText === "" ? anon : targetName));
                        return;
                    }
                }
                var props = ts.arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false));
                if (!headMessage || (headMessage.code !== ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code &&
                    headMessage.code !== ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) {
                    shouldSkipElaboration = true; // Retain top-level error for interface implementing issues, otherwise omit it
                }
                if (props.length === 1) {
                    var propName = symbolToString(unmatchedProperty);
                    reportError.apply(void 0, __spreadArrays([ts.Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName], getTypeNamesForErrorDisplay(source, target)));
                    if (ts.length(unmatchedProperty.declarations)) {
                        associateRelatedInfo(ts.createDiagnosticForNode(unmatchedProperty.declarations[0], ts.Diagnostics._0_is_declared_here, propName));
                    }
                    if (shouldSkipElaboration && errorInfo) {
                        overrideNextErrorInfo++;
                    }
                }
                else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) {
                    if (props.length > 5) { // arbitrary cutoff for too-long list form
                        reportError(ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), ts.map(props.slice(0, 4), function (p) { return symbolToString(p); }).join(", "), props.length - 4);
                    }
                    else {
                        reportError(ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), ts.map(props, function (p) { return symbolToString(p); }).join(", "));
                    }
                    if (shouldSkipElaboration && errorInfo) {
                        overrideNextErrorInfo++;
                    }
                }
                // No array like or unmatched property error - just issue top level error (errorInfo = undefined)
            }
            function propertiesRelatedTo(source, target, reportErrors, excludedProperties, intersectionState) {
                if (relation === identityRelation) {
                    return propertiesIdenticalTo(source, target, excludedProperties);
                }
                var requireOptionalProperties = (relation === subtypeRelation || relation === strictSubtypeRelation) && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) && !isTupleType(source);
                var unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false);
                if (unmatchedProperty) {
                    if (reportErrors) {
                        reportUnmatchedProperty(source, target, unmatchedProperty, requireOptionalProperties);
                    }
                    return 0 /* False */;
                }
                if (isObjectLiteralType(target)) {
                    for (var _i = 0, _a = excludeProperties(getPropertiesOfType(source), excludedProperties); _i < _a.length; _i++) {
                        var sourceProp = _a[_i];
                        if (!getPropertyOfObjectType(target, sourceProp.escapedName)) {
                            var sourceType = getTypeOfSymbol(sourceProp);
                            if (!(sourceType === undefinedType || sourceType === undefinedWideningType || sourceType === optionalType)) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target));
                                }
                                return 0 /* False */;
                            }
                        }
                    }
                }
                var result = -1 /* True */;
                if (isTupleType(target)) {
                    var targetRestType = getRestTypeOfTupleType(target);
                    if (targetRestType) {
                        if (!isTupleType(source)) {
                            return 0 /* False */;
                        }
                        var sourceRestType = getRestTypeOfTupleType(source);
                        if (sourceRestType && !isRelatedTo(sourceRestType, targetRestType, reportErrors)) {
                            if (reportErrors) {
                                reportError(ts.Diagnostics.Rest_signatures_are_incompatible);
                            }
                            return 0 /* False */;
                        }
                        var targetCount = getTypeReferenceArity(target) - 1;
                        var sourceCount = getTypeReferenceArity(source) - (sourceRestType ? 1 : 0);
                        var sourceTypeArguments = getTypeArguments(source);
                        for (var i = targetCount; i < sourceCount; i++) {
                            var related = isRelatedTo(sourceTypeArguments[i], targetRestType, reportErrors);
                            if (!related) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_is_incompatible_with_rest_element_type, "" + i);
                                }
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                    }
                }
                // We only call this for union target types when we're attempting to do excess property checking - in those cases, we want to get _all possible props_
                // from the target union, across all members
                var properties = getPropertiesOfType(target);
                var numericNamesOnly = isTupleType(source) && isTupleType(target);
                for (var _b = 0, _c = excludeProperties(properties, excludedProperties); _b < _c.length; _b++) {
                    var targetProp = _c[_b];
                    var name = targetProp.escapedName;
                    if (!(targetProp.flags & 4194304 /* Prototype */) && (!numericNamesOnly || isNumericLiteralName(name) || name === "length")) {
                        var sourceProp = getPropertyOfType(source, name);
                        if (sourceProp && sourceProp !== targetProp) {
                            var related = propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSymbol, reportErrors, intersectionState, relation === comparableRelation);
                            if (!related) {
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                    }
                }
                return result;
            }
            function propertiesIdenticalTo(source, target, excludedProperties) {
                if (!(source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */)) {
                    return 0 /* False */;
                }
                var sourceProperties = excludeProperties(getPropertiesOfObjectType(source), excludedProperties);
                var targetProperties = excludeProperties(getPropertiesOfObjectType(target), excludedProperties);
                if (sourceProperties.length !== targetProperties.length) {
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                for (var _i = 0, sourceProperties_1 = sourceProperties; _i < sourceProperties_1.length; _i++) {
                    var sourceProp = sourceProperties_1[_i];
                    var targetProp = getPropertyOfObjectType(target, sourceProp.escapedName);
                    if (!targetProp) {
                        return 0 /* False */;
                    }
                    var related = compareProperties(sourceProp, targetProp, isRelatedTo);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function signaturesRelatedTo(source, target, kind, reportErrors) {
                if (relation === identityRelation) {
                    return signaturesIdenticalTo(source, target, kind);
                }
                if (target === anyFunctionType || source === anyFunctionType) {
                    return -1 /* True */;
                }
                var sourceIsJSConstructor = source.symbol && isJSConstructor(source.symbol.valueDeclaration);
                var targetIsJSConstructor = target.symbol && isJSConstructor(target.symbol.valueDeclaration);
                var sourceSignatures = getSignaturesOfType(source, (sourceIsJSConstructor && kind === 1 /* Construct */) ?
                    0 /* Call */ : kind);
                var targetSignatures = getSignaturesOfType(target, (targetIsJSConstructor && kind === 1 /* Construct */) ?
                    0 /* Call */ : kind);
                if (kind === 1 /* Construct */ && sourceSignatures.length && targetSignatures.length) {
                    if (ts.isAbstractConstructorType(source) && !ts.isAbstractConstructorType(target)) {
                        // An abstract constructor type is not assignable to a non-abstract constructor type
                        // as it would otherwise be possible to new an abstract class. Note that the assignability
                        // check we perform for an extends clause excludes construct signatures from the target,
                        // so this check never proceeds.
                        if (reportErrors) {
                            reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
                        }
                        return 0 /* False */;
                    }
                    if (!constructorVisibilitiesAreCompatible(sourceSignatures[0], targetSignatures[0], reportErrors)) {
                        return 0 /* False */;
                    }
                }
                var result = -1 /* True */;
                var saveErrorInfo = captureErrorCalculationState();
                var incompatibleReporter = kind === 1 /* Construct */ ? reportIncompatibleConstructSignatureReturn : reportIncompatibleCallSignatureReturn;
                if (ts.getObjectFlags(source) & 64 /* Instantiated */ && ts.getObjectFlags(target) & 64 /* Instantiated */ && source.symbol === target.symbol) {
                    // We have instantiations of the same anonymous type (which typically will be the type of a
                    // method). Simply do a pairwise comparison of the signatures in the two signature lists instead
                    // of the much more expensive N * M comparison matrix we explore below. We erase type parameters
                    // as they are known to always be the same.
                    for (var i = 0; i < targetSignatures.length; i++) {
                        var related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors, incompatibleReporter(sourceSignatures[i], targetSignatures[i]));
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                else if (sourceSignatures.length === 1 && targetSignatures.length === 1) {
                    // For simple functions (functions with a single signature) we only erase type parameters for
                    // the comparable relation. Otherwise, if the source signature is generic, we instantiate it
                    // in the context of the target signature before checking the relationship. Ideally we'd do
                    // this regardless of the number of signatures, but the potential costs are prohibitive due
                    // to the quadratic nature of the logic below.
                    var eraseGenerics = relation === comparableRelation || !!compilerOptions.noStrictGenericChecks;
                    result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors, incompatibleReporter(sourceSignatures[0], targetSignatures[0]));
                }
                else {
                    outer: for (var _i = 0, targetSignatures_1 = targetSignatures; _i < targetSignatures_1.length; _i++) {
                        var t = targetSignatures_1[_i];
                        // Only elaborate errors from the first failure
                        var shouldElaborateErrors = reportErrors;
                        for (var _a = 0, sourceSignatures_1 = sourceSignatures; _a < sourceSignatures_1.length; _a++) {
                            var s = sourceSignatures_1[_a];
                            var related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors, incompatibleReporter(s, t));
                            if (related) {
                                result &= related;
                                resetErrorInfo(saveErrorInfo);
                                continue outer;
                            }
                            shouldElaborateErrors = false;
                        }
                        if (shouldElaborateErrors) {
                            reportError(ts.Diagnostics.Type_0_provides_no_match_for_the_signature_1, typeToString(source), signatureToString(t, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, kind));
                        }
                        return 0 /* False */;
                    }
                }
                return result;
            }
            function reportIncompatibleCallSignatureReturn(siga, sigb) {
                if (siga.parameters.length === 0 && sigb.parameters.length === 0) {
                    return function (source, target) { return reportIncompatibleError(ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); };
                }
                return function (source, target) { return reportIncompatibleError(ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); };
            }
            function reportIncompatibleConstructSignatureReturn(siga, sigb) {
                if (siga.parameters.length === 0 && sigb.parameters.length === 0) {
                    return function (source, target) { return reportIncompatibleError(ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); };
                }
                return function (source, target) { return reportIncompatibleError(ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); };
            }
            /**
             * See signatureAssignableTo, compareSignaturesIdentical
             */
            function signatureRelatedTo(source, target, erase, reportErrors, incompatibleReporter) {
                return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, relation === strictSubtypeRelation ? 8 /* StrictArity */ : 0, reportErrors, reportError, incompatibleReporter, isRelatedTo, makeFunctionTypeMapper(reportUnreliableMarkers));
            }
            function signaturesIdenticalTo(source, target, kind) {
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                if (sourceSignatures.length !== targetSignatures.length) {
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                for (var i = 0; i < sourceSignatures.length; i++) {
                    var related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function eachPropertyRelatedTo(source, target, kind, reportErrors) {
                var result = -1 /* True */;
                var props = source.flags & 2097152 /* Intersection */ ? getPropertiesOfUnionOrIntersectionType(source) : getPropertiesOfObjectType(source);
                for (var _i = 0, props_2 = props; _i < props_2.length; _i++) {
                    var prop = props_2[_i];
                    // Skip over ignored JSX and symbol-named members
                    if (isIgnoredJsxProperty(source, prop)) {
                        continue;
                    }
                    var nameType = getSymbolLinks(prop).nameType;
                    if (nameType && nameType.flags & 8192 /* UniqueESSymbol */) {
                        continue;
                    }
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
                        var related = isRelatedTo(getTypeOfSymbol(prop), target, reportErrors);
                        if (!related) {
                            if (reportErrors) {
                                reportError(ts.Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop));
                            }
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                return result;
            }
            function indexTypeRelatedTo(sourceType, targetType, reportErrors) {
                var related = isRelatedTo(sourceType, targetType, reportErrors);
                if (!related && reportErrors) {
                    reportError(ts.Diagnostics.Index_signatures_are_incompatible);
                }
                return related;
            }
            function indexTypesRelatedTo(source, target, kind, sourceIsPrimitive, reportErrors, intersectionState) {
                if (relation === identityRelation) {
                    return indexTypesIdenticalTo(source, target, kind);
                }
                var targetType = getIndexTypeOfType(target, kind);
                if (!targetType || targetType.flags & 1 /* Any */ && !sourceIsPrimitive) {
                    // Index signature of type any permits assignment from everything but primitives
                    return -1 /* True */;
                }
                if (isGenericMappedType(source)) {
                    // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U }
                    // if T is related to U.
                    return kind === 0 /* String */ ? isRelatedTo(getTemplateTypeFromMappedType(source), targetType, reportErrors) : 0 /* False */;
                }
                var indexType = getIndexTypeOfType(source, kind) || kind === 1 /* Number */ && getIndexTypeOfType(source, 0 /* String */);
                if (indexType) {
                    return indexTypeRelatedTo(indexType, targetType, reportErrors);
                }
                if (!(intersectionState & 1 /* Source */) && isObjectTypeWithInferableIndex(source)) {
                    // Intersection constituents are never considered to have an inferred index signature
                    var related = eachPropertyRelatedTo(source, targetType, kind, reportErrors);
                    if (related && kind === 0 /* String */) {
                        var numberIndexType = getIndexTypeOfType(source, 1 /* Number */);
                        if (numberIndexType) {
                            related &= indexTypeRelatedTo(numberIndexType, targetType, reportErrors);
                        }
                    }
                    return related;
                }
                if (reportErrors) {
                    reportError(ts.Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source));
                }
                return 0 /* False */;
            }
            function indexTypesIdenticalTo(source, target, indexKind) {
                var targetInfo = getIndexInfoOfType(target, indexKind);
                var sourceInfo = getIndexInfoOfType(source, indexKind);
                if (!sourceInfo && !targetInfo) {
                    return -1 /* True */;
                }
                if (sourceInfo && targetInfo && sourceInfo.isReadonly === targetInfo.isReadonly) {
                    return isRelatedTo(sourceInfo.type, targetInfo.type);
                }
                return 0 /* False */;
            }
            function constructorVisibilitiesAreCompatible(sourceSignature, targetSignature, reportErrors) {
                if (!sourceSignature.declaration || !targetSignature.declaration) {
                    return true;
                }
                var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
                var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
                // A public, protected and private signature is assignable to a private signature.
                if (targetAccessibility === 8 /* Private */) {
                    return true;
                }
                // A public and protected signature is assignable to a protected signature.
                if (targetAccessibility === 16 /* Protected */ && sourceAccessibility !== 8 /* Private */) {
                    return true;
                }
                // Only a public signature is assignable to public signature.
                if (targetAccessibility !== 16 /* Protected */ && !sourceAccessibility) {
                    return true;
                }
                if (reportErrors) {
                    reportError(ts.Diagnostics.Cannot_assign_a_0_constructor_type_to_a_1_constructor_type, visibilityToString(sourceAccessibility), visibilityToString(targetAccessibility));
                }
                return false;
            }
        }
        function getBestMatchingType(source, target, isRelatedTo) {
            if (isRelatedTo === void 0) { isRelatedTo = compareTypesAssignable; }
            return findMatchingDiscriminantType(source, target, isRelatedTo, /*skipPartial*/ true) ||
                findMatchingTypeReferenceOrTypeAliasReference(source, target) ||
                findBestTypeForObjectLiteral(source, target) ||
                findBestTypeForInvokable(source, target) ||
                findMostOverlappyType(source, target);
        }
        function discriminateTypeByDiscriminableItems(target, discriminators, related, defaultValue, skipPartial) {
            // undefined=unknown, true=discriminated, false=not discriminated
            // The state of each type progresses from left to right. Discriminated types stop at 'true'.
            var discriminable = target.types.map(function (_) { return undefined; });
            for (var _i = 0, discriminators_1 = discriminators; _i < discriminators_1.length; _i++) {
                var _a = discriminators_1[_i], getDiscriminatingType = _a[0], propertyName = _a[1];
                var targetProp = getUnionOrIntersectionProperty(target, propertyName);
                if (skipPartial && targetProp && ts.getCheckFlags(targetProp) & 16 /* ReadPartial */) {
                    continue;
                }
                var i = 0;
                for (var _b = 0, _c = target.types; _b < _c.length; _b++) {
                    var type = _c[_b];
                    var targetType = getTypeOfPropertyOfType(type, propertyName);
                    if (targetType && related(getDiscriminatingType(), targetType)) {
                        discriminable[i] = discriminable[i] === undefined ? true : discriminable[i];
                    }
                    else {
                        discriminable[i] = false;
                    }
                    i++;
                }
            }
            var match = discriminable.indexOf(/*searchElement*/ true);
            // make sure exactly 1 matches before returning it
            return match === -1 || discriminable.indexOf(/*searchElement*/ true, match + 1) !== -1 ? defaultValue : target.types[match];
        }
        /**
         * A type is 'weak' if it is an object type with at least one optional property
         * and no required properties, call/construct signatures or index signatures
         */
        function isWeakType(type) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 &&
                    !resolved.stringIndexInfo && !resolved.numberIndexInfo &&
                    resolved.properties.length > 0 &&
                    ts.every(resolved.properties, function (p) { return !!(p.flags & 16777216 /* Optional */); });
            }
            if (type.flags & 2097152 /* Intersection */) {
                return ts.every(type.types, isWeakType);
            }
            return false;
        }
        function hasCommonProperties(source, target, isComparingJsxAttributes) {
            for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                var prop = _a[_i];
                if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
                    return true;
                }
            }
            return false;
        }
        // Return a type reference where the source type parameter is replaced with the target marker
        // type, and flag the result as a marker type reference.
        function getMarkerTypeReference(type, source, target) {
            var result = createTypeReference(type, ts.map(type.typeParameters, function (t) { return t === source ? target : t; }));
            result.objectFlags |= 8192 /* MarkerType */;
            return result;
        }
        function getAliasVariances(symbol) {
            var links = getSymbolLinks(symbol);
            return getVariancesWorker(links.typeParameters, links, function (_links, param, marker) {
                var type = getTypeAliasInstantiation(symbol, instantiateTypes(links.typeParameters, makeUnaryTypeMapper(param, marker)));
                type.aliasTypeArgumentsContainsMarker = true;
                return type;
            });
        }
        // Return an array containing the variance of each type parameter. The variance is effectively
        // a digest of the type comparisons that occur for each type argument when instantiations of the
        // generic type are structurally compared. We infer the variance information by comparing
        // instantiations of the generic type for type arguments with known relations. The function
        // returns the emptyArray singleton when invoked recursively for the given generic type.
        function getVariancesWorker(typeParameters, cache, createMarkerType) {
            if (typeParameters === void 0) { typeParameters = ts.emptyArray; }
            var variances = cache.variances;
            if (!variances) {
                // The emptyArray singleton is used to signal a recursive invocation.
                cache.variances = ts.emptyArray;
                variances = [];
                var _loop_16 = function (tp) {
                    var unmeasurable = false;
                    var unreliable = false;
                    var oldHandler = outofbandVarianceMarkerHandler;
                    outofbandVarianceMarkerHandler = function (onlyUnreliable) { return onlyUnreliable ? unreliable = true : unmeasurable = true; };
                    // We first compare instantiations where the type parameter is replaced with
                    // marker types that have a known subtype relationship. From this we can infer
                    // invariance, covariance, contravariance or bivariance.
                    var typeWithSuper = createMarkerType(cache, tp, markerSuperType);
                    var typeWithSub = createMarkerType(cache, tp, markerSubType);
                    var variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? 1 /* Covariant */ : 0) |
                        (isTypeAssignableTo(typeWithSuper, typeWithSub) ? 2 /* Contravariant */ : 0);
                    // If the instantiations appear to be related bivariantly it may be because the
                    // type parameter is independent (i.e. it isn't witnessed anywhere in the generic
                    // type). To determine this we compare instantiations where the type parameter is
                    // replaced with marker types that are known to be unrelated.
                    if (variance === 3 /* Bivariant */ && isTypeAssignableTo(createMarkerType(cache, tp, markerOtherType), typeWithSuper)) {
                        variance = 4 /* Independent */;
                    }
                    outofbandVarianceMarkerHandler = oldHandler;
                    if (unmeasurable || unreliable) {
                        if (unmeasurable) {
                            variance |= 8 /* Unmeasurable */;
                        }
                        if (unreliable) {
                            variance |= 16 /* Unreliable */;
                        }
                    }
                    variances.push(variance);
                };
                for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) {
                    var tp = typeParameters_1[_i];
                    _loop_16(tp);
                }
                cache.variances = variances;
            }
            return variances;
        }
        function getVariances(type) {
            // Arrays and tuples are known to be covariant, no need to spend time computing this.
            if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8 /* Tuple */) {
                return arrayVariances;
            }
            return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference);
        }
        // Return true if the given type reference has a 'void' type argument for a covariant type parameter.
        // See comment at call in recursiveTypeRelatedTo for when this case matters.
        function hasCovariantVoidArgument(typeArguments, variances) {
            for (var i = 0; i < variances.length; i++) {
                if ((variances[i] & 7 /* VarianceMask */) === 1 /* Covariant */ && typeArguments[i].flags & 16384 /* Void */) {
                    return true;
                }
            }
            return false;
        }
        function isUnconstrainedTypeParameter(type) {
            return type.flags & 262144 /* TypeParameter */ && !getConstraintOfTypeParameter(type);
        }
        function isNonDeferredTypeReference(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && !type.node;
        }
        function isTypeReferenceWithGenericArguments(type) {
            return isNonDeferredTypeReference(type) && ts.some(getTypeArguments(type), function (t) { return isUnconstrainedTypeParameter(t) || isTypeReferenceWithGenericArguments(t); });
        }
        /**
         * getTypeReferenceId(A<T, number, U>) returns "111=0-12=1"
         *   where A.id=111 and number.id=12
         */
        function getTypeReferenceId(type, typeParameters, depth) {
            if (depth === void 0) { depth = 0; }
            var result = "" + type.target.id;
            for (var _i = 0, _a = getTypeArguments(type); _i < _a.length; _i++) {
                var t = _a[_i];
                if (isUnconstrainedTypeParameter(t)) {
                    var index = typeParameters.indexOf(t);
                    if (index < 0) {
                        index = typeParameters.length;
                        typeParameters.push(t);
                    }
                    result += "=" + index;
                }
                else if (depth < 4 && isTypeReferenceWithGenericArguments(t)) {
                    result += "<" + getTypeReferenceId(t, typeParameters, depth + 1) + ">";
                }
                else {
                    result += "-" + t.id;
                }
            }
            return result;
        }
        /**
         * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters.
         * For other cases, the types ids are used.
         */
        function getRelationKey(source, target, intersectionState, relation) {
            if (relation === identityRelation && source.id > target.id) {
                var temp = source;
                source = target;
                target = temp;
            }
            var postFix = intersectionState ? ":" + intersectionState : "";
            if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) {
                var typeParameters = [];
                return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters) + postFix;
            }
            return source.id + "," + target.id + postFix;
        }
        // Invoke the callback for each underlying property symbol of the given symbol and return the first
        // value that isn't undefined.
        function forEachProperty(prop, callback) {
            if (ts.getCheckFlags(prop) & 6 /* Synthetic */) {
                for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    var p = getPropertyOfType(t, prop.escapedName);
                    var result = p && forEachProperty(p, callback);
                    if (result) {
                        return result;
                    }
                }
                return undefined;
            }
            return callback(prop);
        }
        // Return the declaring class type of a property or undefined if property not declared in class
        function getDeclaringClass(prop) {
            return prop.parent && prop.parent.flags & 32 /* Class */ ? getDeclaredTypeOfSymbol(getParentOfSymbol(prop)) : undefined;
        }
        // Return true if some underlying source property is declared in a class that derives
        // from the given base class.
        function isPropertyInClassDerivedFrom(prop, baseClass) {
            return forEachProperty(prop, function (sp) {
                var sourceClass = getDeclaringClass(sp);
                return sourceClass ? hasBaseType(sourceClass, baseClass) : false;
            });
        }
        // Return true if source property is a valid override of protected parts of target property.
        function isValidOverrideOf(sourceProp, targetProp) {
            return !forEachProperty(targetProp, function (tp) { return ts.getDeclarationModifierFlagsFromSymbol(tp) & 16 /* Protected */ ?
                !isPropertyInClassDerivedFrom(sourceProp, getDeclaringClass(tp)) : false; });
        }
        // Return true if the given class derives from each of the declaring classes of the protected
        // constituents of the given property.
        function isClassDerivedFromDeclaringClasses(checkClass, prop) {
            return forEachProperty(prop, function (p) { return ts.getDeclarationModifierFlagsFromSymbol(p) & 16 /* Protected */ ?
                !hasBaseType(checkClass, getDeclaringClass(p)) : false; }) ? undefined : checkClass;
        }
        // Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons
        // for 5 or more occurrences or instantiations of the type have been recorded on the given stack. It is possible,
        // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely
        // expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 5
        // levels, but unequal at some level beyond that.
        // In addition, this will also detect when an indexed access has been chained off of 5 or more times (which is essentially
        // the dual of the structural comparison), and likewise mark the type as deeply nested, potentially adding false positives
        // for finite but deeply expanding indexed accesses (eg, for `Q[P1][P2][P3][P4][P5]`).
        function isDeeplyNestedType(type, stack, depth) {
            // We track all object types that have an associated symbol (representing the origin of the type)
            if (depth >= 5 && type.flags & 524288 /* Object */ && !isObjectOrArrayLiteralType(type)) {
                var symbol = type.symbol;
                if (symbol) {
                    var count = 0;
                    for (var i = 0; i < depth; i++) {
                        var t = stack[i];
                        if (t.flags & 524288 /* Object */ && t.symbol === symbol) {
                            count++;
                            if (count >= 5)
                                return true;
                        }
                    }
                }
            }
            if (depth >= 5 && type.flags & 8388608 /* IndexedAccess */) {
                var root = getRootObjectTypeFromIndexedAccessChain(type);
                var count = 0;
                for (var i = 0; i < depth; i++) {
                    var t = stack[i];
                    if (getRootObjectTypeFromIndexedAccessChain(t) === root) {
                        count++;
                        if (count >= 5)
                            return true;
                    }
                }
            }
            return false;
        }
        /**
         * Gets the leftmost object type in a chain of indexed accesses, eg, in A[P][Q], returns A
         */
        function getRootObjectTypeFromIndexedAccessChain(type) {
            var t = type;
            while (t.flags & 8388608 /* IndexedAccess */) {
                t = t.objectType;
            }
            return t;
        }
        function isPropertyIdenticalTo(sourceProp, targetProp) {
            return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== 0 /* False */;
        }
        function compareProperties(sourceProp, targetProp, compareTypes) {
            // Two members are considered identical when
            // - they are public properties with identical names, optionality, and types,
            // - they are private or protected properties originating in the same declaration and having identical types
            if (sourceProp === targetProp) {
                return -1 /* True */;
            }
            var sourcePropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(sourceProp) & 24 /* NonPublicAccessibilityModifier */;
            var targetPropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(targetProp) & 24 /* NonPublicAccessibilityModifier */;
            if (sourcePropAccessibility !== targetPropAccessibility) {
                return 0 /* False */;
            }
            if (sourcePropAccessibility) {
                if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) {
                    return 0 /* False */;
                }
            }
            else {
                if ((sourceProp.flags & 16777216 /* Optional */) !== (targetProp.flags & 16777216 /* Optional */)) {
                    return 0 /* False */;
                }
            }
            if (isReadonlySymbol(sourceProp) !== isReadonlySymbol(targetProp)) {
                return 0 /* False */;
            }
            return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
        }
        function isMatchingSignature(source, target, partialMatch) {
            var sourceParameterCount = getParameterCount(source);
            var targetParameterCount = getParameterCount(target);
            var sourceMinArgumentCount = getMinArgumentCount(source);
            var targetMinArgumentCount = getMinArgumentCount(target);
            var sourceHasRestParameter = hasEffectiveRestParameter(source);
            var targetHasRestParameter = hasEffectiveRestParameter(target);
            // A source signature matches a target signature if the two signatures have the same number of required,
            // optional, and rest parameters.
            if (sourceParameterCount === targetParameterCount &&
                sourceMinArgumentCount === targetMinArgumentCount &&
                sourceHasRestParameter === targetHasRestParameter) {
                return true;
            }
            // A source signature partially matches a target signature if the target signature has no fewer required
            // parameters
            if (partialMatch && sourceMinArgumentCount <= targetMinArgumentCount) {
                return true;
            }
            return false;
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesIdentical(source, target, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypes) {
            // TODO (drosen): De-duplicate code between related functions.
            if (source === target) {
                return -1 /* True */;
            }
            if (!(isMatchingSignature(source, target, partialMatch))) {
                return 0 /* False */;
            }
            // Check that the two signatures have the same number of type parameters.
            if (ts.length(source.typeParameters) !== ts.length(target.typeParameters)) {
                return 0 /* False */;
            }
            // Check that type parameter constraints and defaults match. If they do, instantiate the source
            // signature with the type parameters of the target signature and continue the comparison.
            if (target.typeParameters) {
                var mapper = createTypeMapper(source.typeParameters, target.typeParameters);
                for (var i = 0; i < target.typeParameters.length; i++) {
                    var s = source.typeParameters[i];
                    var t = target.typeParameters[i];
                    if (!(s === t || compareTypes(instantiateType(getConstraintFromTypeParameter(s), mapper) || unknownType, getConstraintFromTypeParameter(t) || unknownType) &&
                        compareTypes(instantiateType(getDefaultFromTypeParameter(s), mapper) || unknownType, getDefaultFromTypeParameter(t) || unknownType))) {
                        return 0 /* False */;
                    }
                }
                source = instantiateSignature(source, mapper, /*eraseTypeParameters*/ true);
            }
            var result = -1 /* True */;
            if (!ignoreThisTypes) {
                var sourceThisType = getThisTypeOfSignature(source);
                if (sourceThisType) {
                    var targetThisType = getThisTypeOfSignature(target);
                    if (targetThisType) {
                        var related = compareTypes(sourceThisType, targetThisType);
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
            }
            var targetLen = getParameterCount(target);
            for (var i = 0; i < targetLen; i++) {
                var s = getTypeAtPosition(source, i);
                var t = getTypeAtPosition(target, i);
                var related = compareTypes(t, s);
                if (!related) {
                    return 0 /* False */;
                }
                result &= related;
            }
            if (!ignoreReturnTypes) {
                var sourceTypePredicate = getTypePredicateOfSignature(source);
                var targetTypePredicate = getTypePredicateOfSignature(target);
                result &= sourceTypePredicate || targetTypePredicate ?
                    compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes) :
                    compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
            }
            return result;
        }
        function compareTypePredicatesIdentical(source, target, compareTypes) {
            return !(source && target && typePredicateKindsMatch(source, target)) ? 0 /* False */ :
                source.type === target.type ? -1 /* True */ :
                    source.type && target.type ? compareTypes(source.type, target.type) :
                        0 /* False */;
        }
        function literalTypesWithSameBaseType(types) {
            var commonBaseType;
            for (var _i = 0, types_12 = types; _i < types_12.length; _i++) {
                var t = types_12[_i];
                var baseType = getBaseTypeOfLiteralType(t);
                if (!commonBaseType) {
                    commonBaseType = baseType;
                }
                if (baseType === t || baseType !== commonBaseType) {
                    return false;
                }
            }
            return true;
        }
        // When the candidate types are all literal types with the same base type, return a union
        // of those literal types. Otherwise, return the leftmost type for which no type to the
        // right is a supertype.
        function getSupertypeOrUnion(types) {
            return literalTypesWithSameBaseType(types) ?
                getUnionType(types) :
                ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(s, t) ? t : s; });
        }
        function getCommonSupertype(types) {
            if (!strictNullChecks) {
                return getSupertypeOrUnion(types);
            }
            var primaryTypes = ts.filter(types, function (t) { return !(t.flags & 98304 /* Nullable */); });
            return primaryTypes.length ?
                getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & 98304 /* Nullable */) :
                getUnionType(types, 2 /* Subtype */);
        }
        // Return the leftmost type for which no type to the right is a subtype.
        function getCommonSubtype(types) {
            return ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(t, s) ? t : s; });
        }
        function isArrayType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && (type.target === globalArrayType || type.target === globalReadonlyArrayType);
        }
        function isReadonlyArrayType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && type.target === globalReadonlyArrayType;
        }
        function isMutableArrayOrTuple(type) {
            return isArrayType(type) && !isReadonlyArrayType(type) || isTupleType(type) && !type.target.readonly;
        }
        function getElementTypeOfArrayType(type) {
            return isArrayType(type) ? getTypeArguments(type)[0] : undefined;
        }
        function isArrayLikeType(type) {
            // A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
            // or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
            return isArrayType(type) || !(type.flags & 98304 /* Nullable */) && isTypeAssignableTo(type, anyReadonlyArrayType);
        }
        function isEmptyArrayLiteralType(type) {
            var elementType = isArrayType(type) ? getTypeArguments(type)[0] : undefined;
            return elementType === undefinedWideningType || elementType === implicitNeverType;
        }
        function isTupleLikeType(type) {
            return isTupleType(type) || !!getPropertyOfType(type, "0");
        }
        function isArrayOrTupleLikeType(type) {
            return isArrayLikeType(type) || isTupleLikeType(type);
        }
        function getTupleElementType(type, index) {
            var propType = getTypeOfPropertyOfType(type, "" + index);
            if (propType) {
                return propType;
            }
            if (everyType(type, isTupleType)) {
                return mapType(type, function (t) { return getRestTypeOfTupleType(t) || undefinedType; });
            }
            return undefined;
        }
        function isNeitherUnitTypeNorNever(type) {
            return !(type.flags & (109440 /* Unit */ | 131072 /* Never */));
        }
        function isUnitType(type) {
            return !!(type.flags & 109440 /* Unit */);
        }
        function isLiteralType(type) {
            return type.flags & 16 /* Boolean */ ? true :
                type.flags & 1048576 /* Union */ ? type.flags & 1024 /* EnumLiteral */ ? true : ts.every(type.types, isUnitType) :
                    isUnitType(type);
        }
        function getBaseTypeOfLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) :
                type.flags & 128 /* StringLiteral */ ? stringType :
                    type.flags & 256 /* NumberLiteral */ ? numberType :
                        type.flags & 2048 /* BigIntLiteral */ ? bigintType :
                            type.flags & 512 /* BooleanLiteral */ ? booleanType :
                                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getBaseTypeOfLiteralType)) :
                                    type;
        }
        function getWidenedLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ && isFreshLiteralType(type) ? getBaseTypeOfEnumLiteralType(type) :
                type.flags & 128 /* StringLiteral */ && isFreshLiteralType(type) ? stringType :
                    type.flags & 256 /* NumberLiteral */ && isFreshLiteralType(type) ? numberType :
                        type.flags & 2048 /* BigIntLiteral */ && isFreshLiteralType(type) ? bigintType :
                            type.flags & 512 /* BooleanLiteral */ && isFreshLiteralType(type) ? booleanType :
                                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedLiteralType)) :
                                    type;
        }
        function getWidenedUniqueESSymbolType(type) {
            return type.flags & 8192 /* UniqueESSymbol */ ? esSymbolType :
                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedUniqueESSymbolType)) :
                    type;
        }
        function getWidenedLiteralLikeTypeForContextualType(type, contextualType) {
            if (!isLiteralOfContextualType(type, contextualType)) {
                type = getWidenedUniqueESSymbolType(getWidenedLiteralType(type));
            }
            return type;
        }
        function getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(type, contextualSignatureReturnType, isAsync) {
            if (type && isUnitType(type)) {
                var contextualType = !contextualSignatureReturnType ? undefined :
                    isAsync ? getPromisedTypeOfPromise(contextualSignatureReturnType) :
                        contextualSignatureReturnType;
                type = getWidenedLiteralLikeTypeForContextualType(type, contextualType);
            }
            return type;
        }
        function getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(type, contextualSignatureReturnType, kind, isAsyncGenerator) {
            if (type && isUnitType(type)) {
                var contextualType = !contextualSignatureReturnType ? undefined :
                    getIterationTypeOfGeneratorFunctionReturnType(kind, contextualSignatureReturnType, isAsyncGenerator);
                type = getWidenedLiteralLikeTypeForContextualType(type, contextualType);
            }
            return type;
        }
        /**
         * Check if a Type was written as a tuple type literal.
         * Prefer using isTupleLikeType() unless the use of `elementTypes`/`getTypeArguments` is required.
         */
        function isTupleType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */ && type.target.objectFlags & 8 /* Tuple */);
        }
        function getRestTypeOfTupleType(type) {
            return type.target.hasRestElement ? getTypeArguments(type)[type.target.typeParameters.length - 1] : undefined;
        }
        function getRestArrayTypeOfTupleType(type) {
            var restType = getRestTypeOfTupleType(type);
            return restType && createArrayType(restType);
        }
        function getLengthOfTupleType(type) {
            return getTypeReferenceArity(type) - (type.target.hasRestElement ? 1 : 0);
        }
        function isZeroBigInt(_a) {
            var value = _a.value;
            return value.base10Value === "0";
        }
        function getFalsyFlagsOfTypes(types) {
            var result = 0;
            for (var _i = 0, types_13 = types; _i < types_13.length; _i++) {
                var t = types_13[_i];
                result |= getFalsyFlags(t);
            }
            return result;
        }
        // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null
        // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns
        // no flags for all other types (including non-falsy literal types).
        function getFalsyFlags(type) {
            return type.flags & 1048576 /* Union */ ? getFalsyFlagsOfTypes(type.types) :
                type.flags & 128 /* StringLiteral */ ? type.value === "" ? 128 /* StringLiteral */ : 0 :
                    type.flags & 256 /* NumberLiteral */ ? type.value === 0 ? 256 /* NumberLiteral */ : 0 :
                        type.flags & 2048 /* BigIntLiteral */ ? isZeroBigInt(type) ? 2048 /* BigIntLiteral */ : 0 :
                            type.flags & 512 /* BooleanLiteral */ ? (type === falseType || type === regularFalseType) ? 512 /* BooleanLiteral */ : 0 :
                                type.flags & 117724 /* PossiblyFalsy */;
        }
        function removeDefinitelyFalsyTypes(type) {
            return getFalsyFlags(type) & 117632 /* DefinitelyFalsy */ ?
                filterType(type, function (t) { return !(getFalsyFlags(t) & 117632 /* DefinitelyFalsy */); }) :
                type;
        }
        function extractDefinitelyFalsyTypes(type) {
            return mapType(type, getDefinitelyFalsyPartOfType);
        }
        function getDefinitelyFalsyPartOfType(type) {
            return type.flags & 4 /* String */ ? emptyStringType :
                type.flags & 8 /* Number */ ? zeroType :
                    type.flags & 64 /* BigInt */ ? zeroBigIntType :
                        type === regularFalseType ||
                            type === falseType ||
                            type.flags & (16384 /* Void */ | 32768 /* Undefined */ | 65536 /* Null */) ||
                            type.flags & 128 /* StringLiteral */ && type.value === "" ||
                            type.flags & 256 /* NumberLiteral */ && type.value === 0 ||
                            type.flags & 2048 /* BigIntLiteral */ && isZeroBigInt(type) ? type :
                            neverType;
        }
        /**
         * Add undefined or null or both to a type if they are missing.
         * @param type - type to add undefined and/or null to if not present
         * @param flags - Either TypeFlags.Undefined or TypeFlags.Null, or both
         */
        function getNullableType(type, flags) {
            var missing = (flags & ~type.flags) & (32768 /* Undefined */ | 65536 /* Null */);
            return missing === 0 ? type :
                missing === 32768 /* Undefined */ ? getUnionType([type, undefinedType]) :
                    missing === 65536 /* Null */ ? getUnionType([type, nullType]) :
                        getUnionType([type, undefinedType, nullType]);
        }
        function getOptionalType(type) {
            ts.Debug.assert(strictNullChecks);
            return type.flags & 32768 /* Undefined */ ? type : getUnionType([type, undefinedType]);
        }
        function getGlobalNonNullableTypeInstantiation(type) {
            if (!deferredGlobalNonNullableTypeAlias) {
                deferredGlobalNonNullableTypeAlias = getGlobalSymbol("NonNullable", 524288 /* TypeAlias */, /*diagnostic*/ undefined) || unknownSymbol;
            }
            // Use NonNullable global type alias if available to improve quick info/declaration emit
            if (deferredGlobalNonNullableTypeAlias !== unknownSymbol) {
                return getTypeAliasInstantiation(deferredGlobalNonNullableTypeAlias, [type]);
            }
            return getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */); // Type alias unavailable, fall back to non-higher-order behavior
        }
        function getNonNullableType(type) {
            return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type;
        }
        function addOptionalTypeMarker(type) {
            return strictNullChecks ? getUnionType([type, optionalType]) : type;
        }
        function isNotOptionalTypeMarker(type) {
            return type !== optionalType;
        }
        function removeOptionalTypeMarker(type) {
            return strictNullChecks ? filterType(type, isNotOptionalTypeMarker) : type;
        }
        function propagateOptionalTypeMarker(type, node, wasOptional) {
            return wasOptional ? ts.isOutermostOptionalChain(node) ? getOptionalType(type) : addOptionalTypeMarker(type) : type;
        }
        function getOptionalExpressionType(exprType, expression) {
            return ts.isExpressionOfOptionalChainRoot(expression) ? getNonNullableType(exprType) :
                ts.isOptionalChain(expression) ? removeOptionalTypeMarker(exprType) :
                    exprType;
        }
        /**
         * Is source potentially coercible to target type under `==`.
         * Assumes that `source` is a constituent of a union, hence
         * the boolean literal flag on the LHS, but not on the RHS.
         *
         * This does not fully replicate the semantics of `==`. The
         * intention is to catch cases that are clearly not right.
         *
         * Comparing (string | number) to number should not remove the
         * string element.
         *
         * Comparing (string | number) to 1 will remove the string
         * element, though this is not sound. This is a pragmatic
         * choice.
         *
         * @see narrowTypeByEquality
         *
         * @param source
         * @param target
         */
        function isCoercibleUnderDoubleEquals(source, target) {
            return ((source.flags & (8 /* Number */ | 4 /* String */ | 512 /* BooleanLiteral */)) !== 0)
                && ((target.flags & (8 /* Number */ | 4 /* String */ | 16 /* Boolean */)) !== 0);
        }
        /**
         * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
         * with no call or construct signatures.
         */
        function isObjectTypeWithInferableIndex(type) {
            return type.flags & 2097152 /* Intersection */ ? ts.every(type.types, isObjectTypeWithInferableIndex) :
                !!(type.symbol && (type.symbol.flags & (4096 /* ObjectLiteral */ | 2048 /* TypeLiteral */ | 384 /* Enum */ | 512 /* ValueModule */)) !== 0 &&
                    !typeHasCallOrConstructSignatures(type)) || !!(ts.getObjectFlags(type) & 2048 /* ReverseMapped */ && isObjectTypeWithInferableIndex(type.source));
        }
        function createSymbolWithType(source, type) {
            var symbol = createSymbol(source.flags, source.escapedName, ts.getCheckFlags(source) & 8 /* Readonly */);
            symbol.declarations = source.declarations;
            symbol.parent = source.parent;
            symbol.type = type;
            symbol.target = source;
            if (source.valueDeclaration) {
                symbol.valueDeclaration = source.valueDeclaration;
            }
            var nameType = getSymbolLinks(source).nameType;
            if (nameType) {
                symbol.nameType = nameType;
            }
            return symbol;
        }
        function transformTypeOfMembers(type, f) {
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var property = _a[_i];
                var original = getTypeOfSymbol(property);
                var updated = f(original);
                members.set(property.escapedName, updated === original ? property : createSymbolWithType(property, updated));
            }
            return members;
        }
        /**
         * If the the provided object literal is subject to the excess properties check,
         * create a new that is exempt. Recursively mark object literal members as exempt.
         * Leave signatures alone since they are not subject to the check.
         */
        function getRegularTypeOfObjectLiteral(type) {
            if (!(isObjectLiteralType(type) && ts.getObjectFlags(type) & 32768 /* FreshLiteral */)) {
                return type;
            }
            var regularType = type.regularType;
            if (regularType) {
                return regularType;
            }
            var resolved = type;
            var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral);
            var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo);
            regularNew.flags = resolved.flags;
            regularNew.objectFlags |= resolved.objectFlags & ~32768 /* FreshLiteral */;
            type.regularType = regularNew;
            return regularNew;
        }
        function createWideningContext(parent, propertyName, siblings) {
            return { parent: parent, propertyName: propertyName, siblings: siblings, resolvedProperties: undefined };
        }
        function getSiblingsOfContext(context) {
            if (!context.siblings) {
                var siblings_1 = [];
                for (var _i = 0, _a = getSiblingsOfContext(context.parent); _i < _a.length; _i++) {
                    var type = _a[_i];
                    if (isObjectLiteralType(type)) {
                        var prop = getPropertyOfObjectType(type, context.propertyName);
                        if (prop) {
                            forEachType(getTypeOfSymbol(prop), function (t) {
                                siblings_1.push(t);
                            });
                        }
                    }
                }
                context.siblings = siblings_1;
            }
            return context.siblings;
        }
        function getPropertiesOfContext(context) {
            if (!context.resolvedProperties) {
                var names = ts.createMap();
                for (var _i = 0, _a = getSiblingsOfContext(context); _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (isObjectLiteralType(t) && !(ts.getObjectFlags(t) & 1024 /* ContainsSpread */)) {
                        for (var _b = 0, _c = getPropertiesOfType(t); _b < _c.length; _b++) {
                            var prop = _c[_b];
                            names.set(prop.escapedName, prop);
                        }
                    }
                }
                context.resolvedProperties = ts.arrayFrom(names.values());
            }
            return context.resolvedProperties;
        }
        function getWidenedProperty(prop, context) {
            if (!(prop.flags & 4 /* Property */)) {
                // Since get accessors already widen their return value there is no need to
                // widen accessor based properties here.
                return prop;
            }
            var original = getTypeOfSymbol(prop);
            var propContext = context && createWideningContext(context, prop.escapedName, /*siblings*/ undefined);
            var widened = getWidenedTypeWithContext(original, propContext);
            return widened === original ? prop : createSymbolWithType(prop, widened);
        }
        function getUndefinedProperty(prop) {
            var cached = undefinedProperties.get(prop.escapedName);
            if (cached) {
                return cached;
            }
            var result = createSymbolWithType(prop, undefinedType);
            result.flags |= 16777216 /* Optional */;
            undefinedProperties.set(prop.escapedName, result);
            return result;
        }
        function getWidenedTypeOfObjectLiteral(type, context) {
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var prop = _a[_i];
                members.set(prop.escapedName, getWidenedProperty(prop, context));
            }
            if (context) {
                for (var _b = 0, _c = getPropertiesOfContext(context); _b < _c.length; _b++) {
                    var prop = _c[_b];
                    if (!members.has(prop.escapedName)) {
                        members.set(prop.escapedName, getUndefinedProperty(prop));
                    }
                }
            }
            var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
            var result = createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly), numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
            result.objectFlags |= (ts.getObjectFlags(type) & (16384 /* JSLiteral */ | 2097152 /* NonInferrableType */)); // Retain js literal flag through widening
            return result;
        }
        function getWidenedType(type) {
            return getWidenedTypeWithContext(type, /*context*/ undefined);
        }
        function getWidenedTypeWithContext(type, context) {
            if (ts.getObjectFlags(type) & 1572864 /* RequiresWidening */) {
                if (context === undefined && type.widened) {
                    return type.widened;
                }
                var result = void 0;
                if (type.flags & (1 /* Any */ | 98304 /* Nullable */)) {
                    result = anyType;
                }
                else if (isObjectLiteralType(type)) {
                    result = getWidenedTypeOfObjectLiteral(type, context);
                }
                else if (type.flags & 1048576 /* Union */) {
                    var unionContext_1 = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, type.types);
                    var widenedTypes = ts.sameMap(type.types, function (t) { return t.flags & 98304 /* Nullable */ ? t : getWidenedTypeWithContext(t, unionContext_1); });
                    // Widening an empty object literal transitions from a highly restrictive type to
                    // a highly inclusive one. For that reason we perform subtype reduction here if the
                    // union includes empty object types (e.g. reducing {} | string to just {}).
                    result = getUnionType(widenedTypes, ts.some(widenedTypes, isEmptyObjectType) ? 2 /* Subtype */ : 1 /* Literal */);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    result = getIntersectionType(ts.sameMap(type.types, getWidenedType));
                }
                else if (isArrayType(type) || isTupleType(type)) {
                    result = createTypeReference(type.target, ts.sameMap(getTypeArguments(type), getWidenedType));
                }
                if (result && context === undefined) {
                    type.widened = result;
                }
                return result || type;
            }
            return type;
        }
        /**
         * Reports implicit any errors that occur as a result of widening 'null' and 'undefined'
         * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to
         * getWidenedType. But in some cases getWidenedType is called without reporting errors
         * (type argument inference is an example).
         *
         * The return value indicates whether an error was in fact reported. The particular circumstances
         * are on a best effort basis. Currently, if the null or undefined that causes widening is inside
         * an object literal property (arbitrarily deeply), this function reports an error. If no error is
         * reported, reportImplicitAnyError is a suitable fallback to report a general error.
         */
        function reportWideningErrorsInType(type) {
            var errorReported = false;
            if (ts.getObjectFlags(type) & 524288 /* ContainsWideningType */) {
                if (type.flags & 1048576 /* Union */) {
                    if (ts.some(type.types, isEmptyObjectType)) {
                        errorReported = true;
                    }
                    else {
                        for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                            var t = _a[_i];
                            if (reportWideningErrorsInType(t)) {
                                errorReported = true;
                            }
                        }
                    }
                }
                if (isArrayType(type) || isTupleType(type)) {
                    for (var _b = 0, _c = getTypeArguments(type); _b < _c.length; _b++) {
                        var t = _c[_b];
                        if (reportWideningErrorsInType(t)) {
                            errorReported = true;
                        }
                    }
                }
                if (isObjectLiteralType(type)) {
                    for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) {
                        var p = _e[_d];
                        var t = getTypeOfSymbol(p);
                        if (ts.getObjectFlags(t) & 524288 /* ContainsWideningType */) {
                            if (!reportWideningErrorsInType(t)) {
                                error(p.valueDeclaration, ts.Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), typeToString(getWidenedType(t)));
                            }
                            errorReported = true;
                        }
                    }
                }
            }
            return errorReported;
        }
        function reportImplicitAny(declaration, type, wideningKind) {
            var typeAsString = typeToString(getWidenedType(type));
            if (ts.isInJSFile(declaration) && !ts.isCheckJsEnabledForFile(ts.getSourceFileOfNode(declaration), compilerOptions)) {
                // Only report implicit any errors/suggestions in TS and ts-check JS files
                return;
            }
            var diagnostic;
            switch (declaration.kind) {
                case 209 /* BinaryExpression */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    diagnostic = noImplicitAny ? ts.Diagnostics.Member_0_implicitly_has_an_1_type : ts.Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
                    break;
                case 156 /* Parameter */:
                    var param = declaration;
                    if (ts.isIdentifier(param.name) &&
                        (ts.isCallSignatureDeclaration(param.parent) || ts.isMethodSignature(param.parent) || ts.isFunctionTypeNode(param.parent)) &&
                        param.parent.parameters.indexOf(param) > -1 &&
                        (resolveName(param, param.name.escapedText, 788968 /* Type */, undefined, param.name.escapedText, /*isUse*/ true) ||
                            param.name.originalKeywordKind && ts.isTypeNodeKind(param.name.originalKeywordKind))) {
                        var newName = "arg" + param.parent.parameters.indexOf(param);
                        errorOrSuggestion(noImplicitAny, declaration, ts.Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, ts.declarationNameToString(param.name));
                        return;
                    }
                    diagnostic = declaration.dotDotDotToken ?
                        noImplicitAny ? ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage :
                        noImplicitAny ? ts.Diagnostics.Parameter_0_implicitly_has_an_1_type : ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
                    break;
                case 191 /* BindingElement */:
                    diagnostic = ts.Diagnostics.Binding_element_0_implicitly_has_an_1_type;
                    if (!noImplicitAny) {
                        // Don't issue a suggestion for binding elements since the codefix doesn't yet support them.
                        return;
                    }
                    break;
                case 300 /* JSDocFunctionType */:
                    error(declaration, ts.Diagnostics.Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
                    return;
                case 244 /* FunctionDeclaration */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    if (noImplicitAny && !declaration.name) {
                        if (wideningKind === 3 /* GeneratorYield */) {
                            error(declaration, ts.Diagnostics.Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type_annotation, typeAsString);
                        }
                        else {
                            error(declaration, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
                        }
                        return;
                    }
                    diagnostic = !noImplicitAny ? ts.Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage :
                        wideningKind === 3 /* GeneratorYield */ ? ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type :
                            ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type;
                    break;
                case 186 /* MappedType */:
                    if (noImplicitAny) {
                        error(declaration, ts.Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type);
                    }
                    return;
                default:
                    diagnostic = noImplicitAny ? ts.Diagnostics.Variable_0_implicitly_has_an_1_type : ts.Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
            }
            errorOrSuggestion(noImplicitAny, declaration, diagnostic, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)), typeAsString);
        }
        function reportErrorsFromWidening(declaration, type, wideningKind) {
            if (produceDiagnostics && noImplicitAny && ts.getObjectFlags(type) & 524288 /* ContainsWideningType */ && (!wideningKind || !getContextualSignatureForFunctionLikeDeclaration(declaration))) {
                // Report implicit any error within type if possible, otherwise report error on declaration
                if (!reportWideningErrorsInType(type)) {
                    reportImplicitAny(declaration, type, wideningKind);
                }
            }
        }
        function applyToParameterTypes(source, target, callback) {
            var sourceCount = getParameterCount(source);
            var targetCount = getParameterCount(target);
            var sourceRestType = getEffectiveRestType(source);
            var targetRestType = getEffectiveRestType(target);
            var targetNonRestCount = targetRestType ? targetCount - 1 : targetCount;
            var paramCount = sourceRestType ? targetNonRestCount : Math.min(sourceCount, targetNonRestCount);
            var sourceThisType = getThisTypeOfSignature(source);
            if (sourceThisType) {
                var targetThisType = getThisTypeOfSignature(target);
                if (targetThisType) {
                    callback(sourceThisType, targetThisType);
                }
            }
            for (var i = 0; i < paramCount; i++) {
                callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
            }
            if (targetRestType) {
                callback(getRestTypeAtPosition(source, paramCount), targetRestType);
            }
        }
        function applyToReturnTypes(source, target, callback) {
            var sourceTypePredicate = getTypePredicateOfSignature(source);
            var targetTypePredicate = getTypePredicateOfSignature(target);
            if (sourceTypePredicate && targetTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
                callback(sourceTypePredicate.type, targetTypePredicate.type);
            }
            else {
                callback(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
            }
        }
        function createInferenceContext(typeParameters, signature, flags, compareTypes) {
            return createInferenceContextWorker(typeParameters.map(createInferenceInfo), signature, flags, compareTypes || compareTypesAssignable);
        }
        function cloneInferenceContext(context, extraFlags) {
            if (extraFlags === void 0) { extraFlags = 0; }
            return context && createInferenceContextWorker(ts.map(context.inferences, cloneInferenceInfo), context.signature, context.flags | extraFlags, context.compareTypes);
        }
        function createInferenceContextWorker(inferences, signature, flags, compareTypes) {
            var context = {
                inferences: inferences,
                signature: signature,
                flags: flags,
                compareTypes: compareTypes,
                mapper: makeFunctionTypeMapper(function (t) { return mapToInferredType(context, t, /*fix*/ true); }),
                nonFixingMapper: makeFunctionTypeMapper(function (t) { return mapToInferredType(context, t, /*fix*/ false); }),
            };
            return context;
        }
        function mapToInferredType(context, t, fix) {
            var inferences = context.inferences;
            for (var i = 0; i < inferences.length; i++) {
                var inference = inferences[i];
                if (t === inference.typeParameter) {
                    if (fix && !inference.isFixed) {
                        clearCachedInferences(inferences);
                        inference.isFixed = true;
                    }
                    return getInferredType(context, i);
                }
            }
            return t;
        }
        function clearCachedInferences(inferences) {
            for (var _i = 0, inferences_1 = inferences; _i < inferences_1.length; _i++) {
                var inference = inferences_1[_i];
                if (!inference.isFixed) {
                    inference.inferredType = undefined;
                }
            }
        }
        function createInferenceInfo(typeParameter) {
            return {
                typeParameter: typeParameter,
                candidates: undefined,
                contraCandidates: undefined,
                inferredType: undefined,
                priority: undefined,
                topLevel: true,
                isFixed: false
            };
        }
        function cloneInferenceInfo(inference) {
            return {
                typeParameter: inference.typeParameter,
                candidates: inference.candidates && inference.candidates.slice(),
                contraCandidates: inference.contraCandidates && inference.contraCandidates.slice(),
                inferredType: inference.inferredType,
                priority: inference.priority,
                topLevel: inference.topLevel,
                isFixed: inference.isFixed
            };
        }
        function cloneInferredPartOfContext(context) {
            var inferences = ts.filter(context.inferences, hasInferenceCandidates);
            return inferences.length ?
                createInferenceContextWorker(ts.map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) :
                undefined;
        }
        function getMapperFromContext(context) {
            return context && context.mapper;
        }
        // Return true if the given type could possibly reference a type parameter for which
        // we perform type inference (i.e. a type parameter of a generic function). We cache
        // results for union and intersection types for performance reasons.
        function couldContainTypeVariables(type) {
            var objectFlags = ts.getObjectFlags(type);
            if (objectFlags & 67108864 /* CouldContainTypeVariablesComputed */) {
                return !!(objectFlags & 134217728 /* CouldContainTypeVariables */);
            }
            var result = !!(type.flags & 63176704 /* Instantiable */ ||
                objectFlags & 4 /* Reference */ && (type.node || ts.forEach(getTypeArguments(type), couldContainTypeVariables)) ||
                objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && type.symbol.declarations ||
                objectFlags & (32 /* Mapped */ | 131072 /* ObjectRestType */) ||
                type.flags & 3145728 /* UnionOrIntersection */ && !(type.flags & 1024 /* EnumLiteral */) && ts.some(type.types, couldContainTypeVariables));
            if (type.flags & 3899393 /* ObjectFlagsType */) {
                type.objectFlags |= 67108864 /* CouldContainTypeVariablesComputed */ | (result ? 134217728 /* CouldContainTypeVariables */ : 0);
            }
            return result;
        }
        function isTypeParameterAtTopLevel(type, typeParameter) {
            return !!(type === typeParameter ||
                type.flags & 3145728 /* UnionOrIntersection */ && ts.some(type.types, function (t) { return isTypeParameterAtTopLevel(t, typeParameter); }) ||
                type.flags & 16777216 /* Conditional */ && (isTypeParameterAtTopLevel(getTrueTypeFromConditionalType(type), typeParameter) ||
                    isTypeParameterAtTopLevel(getFalseTypeFromConditionalType(type), typeParameter)));
        }
        /** Create an object with properties named in the string literal type. Every property has type `any` */
        function createEmptyObjectTypeFromStringLiteral(type) {
            var members = ts.createSymbolTable();
            forEachType(type, function (t) {
                if (!(t.flags & 128 /* StringLiteral */)) {
                    return;
                }
                var name = ts.escapeLeadingUnderscores(t.value);
                var literalProp = createSymbol(4 /* Property */, name);
                literalProp.type = anyType;
                if (t.symbol) {
                    literalProp.declarations = t.symbol.declarations;
                    literalProp.valueDeclaration = t.symbol.valueDeclaration;
                }
                members.set(name, literalProp);
            });
            var indexInfo = type.flags & 4 /* String */ ? createIndexInfo(emptyObjectType, /*isReadonly*/ false) : undefined;
            return createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, indexInfo, undefined);
        }
        /**
         * Infer a suitable input type for a homomorphic mapped type { [P in keyof T]: X }. We construct
         * an object type with the same set of properties as the source type, where the type of each
         * property is computed by inferring from the source property type to X for the type
         * variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for).
         */
        function inferTypeForHomomorphicMappedType(source, target, constraint) {
            var key = source.id + "," + target.id + "," + constraint.id;
            if (reverseMappedCache.has(key)) {
                return reverseMappedCache.get(key);
            }
            reverseMappedCache.set(key, undefined);
            var type = createReverseMappedType(source, target, constraint);
            reverseMappedCache.set(key, type);
            return type;
        }
        // We consider a type to be partially inferable if it isn't marked non-inferable or if it is
        // an object literal type with at least one property of an inferable type. For example, an object
        // literal { a: 123, b: x => true } is marked non-inferable because it contains a context sensitive
        // arrow function, but is considered partially inferable because property 'a' has an inferable type.
        function isPartiallyInferableType(type) {
            return !(ts.getObjectFlags(type) & 2097152 /* NonInferrableType */) ||
                isObjectLiteralType(type) && ts.some(getPropertiesOfType(type), function (prop) { return isPartiallyInferableType(getTypeOfSymbol(prop)); });
        }
        function createReverseMappedType(source, target, constraint) {
            // We consider a source type reverse mappable if it has a string index signature or if
            // it has one or more properties and is of a partially inferable type.
            if (!(getIndexInfoOfType(source, 0 /* String */) || getPropertiesOfType(source).length !== 0 && isPartiallyInferableType(source))) {
                return undefined;
            }
            // For arrays and tuples we infer new arrays and tuples where the reverse mapping has been
            // applied to the element type(s).
            if (isArrayType(source)) {
                return createArrayType(inferReverseMappedType(getTypeArguments(source)[0], target, constraint), isReadonlyArrayType(source));
            }
            if (isTupleType(source)) {
                var elementTypes = ts.map(getTypeArguments(source), function (t) { return inferReverseMappedType(t, target, constraint); });
                var minLength = getMappedTypeModifiers(target) & 4 /* IncludeOptional */ ?
                    getTypeReferenceArity(source) - (source.target.hasRestElement ? 1 : 0) : source.target.minLength;
                return createTupleType(elementTypes, minLength, source.target.hasRestElement, source.target.readonly, source.target.associatedNames);
            }
            // For all other object types we infer a new object type where the reverse mapping has been
            // applied to the type of each property.
            var reversed = createObjectType(2048 /* ReverseMapped */ | 16 /* Anonymous */, /*symbol*/ undefined);
            reversed.source = source;
            reversed.mappedType = target;
            reversed.constraintType = constraint;
            return reversed;
        }
        function getTypeOfReverseMappedSymbol(symbol) {
            return inferReverseMappedType(symbol.propertyType, symbol.mappedType, symbol.constraintType);
        }
        function inferReverseMappedType(sourceType, target, constraint) {
            var typeParameter = getIndexedAccessType(constraint.type, getTypeParameterFromMappedType(target));
            var templateType = getTemplateTypeFromMappedType(target);
            var inference = createInferenceInfo(typeParameter);
            inferTypes([inference], sourceType, templateType);
            return getTypeFromInference(inference) || unknownType;
        }
        function getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties) {
            var properties, _i, properties_2, targetProp, sourceProp, targetType, sourceType;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        properties = getPropertiesOfType(target);
                        _i = 0, properties_2 = properties;
                        _a.label = 1;
                    case 1:
                        if (!(_i < properties_2.length)) return [3 /*break*/, 6];
                        targetProp = properties_2[_i];
                        // TODO: remove this when we support static private identifier fields and find other solutions to get privateNamesAndStaticFields test to pass
                        if (isStaticPrivateIdentifierProperty(targetProp)) {
                            return [3 /*break*/, 5];
                        }
                        if (!(requireOptionalProperties || !(targetProp.flags & 16777216 /* Optional */ || ts.getCheckFlags(targetProp) & 48 /* Partial */))) return [3 /*break*/, 5];
                        sourceProp = getPropertyOfType(source, targetProp.escapedName);
                        if (!!sourceProp) return [3 /*break*/, 3];
                        return [4 /*yield*/, targetProp];
                    case 2:
                        _a.sent();
                        return [3 /*break*/, 5];
                    case 3:
                        if (!matchDiscriminantProperties) return [3 /*break*/, 5];
                        targetType = getTypeOfSymbol(targetProp);
                        if (!(targetType.flags & 109440 /* Unit */)) return [3 /*break*/, 5];
                        sourceType = getTypeOfSymbol(sourceProp);
                        if (!!(sourceType.flags & 1 /* Any */ || getRegularTypeOfLiteralType(sourceType) === getRegularTypeOfLiteralType(targetType))) return [3 /*break*/, 5];
                        return [4 /*yield*/, targetProp];
                    case 4:
                        _a.sent();
                        _a.label = 5;
                    case 5:
                        _i++;
                        return [3 /*break*/, 1];
                    case 6: return [2 /*return*/];
                }
            });
        }
        function getUnmatchedProperty(source, target, requireOptionalProperties, matchDiscriminantProperties) {
            var result = getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties).next();
            if (!result.done)
                return result.value;
        }
        function tupleTypesDefinitelyUnrelated(source, target) {
            return target.target.minLength > source.target.minLength ||
                !getRestTypeOfTupleType(target) && (!!getRestTypeOfTupleType(source) || getLengthOfTupleType(target) < getLengthOfTupleType(source));
        }
        function typesDefinitelyUnrelated(source, target) {
            // Two tuple types with incompatible arities are definitely unrelated.
            // Two object types that each have a property that is unmatched in the other are definitely unrelated.
            return isTupleType(source) && isTupleType(target) && tupleTypesDefinitelyUnrelated(source, target) ||
                !!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true) &&
                    !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true);
        }
        function getTypeFromInference(inference) {
            return inference.candidates ? getUnionType(inference.candidates, 2 /* Subtype */) :
                inference.contraCandidates ? getIntersectionType(inference.contraCandidates) :
                    undefined;
        }
        function hasSkipDirectInferenceFlag(node) {
            return !!getNodeLinks(node).skipDirectInference;
        }
        function isFromInferenceBlockedSource(type) {
            return !!(type.symbol && ts.some(type.symbol.declarations, hasSkipDirectInferenceFlag));
        }
        function inferTypes(inferences, originalSource, originalTarget, priority, contravariant) {
            if (priority === void 0) { priority = 0; }
            if (contravariant === void 0) { contravariant = false; }
            var symbolOrTypeStack;
            var visited;
            var bivariant = false;
            var propagationType;
            var inferencePriority = 512 /* MaxValue */;
            var allowComplexConstraintInference = true;
            inferFromTypes(originalSource, originalTarget);
            function inferFromTypes(source, target) {
                if (!couldContainTypeVariables(target)) {
                    return;
                }
                if (source === wildcardType) {
                    // We are inferring from an 'any' type. We want to infer this type for every type parameter
                    // referenced in the target type, so we record it as the propagation type and infer from the
                    // target to itself. Then, as we find candidates we substitute the propagation type.
                    var savePropagationType = propagationType;
                    propagationType = source;
                    inferFromTypes(target, target);
                    propagationType = savePropagationType;
                    return;
                }
                if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
                    // Source and target are types originating in the same generic type alias declaration.
                    // Simply infer from source type arguments to target type arguments.
                    inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments, getAliasVariances(source.aliasSymbol));
                    return;
                }
                if (source === target && source.flags & 3145728 /* UnionOrIntersection */) {
                    // When source and target are the same union or intersection type, just relate each constituent
                    // type to itself.
                    for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                        var t = _a[_i];
                        inferFromTypes(t, t);
                    }
                    return;
                }
                if (target.flags & 1048576 /* Union */) {
                    // First, infer between identically matching source and target constituents and remove the
                    // matching types.
                    var _b = inferFromMatchingTypes(source.flags & 1048576 /* Union */ ? source.types : [source], target.types, isTypeOrBaseIdenticalTo), tempSources = _b[0], tempTargets = _b[1];
                    // Next, infer between closely matching source and target constituents and remove
                    // the matching types. Types closely match when they are instantiations of the same
                    // object type or instantiations of the same type alias.
                    var _c = inferFromMatchingTypes(tempSources, tempTargets, isTypeCloselyMatchedBy), sources = _c[0], targets = _c[1];
                    if (targets.length === 0) {
                        return;
                    }
                    target = getUnionType(targets);
                    if (sources.length === 0) {
                        // All source constituents have been matched and there is nothing further to infer from.
                        // However, simply making no inferences is undesirable because it could ultimately mean
                        // inferring a type parameter constraint. Instead, make a lower priority inference from
                        // the full source to whatever remains in the target. For example, when inferring from
                        // string to 'string | T', make a lower priority inference of string for T.
                        inferWithPriority(source, target, 1 /* NakedTypeVariable */);
                        return;
                    }
                    source = getUnionType(sources);
                }
                else if (target.flags & 2097152 /* Intersection */ && ts.some(target.types, function (t) { return !!getInferenceInfoForType(t) || (isGenericMappedType(t) && !!getInferenceInfoForType(getHomomorphicTypeVariable(t) || neverType)); })) {
                    // We reduce intersection types only when they contain naked type parameters. For example, when
                    // inferring from 'string[] & { extra: any }' to 'string[] & T' we want to remove string[] and
                    // infer { extra: any } for T. But when inferring to 'string[] & Iterable<T>' we want to keep the
                    // string[] on the source side and infer string for T.
                    // Likewise, we consider a homomorphic mapped type constrainted to the target type parameter as similar to a "naked type variable"
                    // in such scenarios.
                    if (!(source.flags & 1048576 /* Union */)) {
                        // Infer between identically matching source and target constituents and remove the matching types.
                        var _d = inferFromMatchingTypes(source.flags & 2097152 /* Intersection */ ? source.types : [source], target.types, isTypeIdenticalTo), sources = _d[0], targets = _d[1];
                        if (sources.length === 0 || targets.length === 0) {
                            return;
                        }
                        source = getIntersectionType(sources);
                        target = getIntersectionType(targets);
                    }
                }
                else if (target.flags & (8388608 /* IndexedAccess */ | 33554432 /* Substitution */)) {
                    target = getActualTypeVariable(target);
                }
                if (target.flags & 8650752 /* TypeVariable */) {
                    // If target is a type parameter, make an inference, unless the source type contains
                    // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
                    // Because the anyFunctionType is internal, it should not be exposed to the user by adding
                    // it as an inference candidate. Hopefully, a better candidate will come along that does
                    // not contain anyFunctionType when we come back to this argument for its second round
                    // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard
                    // when constructing types from type parameters that had no inference candidates).
                    if (ts.getObjectFlags(source) & 2097152 /* NonInferrableType */ || source === nonInferrableAnyType || source === silentNeverType ||
                        (priority & 32 /* ReturnType */ && (source === autoType || source === autoArrayType)) || isFromInferenceBlockedSource(source)) {
                        return;
                    }
                    var inference = getInferenceInfoForType(target);
                    if (inference) {
                        if (!inference.isFixed) {
                            if (inference.priority === undefined || priority < inference.priority) {
                                inference.candidates = undefined;
                                inference.contraCandidates = undefined;
                                inference.topLevel = true;
                                inference.priority = priority;
                            }
                            if (priority === inference.priority) {
                                var candidate = propagationType || source;
                                // We make contravariant inferences only if we are in a pure contravariant position,
                                // i.e. only if we have not descended into a bivariant position.
                                if (contravariant && !bivariant) {
                                    if (!ts.contains(inference.contraCandidates, candidate)) {
                                        inference.contraCandidates = ts.append(inference.contraCandidates, candidate);
                                        clearCachedInferences(inferences);
                                    }
                                }
                                else if (!ts.contains(inference.candidates, candidate)) {
                                    inference.candidates = ts.append(inference.candidates, candidate);
                                    clearCachedInferences(inferences);
                                }
                            }
                            if (!(priority & 32 /* ReturnType */) && target.flags & 262144 /* TypeParameter */ && inference.topLevel && !isTypeParameterAtTopLevel(originalTarget, target)) {
                                inference.topLevel = false;
                                clearCachedInferences(inferences);
                            }
                        }
                        inferencePriority = Math.min(inferencePriority, priority);
                        return;
                    }
                    else {
                        // Infer to the simplified version of an indexed access, if possible, to (hopefully) expose more bare type parameters to the inference engine
                        var simplified = getSimplifiedType(target, /*writing*/ false);
                        if (simplified !== target) {
                            invokeOnce(source, simplified, inferFromTypes);
                        }
                        else if (target.flags & 8388608 /* IndexedAccess */) {
                            var indexType = getSimplifiedType(target.indexType, /*writing*/ false);
                            // Generally simplifications of instantiable indexes are avoided to keep relationship checking correct, however if our target is an access, we can consider
                            // that key of that access to be "instantiated", since we're looking to find the infernce goal in any way we can.
                            if (indexType.flags & 63176704 /* Instantiable */) {
                                var simplified_1 = distributeIndexOverObjectType(getSimplifiedType(target.objectType, /*writing*/ false), indexType, /*writing*/ false);
                                if (simplified_1 && simplified_1 !== target) {
                                    invokeOnce(source, simplified_1, inferFromTypes);
                                }
                            }
                        }
                    }
                }
                if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && (source.target === target.target || isArrayType(source) && isArrayType(target)) &&
                    !(source.node && target.node)) {
                    // If source and target are references to the same generic type, infer from type arguments
                    inferFromTypeArguments(getTypeArguments(source), getTypeArguments(target), getVariances(source.target));
                }
                else if (source.flags & 4194304 /* Index */ && target.flags & 4194304 /* Index */) {
                    contravariant = !contravariant;
                    inferFromTypes(source.type, target.type);
                    contravariant = !contravariant;
                }
                else if ((isLiteralType(source) || source.flags & 4 /* String */) && target.flags & 4194304 /* Index */) {
                    var empty = createEmptyObjectTypeFromStringLiteral(source);
                    contravariant = !contravariant;
                    inferWithPriority(empty, target.type, 64 /* LiteralKeyof */);
                    contravariant = !contravariant;
                }
                else if (source.flags & 8388608 /* IndexedAccess */ && target.flags & 8388608 /* IndexedAccess */) {
                    inferFromTypes(source.objectType, target.objectType);
                    inferFromTypes(source.indexType, target.indexType);
                }
                else if (source.flags & 16777216 /* Conditional */ && target.flags & 16777216 /* Conditional */) {
                    inferFromTypes(source.checkType, target.checkType);
                    inferFromTypes(source.extendsType, target.extendsType);
                    inferFromTypes(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target));
                    inferFromTypes(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target));
                }
                else if (target.flags & 16777216 /* Conditional */) {
                    var savePriority = priority;
                    priority |= contravariant ? 16 /* ContravariantConditional */ : 0;
                    var targetTypes = [getTrueTypeFromConditionalType(target), getFalseTypeFromConditionalType(target)];
                    inferToMultipleTypes(source, targetTypes, target.flags);
                    priority = savePriority;
                }
                else if (target.flags & 3145728 /* UnionOrIntersection */) {
                    inferToMultipleTypes(source, target.types, target.flags);
                }
                else if (source.flags & 1048576 /* Union */) {
                    // Source is a union or intersection type, infer from each constituent type
                    var sourceTypes = source.types;
                    for (var _e = 0, sourceTypes_2 = sourceTypes; _e < sourceTypes_2.length; _e++) {
                        var sourceType = sourceTypes_2[_e];
                        inferFromTypes(sourceType, target);
                    }
                }
                else {
                    source = getReducedType(source);
                    if (!(priority & 128 /* NoConstraints */ && source.flags & (2097152 /* Intersection */ | 63176704 /* Instantiable */))) {
                        var apparentSource = getApparentType(source);
                        // getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type.
                        // If that occurs and it doesn't simplify to an object or intersection, we'll need to restart `inferFromTypes`
                        // with the simplified source.
                        if (apparentSource !== source && allowComplexConstraintInference && !(apparentSource.flags & (524288 /* Object */ | 2097152 /* Intersection */))) {
                            // TODO: The `allowComplexConstraintInference` flag is a hack! This forbids inference from complex constraints within constraints!
                            // This isn't required algorithmically, but rather is used to lower the memory burden caused by performing inference
                            // that is _too good_ in projects with complicated constraints (eg, fp-ts). In such cases, if we did not limit ourselves
                            // here, we might produce more valid inferences for types, causing us to do more checks and perform more instantiations
                            // (in addition to the extra stack depth here) which, in turn, can push the already close process over its limit.
                            // TL;DR: If we ever become generally more memory efficient (or our resource budget ever increases), we should just
                            // remove this `allowComplexConstraintInference` flag.
                            allowComplexConstraintInference = false;
                            return inferFromTypes(apparentSource, target);
                        }
                        source = apparentSource;
                    }
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */)) {
                        invokeOnce(source, target, inferFromObjectTypes);
                    }
                }
                if (source.flags & 25165824 /* Simplifiable */) {
                    var simplified = getSimplifiedType(source, contravariant);
                    if (simplified !== source) {
                        inferFromTypes(simplified, target);
                    }
                }
            }
            function inferWithPriority(source, target, newPriority) {
                var savePriority = priority;
                priority |= newPriority;
                inferFromTypes(source, target);
                priority = savePriority;
            }
            function invokeOnce(source, target, action) {
                var key = source.id + "," + target.id;
                var status = visited && visited.get(key);
                if (status !== undefined) {
                    inferencePriority = Math.min(inferencePriority, status);
                    return;
                }
                (visited || (visited = ts.createMap())).set(key, -1 /* Circularity */);
                var saveInferencePriority = inferencePriority;
                inferencePriority = 512 /* MaxValue */;
                action(source, target);
                visited.set(key, inferencePriority);
                inferencePriority = Math.min(inferencePriority, saveInferencePriority);
            }
            function inferFromMatchingTypes(sources, targets, matches) {
                var matchedSources;
                var matchedTargets;
                for (var _i = 0, targets_1 = targets; _i < targets_1.length; _i++) {
                    var t = targets_1[_i];
                    for (var _a = 0, sources_1 = sources; _a < sources_1.length; _a++) {
                        var s = sources_1[_a];
                        if (matches(s, t)) {
                            inferFromTypes(s, t);
                            matchedSources = ts.appendIfUnique(matchedSources, s);
                            matchedTargets = ts.appendIfUnique(matchedTargets, t);
                        }
                    }
                }
                return [
                    matchedSources ? ts.filter(sources, function (t) { return !ts.contains(matchedSources, t); }) : sources,
                    matchedTargets ? ts.filter(targets, function (t) { return !ts.contains(matchedTargets, t); }) : targets,
                ];
            }
            function inferFromTypeArguments(sourceTypes, targetTypes, variances) {
                var count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
                for (var i = 0; i < count; i++) {
                    if (i < variances.length && (variances[i] & 7 /* VarianceMask */) === 2 /* Contravariant */) {
                        inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
                    }
                    else {
                        inferFromTypes(sourceTypes[i], targetTypes[i]);
                    }
                }
            }
            function inferFromContravariantTypes(source, target) {
                if (strictFunctionTypes || priority & 256 /* AlwaysStrict */) {
                    contravariant = !contravariant;
                    inferFromTypes(source, target);
                    contravariant = !contravariant;
                }
                else {
                    inferFromTypes(source, target);
                }
            }
            function getInferenceInfoForType(type) {
                if (type.flags & 8650752 /* TypeVariable */) {
                    for (var _i = 0, inferences_2 = inferences; _i < inferences_2.length; _i++) {
                        var inference = inferences_2[_i];
                        if (type === inference.typeParameter) {
                            return inference;
                        }
                    }
                }
                return undefined;
            }
            function getSingleTypeVariableFromIntersectionTypes(types) {
                var typeVariable;
                for (var _i = 0, types_14 = types; _i < types_14.length; _i++) {
                    var type = types_14[_i];
                    var t = type.flags & 2097152 /* Intersection */ && ts.find(type.types, function (t) { return !!getInferenceInfoForType(t); });
                    if (!t || typeVariable && t !== typeVariable) {
                        return undefined;
                    }
                    typeVariable = t;
                }
                return typeVariable;
            }
            function inferToMultipleTypes(source, targets, targetFlags) {
                var typeVariableCount = 0;
                if (targetFlags & 1048576 /* Union */) {
                    var nakedTypeVariable = void 0;
                    var sources = source.flags & 1048576 /* Union */ ? source.types : [source];
                    var matched_1 = new Array(sources.length);
                    var inferenceCircularity = false;
                    // First infer to types that are not naked type variables. For each source type we
                    // track whether inferences were made from that particular type to some target with
                    // equal priority (i.e. of equal quality) to what we would infer for a naked type
                    // parameter.
                    for (var _i = 0, targets_2 = targets; _i < targets_2.length; _i++) {
                        var t = targets_2[_i];
                        if (getInferenceInfoForType(t)) {
                            nakedTypeVariable = t;
                            typeVariableCount++;
                        }
                        else {
                            for (var i = 0; i < sources.length; i++) {
                                var saveInferencePriority = inferencePriority;
                                inferencePriority = 512 /* MaxValue */;
                                inferFromTypes(sources[i], t);
                                if (inferencePriority === priority)
                                    matched_1[i] = true;
                                inferenceCircularity = inferenceCircularity || inferencePriority === -1 /* Circularity */;
                                inferencePriority = Math.min(inferencePriority, saveInferencePriority);
                            }
                        }
                    }
                    if (typeVariableCount === 0) {
                        // If every target is an intersection of types containing a single naked type variable,
                        // make a lower priority inference to that type variable. This handles inferring from
                        // 'A | B' to 'T & (X | Y)' where we want to infer 'A | B' for T.
                        var intersectionTypeVariable = getSingleTypeVariableFromIntersectionTypes(targets);
                        if (intersectionTypeVariable) {
                            inferWithPriority(source, intersectionTypeVariable, 1 /* NakedTypeVariable */);
                        }
                        return;
                    }
                    // If the target has a single naked type variable and no inference circularities were
                    // encountered above (meaning we explored the types fully), create a union of the source
                    // types from which no inferences have been made so far and infer from that union to the
                    // naked type variable.
                    if (typeVariableCount === 1 && !inferenceCircularity) {
                        var unmatched = ts.flatMap(sources, function (s, i) { return matched_1[i] ? undefined : s; });
                        if (unmatched.length) {
                            inferFromTypes(getUnionType(unmatched), nakedTypeVariable);
                            return;
                        }
                    }
                }
                else {
                    // We infer from types that are not naked type variables first so that inferences we
                    // make from nested naked type variables and given slightly higher priority by virtue
                    // of being first in the candidates array.
                    for (var _a = 0, targets_3 = targets; _a < targets_3.length; _a++) {
                        var t = targets_3[_a];
                        if (getInferenceInfoForType(t)) {
                            typeVariableCount++;
                        }
                        else {
                            inferFromTypes(source, t);
                        }
                    }
                }
                // Inferences directly to naked type variables are given lower priority as they are
                // less specific. For example, when inferring from Promise<string> to T | Promise<T>,
                // we want to infer string for T, not Promise<string> | string. For intersection types
                // we only infer to single naked type variables.
                if (targetFlags & 2097152 /* Intersection */ ? typeVariableCount === 1 : typeVariableCount > 0) {
                    for (var _b = 0, targets_4 = targets; _b < targets_4.length; _b++) {
                        var t = targets_4[_b];
                        if (getInferenceInfoForType(t)) {
                            inferWithPriority(source, t, 1 /* NakedTypeVariable */);
                        }
                    }
                }
            }
            function inferToMappedType(source, target, constraintType) {
                if (constraintType.flags & 1048576 /* Union */) {
                    var result = false;
                    for (var _i = 0, _a = constraintType.types; _i < _a.length; _i++) {
                        var type = _a[_i];
                        result = inferToMappedType(source, target, type) || result;
                    }
                    return result;
                }
                if (constraintType.flags & 4194304 /* Index */) {
                    // We're inferring from some source type S to a homomorphic mapped type { [P in keyof T]: X },
                    // where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source
                    // type and then make a secondary inference from that type to T. We make a secondary inference
                    // such that direct inferences to T get priority over inferences to Partial<T>, for example.
                    var inference = getInferenceInfoForType(constraintType.type);
                    if (inference && !inference.isFixed && !isFromInferenceBlockedSource(source)) {
                        var inferredType = inferTypeForHomomorphicMappedType(source, target, constraintType);
                        if (inferredType) {
                            // We assign a lower priority to inferences made from types containing non-inferrable
                            // types because we may only have a partial result (i.e. we may have failed to make
                            // reverse inferences for some properties).
                            inferWithPriority(inferredType, inference.typeParameter, ts.getObjectFlags(source) & 2097152 /* NonInferrableType */ ?
                                4 /* PartialHomomorphicMappedType */ :
                                2 /* HomomorphicMappedType */);
                        }
                    }
                    return true;
                }
                if (constraintType.flags & 262144 /* TypeParameter */) {
                    // We're inferring from some source type S to a mapped type { [P in K]: X }, where K is a type
                    // parameter. First infer from 'keyof S' to K.
                    inferWithPriority(getIndexType(source), constraintType, 8 /* MappedTypeConstraint */);
                    // If K is constrained to a type C, also infer to C. Thus, for a mapped type { [P in K]: X },
                    // where K extends keyof T, we make the same inferences as for a homomorphic mapped type
                    // { [P in keyof T]: X }. This enables us to make meaningful inferences when the target is a
                    // Pick<T, K>.
                    var extendedConstraint = getConstraintOfType(constraintType);
                    if (extendedConstraint && inferToMappedType(source, target, extendedConstraint)) {
                        return true;
                    }
                    // If no inferences can be made to K's constraint, infer from a union of the property types
                    // in the source to the template type X.
                    var propTypes = ts.map(getPropertiesOfType(source), getTypeOfSymbol);
                    var stringIndexType = getIndexTypeOfType(source, 0 /* String */);
                    var numberIndexInfo = getNonEnumNumberIndexInfo(source);
                    var numberIndexType = numberIndexInfo && numberIndexInfo.type;
                    inferFromTypes(getUnionType(ts.append(ts.append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target));
                    return true;
                }
                return false;
            }
            function inferFromObjectTypes(source, target) {
                // If we are already processing another target type with the same associated symbol (such as
                // an instantiation of the same generic type), we do not explore this target as it would yield
                // no further inferences. We exclude the static side of classes from this check since it shares
                // its symbol with the instance side which would lead to false positives.
                var isNonConstructorObject = target.flags & 524288 /* Object */ &&
                    !(ts.getObjectFlags(target) & 16 /* Anonymous */ && target.symbol && target.symbol.flags & 32 /* Class */);
                var symbolOrType = isNonConstructorObject ? isTupleType(target) ? target.target : target.symbol : undefined;
                if (symbolOrType) {
                    if (ts.contains(symbolOrTypeStack, symbolOrType)) {
                        inferencePriority = -1 /* Circularity */;
                        return;
                    }
                    (symbolOrTypeStack || (symbolOrTypeStack = [])).push(symbolOrType);
                    inferFromObjectTypesWorker(source, target);
                    symbolOrTypeStack.pop();
                }
                else {
                    inferFromObjectTypesWorker(source, target);
                }
            }
            function inferFromObjectTypesWorker(source, target) {
                if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && (source.target === target.target || isArrayType(source) && isArrayType(target))) {
                    // If source and target are references to the same generic type, infer from type arguments
                    inferFromTypeArguments(getTypeArguments(source), getTypeArguments(target), getVariances(source.target));
                    return;
                }
                if (isGenericMappedType(source) && isGenericMappedType(target)) {
                    // The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
                    // from S to T and from X to Y.
                    inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target));
                    inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target));
                }
                if (ts.getObjectFlags(target) & 32 /* Mapped */) {
                    var constraintType = getConstraintTypeFromMappedType(target);
                    if (inferToMappedType(source, target, constraintType)) {
                        return;
                    }
                }
                // Infer from the members of source and target only if the two types are possibly related
                if (!typesDefinitelyUnrelated(source, target)) {
                    if (isArrayType(source) || isTupleType(source)) {
                        if (isTupleType(target)) {
                            var sourceLength = isTupleType(source) ? getLengthOfTupleType(source) : 0;
                            var targetLength = getLengthOfTupleType(target);
                            var sourceRestType = isTupleType(source) ? getRestTypeOfTupleType(source) : getElementTypeOfArrayType(source);
                            var targetRestType = getRestTypeOfTupleType(target);
                            var fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength;
                            for (var i = 0; i < fixedLength; i++) {
                                inferFromTypes(i < sourceLength ? getTypeArguments(source)[i] : sourceRestType, getTypeArguments(target)[i]);
                            }
                            if (targetRestType) {
                                var types = fixedLength < sourceLength ? getTypeArguments(source).slice(fixedLength, sourceLength) : [];
                                if (sourceRestType) {
                                    types.push(sourceRestType);
                                }
                                if (types.length) {
                                    inferFromTypes(getUnionType(types), targetRestType);
                                }
                            }
                            return;
                        }
                        if (isArrayType(target)) {
                            inferFromIndexTypes(source, target);
                            return;
                        }
                    }
                    inferFromProperties(source, target);
                    inferFromSignatures(source, target, 0 /* Call */);
                    inferFromSignatures(source, target, 1 /* Construct */);
                    inferFromIndexTypes(source, target);
                }
            }
            function inferFromProperties(source, target) {
                var properties = getPropertiesOfObjectType(target);
                for (var _i = 0, properties_3 = properties; _i < properties_3.length; _i++) {
                    var targetProp = properties_3[_i];
                    var sourceProp = getPropertyOfType(source, targetProp.escapedName);
                    if (sourceProp) {
                        inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
                    }
                }
            }
            function inferFromSignatures(source, target, kind) {
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                var sourceLen = sourceSignatures.length;
                var targetLen = targetSignatures.length;
                var len = sourceLen < targetLen ? sourceLen : targetLen;
                var skipParameters = !!(ts.getObjectFlags(source) & 2097152 /* NonInferrableType */);
                for (var i = 0; i < len; i++) {
                    inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]), skipParameters);
                }
            }
            function inferFromSignature(source, target, skipParameters) {
                if (!skipParameters) {
                    var saveBivariant = bivariant;
                    var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */;
                    // Once we descend into a bivariant signature we remain bivariant for all nested inferences
                    bivariant = bivariant || kind === 161 /* MethodDeclaration */ || kind === 160 /* MethodSignature */ || kind === 162 /* Constructor */;
                    applyToParameterTypes(source, target, inferFromContravariantTypes);
                    bivariant = saveBivariant;
                }
                applyToReturnTypes(source, target, inferFromTypes);
            }
            function inferFromIndexTypes(source, target) {
                var targetStringIndexType = getIndexTypeOfType(target, 0 /* String */);
                if (targetStringIndexType) {
                    var sourceIndexType = getIndexTypeOfType(source, 0 /* String */) ||
                        getImplicitIndexTypeOfType(source, 0 /* String */);
                    if (sourceIndexType) {
                        inferFromTypes(sourceIndexType, targetStringIndexType);
                    }
                }
                var targetNumberIndexType = getIndexTypeOfType(target, 1 /* Number */);
                if (targetNumberIndexType) {
                    var sourceIndexType = getIndexTypeOfType(source, 1 /* Number */) ||
                        getIndexTypeOfType(source, 0 /* String */) ||
                        getImplicitIndexTypeOfType(source, 1 /* Number */);
                    if (sourceIndexType) {
                        inferFromTypes(sourceIndexType, targetNumberIndexType);
                    }
                }
            }
        }
        function isTypeOrBaseIdenticalTo(s, t) {
            return isTypeIdenticalTo(s, t) || !!(t.flags & 4 /* String */ && s.flags & 128 /* StringLiteral */ || t.flags & 8 /* Number */ && s.flags & 256 /* NumberLiteral */);
        }
        function isTypeCloselyMatchedBy(s, t) {
            return !!(s.flags & 524288 /* Object */ && t.flags & 524288 /* Object */ && s.symbol && s.symbol === t.symbol ||
                s.aliasSymbol && s.aliasTypeArguments && s.aliasSymbol === t.aliasSymbol);
        }
        function hasPrimitiveConstraint(type) {
            var constraint = getConstraintOfTypeParameter(type);
            return !!constraint && maybeTypeOfKind(constraint.flags & 16777216 /* Conditional */ ? getDefaultConstraintOfConditionalType(constraint) : constraint, 131068 /* Primitive */ | 4194304 /* Index */);
        }
        function isObjectLiteralType(type) {
            return !!(ts.getObjectFlags(type) & 128 /* ObjectLiteral */);
        }
        function isObjectOrArrayLiteralType(type) {
            return !!(ts.getObjectFlags(type) & (128 /* ObjectLiteral */ | 65536 /* ArrayLiteral */));
        }
        function unionObjectAndArrayLiteralCandidates(candidates) {
            if (candidates.length > 1) {
                var objectLiterals = ts.filter(candidates, isObjectOrArrayLiteralType);
                if (objectLiterals.length) {
                    var literalsType = getUnionType(objectLiterals, 2 /* Subtype */);
                    return ts.concatenate(ts.filter(candidates, function (t) { return !isObjectOrArrayLiteralType(t); }), [literalsType]);
                }
            }
            return candidates;
        }
        function getContravariantInference(inference) {
            return inference.priority & 104 /* PriorityImpliesCombination */ ? getIntersectionType(inference.contraCandidates) : getCommonSubtype(inference.contraCandidates);
        }
        function getCovariantInference(inference, signature) {
            // Extract all object and array literal types and replace them with a single widened and normalized type.
            var candidates = unionObjectAndArrayLiteralCandidates(inference.candidates);
            // We widen inferred literal types if
            // all inferences were made to top-level occurrences of the type parameter, and
            // the type parameter has no constraint or its constraint includes no primitive or literal types, and
            // the type parameter was fixed during inference or does not occur at top-level in the return type.
            var primitiveConstraint = hasPrimitiveConstraint(inference.typeParameter);
            var widenLiteralTypes = !primitiveConstraint && inference.topLevel &&
                (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
            var baseCandidates = primitiveConstraint ? ts.sameMap(candidates, getRegularTypeOfLiteralType) :
                widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) :
                    candidates;
            // If all inferences were made from a position that implies a combined result, infer a union type.
            // Otherwise, infer a common supertype.
            var unwidenedType = inference.priority & 104 /* PriorityImpliesCombination */ ?
                getUnionType(baseCandidates, 2 /* Subtype */) :
                getCommonSupertype(baseCandidates);
            return getWidenedType(unwidenedType);
        }
        function getInferredType(context, index) {
            var inference = context.inferences[index];
            if (!inference.inferredType) {
                var inferredType = void 0;
                var signature = context.signature;
                if (signature) {
                    var inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined;
                    if (inference.contraCandidates) {
                        var inferredContravariantType = getContravariantInference(inference);
                        // If we have both co- and contra-variant inferences, we prefer the contra-variant inference
                        // unless the co-variant inference is a subtype and not 'never'.
                        inferredType = inferredCovariantType && !(inferredCovariantType.flags & 131072 /* Never */) &&
                            isTypeSubtypeOf(inferredCovariantType, inferredContravariantType) ?
                            inferredCovariantType : inferredContravariantType;
                    }
                    else if (inferredCovariantType) {
                        inferredType = inferredCovariantType;
                    }
                    else if (context.flags & 1 /* NoDefault */) {
                        // We use silentNeverType as the wildcard that signals no inferences.
                        inferredType = silentNeverType;
                    }
                    else {
                        // Infer either the default or the empty object type when no inferences were
                        // made. It is important to remember that in this case, inference still
                        // succeeds, meaning there is no error for not having inference candidates. An
                        // inference error only occurs when there are *conflicting* candidates, i.e.
                        // candidates with no common supertype.
                        var defaultType = getDefaultFromTypeParameter(inference.typeParameter);
                        if (defaultType) {
                            // Instantiate the default type. Any forward reference to a type
                            // parameter should be instantiated to the empty object type.
                            inferredType = instantiateType(defaultType, mergeTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
                        }
                    }
                }
                else {
                    inferredType = getTypeFromInference(inference);
                }
                inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & 2 /* AnyDefault */));
                var constraint = getConstraintOfTypeParameter(inference.typeParameter);
                if (constraint) {
                    var instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper);
                    if (!inferredType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
                        inference.inferredType = inferredType = instantiatedConstraint;
                    }
                }
            }
            return inference.inferredType;
        }
        function getDefaultTypeArgumentType(isInJavaScriptFile) {
            return isInJavaScriptFile ? anyType : unknownType;
        }
        function getInferredTypes(context) {
            var result = [];
            for (var i = 0; i < context.inferences.length; i++) {
                result.push(getInferredType(context, i));
            }
            return result;
        }
        // EXPRESSION TYPE CHECKING
        function getCannotFindNameDiagnosticForName(node) {
            switch (node.escapedText) {
                case "document":
                case "console":
                    return ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom;
                case "$":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery;
                case "describe":
                case "suite":
                case "it":
                case "test":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha;
                case "process":
                case "require":
                case "Buffer":
                case "module":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode;
                case "Map":
                case "Set":
                case "Promise":
                case "Symbol":
                case "WeakMap":
                case "WeakSet":
                case "Iterator":
                case "AsyncIterator":
                    return ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later;
                default:
                    if (node.parent.kind === 282 /* ShorthandPropertyAssignment */) {
                        return ts.Diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer;
                    }
                    else {
                        return ts.Diagnostics.Cannot_find_name_0;
                    }
            }
        }
        function getResolvedSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                links.resolvedSymbol = !ts.nodeIsMissing(node) &&
                    resolveName(node, node.escapedText, 111551 /* Value */ | 1048576 /* ExportValue */, getCannotFindNameDiagnosticForName(node), node, !ts.isWriteOnlyAccess(node), 
                    /*excludeGlobals*/ false, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol;
            }
            return links.resolvedSymbol;
        }
        function isInTypeQuery(node) {
            // TypeScript 1.0 spec (April 2014): 3.6.3
            // A type query consists of the keyword typeof followed by an expression.
            // The expression is restricted to a single identifier or a sequence of identifiers separated by periods
            return !!ts.findAncestor(node, function (n) { return n.kind === 172 /* TypeQuery */ ? true : n.kind === 75 /* Identifier */ || n.kind === 153 /* QualifiedName */ ? false : "quit"; });
        }
        // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers
        // separated by dots). The key consists of the id of the symbol referenced by the
        // leftmost identifier followed by zero or more property names separated by dots.
        // The result is undefined if the reference isn't a dotted name. We prefix nodes
        // occurring in an apparent type position with '@' because the control flow type
        // of such nodes may be based on the apparent type instead of the declared type.
        function getFlowCacheKey(node, declaredType, initialType, flowContainer) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    var symbol = getResolvedSymbol(node);
                    return symbol !== unknownSymbol ? (flowContainer ? getNodeId(flowContainer) : "-1") + "|" + getTypeId(declaredType) + "|" + getTypeId(initialType) + "|" + (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
                case 104 /* ThisKeyword */:
                    return "0";
                case 218 /* NonNullExpression */:
                case 200 /* ParenthesizedExpression */:
                    return getFlowCacheKey(node.expression, declaredType, initialType, flowContainer);
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    var propName = getAccessedPropertyName(node);
                    if (propName !== undefined) {
                        var key = getFlowCacheKey(node.expression, declaredType, initialType, flowContainer);
                        return key && key + "." + propName;
                    }
            }
            return undefined;
        }
        function isMatchingReference(source, target) {
            switch (target.kind) {
                case 200 /* ParenthesizedExpression */:
                case 218 /* NonNullExpression */:
                    return isMatchingReference(source, target.expression);
            }
            switch (source.kind) {
                case 75 /* Identifier */:
                    return target.kind === 75 /* Identifier */ && getResolvedSymbol(source) === getResolvedSymbol(target) ||
                        (target.kind === 242 /* VariableDeclaration */ || target.kind === 191 /* BindingElement */) &&
                            getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source)) === getSymbolOfNode(target);
                case 104 /* ThisKeyword */:
                    return target.kind === 104 /* ThisKeyword */;
                case 102 /* SuperKeyword */:
                    return target.kind === 102 /* SuperKeyword */;
                case 218 /* NonNullExpression */:
                case 200 /* ParenthesizedExpression */:
                    return isMatchingReference(source.expression, target);
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    return ts.isAccessExpression(target) &&
                        getAccessedPropertyName(source) === getAccessedPropertyName(target) &&
                        isMatchingReference(source.expression, target.expression);
            }
            return false;
        }
        // Given a source x, check if target matches x or is an && operation with an operand that matches x.
        function containsTruthyCheck(source, target) {
            return isMatchingReference(source, target) ||
                (target.kind === 209 /* BinaryExpression */ && target.operatorToken.kind === 55 /* AmpersandAmpersandToken */ &&
                    (containsTruthyCheck(source, target.left) || containsTruthyCheck(source, target.right)));
        }
        function getAccessedPropertyName(access) {
            return access.kind === 194 /* PropertyAccessExpression */ ? access.name.escapedText :
                ts.isStringOrNumericLiteralLike(access.argumentExpression) ? ts.escapeLeadingUnderscores(access.argumentExpression.text) :
                    undefined;
        }
        function containsMatchingReference(source, target) {
            while (ts.isAccessExpression(source)) {
                source = source.expression;
                if (isMatchingReference(source, target)) {
                    return true;
                }
            }
            return false;
        }
        function optionalChainContainsReference(source, target) {
            while (ts.isOptionalChain(source)) {
                source = source.expression;
                if (isMatchingReference(source, target)) {
                    return true;
                }
            }
            return false;
        }
        function isDiscriminantProperty(type, name) {
            if (type && type.flags & 1048576 /* Union */) {
                var prop = getUnionOrIntersectionProperty(type, name);
                if (prop && ts.getCheckFlags(prop) & 2 /* SyntheticProperty */) {
                    if (prop.isDiscriminantProperty === undefined) {
                        prop.isDiscriminantProperty =
                            (prop.checkFlags & 192 /* Discriminant */) === 192 /* Discriminant */ &&
                                !maybeTypeOfKind(getTypeOfSymbol(prop), 63176704 /* Instantiable */);
                    }
                    return !!prop.isDiscriminantProperty;
                }
            }
            return false;
        }
        function findDiscriminantProperties(sourceProperties, target) {
            var result;
            for (var _i = 0, sourceProperties_2 = sourceProperties; _i < sourceProperties_2.length; _i++) {
                var sourceProperty = sourceProperties_2[_i];
                if (isDiscriminantProperty(target, sourceProperty.escapedName)) {
                    if (result) {
                        result.push(sourceProperty);
                        continue;
                    }
                    result = [sourceProperty];
                }
            }
            return result;
        }
        function isOrContainsMatchingReference(source, target) {
            return isMatchingReference(source, target) || containsMatchingReference(source, target);
        }
        function hasMatchingArgument(callExpression, reference) {
            if (callExpression.arguments) {
                for (var _i = 0, _a = callExpression.arguments; _i < _a.length; _i++) {
                    var argument = _a[_i];
                    if (isOrContainsMatchingReference(reference, argument)) {
                        return true;
                    }
                }
            }
            if (callExpression.expression.kind === 194 /* PropertyAccessExpression */ &&
                isOrContainsMatchingReference(reference, callExpression.expression.expression)) {
                return true;
            }
            return false;
        }
        function getFlowNodeId(flow) {
            if (!flow.id || flow.id < 0) {
                flow.id = nextFlowId;
                nextFlowId++;
            }
            return flow.id;
        }
        function typeMaybeAssignableTo(source, target) {
            if (!(source.flags & 1048576 /* Union */)) {
                return isTypeAssignableTo(source, target);
            }
            for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (isTypeAssignableTo(t, target)) {
                    return true;
                }
            }
            return false;
        }
        // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
        // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
        // we remove type string.
        function getAssignmentReducedType(declaredType, assignedType) {
            if (declaredType !== assignedType) {
                if (assignedType.flags & 131072 /* Never */) {
                    return assignedType;
                }
                var reducedType = filterType(declaredType, function (t) { return typeMaybeAssignableTo(assignedType, t); });
                if (assignedType.flags & 512 /* BooleanLiteral */ && isFreshLiteralType(assignedType)) {
                    reducedType = mapType(reducedType, getFreshTypeOfLiteralType); // Ensure that if the assignment is a fresh type, that we narrow to fresh types
                }
                // Our crude heuristic produces an invalid result in some cases: see GH#26130.
                // For now, when that happens, we give up and don't narrow at all.  (This also
                // means we'll never narrow for erroneous assignments where the assigned type
                // is not assignable to the declared type.)
                if (isTypeAssignableTo(assignedType, reducedType)) {
                    return reducedType;
                }
            }
            return declaredType;
        }
        function getTypeFactsOfTypes(types) {
            var result = 0 /* None */;
            for (var _i = 0, types_15 = types; _i < types_15.length; _i++) {
                var t = types_15[_i];
                result |= getTypeFacts(t);
            }
            return result;
        }
        function isFunctionObjectType(type) {
            // We do a quick check for a "bind" property before performing the more expensive subtype
            // check. This gives us a quicker out in the common case where an object type is not a function.
            var resolved = resolveStructuredTypeMembers(type);
            return !!(resolved.callSignatures.length || resolved.constructSignatures.length ||
                resolved.members.get("bind") && isTypeSubtypeOf(type, globalFunctionType));
        }
        function getTypeFacts(type) {
            var flags = type.flags;
            if (flags & 4 /* String */) {
                return strictNullChecks ? 16317953 /* StringStrictFacts */ : 16776705 /* StringFacts */;
            }
            if (flags & 128 /* StringLiteral */) {
                var isEmpty = type.value === "";
                return strictNullChecks ?
                    isEmpty ? 12123649 /* EmptyStringStrictFacts */ : 7929345 /* NonEmptyStringStrictFacts */ :
                    isEmpty ? 12582401 /* EmptyStringFacts */ : 16776705 /* NonEmptyStringFacts */;
            }
            if (flags & (8 /* Number */ | 32 /* Enum */)) {
                return strictNullChecks ? 16317698 /* NumberStrictFacts */ : 16776450 /* NumberFacts */;
            }
            if (flags & 256 /* NumberLiteral */) {
                var isZero = type.value === 0;
                return strictNullChecks ?
                    isZero ? 12123394 /* ZeroNumberStrictFacts */ : 7929090 /* NonZeroNumberStrictFacts */ :
                    isZero ? 12582146 /* ZeroNumberFacts */ : 16776450 /* NonZeroNumberFacts */;
            }
            if (flags & 64 /* BigInt */) {
                return strictNullChecks ? 16317188 /* BigIntStrictFacts */ : 16775940 /* BigIntFacts */;
            }
            if (flags & 2048 /* BigIntLiteral */) {
                var isZero = isZeroBigInt(type);
                return strictNullChecks ?
                    isZero ? 12122884 /* ZeroBigIntStrictFacts */ : 7928580 /* NonZeroBigIntStrictFacts */ :
                    isZero ? 12581636 /* ZeroBigIntFacts */ : 16775940 /* NonZeroBigIntFacts */;
            }
            if (flags & 16 /* Boolean */) {
                return strictNullChecks ? 16316168 /* BooleanStrictFacts */ : 16774920 /* BooleanFacts */;
            }
            if (flags & 528 /* BooleanLike */) {
                return strictNullChecks ?
                    (type === falseType || type === regularFalseType) ? 12121864 /* FalseStrictFacts */ : 7927560 /* TrueStrictFacts */ :
                    (type === falseType || type === regularFalseType) ? 12580616 /* FalseFacts */ : 16774920 /* TrueFacts */;
            }
            if (flags & 524288 /* Object */) {
                return ts.getObjectFlags(type) & 16 /* Anonymous */ && isEmptyObjectType(type) ?
                    strictNullChecks ? 16318463 /* EmptyObjectStrictFacts */ : 16777215 /* EmptyObjectFacts */ :
                    isFunctionObjectType(type) ?
                        strictNullChecks ? 7880640 /* FunctionStrictFacts */ : 16728000 /* FunctionFacts */ :
                        strictNullChecks ? 7888800 /* ObjectStrictFacts */ : 16736160 /* ObjectFacts */;
            }
            if (flags & (16384 /* Void */ | 32768 /* Undefined */)) {
                return 9830144 /* UndefinedFacts */;
            }
            if (flags & 65536 /* Null */) {
                return 9363232 /* NullFacts */;
            }
            if (flags & 12288 /* ESSymbolLike */) {
                return strictNullChecks ? 7925520 /* SymbolStrictFacts */ : 16772880 /* SymbolFacts */;
            }
            if (flags & 67108864 /* NonPrimitive */) {
                return strictNullChecks ? 7888800 /* ObjectStrictFacts */ : 16736160 /* ObjectFacts */;
            }
            if (flags & 131072 /* Never */) {
                return 0 /* None */;
            }
            if (flags & 63176704 /* Instantiable */) {
                return getTypeFacts(getBaseConstraintOfType(type) || unknownType);
            }
            if (flags & 3145728 /* UnionOrIntersection */) {
                return getTypeFactsOfTypes(type.types);
            }
            return 16777215 /* All */;
        }
        function getTypeWithFacts(type, include) {
            return filterType(type, function (t) { return (getTypeFacts(t) & include) !== 0; });
        }
        function getTypeWithDefault(type, defaultExpression) {
            if (defaultExpression) {
                var defaultType = getTypeOfExpression(defaultExpression);
                return getUnionType([getTypeWithFacts(type, 524288 /* NEUndefined */), defaultType]);
            }
            return type;
        }
        function getTypeOfDestructuredProperty(type, name) {
            var nameType = getLiteralTypeFromPropertyName(name);
            if (!isTypeUsableAsPropertyName(nameType))
                return errorType;
            var text = getPropertyNameFromType(nameType);
            return getConstraintForLocation(getTypeOfPropertyOfType(type, text), name) ||
                isNumericLiteralName(text) && getIndexTypeOfType(type, 1 /* Number */) ||
                getIndexTypeOfType(type, 0 /* String */) ||
                errorType;
        }
        function getTypeOfDestructuredArrayElement(type, index) {
            return everyType(type, isTupleLikeType) && getTupleElementType(type, index) ||
                checkIteratedTypeOrElementType(65 /* Destructuring */, type, undefinedType, /*errorNode*/ undefined) ||
                errorType;
        }
        function getTypeOfDestructuredSpreadExpression(type) {
            return createArrayType(checkIteratedTypeOrElementType(65 /* Destructuring */, type, undefinedType, /*errorNode*/ undefined) || errorType);
        }
        function getAssignedTypeOfBinaryExpression(node) {
            var isDestructuringDefaultAssignment = node.parent.kind === 192 /* ArrayLiteralExpression */ && isDestructuringAssignmentTarget(node.parent) ||
                node.parent.kind === 281 /* PropertyAssignment */ && isDestructuringAssignmentTarget(node.parent.parent);
            return isDestructuringDefaultAssignment ?
                getTypeWithDefault(getAssignedType(node), node.right) :
                getTypeOfExpression(node.right);
        }
        function isDestructuringAssignmentTarget(parent) {
            return parent.parent.kind === 209 /* BinaryExpression */ && parent.parent.left === parent ||
                parent.parent.kind === 232 /* ForOfStatement */ && parent.parent.initializer === parent;
        }
        function getAssignedTypeOfArrayLiteralElement(node, element) {
            return getTypeOfDestructuredArrayElement(getAssignedType(node), node.elements.indexOf(element));
        }
        function getAssignedTypeOfSpreadExpression(node) {
            return getTypeOfDestructuredSpreadExpression(getAssignedType(node.parent));
        }
        function getAssignedTypeOfPropertyAssignment(node) {
            return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name);
        }
        function getAssignedTypeOfShorthandPropertyAssignment(node) {
            return getTypeWithDefault(getAssignedTypeOfPropertyAssignment(node), node.objectAssignmentInitializer);
        }
        function getAssignedType(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 231 /* ForInStatement */:
                    return stringType;
                case 232 /* ForOfStatement */:
                    return checkRightHandSideOfForOf(parent) || errorType;
                case 209 /* BinaryExpression */:
                    return getAssignedTypeOfBinaryExpression(parent);
                case 203 /* DeleteExpression */:
                    return undefinedType;
                case 192 /* ArrayLiteralExpression */:
                    return getAssignedTypeOfArrayLiteralElement(parent, node);
                case 213 /* SpreadElement */:
                    return getAssignedTypeOfSpreadExpression(parent);
                case 281 /* PropertyAssignment */:
                    return getAssignedTypeOfPropertyAssignment(parent);
                case 282 /* ShorthandPropertyAssignment */:
                    return getAssignedTypeOfShorthandPropertyAssignment(parent);
            }
            return errorType;
        }
        function getInitialTypeOfBindingElement(node) {
            var pattern = node.parent;
            var parentType = getInitialType(pattern.parent);
            var type = pattern.kind === 189 /* ObjectBindingPattern */ ?
                getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) :
                !node.dotDotDotToken ?
                    getTypeOfDestructuredArrayElement(parentType, pattern.elements.indexOf(node)) :
                    getTypeOfDestructuredSpreadExpression(parentType);
            return getTypeWithDefault(type, node.initializer);
        }
        function getTypeOfInitializer(node) {
            // Return the cached type if one is available. If the type of the variable was inferred
            // from its initializer, we'll already have cached the type. Otherwise we compute it now
            // without caching such that transient types are reflected.
            var links = getNodeLinks(node);
            return links.resolvedType || getTypeOfExpression(node);
        }
        function getInitialTypeOfVariableDeclaration(node) {
            if (node.initializer) {
                return getTypeOfInitializer(node.initializer);
            }
            if (node.parent.parent.kind === 231 /* ForInStatement */) {
                return stringType;
            }
            if (node.parent.parent.kind === 232 /* ForOfStatement */) {
                return checkRightHandSideOfForOf(node.parent.parent) || errorType;
            }
            return errorType;
        }
        function getInitialType(node) {
            return node.kind === 242 /* VariableDeclaration */ ?
                getInitialTypeOfVariableDeclaration(node) :
                getInitialTypeOfBindingElement(node);
        }
        function isEmptyArrayAssignment(node) {
            return node.kind === 242 /* VariableDeclaration */ && node.initializer &&
                isEmptyArrayLiteral(node.initializer) ||
                node.kind !== 191 /* BindingElement */ && node.parent.kind === 209 /* BinaryExpression */ &&
                    isEmptyArrayLiteral(node.parent.right);
        }
        function getReferenceCandidate(node) {
            switch (node.kind) {
                case 200 /* ParenthesizedExpression */:
                    return getReferenceCandidate(node.expression);
                case 209 /* BinaryExpression */:
                    switch (node.operatorToken.kind) {
                        case 62 /* EqualsToken */:
                            return getReferenceCandidate(node.left);
                        case 27 /* CommaToken */:
                            return getReferenceCandidate(node.right);
                    }
            }
            return node;
        }
        function getReferenceRoot(node) {
            var parent = node.parent;
            return parent.kind === 200 /* ParenthesizedExpression */ ||
                parent.kind === 209 /* BinaryExpression */ && parent.operatorToken.kind === 62 /* EqualsToken */ && parent.left === node ||
                parent.kind === 209 /* BinaryExpression */ && parent.operatorToken.kind === 27 /* CommaToken */ && parent.right === node ?
                getReferenceRoot(parent) : node;
        }
        function getTypeOfSwitchClause(clause) {
            if (clause.kind === 277 /* CaseClause */) {
                return getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression));
            }
            return neverType;
        }
        function getSwitchClauseTypes(switchStatement) {
            var links = getNodeLinks(switchStatement);
            if (!links.switchTypes) {
                links.switchTypes = [];
                for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) {
                    var clause = _a[_i];
                    links.switchTypes.push(getTypeOfSwitchClause(clause));
                }
            }
            return links.switchTypes;
        }
        function getSwitchClauseTypeOfWitnesses(switchStatement, retainDefault) {
            var witnesses = [];
            for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) {
                var clause = _a[_i];
                if (clause.kind === 277 /* CaseClause */) {
                    if (ts.isStringLiteralLike(clause.expression)) {
                        witnesses.push(clause.expression.text);
                        continue;
                    }
                    return ts.emptyArray;
                }
                if (retainDefault)
                    witnesses.push(/*explicitDefaultStatement*/ undefined);
            }
            return witnesses;
        }
        function eachTypeContainedIn(source, types) {
            return source.flags & 1048576 /* Union */ ? !ts.forEach(source.types, function (t) { return !ts.contains(types, t); }) : ts.contains(types, source);
        }
        function isTypeSubsetOf(source, target) {
            return source === target || target.flags & 1048576 /* Union */ && isTypeSubsetOfUnion(source, target);
        }
        function isTypeSubsetOfUnion(source, target) {
            if (source.flags & 1048576 /* Union */) {
                for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (!containsType(target.types, t)) {
                        return false;
                    }
                }
                return true;
            }
            if (source.flags & 1024 /* EnumLiteral */ && getBaseTypeOfEnumLiteralType(source) === target) {
                return true;
            }
            return containsType(target.types, source);
        }
        function forEachType(type, f) {
            return type.flags & 1048576 /* Union */ ? ts.forEach(type.types, f) : f(type);
        }
        function everyType(type, f) {
            return type.flags & 1048576 /* Union */ ? ts.every(type.types, f) : f(type);
        }
        function filterType(type, f) {
            if (type.flags & 1048576 /* Union */) {
                var types = type.types;
                var filtered = ts.filter(types, f);
                return filtered === types ? type : getUnionTypeFromSortedList(filtered, type.objectFlags);
            }
            return type.flags & 131072 /* Never */ || f(type) ? type : neverType;
        }
        function countTypes(type) {
            return type.flags & 1048576 /* Union */ ? type.types.length : 1;
        }
        function mapType(type, mapper, noReductions) {
            if (type.flags & 131072 /* Never */) {
                return type;
            }
            if (!(type.flags & 1048576 /* Union */)) {
                return mapper(type);
            }
            var mappedTypes;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                var mapped = mapper(t);
                if (mapped) {
                    if (!mappedTypes) {
                        mappedTypes = [mapped];
                    }
                    else {
                        mappedTypes.push(mapped);
                    }
                }
            }
            return mappedTypes && getUnionType(mappedTypes, noReductions ? 0 /* None */ : 1 /* Literal */);
        }
        function extractTypesOfKind(type, kind) {
            return filterType(type, function (t) { return (t.flags & kind) !== 0; });
        }
        // Return a new type in which occurrences of the string and number primitive types in
        // typeWithPrimitives have been replaced with occurrences of string literals and numeric
        // literals in typeWithLiterals, respectively.
        function replacePrimitivesWithLiterals(typeWithPrimitives, typeWithLiterals) {
            if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 128 /* StringLiteral */) ||
                isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 256 /* NumberLiteral */) ||
                isTypeSubsetOf(bigintType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 2048 /* BigIntLiteral */)) {
                return mapType(typeWithPrimitives, function (t) {
                    return t.flags & 4 /* String */ ? extractTypesOfKind(typeWithLiterals, 4 /* String */ | 128 /* StringLiteral */) :
                        t.flags & 8 /* Number */ ? extractTypesOfKind(typeWithLiterals, 8 /* Number */ | 256 /* NumberLiteral */) :
                            t.flags & 64 /* BigInt */ ? extractTypesOfKind(typeWithLiterals, 64 /* BigInt */ | 2048 /* BigIntLiteral */) : t;
                });
            }
            return typeWithPrimitives;
        }
        function isIncomplete(flowType) {
            return flowType.flags === 0;
        }
        function getTypeFromFlowType(flowType) {
            return flowType.flags === 0 ? flowType.type : flowType;
        }
        function createFlowType(type, incomplete) {
            return incomplete ? { flags: 0, type: type } : type;
        }
        // An evolving array type tracks the element types that have so far been seen in an
        // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving
        // array types are ultimately converted into manifest array types (using getFinalArrayType)
        // and never escape the getFlowTypeOfReference function.
        function createEvolvingArrayType(elementType) {
            var result = createObjectType(256 /* EvolvingArray */);
            result.elementType = elementType;
            return result;
        }
        function getEvolvingArrayType(elementType) {
            return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType));
        }
        // When adding evolving array element types we do not perform subtype reduction. Instead,
        // we defer subtype reduction until the evolving array type is finalized into a manifest
        // array type.
        function addEvolvingArrayElementType(evolvingArrayType, node) {
            var elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node));
            return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
        }
        function createFinalArrayType(elementType) {
            return elementType.flags & 131072 /* Never */ ?
                autoArrayType :
                createArrayType(elementType.flags & 1048576 /* Union */ ?
                    getUnionType(elementType.types, 2 /* Subtype */) :
                    elementType);
        }
        // We perform subtype reduction upon obtaining the final array type from an evolving array type.
        function getFinalArrayType(evolvingArrayType) {
            return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType));
        }
        function finalizeEvolvingArrayType(type) {
            return ts.getObjectFlags(type) & 256 /* EvolvingArray */ ? getFinalArrayType(type) : type;
        }
        function getElementTypeOfEvolvingArrayType(type) {
            return ts.getObjectFlags(type) & 256 /* EvolvingArray */ ? type.elementType : neverType;
        }
        function isEvolvingArrayTypeList(types) {
            var hasEvolvingArrayType = false;
            for (var _i = 0, types_16 = types; _i < types_16.length; _i++) {
                var t = types_16[_i];
                if (!(t.flags & 131072 /* Never */)) {
                    if (!(ts.getObjectFlags(t) & 256 /* EvolvingArray */)) {
                        return false;
                    }
                    hasEvolvingArrayType = true;
                }
            }
            return hasEvolvingArrayType;
        }
        // At flow control branch or loop junctions, if the type along every antecedent code path
        // is an evolving array type, we construct a combined evolving array type. Otherwise we
        // finalize all evolving array types.
        function getUnionOrEvolvingArrayType(types, subtypeReduction) {
            return isEvolvingArrayTypeList(types) ?
                getEvolvingArrayType(getUnionType(ts.map(types, getElementTypeOfEvolvingArrayType))) :
                getUnionType(ts.sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
        }
        // Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or
        // 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type.
        function isEvolvingArrayOperationTarget(node) {
            var root = getReferenceRoot(node);
            var parent = root.parent;
            var isLengthPushOrUnshift = ts.isPropertyAccessExpression(parent) && (parent.name.escapedText === "length" ||
                parent.parent.kind === 196 /* CallExpression */
                    && ts.isIdentifier(parent.name)
                    && ts.isPushOrUnshiftIdentifier(parent.name));
            var isElementAssignment = parent.kind === 195 /* ElementAccessExpression */ &&
                parent.expression === root &&
                parent.parent.kind === 209 /* BinaryExpression */ &&
                parent.parent.operatorToken.kind === 62 /* EqualsToken */ &&
                parent.parent.left === parent &&
                !ts.isAssignmentTarget(parent.parent) &&
                isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 296 /* NumberLike */);
            return isLengthPushOrUnshift || isElementAssignment;
        }
        function isDeclarationWithExplicitTypeAnnotation(declaration) {
            return (declaration.kind === 242 /* VariableDeclaration */ || declaration.kind === 156 /* Parameter */ ||
                declaration.kind === 159 /* PropertyDeclaration */ || declaration.kind === 158 /* PropertySignature */) &&
                !!ts.getEffectiveTypeAnnotationNode(declaration);
        }
        function getExplicitTypeOfSymbol(symbol, diagnostic) {
            if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 512 /* ValueModule */)) {
                return getTypeOfSymbol(symbol);
            }
            if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) {
                var declaration = symbol.valueDeclaration;
                if (declaration) {
                    if (isDeclarationWithExplicitTypeAnnotation(declaration)) {
                        return getTypeOfSymbol(symbol);
                    }
                    if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === 232 /* ForOfStatement */) {
                        var statement = declaration.parent.parent;
                        var expressionType = getTypeOfDottedName(statement.expression, /*diagnostic*/ undefined);
                        if (expressionType) {
                            var use = statement.awaitModifier ? 15 /* ForAwaitOf */ : 13 /* ForOf */;
                            return checkIteratedTypeOrElementType(use, expressionType, undefinedType, /*errorNode*/ undefined);
                        }
                    }
                    if (diagnostic) {
                        ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(declaration, ts.Diagnostics._0_needs_an_explicit_type_annotation, symbolToString(symbol)));
                    }
                }
            }
        }
        // We require the dotted function name in an assertion expression to be comprised of identifiers
        // that reference function, method, class or value module symbols; or variable, property or
        // parameter symbols with declarations that have explicit type annotations. Such references are
        // resolvable with no possibility of triggering circularities in control flow analysis.
        function getTypeOfDottedName(node, diagnostic) {
            if (!(node.flags & 16777216 /* InWithStatement */)) {
                switch (node.kind) {
                    case 75 /* Identifier */:
                        var symbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(node));
                        return getExplicitTypeOfSymbol(symbol.flags & 2097152 /* Alias */ ? resolveAlias(symbol) : symbol, diagnostic);
                    case 104 /* ThisKeyword */:
                        return getExplicitThisType(node);
                    case 102 /* SuperKeyword */:
                        return checkSuperExpression(node);
                    case 194 /* PropertyAccessExpression */:
                        var type = getTypeOfDottedName(node.expression, diagnostic);
                        var prop = type && getPropertyOfType(type, node.name.escapedText);
                        return prop && getExplicitTypeOfSymbol(prop, diagnostic);
                    case 200 /* ParenthesizedExpression */:
                        return getTypeOfDottedName(node.expression, diagnostic);
                }
            }
        }
        function getEffectsSignature(node) {
            var links = getNodeLinks(node);
            var signature = links.effectsSignature;
            if (signature === undefined) {
                // A call expression parented by an expression statement is a potential assertion. Other call
                // expressions are potential type predicate function calls. In order to avoid triggering
                // circularities in control flow analysis, we use getTypeOfDottedName when resolving the call
                // target expression of an assertion.
                var funcType = void 0;
                if (node.parent.kind === 226 /* ExpressionStatement */) {
                    funcType = getTypeOfDottedName(node.expression, /*diagnostic*/ undefined);
                }
                else if (node.expression.kind !== 102 /* SuperKeyword */) {
                    if (ts.isOptionalChain(node)) {
                        funcType = checkNonNullType(getOptionalExpressionType(checkExpression(node.expression), node.expression), node.expression);
                    }
                    else {
                        funcType = checkNonNullExpression(node.expression);
                    }
                }
                var signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, 0 /* Call */);
                var candidate = signatures.length === 1 && !signatures[0].typeParameters ? signatures[0] :
                    ts.some(signatures, hasTypePredicateOrNeverReturnType) ? getResolvedSignature(node) :
                        undefined;
                signature = links.effectsSignature = candidate && hasTypePredicateOrNeverReturnType(candidate) ? candidate : unknownSignature;
            }
            return signature === unknownSignature ? undefined : signature;
        }
        function hasTypePredicateOrNeverReturnType(signature) {
            return !!(getTypePredicateOfSignature(signature) ||
                signature.declaration && (getReturnTypeFromAnnotation(signature.declaration) || unknownType).flags & 131072 /* Never */);
        }
        function getTypePredicateArgument(predicate, callExpression) {
            if (predicate.kind === 1 /* Identifier */ || predicate.kind === 3 /* AssertsIdentifier */) {
                return callExpression.arguments[predicate.parameterIndex];
            }
            var invokedExpression = ts.skipParentheses(callExpression.expression);
            return ts.isAccessExpression(invokedExpression) ? ts.skipParentheses(invokedExpression.expression) : undefined;
        }
        function reportFlowControlError(node) {
            var block = ts.findAncestor(node, ts.isFunctionOrModuleBlock);
            var sourceFile = ts.getSourceFileOfNode(node);
            var span = ts.getSpanOfTokenAtPosition(sourceFile, block.statements.pos);
            diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis));
        }
        function isReachableFlowNode(flow) {
            var result = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ false);
            lastFlowNode = flow;
            lastFlowNodeReachable = result;
            return result;
        }
        function isFalseExpression(expr) {
            var node = ts.skipParentheses(expr);
            return node.kind === 91 /* FalseKeyword */ || node.kind === 209 /* BinaryExpression */ && (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */ && (isFalseExpression(node.left) || isFalseExpression(node.right)) ||
                node.operatorToken.kind === 56 /* BarBarToken */ && isFalseExpression(node.left) && isFalseExpression(node.right));
        }
        function isReachableFlowNodeWorker(flow, noCacheCheck) {
            while (true) {
                if (flow === lastFlowNode) {
                    return lastFlowNodeReachable;
                }
                var flags = flow.flags;
                if (flags & 4096 /* Shared */) {
                    if (!noCacheCheck) {
                        var id = getFlowNodeId(flow);
                        var reachable = flowNodeReachable[id];
                        return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ true));
                    }
                    noCacheCheck = false;
                }
                if (flags & (16 /* Assignment */ | 96 /* Condition */ | 256 /* ArrayMutation */)) {
                    flow = flow.antecedent;
                }
                else if (flags & 512 /* Call */) {
                    var signature = getEffectsSignature(flow.node);
                    if (signature) {
                        var predicate = getTypePredicateOfSignature(signature);
                        if (predicate && predicate.kind === 3 /* AssertsIdentifier */) {
                            var predicateArgument = flow.node.arguments[predicate.parameterIndex];
                            if (predicateArgument && isFalseExpression(predicateArgument)) {
                                return false;
                            }
                        }
                        if (getReturnTypeOfSignature(signature).flags & 131072 /* Never */) {
                            return false;
                        }
                    }
                    flow = flow.antecedent;
                }
                else if (flags & 4 /* BranchLabel */) {
                    // A branching point is reachable if any branch is reachable.
                    return ts.some(flow.antecedents, function (f) { return isReachableFlowNodeWorker(f, /*noCacheCheck*/ false); });
                }
                else if (flags & 8 /* LoopLabel */) {
                    // A loop is reachable if the control flow path that leads to the top is reachable.
                    flow = flow.antecedents[0];
                }
                else if (flags & 128 /* SwitchClause */) {
                    // The control flow path representing an unmatched value in a switch statement with
                    // no default clause is unreachable if the switch statement is exhaustive.
                    if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) {
                        return false;
                    }
                    flow = flow.antecedent;
                }
                else if (flags & 1024 /* ReduceLabel */) {
                    // Cache is unreliable once we start adjusting labels
                    lastFlowNode = undefined;
                    var target = flow.target;
                    var saveAntecedents = target.antecedents;
                    target.antecedents = flow.antecedents;
                    var result = isReachableFlowNodeWorker(flow.antecedent, /*noCacheCheck*/ false);
                    target.antecedents = saveAntecedents;
                    return result;
                }
                else {
                    return !(flags & 1 /* Unreachable */);
                }
            }
        }
        function getFlowTypeOfReference(reference, declaredType, initialType, flowContainer, couldBeUninitialized) {
            if (initialType === void 0) { initialType = declaredType; }
            var key;
            var keySet = false;
            var flowDepth = 0;
            if (flowAnalysisDisabled) {
                return errorType;
            }
            if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & 133970943 /* Narrowable */)) {
                return declaredType;
            }
            flowInvocationCount++;
            var sharedFlowStart = sharedFlowCount;
            var evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
            sharedFlowCount = sharedFlowStart;
            // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation,
            // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations
            // on empty arrays are possible without implicit any errors and new element types can be inferred without
            // type mismatch errors.
            var resultType = ts.getObjectFlags(evolvedType) & 256 /* EvolvingArray */ && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType);
            if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === 218 /* NonNullExpression */ && getTypeWithFacts(resultType, 2097152 /* NEUndefinedOrNull */).flags & 131072 /* Never */) {
                return declaredType;
            }
            return resultType;
            function getOrSetCacheKey() {
                if (keySet) {
                    return key;
                }
                keySet = true;
                return key = getFlowCacheKey(reference, declaredType, initialType, flowContainer);
            }
            function getTypeAtFlowNode(flow) {
                if (flowDepth === 2000) {
                    // We have made 2000 recursive invocations. To avoid overflowing the call stack we report an error
                    // and disable further control flow analysis in the containing function or module body.
                    flowAnalysisDisabled = true;
                    reportFlowControlError(reference);
                    return errorType;
                }
                flowDepth++;
                while (true) {
                    var flags = flow.flags;
                    if (flags & 4096 /* Shared */) {
                        // We cache results of flow type resolution for shared nodes that were previously visited in
                        // the same getFlowTypeOfReference invocation. A node is considered shared when it is the
                        // antecedent of more than one node.
                        for (var i = sharedFlowStart; i < sharedFlowCount; i++) {
                            if (sharedFlowNodes[i] === flow) {
                                flowDepth--;
                                return sharedFlowTypes[i];
                            }
                        }
                    }
                    var type = void 0;
                    if (flags & 16 /* Assignment */) {
                        type = getTypeAtFlowAssignment(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 512 /* Call */) {
                        type = getTypeAtFlowCall(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 96 /* Condition */) {
                        type = getTypeAtFlowCondition(flow);
                    }
                    else if (flags & 128 /* SwitchClause */) {
                        type = getTypeAtSwitchClause(flow);
                    }
                    else if (flags & 12 /* Label */) {
                        if (flow.antecedents.length === 1) {
                            flow = flow.antecedents[0];
                            continue;
                        }
                        type = flags & 4 /* BranchLabel */ ?
                            getTypeAtFlowBranchLabel(flow) :
                            getTypeAtFlowLoopLabel(flow);
                    }
                    else if (flags & 256 /* ArrayMutation */) {
                        type = getTypeAtFlowArrayMutation(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 1024 /* ReduceLabel */) {
                        var target = flow.target;
                        var saveAntecedents = target.antecedents;
                        target.antecedents = flow.antecedents;
                        type = getTypeAtFlowNode(flow.antecedent);
                        target.antecedents = saveAntecedents;
                    }
                    else if (flags & 2 /* Start */) {
                        // Check if we should continue with the control flow of the containing function.
                        var container = flow.node;
                        if (container && container !== flowContainer &&
                            reference.kind !== 194 /* PropertyAccessExpression */ &&
                            reference.kind !== 195 /* ElementAccessExpression */ &&
                            reference.kind !== 104 /* ThisKeyword */) {
                            flow = container.flowNode;
                            continue;
                        }
                        // At the top of the flow we have the initial type.
                        type = initialType;
                    }
                    else {
                        // Unreachable code errors are reported in the binding phase. Here we
                        // simply return the non-auto declared type to reduce follow-on errors.
                        type = convertAutoToAny(declaredType);
                    }
                    if (flags & 4096 /* Shared */) {
                        // Record visited node and the associated type in the cache.
                        sharedFlowNodes[sharedFlowCount] = flow;
                        sharedFlowTypes[sharedFlowCount] = type;
                        sharedFlowCount++;
                    }
                    flowDepth--;
                    return type;
                }
            }
            function getInitialOrAssignedType(flow) {
                var node = flow.node;
                return getConstraintForLocation(node.kind === 242 /* VariableDeclaration */ || node.kind === 191 /* BindingElement */ ?
                    getInitialType(node) :
                    getAssignedType(node), reference);
            }
            function getTypeAtFlowAssignment(flow) {
                var node = flow.node;
                // Assignments only narrow the computed type if the declared type is a union type. Thus, we
                // only need to evaluate the assigned type if the declared type is a union type.
                if (isMatchingReference(reference, node)) {
                    if (!isReachableFlowNode(flow)) {
                        return unreachableNeverType;
                    }
                    if (ts.getAssignmentTargetKind(node) === 2 /* Compound */) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
                    }
                    if (declaredType === autoType || declaredType === autoArrayType) {
                        if (isEmptyArrayAssignment(node)) {
                            return getEvolvingArrayType(neverType);
                        }
                        var assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(flow));
                        return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType;
                    }
                    if (declaredType.flags & 1048576 /* Union */) {
                        return getAssignmentReducedType(declaredType, getInitialOrAssignedType(flow));
                    }
                    return declaredType;
                }
                // We didn't have a direct match. However, if the reference is a dotted name, this
                // may be an assignment to a left hand part of the reference. For example, for a
                // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
                // return the declared type.
                if (containsMatchingReference(reference, node)) {
                    if (!isReachableFlowNode(flow)) {
                        return unreachableNeverType;
                    }
                    // A matching dotted name might also be an expando property on a function *expression*,
                    // in which case we continue control flow analysis back to the function's declaration
                    if (ts.isVariableDeclaration(node) && (ts.isInJSFile(node) || ts.isVarConst(node))) {
                        var init = ts.getDeclaredExpandoInitializer(node);
                        if (init && (init.kind === 201 /* FunctionExpression */ || init.kind === 202 /* ArrowFunction */)) {
                            return getTypeAtFlowNode(flow.antecedent);
                        }
                    }
                    return declaredType;
                }
                // for (const _ in ref) acts as a nonnull on ref
                if (ts.isVariableDeclaration(node) && node.parent.parent.kind === 231 /* ForInStatement */ && isMatchingReference(reference, node.parent.parent.expression)) {
                    return getNonNullableTypeIfNeeded(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent)));
                }
                // Assignment doesn't affect reference
                return undefined;
            }
            function narrowTypeByAssertion(type, expr) {
                var node = ts.skipParentheses(expr);
                if (node.kind === 91 /* FalseKeyword */) {
                    return unreachableNeverType;
                }
                if (node.kind === 209 /* BinaryExpression */) {
                    if (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */) {
                        return narrowTypeByAssertion(narrowTypeByAssertion(type, node.left), node.right);
                    }
                    if (node.operatorToken.kind === 56 /* BarBarToken */) {
                        return getUnionType([narrowTypeByAssertion(type, node.left), narrowTypeByAssertion(type, node.right)]);
                    }
                }
                return narrowType(type, node, /*assumeTrue*/ true);
            }
            function getTypeAtFlowCall(flow) {
                var signature = getEffectsSignature(flow.node);
                if (signature) {
                    var predicate = getTypePredicateOfSignature(signature);
                    if (predicate && (predicate.kind === 2 /* AssertsThis */ || predicate.kind === 3 /* AssertsIdentifier */)) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        var type = finalizeEvolvingArrayType(getTypeFromFlowType(flowType));
                        var narrowedType = predicate.type ? narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) :
                            predicate.kind === 3 /* AssertsIdentifier */ && predicate.parameterIndex >= 0 && predicate.parameterIndex < flow.node.arguments.length ? narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]) :
                                type;
                        return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType));
                    }
                    if (getReturnTypeOfSignature(signature).flags & 131072 /* Never */) {
                        return unreachableNeverType;
                    }
                }
                return undefined;
            }
            function getTypeAtFlowArrayMutation(flow) {
                if (declaredType === autoType || declaredType === autoArrayType) {
                    var node = flow.node;
                    var expr = node.kind === 196 /* CallExpression */ ?
                        node.expression.expression :
                        node.left.expression;
                    if (isMatchingReference(reference, getReferenceCandidate(expr))) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        var type = getTypeFromFlowType(flowType);
                        if (ts.getObjectFlags(type) & 256 /* EvolvingArray */) {
                            var evolvedType_1 = type;
                            if (node.kind === 196 /* CallExpression */) {
                                for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) {
                                    var arg = _a[_i];
                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, arg);
                                }
                            }
                            else {
                                // We must get the context free expression type so as to not recur in an uncached fashion on the LHS (which causes exponential blowup in compile time)
                                var indexType = getContextFreeTypeOfExpression(node.left.argumentExpression);
                                if (isTypeAssignableToKind(indexType, 296 /* NumberLike */)) {
                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right);
                                }
                            }
                            return evolvedType_1 === type ? flowType : createFlowType(evolvedType_1, isIncomplete(flowType));
                        }
                        return flowType;
                    }
                }
                return undefined;
            }
            function getTypeAtFlowCondition(flow) {
                var flowType = getTypeAtFlowNode(flow.antecedent);
                var type = getTypeFromFlowType(flowType);
                if (type.flags & 131072 /* Never */) {
                    return flowType;
                }
                // If we have an antecedent type (meaning we're reachable in some way), we first
                // attempt to narrow the antecedent type. If that produces the never type, and if
                // the antecedent type is incomplete (i.e. a transient type in a loop), then we
                // take the type guard as an indication that control *could* reach here once we
                // have the complete type. We proceed by switching to the silent never type which
                // doesn't report errors when operators are applied to it. Note that this is the
                // *only* place a silent never type is ever generated.
                var assumeTrue = (flow.flags & 32 /* TrueCondition */) !== 0;
                var nonEvolvingType = finalizeEvolvingArrayType(type);
                var narrowedType = narrowType(nonEvolvingType, flow.node, assumeTrue);
                if (narrowedType === nonEvolvingType) {
                    return flowType;
                }
                var incomplete = isIncomplete(flowType);
                var resultType = incomplete && narrowedType.flags & 131072 /* Never */ ? silentNeverType : narrowedType;
                return createFlowType(resultType, incomplete);
            }
            function getTypeAtSwitchClause(flow) {
                var expr = flow.switchStatement.expression;
                var flowType = getTypeAtFlowNode(flow.antecedent);
                var type = getTypeFromFlowType(flowType);
                if (isMatchingReference(reference, expr)) {
                    type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
                }
                else if (expr.kind === 204 /* TypeOfExpression */ && isMatchingReference(reference, expr.expression)) {
                    type = narrowBySwitchOnTypeOf(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
                }
                else {
                    if (strictNullChecks) {
                        if (optionalChainContainsReference(expr, reference)) {
                            type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, function (t) { return !(t.flags & (32768 /* Undefined */ | 131072 /* Never */)); });
                        }
                        else if (expr.kind === 204 /* TypeOfExpression */ && optionalChainContainsReference(expr.expression, reference)) {
                            type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, function (t) { return !(t.flags & 131072 /* Never */ || t.flags & 128 /* StringLiteral */ && t.value === "undefined"); });
                        }
                    }
                    if (isMatchingReferenceDiscriminant(expr, type)) {
                        type = narrowTypeByDiscriminant(type, expr, function (t) { return narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd); });
                    }
                }
                return createFlowType(type, isIncomplete(flowType));
            }
            function getTypeAtFlowBranchLabel(flow) {
                var antecedentTypes = [];
                var subtypeReduction = false;
                var seenIncomplete = false;
                var bypassFlow;
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    if (!bypassFlow && antecedent.flags & 128 /* SwitchClause */ && antecedent.clauseStart === antecedent.clauseEnd) {
                        // The antecedent is the bypass branch of a potentially exhaustive switch statement.
                        bypassFlow = antecedent;
                        continue;
                    }
                    var flowType = getTypeAtFlowNode(antecedent);
                    var type = getTypeFromFlowType(flowType);
                    // If the type at a particular antecedent path is the declared type and the
                    // reference is known to always be assigned (i.e. when declared and initial types
                    // are the same), there is no reason to process more antecedents since the only
                    // possible outcome is subtypes that will be removed in the final union type anyway.
                    if (type === declaredType && declaredType === initialType) {
                        return type;
                    }
                    ts.pushIfUnique(antecedentTypes, type);
                    // If an antecedent type is not a subset of the declared type, we need to perform
                    // subtype reduction. This happens when a "foreign" type is injected into the control
                    // flow using the instanceof operator or a user defined type predicate.
                    if (!isTypeSubsetOf(type, declaredType)) {
                        subtypeReduction = true;
                    }
                    if (isIncomplete(flowType)) {
                        seenIncomplete = true;
                    }
                }
                if (bypassFlow) {
                    var flowType = getTypeAtFlowNode(bypassFlow);
                    var type = getTypeFromFlowType(flowType);
                    // If the bypass flow contributes a type we haven't seen yet and the switch statement
                    // isn't exhaustive, process the bypass flow type. Since exhaustiveness checks increase
                    // the risk of circularities, we only want to perform them when they make a difference.
                    if (!ts.contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) {
                        if (type === declaredType && declaredType === initialType) {
                            return type;
                        }
                        antecedentTypes.push(type);
                        if (!isTypeSubsetOf(type, declaredType)) {
                            subtypeReduction = true;
                        }
                        if (isIncomplete(flowType)) {
                            seenIncomplete = true;
                        }
                    }
                }
                return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? 2 /* Subtype */ : 1 /* Literal */), seenIncomplete);
            }
            function getTypeAtFlowLoopLabel(flow) {
                // If we have previously computed the control flow type for the reference at
                // this flow loop junction, return the cached type.
                var id = getFlowNodeId(flow);
                var cache = flowLoopCaches[id] || (flowLoopCaches[id] = ts.createMap());
                var key = getOrSetCacheKey();
                if (!key) {
                    // No cache key is generated when binding patterns are in unnarrowable situations
                    return declaredType;
                }
                var cached = cache.get(key);
                if (cached) {
                    return cached;
                }
                // If this flow loop junction and reference are already being processed, return
                // the union of the types computed for each branch so far, marked as incomplete.
                // It is possible to see an empty array in cases where loops are nested and the
                // back edge of the outer loop reaches an inner loop that is already being analyzed.
                // In such cases we restart the analysis of the inner loop, which will then see
                // a non-empty in-process array for the outer loop and eventually terminate because
                // the first antecedent of a loop junction is always the non-looping control flow
                // path that leads to the top.
                for (var i = flowLoopStart; i < flowLoopCount; i++) {
                    if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) {
                        return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], 1 /* Literal */), /*incomplete*/ true);
                    }
                }
                // Add the flow loop junction and reference to the in-process stack and analyze
                // each antecedent code path.
                var antecedentTypes = [];
                var subtypeReduction = false;
                var firstAntecedentType;
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    var flowType = void 0;
                    if (!firstAntecedentType) {
                        // The first antecedent of a loop junction is always the non-looping control
                        // flow path that leads to the top.
                        flowType = firstAntecedentType = getTypeAtFlowNode(antecedent);
                    }
                    else {
                        // All but the first antecedent are the looping control flow paths that lead
                        // back to the loop junction. We track these on the flow loop stack.
                        flowLoopNodes[flowLoopCount] = flow;
                        flowLoopKeys[flowLoopCount] = key;
                        flowLoopTypes[flowLoopCount] = antecedentTypes;
                        flowLoopCount++;
                        var saveFlowTypeCache = flowTypeCache;
                        flowTypeCache = undefined;
                        flowType = getTypeAtFlowNode(antecedent);
                        flowTypeCache = saveFlowTypeCache;
                        flowLoopCount--;
                        // If we see a value appear in the cache it is a sign that control flow analysis
                        // was restarted and completed by checkExpressionCached. We can simply pick up
                        // the resulting type and bail out.
                        var cached_1 = cache.get(key);
                        if (cached_1) {
                            return cached_1;
                        }
                    }
                    var type = getTypeFromFlowType(flowType);
                    ts.pushIfUnique(antecedentTypes, type);
                    // If an antecedent type is not a subset of the declared type, we need to perform
                    // subtype reduction. This happens when a "foreign" type is injected into the control
                    // flow using the instanceof operator or a user defined type predicate.
                    if (!isTypeSubsetOf(type, declaredType)) {
                        subtypeReduction = true;
                    }
                    // If the type at a particular antecedent path is the declared type there is no
                    // reason to process more antecedents since the only possible outcome is subtypes
                    // that will be removed in the final union type anyway.
                    if (type === declaredType) {
                        break;
                    }
                }
                // The result is incomplete if the first antecedent (the non-looping control flow path)
                // is incomplete.
                var result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? 2 /* Subtype */ : 1 /* Literal */);
                if (isIncomplete(firstAntecedentType)) {
                    return createFlowType(result, /*incomplete*/ true);
                }
                cache.set(key, result);
                return result;
            }
            function isMatchingReferenceDiscriminant(expr, computedType) {
                if (!(computedType.flags & 1048576 /* Union */) || !ts.isAccessExpression(expr)) {
                    return false;
                }
                var name = getAccessedPropertyName(expr);
                if (name === undefined) {
                    return false;
                }
                return isMatchingReference(reference, expr.expression) && isDiscriminantProperty(computedType, name);
            }
            function narrowTypeByDiscriminant(type, access, narrowType) {
                var propName = getAccessedPropertyName(access);
                if (propName === undefined) {
                    return type;
                }
                var propType = getTypeOfPropertyOfType(type, propName);
                if (!propType) {
                    return type;
                }
                var narrowedPropType = narrowType(propType);
                return filterType(type, function (t) {
                    var discriminantType = getTypeOfPropertyOrIndexSignature(t, propName);
                    return !(discriminantType.flags & 131072 /* Never */) && isTypeComparableTo(discriminantType, narrowedPropType);
                });
            }
            function narrowTypeByTruthiness(type, expr, assumeTrue) {
                if (isMatchingReference(reference, expr)) {
                    return getTypeWithFacts(type, assumeTrue ? 4194304 /* Truthy */ : 8388608 /* Falsy */);
                }
                if (strictNullChecks && assumeTrue && optionalChainContainsReference(expr, reference)) {
                    type = getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */);
                }
                if (isMatchingReferenceDiscriminant(expr, declaredType)) {
                    return narrowTypeByDiscriminant(type, expr, function (t) { return getTypeWithFacts(t, assumeTrue ? 4194304 /* Truthy */ : 8388608 /* Falsy */); });
                }
                return type;
            }
            function isTypePresencePossible(type, propName, assumeTrue) {
                if (getIndexInfoOfType(type, 0 /* String */)) {
                    return true;
                }
                var prop = getPropertyOfType(type, propName);
                if (prop) {
                    return prop.flags & 16777216 /* Optional */ ? true : assumeTrue;
                }
                return !assumeTrue;
            }
            function narrowByInKeyword(type, literal, assumeTrue) {
                if (type.flags & (1048576 /* Union */ | 524288 /* Object */) || isThisTypeParameter(type)) {
                    var propName_1 = ts.escapeLeadingUnderscores(literal.text);
                    return filterType(type, function (t) { return isTypePresencePossible(t, propName_1, assumeTrue); });
                }
                return type;
            }
            function narrowTypeByBinaryExpression(type, expr, assumeTrue) {
                switch (expr.operatorToken.kind) {
                    case 62 /* EqualsToken */:
                        return narrowTypeByTruthiness(narrowType(type, expr.right, assumeTrue), expr.left, assumeTrue);
                    case 34 /* EqualsEqualsToken */:
                    case 35 /* ExclamationEqualsToken */:
                    case 36 /* EqualsEqualsEqualsToken */:
                    case 37 /* ExclamationEqualsEqualsToken */:
                        var operator_1 = expr.operatorToken.kind;
                        var left_1 = getReferenceCandidate(expr.left);
                        var right_1 = getReferenceCandidate(expr.right);
                        if (left_1.kind === 204 /* TypeOfExpression */ && ts.isStringLiteralLike(right_1)) {
                            return narrowTypeByTypeof(type, left_1, operator_1, right_1, assumeTrue);
                        }
                        if (right_1.kind === 204 /* TypeOfExpression */ && ts.isStringLiteralLike(left_1)) {
                            return narrowTypeByTypeof(type, right_1, operator_1, left_1, assumeTrue);
                        }
                        if (isMatchingReference(reference, left_1)) {
                            return narrowTypeByEquality(type, operator_1, right_1, assumeTrue);
                        }
                        if (isMatchingReference(reference, right_1)) {
                            return narrowTypeByEquality(type, operator_1, left_1, assumeTrue);
                        }
                        if (strictNullChecks) {
                            if (optionalChainContainsReference(left_1, reference)) {
                                type = narrowTypeByOptionalChainContainment(type, operator_1, right_1, assumeTrue);
                            }
                            else if (optionalChainContainsReference(right_1, reference)) {
                                type = narrowTypeByOptionalChainContainment(type, operator_1, left_1, assumeTrue);
                            }
                        }
                        if (isMatchingReferenceDiscriminant(left_1, declaredType)) {
                            return narrowTypeByDiscriminant(type, left_1, function (t) { return narrowTypeByEquality(t, operator_1, right_1, assumeTrue); });
                        }
                        if (isMatchingReferenceDiscriminant(right_1, declaredType)) {
                            return narrowTypeByDiscriminant(type, right_1, function (t) { return narrowTypeByEquality(t, operator_1, left_1, assumeTrue); });
                        }
                        if (isMatchingConstructorReference(left_1)) {
                            return narrowTypeByConstructor(type, operator_1, right_1, assumeTrue);
                        }
                        if (isMatchingConstructorReference(right_1)) {
                            return narrowTypeByConstructor(type, operator_1, left_1, assumeTrue);
                        }
                        break;
                    case 98 /* InstanceOfKeyword */:
                        return narrowTypeByInstanceof(type, expr, assumeTrue);
                    case 97 /* InKeyword */:
                        var target = getReferenceCandidate(expr.right);
                        if (ts.isStringLiteralLike(expr.left) && isMatchingReference(reference, target)) {
                            return narrowByInKeyword(type, expr.left, assumeTrue);
                        }
                        break;
                    case 27 /* CommaToken */:
                        return narrowType(type, expr.right, assumeTrue);
                }
                return type;
            }
            function narrowTypeByOptionalChainContainment(type, operator, value, assumeTrue) {
                // We are in a branch of obj?.foo === value (or any one of the other equality operators). We narrow obj as follows:
                // When operator is === and type of value excludes undefined, null and undefined is removed from type of obj in true branch.
                // When operator is !== and type of value excludes undefined, null and undefined is removed from type of obj in false branch.
                // When operator is == and type of value excludes null and undefined, null and undefined is removed from type of obj in true branch.
                // When operator is != and type of value excludes null and undefined, null and undefined is removed from type of obj in false branch.
                // When operator is === and type of value is undefined, null and undefined is removed from type of obj in false branch.
                // When operator is !== and type of value is undefined, null and undefined is removed from type of obj in true branch.
                // When operator is == and type of value is null or undefined, null and undefined is removed from type of obj in false branch.
                // When operator is != and type of value is null or undefined, null and undefined is removed from type of obj in true branch.
                var equalsOperator = operator === 34 /* EqualsEqualsToken */ || operator === 36 /* EqualsEqualsEqualsToken */;
                var nullableFlags = operator === 34 /* EqualsEqualsToken */ || operator === 35 /* ExclamationEqualsToken */ ? 98304 /* Nullable */ : 32768 /* Undefined */;
                var valueType = getTypeOfExpression(value);
                // Note that we include any and unknown in the exclusion test because their domain includes null and undefined.
                var removeNullable = equalsOperator !== assumeTrue && everyType(valueType, function (t) { return !!(t.flags & nullableFlags); }) ||
                    equalsOperator === assumeTrue && everyType(valueType, function (t) { return !(t.flags & (3 /* AnyOrUnknown */ | nullableFlags)); });
                return removeNullable ? getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */) : type;
            }
            function narrowTypeByEquality(type, operator, value, assumeTrue) {
                if (type.flags & 1 /* Any */) {
                    return type;
                }
                if (operator === 35 /* ExclamationEqualsToken */ || operator === 37 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                var valueType = getTypeOfExpression(value);
                if ((type.flags & 2 /* Unknown */) && assumeTrue && (operator === 36 /* EqualsEqualsEqualsToken */ || operator === 37 /* ExclamationEqualsEqualsToken */)) {
                    if (valueType.flags & (131068 /* Primitive */ | 67108864 /* NonPrimitive */)) {
                        return valueType;
                    }
                    if (valueType.flags & 524288 /* Object */) {
                        return nonPrimitiveType;
                    }
                    return type;
                }
                if (valueType.flags & 98304 /* Nullable */) {
                    if (!strictNullChecks) {
                        return type;
                    }
                    var doubleEquals = operator === 34 /* EqualsEqualsToken */ || operator === 35 /* ExclamationEqualsToken */;
                    var facts = doubleEquals ?
                        assumeTrue ? 262144 /* EQUndefinedOrNull */ : 2097152 /* NEUndefinedOrNull */ :
                        valueType.flags & 65536 /* Null */ ?
                            assumeTrue ? 131072 /* EQNull */ : 1048576 /* NENull */ :
                            assumeTrue ? 65536 /* EQUndefined */ : 524288 /* NEUndefined */;
                    return getTypeWithFacts(type, facts);
                }
                if (type.flags & 67637251 /* NotUnionOrUnit */) {
                    return type;
                }
                if (assumeTrue) {
                    var filterFn = operator === 34 /* EqualsEqualsToken */ ?
                        (function (t) { return areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType); }) :
                        function (t) { return areTypesComparable(t, valueType); };
                    var narrowedType = filterType(type, filterFn);
                    return narrowedType.flags & 131072 /* Never */ ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
                }
                if (isUnitType(valueType)) {
                    var regularType_1 = getRegularTypeOfLiteralType(valueType);
                    return filterType(type, function (t) { return isUnitType(t) ? !areTypesComparable(t, valueType) : getRegularTypeOfLiteralType(t) !== regularType_1; });
                }
                return type;
            }
            function narrowTypeByTypeof(type, typeOfExpr, operator, literal, assumeTrue) {
                // We have '==', '!=', '===', or !==' operator with 'typeof xxx' and string literal operands
                if (operator === 35 /* ExclamationEqualsToken */ || operator === 37 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                var target = getReferenceCandidate(typeOfExpr.expression);
                if (!isMatchingReference(reference, target)) {
                    if (strictNullChecks && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) {
                        return getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */);
                    }
                    return type;
                }
                if (type.flags & 1 /* Any */ && literal.text === "function") {
                    return type;
                }
                if (assumeTrue && type.flags & 2 /* Unknown */ && literal.text === "object") {
                    // The pattern x && typeof x === 'object', where x is of type unknown, narrows x to type object. We don't
                    // need to check for the reverse typeof x === 'object' && x since that already narrows correctly.
                    if (typeOfExpr.parent.parent.kind === 209 /* BinaryExpression */) {
                        var expr = typeOfExpr.parent.parent;
                        if (expr.operatorToken.kind === 55 /* AmpersandAmpersandToken */ && expr.right === typeOfExpr.parent && containsTruthyCheck(reference, expr.left)) {
                            return nonPrimitiveType;
                        }
                    }
                    return getUnionType([nonPrimitiveType, nullType]);
                }
                var facts = assumeTrue ?
                    typeofEQFacts.get(literal.text) || 128 /* TypeofEQHostObject */ :
                    typeofNEFacts.get(literal.text) || 32768 /* TypeofNEHostObject */;
                return getTypeWithFacts(assumeTrue ? mapType(type, narrowTypeForTypeof) : type, facts);
                function narrowTypeForTypeof(type) {
                    // We narrow a non-union type to an exact primitive type if the non-union type
                    // is a supertype of that primitive type. For example, type 'any' can be narrowed
                    // to one of the primitive types.
                    var targetType = literal.text === "function" ? globalFunctionType : typeofTypesByName.get(literal.text);
                    if (targetType) {
                        if (isTypeSubtypeOf(type, targetType)) {
                            return type;
                        }
                        if (isTypeSubtypeOf(targetType, type)) {
                            return targetType;
                        }
                        if (type.flags & 63176704 /* Instantiable */) {
                            var constraint = getBaseConstraintOfType(type) || anyType;
                            if (isTypeSubtypeOf(targetType, constraint)) {
                                return getIntersectionType([type, targetType]);
                            }
                        }
                    }
                    return type;
                }
            }
            function narrowTypeBySwitchOptionalChainContainment(type, switchStatement, clauseStart, clauseEnd, clauseCheck) {
                var everyClauseChecks = clauseStart !== clauseEnd && ts.every(getSwitchClauseTypes(switchStatement).slice(clauseStart, clauseEnd), clauseCheck);
                return everyClauseChecks ? getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */) : type;
            }
            function narrowTypeBySwitchOnDiscriminant(type, switchStatement, clauseStart, clauseEnd) {
                // We only narrow if all case expressions specify
                // values with unit types, except for the case where
                // `type` is unknown. In this instance we map object
                // types to the nonPrimitive type and narrow with that.
                var switchTypes = getSwitchClauseTypes(switchStatement);
                if (!switchTypes.length) {
                    return type;
                }
                var clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
                var hasDefaultClause = clauseStart === clauseEnd || ts.contains(clauseTypes, neverType);
                if ((type.flags & 2 /* Unknown */) && !hasDefaultClause) {
                    var groundClauseTypes = void 0;
                    for (var i = 0; i < clauseTypes.length; i += 1) {
                        var t = clauseTypes[i];
                        if (t.flags & (131068 /* Primitive */ | 67108864 /* NonPrimitive */)) {
                            if (groundClauseTypes !== undefined) {
                                groundClauseTypes.push(t);
                            }
                        }
                        else if (t.flags & 524288 /* Object */) {
                            if (groundClauseTypes === undefined) {
                                groundClauseTypes = clauseTypes.slice(0, i);
                            }
                            groundClauseTypes.push(nonPrimitiveType);
                        }
                        else {
                            return type;
                        }
                    }
                    return getUnionType(groundClauseTypes === undefined ? clauseTypes : groundClauseTypes);
                }
                var discriminantType = getUnionType(clauseTypes);
                var caseType = discriminantType.flags & 131072 /* Never */ ? neverType :
                    replacePrimitivesWithLiterals(filterType(type, function (t) { return areTypesComparable(discriminantType, t); }), discriminantType);
                if (!hasDefaultClause) {
                    return caseType;
                }
                var defaultType = filterType(type, function (t) { return !(isUnitType(t) && ts.contains(switchTypes, getRegularTypeOfLiteralType(t))); });
                return caseType.flags & 131072 /* Never */ ? defaultType : getUnionType([caseType, defaultType]);
            }
            function getImpliedTypeFromTypeofCase(type, text) {
                switch (text) {
                    case "function":
                        return type.flags & 1 /* Any */ ? type : globalFunctionType;
                    case "object":
                        return type.flags & 2 /* Unknown */ ? getUnionType([nonPrimitiveType, nullType]) : type;
                    default:
                        return typeofTypesByName.get(text) || type;
                }
            }
            function narrowTypeForTypeofSwitch(candidate) {
                return function (type) {
                    if (isTypeSubtypeOf(candidate, type)) {
                        return candidate;
                    }
                    if (type.flags & 63176704 /* Instantiable */) {
                        var constraint = getBaseConstraintOfType(type) || anyType;
                        if (isTypeSubtypeOf(candidate, constraint)) {
                            return getIntersectionType([type, candidate]);
                        }
                    }
                    return type;
                };
            }
            function narrowBySwitchOnTypeOf(type, switchStatement, clauseStart, clauseEnd) {
                var switchWitnesses = getSwitchClauseTypeOfWitnesses(switchStatement, /*retainDefault*/ true);
                if (!switchWitnesses.length) {
                    return type;
                }
                //  Equal start and end denotes implicit fallthrough; undefined marks explicit default clause
                var defaultCaseLocation = ts.findIndex(switchWitnesses, function (elem) { return elem === undefined; });
                var hasDefaultClause = clauseStart === clauseEnd || (defaultCaseLocation >= clauseStart && defaultCaseLocation < clauseEnd);
                var clauseWitnesses;
                var switchFacts;
                if (defaultCaseLocation > -1) {
                    // We no longer need the undefined denoting an
                    // explicit default case. Remove the undefined and
                    // fix-up clauseStart and clauseEnd.  This means
                    // that we don't have to worry about undefined
                    // in the witness array.
                    var witnesses = switchWitnesses.filter(function (witness) { return witness !== undefined; });
                    // The adjusted clause start and end after removing the `default` statement.
                    var fixedClauseStart = defaultCaseLocation < clauseStart ? clauseStart - 1 : clauseStart;
                    var fixedClauseEnd = defaultCaseLocation < clauseEnd ? clauseEnd - 1 : clauseEnd;
                    clauseWitnesses = witnesses.slice(fixedClauseStart, fixedClauseEnd);
                    switchFacts = getFactsFromTypeofSwitch(fixedClauseStart, fixedClauseEnd, witnesses, hasDefaultClause);
                }
                else {
                    clauseWitnesses = switchWitnesses.slice(clauseStart, clauseEnd);
                    switchFacts = getFactsFromTypeofSwitch(clauseStart, clauseEnd, switchWitnesses, hasDefaultClause);
                }
                if (hasDefaultClause) {
                    return filterType(type, function (t) { return (getTypeFacts(t) & switchFacts) === switchFacts; });
                }
                /*
                  The implied type is the raw type suggested by a
                  value being caught in this clause.

                  When the clause contains a default case we ignore
                  the implied type and try to narrow using any facts
                  we can learn: see `switchFacts`.

                  Example:
                  switch (typeof x) {
                      case 'number':
                      case 'string': break;
                      default: break;
                      case 'number':
                      case 'boolean': break
                  }

                  In the first clause (case `number` and `string`) the
                  implied type is number | string.

                  In the default clause we de not compute an implied type.

                  In the third clause (case `number` and `boolean`)
                  the naive implied type is number | boolean, however
                  we use the type facts to narrow the implied type to
                  boolean. We know that number cannot be selected
                  because it is caught in the first clause.
                */
                var impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(function (text) { return getImpliedTypeFromTypeofCase(type, text); })), switchFacts);
                if (impliedType.flags & 1048576 /* Union */) {
                    impliedType = getAssignmentReducedType(impliedType, getBaseConstraintOrType(type));
                }
                return getTypeWithFacts(mapType(type, narrowTypeForTypeofSwitch(impliedType)), switchFacts);
            }
            function isMatchingConstructorReference(expr) {
                return (ts.isPropertyAccessExpression(expr) && ts.idText(expr.name) === "constructor" ||
                    ts.isElementAccessExpression(expr) && ts.isStringLiteralLike(expr.argumentExpression) && expr.argumentExpression.text === "constructor") &&
                    isMatchingReference(reference, expr.expression);
            }
            function narrowTypeByConstructor(type, operator, identifier, assumeTrue) {
                // Do not narrow when checking inequality.
                if (assumeTrue ? (operator !== 34 /* EqualsEqualsToken */ && operator !== 36 /* EqualsEqualsEqualsToken */) : (operator !== 35 /* ExclamationEqualsToken */ && operator !== 37 /* ExclamationEqualsEqualsToken */)) {
                    return type;
                }
                // Get the type of the constructor identifier expression, if it is not a function then do not narrow.
                var identifierType = getTypeOfExpression(identifier);
                if (!isFunctionType(identifierType) && !isConstructorType(identifierType)) {
                    return type;
                }
                // Get the prototype property of the type identifier so we can find out its type.
                var prototypeProperty = getPropertyOfType(identifierType, "prototype");
                if (!prototypeProperty) {
                    return type;
                }
                // Get the type of the prototype, if it is undefined, or the global `Object` or `Function` types then do not narrow.
                var prototypeType = getTypeOfSymbol(prototypeProperty);
                var candidate = !isTypeAny(prototypeType) ? prototypeType : undefined;
                if (!candidate || candidate === globalObjectType || candidate === globalFunctionType) {
                    return type;
                }
                // If the type that is being narrowed is `any` then just return the `candidate` type since every type is a subtype of `any`.
                if (isTypeAny(type)) {
                    return candidate;
                }
                // Filter out types that are not considered to be "constructed by" the `candidate` type.
                return filterType(type, function (t) { return isConstructedBy(t, candidate); });
                function isConstructedBy(source, target) {
                    // If either the source or target type are a class type then we need to check that they are the same exact type.
                    // This is because you may have a class `A` that defines some set of properties, and another class `B`
                    // that defines the same set of properties as class `A`, in that case they are structurally the same
                    // type, but when you do something like `instanceOfA.constructor === B` it will return false.
                    if (source.flags & 524288 /* Object */ && ts.getObjectFlags(source) & 1 /* Class */ ||
                        target.flags & 524288 /* Object */ && ts.getObjectFlags(target) & 1 /* Class */) {
                        return source.symbol === target.symbol;
                    }
                    // For all other types just check that the `source` type is a subtype of the `target` type.
                    return isTypeSubtypeOf(source, target);
                }
            }
            function narrowTypeByInstanceof(type, expr, assumeTrue) {
                var left = getReferenceCandidate(expr.left);
                if (!isMatchingReference(reference, left)) {
                    if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) {
                        return getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */);
                    }
                    return type;
                }
                // Check that right operand is a function type with a prototype property
                var rightType = getTypeOfExpression(expr.right);
                if (!isTypeDerivedFrom(rightType, globalFunctionType)) {
                    return type;
                }
                var targetType;
                var prototypeProperty = getPropertyOfType(rightType, "prototype");
                if (prototypeProperty) {
                    // Target type is type of the prototype property
                    var prototypePropertyType = getTypeOfSymbol(prototypeProperty);
                    if (!isTypeAny(prototypePropertyType)) {
                        targetType = prototypePropertyType;
                    }
                }
                // Don't narrow from 'any' if the target type is exactly 'Object' or 'Function'
                if (isTypeAny(type) && (targetType === globalObjectType || targetType === globalFunctionType)) {
                    return type;
                }
                if (!targetType) {
                    var constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */);
                    targetType = constructSignatures.length ?
                        getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })) :
                        emptyObjectType;
                }
                return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom);
            }
            function getNarrowedType(type, candidate, assumeTrue, isRelated) {
                if (!assumeTrue) {
                    return filterType(type, function (t) { return !isRelated(t, candidate); });
                }
                // If the current type is a union type, remove all constituents that couldn't be instances of
                // the candidate type. If one or more constituents remain, return a union of those.
                if (type.flags & 1048576 /* Union */) {
                    var assignableType = filterType(type, function (t) { return isRelated(t, candidate); });
                    if (!(assignableType.flags & 131072 /* Never */)) {
                        return assignableType;
                    }
                }
                // If the candidate type is a subtype of the target type, narrow to the candidate type.
                // Otherwise, if the target type is assignable to the candidate type, keep the target type.
                // Otherwise, if the candidate type is assignable to the target type, narrow to the candidate
                // type. Otherwise, the types are completely unrelated, so narrow to an intersection of the
                // two types.
                return isTypeSubtypeOf(candidate, type) ? candidate :
                    isTypeAssignableTo(type, candidate) ? type :
                        isTypeAssignableTo(candidate, type) ? candidate :
                            getIntersectionType([type, candidate]);
            }
            function narrowTypeByCallExpression(type, callExpression, assumeTrue) {
                if (hasMatchingArgument(callExpression, reference)) {
                    var signature = assumeTrue || !ts.isCallChain(callExpression) ? getEffectsSignature(callExpression) : undefined;
                    var predicate = signature && getTypePredicateOfSignature(signature);
                    if (predicate && (predicate.kind === 0 /* This */ || predicate.kind === 1 /* Identifier */)) {
                        return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue);
                    }
                }
                return type;
            }
            function narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue) {
                // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function'
                if (predicate.type && !(isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType))) {
                    var predicateArgument = getTypePredicateArgument(predicate, callExpression);
                    if (predicateArgument) {
                        if (isMatchingReference(reference, predicateArgument)) {
                            return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
                        }
                        if (strictNullChecks && assumeTrue && optionalChainContainsReference(predicateArgument, reference) &&
                            !(getTypeFacts(predicate.type) & 65536 /* EQUndefined */)) {
                            type = getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */);
                        }
                        if (isMatchingReferenceDiscriminant(predicateArgument, declaredType)) {
                            return narrowTypeByDiscriminant(type, predicateArgument, function (t) { return getNarrowedType(t, predicate.type, assumeTrue, isTypeSubtypeOf); });
                        }
                    }
                }
                return type;
            }
            // Narrow the given type based on the given expression having the assumed boolean value. The returned type
            // will be a subtype or the same type as the argument.
            function narrowType(type, expr, assumeTrue) {
                // for `a?.b`, we emulate a synthetic `a !== null && a !== undefined` condition for `a`
                if (ts.isExpressionOfOptionalChainRoot(expr) ||
                    ts.isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === 60 /* QuestionQuestionToken */ && expr.parent.left === expr) {
                    return narrowTypeByOptionality(type, expr, assumeTrue);
                }
                switch (expr.kind) {
                    case 75 /* Identifier */:
                    case 104 /* ThisKeyword */:
                    case 102 /* SuperKeyword */:
                    case 194 /* PropertyAccessExpression */:
                    case 195 /* ElementAccessExpression */:
                        return narrowTypeByTruthiness(type, expr, assumeTrue);
                    case 196 /* CallExpression */:
                        return narrowTypeByCallExpression(type, expr, assumeTrue);
                    case 200 /* ParenthesizedExpression */:
                        return narrowType(type, expr.expression, assumeTrue);
                    case 209 /* BinaryExpression */:
                        return narrowTypeByBinaryExpression(type, expr, assumeTrue);
                    case 207 /* PrefixUnaryExpression */:
                        if (expr.operator === 53 /* ExclamationToken */) {
                            return narrowType(type, expr.operand, !assumeTrue);
                        }
                        break;
                }
                return type;
            }
            function narrowTypeByOptionality(type, expr, assumePresent) {
                if (isMatchingReference(reference, expr)) {
                    return getTypeWithFacts(type, assumePresent ? 2097152 /* NEUndefinedOrNull */ : 262144 /* EQUndefinedOrNull */);
                }
                if (isMatchingReferenceDiscriminant(expr, declaredType)) {
                    return narrowTypeByDiscriminant(type, expr, function (t) { return getTypeWithFacts(t, assumePresent ? 2097152 /* NEUndefinedOrNull */ : 262144 /* EQUndefinedOrNull */); });
                }
                return type;
            }
        }
        function getTypeOfSymbolAtLocation(symbol, location) {
            symbol = symbol.exportSymbol || symbol;
            // If we have an identifier or a property access at the given location, if the location is
            // an dotted name expression, and if the location is not an assignment target, obtain the type
            // of the expression (which will reflect control flow analysis). If the expression indeed
            // resolved to the given symbol, return the narrowed type.
            if (location.kind === 75 /* Identifier */) {
                if (ts.isRightSideOfQualifiedNameOrPropertyAccess(location)) {
                    location = location.parent;
                }
                if (ts.isExpressionNode(location) && !ts.isAssignmentTarget(location)) {
                    var type = getTypeOfExpression(location);
                    if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
                        return type;
                    }
                }
            }
            // The location isn't a reference to the given symbol, meaning we're being asked
            // a hypothetical question of what type the symbol would have if there was a reference
            // to it at the given location. Since we have no control flow information for the
            // hypothetical reference (control flow information is created and attached by the
            // binder), we simply return the declared type of the symbol.
            return getTypeOfSymbol(symbol);
        }
        function getControlFlowContainer(node) {
            return ts.findAncestor(node.parent, function (node) {
                return ts.isFunctionLike(node) && !ts.getImmediatelyInvokedFunctionExpression(node) ||
                    node.kind === 250 /* ModuleBlock */ ||
                    node.kind === 290 /* SourceFile */ ||
                    node.kind === 159 /* PropertyDeclaration */;
            });
        }
        // Check if a parameter is assigned anywhere within its declaring function.
        function isParameterAssigned(symbol) {
            var func = ts.getRootDeclaration(symbol.valueDeclaration).parent;
            var links = getNodeLinks(func);
            if (!(links.flags & 8388608 /* AssignmentsMarked */)) {
                links.flags |= 8388608 /* AssignmentsMarked */;
                if (!hasParentWithAssignmentsMarked(func)) {
                    markParameterAssignments(func);
                }
            }
            return symbol.isAssigned || false;
        }
        function hasParentWithAssignmentsMarked(node) {
            return !!ts.findAncestor(node.parent, function (node) { return ts.isFunctionLike(node) && !!(getNodeLinks(node).flags & 8388608 /* AssignmentsMarked */); });
        }
        function markParameterAssignments(node) {
            if (node.kind === 75 /* Identifier */) {
                if (ts.isAssignmentTarget(node)) {
                    var symbol = getResolvedSymbol(node);
                    if (symbol.valueDeclaration && ts.getRootDeclaration(symbol.valueDeclaration).kind === 156 /* Parameter */) {
                        symbol.isAssigned = true;
                    }
                }
            }
            else {
                ts.forEachChild(node, markParameterAssignments);
            }
        }
        function isConstVariable(symbol) {
            return symbol.flags & 3 /* Variable */ && (getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */) !== 0 && getTypeOfSymbol(symbol) !== autoArrayType;
        }
        /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
        function removeOptionalityFromDeclaredType(declaredType, declaration) {
            if (pushTypeResolution(declaration.symbol, 2 /* DeclaredType */)) {
                var annotationIncludesUndefined = strictNullChecks &&
                    declaration.kind === 156 /* Parameter */ &&
                    declaration.initializer &&
                    getFalsyFlags(declaredType) & 32768 /* Undefined */ &&
                    !(getFalsyFlags(checkExpression(declaration.initializer)) & 32768 /* Undefined */);
                popTypeResolution();
                return annotationIncludesUndefined ? getTypeWithFacts(declaredType, 524288 /* NEUndefined */) : declaredType;
            }
            else {
                reportCircularityError(declaration.symbol);
                return declaredType;
            }
        }
        function isConstraintPosition(node) {
            var parent = node.parent;
            return parent.kind === 194 /* PropertyAccessExpression */ ||
                parent.kind === 196 /* CallExpression */ && parent.expression === node ||
                parent.kind === 195 /* ElementAccessExpression */ && parent.expression === node ||
                parent.kind === 191 /* BindingElement */ && parent.name === node && !!parent.initializer;
        }
        function typeHasNullableConstraint(type) {
            return type.flags & 58982400 /* InstantiableNonPrimitive */ && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, 98304 /* Nullable */);
        }
        function getConstraintForLocation(type, node) {
            // When a node is the left hand expression of a property access, element access, or call expression,
            // and the type of the node includes type variables with constraints that are nullable, we fetch the
            // apparent type of the node *before* performing control flow analysis such that narrowings apply to
            // the constraint type.
            if (type && isConstraintPosition(node) && forEachType(type, typeHasNullableConstraint)) {
                return mapType(getWidenedType(type), getBaseConstraintOrType);
            }
            return type;
        }
        function isExportOrExportExpression(location) {
            return !!ts.findAncestor(location, function (e) { return e.parent && ts.isExportAssignment(e.parent) && e.parent.expression === e && ts.isEntityNameExpression(e); });
        }
        function markAliasReferenced(symbol, location) {
            if (isNonLocalAlias(symbol, /*excludes*/ 111551 /* Value */) && !isInTypeQuery(location) && !getTypeOnlyAliasDeclaration(symbol)) {
                if (compilerOptions.preserveConstEnums && isExportOrExportExpression(location) || !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
                    markAliasSymbolAsReferenced(symbol);
                }
                else {
                    markConstEnumAliasAsReferenced(symbol);
                }
            }
        }
        function checkIdentifier(node) {
            var symbol = getResolvedSymbol(node);
            if (symbol === unknownSymbol) {
                return errorType;
            }
            // As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects.
            // Although in down-level emit of arrow function, we emit it using function expression which means that
            // arguments objects will be bound to the inner object; emitting arrow function natively in ES6, arguments objects
            // will be bound to non-arrow function that contain this arrow function. This results in inconsistent behavior.
            // To avoid that we will give an error to users if they use arguments objects in arrow function so that they
            // can explicitly bound arguments objects
            if (symbol === argumentsSymbol) {
                var container = ts.getContainingFunction(node);
                if (languageVersion < 2 /* ES2015 */) {
                    if (container.kind === 202 /* ArrowFunction */) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
                    }
                    else if (ts.hasModifier(container, 256 /* Async */)) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method);
                    }
                }
                getNodeLinks(container).flags |= 8192 /* CaptureArguments */;
                return getTypeOfSymbol(symbol);
            }
            // We should only mark aliases as referenced if there isn't a local value declaration
            // for the symbol. Also, don't mark any property access expression LHS - checkPropertyAccessExpression will handle that
            if (!(node.parent && ts.isPropertyAccessExpression(node.parent) && node.parent.expression === node)) {
                markAliasReferenced(symbol, node);
            }
            var localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
            var declaration = localOrExportSymbol.valueDeclaration;
            if (localOrExportSymbol.flags & 32 /* Class */) {
                // Due to the emit for class decorators, any reference to the class from inside of the class body
                // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                // behavior of class names in ES6.
                if (declaration.kind === 245 /* ClassDeclaration */
                    && ts.nodeIsDecorated(declaration)) {
                    var container = ts.getContainingClass(node);
                    while (container !== undefined) {
                        if (container === declaration && container.name !== node) {
                            getNodeLinks(declaration).flags |= 16777216 /* ClassWithConstructorReference */;
                            getNodeLinks(node).flags |= 33554432 /* ConstructorReferenceInClass */;
                            break;
                        }
                        container = ts.getContainingClass(container);
                    }
                }
                else if (declaration.kind === 214 /* ClassExpression */) {
                    // When we emit a class expression with static members that contain a reference
                    // to the constructor in the initializer, we will need to substitute that
                    // binding with an alias as the class name is not in scope.
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    while (container.kind !== 290 /* SourceFile */) {
                        if (container.parent === declaration) {
                            if (container.kind === 159 /* PropertyDeclaration */ && ts.hasModifier(container, 32 /* Static */)) {
                                getNodeLinks(declaration).flags |= 16777216 /* ClassWithConstructorReference */;
                                getNodeLinks(node).flags |= 33554432 /* ConstructorReferenceInClass */;
                            }
                            break;
                        }
                        container = ts.getThisContainer(container, /*includeArrowFunctions*/ false);
                    }
                }
            }
            checkNestedBlockScopedBinding(node, symbol);
            var type = getConstraintForLocation(getTypeOfSymbol(localOrExportSymbol), node);
            var assignmentKind = ts.getAssignmentTargetKind(node);
            if (assignmentKind) {
                if (!(localOrExportSymbol.flags & 3 /* Variable */) &&
                    !(ts.isInJSFile(node) && localOrExportSymbol.flags & 512 /* ValueModule */)) {
                    error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable, symbolToString(symbol));
                    return errorType;
                }
                if (isReadonlySymbol(localOrExportSymbol)) {
                    if (localOrExportSymbol.flags & 3 /* Variable */) {
                        error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant, symbolToString(symbol));
                    }
                    else {
                        error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(symbol));
                    }
                    return errorType;
                }
            }
            var isAlias = localOrExportSymbol.flags & 2097152 /* Alias */;
            // We only narrow variables and parameters occurring in a non-assignment position. For all other
            // entities we simply return the declared type.
            if (localOrExportSymbol.flags & 3 /* Variable */) {
                if (assignmentKind === 1 /* Definite */) {
                    return type;
                }
            }
            else if (isAlias) {
                declaration = ts.find(symbol.declarations, isSomeImportDeclaration);
            }
            else {
                return type;
            }
            if (!declaration) {
                return type;
            }
            // The declaration container is the innermost function that encloses the declaration of the variable
            // or parameter. The flow container is the innermost function starting with which we analyze the control
            // flow graph to determine the control flow based type.
            var isParameter = ts.getRootDeclaration(declaration).kind === 156 /* Parameter */;
            var declarationContainer = getControlFlowContainer(declaration);
            var flowContainer = getControlFlowContainer(node);
            var isOuterVariable = flowContainer !== declarationContainer;
            var isSpreadDestructuringAssignmentTarget = node.parent && node.parent.parent && ts.isSpreadAssignment(node.parent) && isDestructuringAssignmentTarget(node.parent.parent);
            var isModuleExports = symbol.flags & 134217728 /* ModuleExports */;
            // When the control flow originates in a function expression or arrow function and we are referencing
            // a const variable or parameter from an outer function, we extend the origin of the control flow
            // analysis to include the immediately enclosing function.
            while (flowContainer !== declarationContainer && (flowContainer.kind === 201 /* FunctionExpression */ ||
                flowContainer.kind === 202 /* ArrowFunction */ || ts.isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
                (isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
                flowContainer = getControlFlowContainer(flowContainer);
            }
            // We only look for uninitialized variables in strict null checking mode, and only when we can analyze
            // the entire control flow graph from the variable's declaration (i.e. when the flow container and
            // declaration container are the same).
            var assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || ts.isBindingElement(declaration) ||
                type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (3 /* AnyOrUnknown */ | 16384 /* Void */)) !== 0 ||
                    isInTypeQuery(node) || node.parent.kind === 263 /* ExportSpecifier */) ||
                node.parent.kind === 218 /* NonNullExpression */ ||
                declaration.kind === 242 /* VariableDeclaration */ && declaration.exclamationToken ||
                declaration.flags & 8388608 /* Ambient */;
            var initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration) : type) :
                type === autoType || type === autoArrayType ? undefinedType :
                    getOptionalType(type);
            var flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);
            // A variable is considered uninitialized when it is possible to analyze the entire control flow graph
            // from declaration to use, and when the variable's declared type doesn't include undefined but the
            // control flow based type does include undefined.
            if (!isEvolvingArrayOperationTarget(node) && (type === autoType || type === autoArrayType)) {
                if (flowType === autoType || flowType === autoArrayType) {
                    if (noImplicitAny) {
                        error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType));
                        error(node, ts.Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType));
                    }
                    return convertAutoToAny(flowType);
                }
            }
            else if (!assumeInitialized && !(getFalsyFlags(type) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) {
                error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
                // Return the declared type to reduce follow-on errors
                return type;
            }
            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
        }
        function isInsideFunction(node, threshold) {
            return !!ts.findAncestor(node, function (n) { return n === threshold ? "quit" : ts.isFunctionLike(n); });
        }
        function getPartOfForStatementContainingNode(node, container) {
            return ts.findAncestor(node, function (n) { return n === container ? "quit" : n === container.initializer || n === container.condition || n === container.incrementor || n === container.statement; });
        }
        function checkNestedBlockScopedBinding(node, symbol) {
            if (languageVersion >= 2 /* ES2015 */ ||
                (symbol.flags & (2 /* BlockScopedVariable */ | 32 /* Class */)) === 0 ||
                ts.isSourceFile(symbol.valueDeclaration) ||
                symbol.valueDeclaration.parent.kind === 280 /* CatchClause */) {
                return;
            }
            // 1. walk from the use site up to the declaration and check
            // if there is anything function like between declaration and use-site (is binding/class is captured in function).
            // 2. walk from the declaration up to the boundary of lexical environment and check
            // if there is an iteration statement in between declaration and boundary (is binding/class declared inside iteration statement)
            var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
            var usedInFunction = isInsideFunction(node.parent, container);
            var current = container;
            var containedInIterationStatement = false;
            while (current && !ts.nodeStartsNewLexicalEnvironment(current)) {
                if (ts.isIterationStatement(current, /*lookInLabeledStatements*/ false)) {
                    containedInIterationStatement = true;
                    break;
                }
                current = current.parent;
            }
            if (containedInIterationStatement) {
                if (usedInFunction) {
                    // mark iteration statement as containing block-scoped binding captured in some function
                    var capturesBlockScopeBindingInLoopBody = true;
                    if (ts.isForStatement(container)) {
                        var varDeclList = ts.getAncestor(symbol.valueDeclaration, 243 /* VariableDeclarationList */);
                        if (varDeclList && varDeclList.parent === container) {
                            var part = getPartOfForStatementContainingNode(node.parent, container);
                            if (part) {
                                var links = getNodeLinks(part);
                                links.flags |= 131072 /* ContainsCapturedBlockScopeBinding */;
                                var capturedBindings = links.capturedBlockScopeBindings || (links.capturedBlockScopeBindings = []);
                                ts.pushIfUnique(capturedBindings, symbol);
                                if (part === container.initializer) {
                                    capturesBlockScopeBindingInLoopBody = false; // Initializer is outside of loop body
                                }
                            }
                        }
                    }
                    if (capturesBlockScopeBindingInLoopBody) {
                        getNodeLinks(current).flags |= 65536 /* LoopWithCapturedBlockScopedBinding */;
                    }
                }
                // mark variables that are declared in loop initializer and reassigned inside the body of ForStatement.
                // if body of ForStatement will be converted to function then we'll need a extra machinery to propagate reassigned values back.
                if (ts.isForStatement(container)) {
                    var varDeclList = ts.getAncestor(symbol.valueDeclaration, 243 /* VariableDeclarationList */);
                    if (varDeclList && varDeclList.parent === container && isAssignedInBodyOfForStatement(node, container)) {
                        getNodeLinks(symbol.valueDeclaration).flags |= 4194304 /* NeedsLoopOutParameter */;
                    }
                }
                // set 'declared inside loop' bit on the block-scoped binding
                getNodeLinks(symbol.valueDeclaration).flags |= 524288 /* BlockScopedBindingInLoop */;
            }
            if (usedInFunction) {
                getNodeLinks(symbol.valueDeclaration).flags |= 262144 /* CapturedBlockScopedBinding */;
            }
        }
        function isBindingCapturedByNode(node, decl) {
            var links = getNodeLinks(node);
            return !!links && ts.contains(links.capturedBlockScopeBindings, getSymbolOfNode(decl));
        }
        function isAssignedInBodyOfForStatement(node, container) {
            // skip parenthesized nodes
            var current = node;
            while (current.parent.kind === 200 /* ParenthesizedExpression */) {
                current = current.parent;
            }
            // check if node is used as LHS in some assignment expression
            var isAssigned = false;
            if (ts.isAssignmentTarget(current)) {
                isAssigned = true;
            }
            else if ((current.parent.kind === 207 /* PrefixUnaryExpression */ || current.parent.kind === 208 /* PostfixUnaryExpression */)) {
                var expr = current.parent;
                isAssigned = expr.operator === 45 /* PlusPlusToken */ || expr.operator === 46 /* MinusMinusToken */;
            }
            if (!isAssigned) {
                return false;
            }
            // at this point we know that node is the target of assignment
            // now check that modification happens inside the statement part of the ForStatement
            return !!ts.findAncestor(current, function (n) { return n === container ? "quit" : n === container.statement; });
        }
        function captureLexicalThis(node, container) {
            getNodeLinks(node).flags |= 2 /* LexicalThis */;
            if (container.kind === 159 /* PropertyDeclaration */ || container.kind === 162 /* Constructor */) {
                var classNode = container.parent;
                getNodeLinks(classNode).flags |= 4 /* CaptureThis */;
            }
            else {
                getNodeLinks(container).flags |= 4 /* CaptureThis */;
            }
        }
        function findFirstSuperCall(n) {
            if (ts.isSuperCall(n)) {
                return n;
            }
            else if (ts.isFunctionLike(n)) {
                return undefined;
            }
            return ts.forEachChild(n, findFirstSuperCall);
        }
        /**
         * Return a cached result if super-statement is already found.
         * Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor
         *
         * @param constructor constructor-function to look for super statement
         */
        function getSuperCallInConstructor(constructor) {
            var links = getNodeLinks(constructor);
            // Only trying to find super-call if we haven't yet tried to find one.  Once we try, we will record the result
            if (links.hasSuperCall === undefined) {
                links.superCall = findFirstSuperCall(constructor.body);
                links.hasSuperCall = links.superCall ? true : false;
            }
            return links.superCall;
        }
        /**
         * Check if the given class-declaration extends null then return true.
         * Otherwise, return false
         * @param classDecl a class declaration to check if it extends null
         */
        function classDeclarationExtendsNull(classDecl) {
            var classSymbol = getSymbolOfNode(classDecl);
            var classInstanceType = getDeclaredTypeOfSymbol(classSymbol);
            var baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
            return baseConstructorType === nullWideningType;
        }
        function checkThisBeforeSuper(node, container, diagnosticMessage) {
            var containingClassDecl = container.parent;
            var baseTypeNode = ts.getClassExtendsHeritageElement(containingClassDecl);
            // If a containing class does not have extends clause or the class extends null
            // skip checking whether super statement is called before "this" accessing.
            if (baseTypeNode && !classDeclarationExtendsNull(containingClassDecl)) {
                var superCall = getSuperCallInConstructor(container);
                // We should give an error in the following cases:
                //      - No super-call
                //      - "this" is accessing before super-call.
                //          i.e super(this)
                //              this.x; super();
                // We want to make sure that super-call is done before accessing "this" so that
                // "this" is not accessed as a parameter of the super-call.
                if (!superCall || superCall.end > node.pos) {
                    // In ES6, super inside constructor of class-declaration has to precede "this" accessing
                    error(node, diagnosticMessage);
                }
            }
        }
        function checkThisExpression(node) {
            // Stop at the first arrow function so that we can
            // tell whether 'this' needs to be captured.
            var container = ts.getThisContainer(node, /* includeArrowFunctions */ true);
            var capturedByArrowFunction = false;
            if (container.kind === 162 /* Constructor */) {
                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
            }
            // Now skip arrow functions to get the "real" owner of 'this'.
            if (container.kind === 202 /* ArrowFunction */) {
                container = ts.getThisContainer(container, /* includeArrowFunctions */ false);
                capturedByArrowFunction = true;
            }
            switch (container.kind) {
                case 249 /* ModuleDeclaration */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body);
                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    break;
                case 248 /* EnumDeclaration */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_current_location);
                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    break;
                case 162 /* Constructor */:
                    if (isInConstructorArgumentInitializer(node, container)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    }
                    break;
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    if (ts.hasModifier(container, 32 /* Static */) && !(compilerOptions.target === 99 /* ESNext */ && compilerOptions.useDefineForClassFields)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    }
                    break;
                case 154 /* ComputedPropertyName */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_computed_property_name);
                    break;
            }
            // When targeting es6, mark that we'll need to capture `this` in its lexically bound scope.
            if (capturedByArrowFunction && languageVersion < 2 /* ES2015 */) {
                captureLexicalThis(node, container);
            }
            var type = tryGetThisTypeAt(node, /*includeGlobalThis*/ true, container);
            if (noImplicitThis) {
                var globalThisType_1 = getTypeOfSymbol(globalThisSymbol);
                if (type === globalThisType_1 && capturedByArrowFunction) {
                    error(node, ts.Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this);
                }
                else if (!type) {
                    // With noImplicitThis, functions may not reference 'this' if it has type 'any'
                    var diag = error(node, ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
                    if (!ts.isSourceFile(container)) {
                        var outsideThis = tryGetThisTypeAt(container);
                        if (outsideThis && outsideThis !== globalThisType_1) {
                            ts.addRelatedInfo(diag, ts.createDiagnosticForNode(container, ts.Diagnostics.An_outer_value_of_this_is_shadowed_by_this_container));
                        }
                    }
                }
            }
            return type || anyType;
        }
        function tryGetThisTypeAt(node, includeGlobalThis, container) {
            if (includeGlobalThis === void 0) { includeGlobalThis = true; }
            if (container === void 0) { container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); }
            var isInJS = ts.isInJSFile(node);
            if (ts.isFunctionLike(container) &&
                (!isInParameterInitializerBeforeContainingFunction(node) || ts.getThisParameter(container))) {
                // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
                // If this is a function in a JS file, it might be a class method.
                var className = getClassNameFromPrototypeMethod(container);
                if (isInJS && className) {
                    var classSymbol = checkExpression(className).symbol;
                    if (classSymbol && classSymbol.members && (classSymbol.flags & 16 /* Function */)) {
                        var classType = getDeclaredTypeOfSymbol(classSymbol).thisType;
                        if (classType) {
                            return getFlowTypeOfReference(node, classType);
                        }
                    }
                }
                // Check if it's a constructor definition, can be either a variable decl or function decl
                // i.e.
                //   * /** @constructor */ function [name]() { ... }
                //   * /** @constructor */ var x = function() { ... }
                else if (isInJS &&
                    (container.kind === 201 /* FunctionExpression */ || container.kind === 244 /* FunctionDeclaration */) &&
                    ts.getJSDocClassTag(container)) {
                    var classType = getDeclaredTypeOfSymbol(getMergedSymbol(container.symbol)).thisType;
                    return getFlowTypeOfReference(node, classType);
                }
                var thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
                if (thisType) {
                    return getFlowTypeOfReference(node, thisType);
                }
            }
            if (ts.isClassLike(container.parent)) {
                var symbol = getSymbolOfNode(container.parent);
                var type = ts.hasModifier(container, 32 /* Static */) ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType;
                return getFlowTypeOfReference(node, type);
            }
            if (isInJS) {
                var type = getTypeForThisExpressionFromJSDoc(container);
                if (type && type !== errorType) {
                    return getFlowTypeOfReference(node, type);
                }
            }
            if (ts.isSourceFile(container)) {
                // look up in the source file's locals or exports
                if (container.commonJsModuleIndicator) {
                    var fileSymbol = getSymbolOfNode(container);
                    return fileSymbol && getTypeOfSymbol(fileSymbol);
                }
                else if (includeGlobalThis) {
                    return getTypeOfSymbol(globalThisSymbol);
                }
            }
        }
        function getExplicitThisType(node) {
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            if (ts.isFunctionLike(container)) {
                var signature = getSignatureFromDeclaration(container);
                if (signature.thisParameter) {
                    return getExplicitTypeOfSymbol(signature.thisParameter);
                }
            }
            if (ts.isClassLike(container.parent)) {
                var symbol = getSymbolOfNode(container.parent);
                return ts.hasModifier(container, 32 /* Static */) ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType;
            }
        }
        function getClassNameFromPrototypeMethod(container) {
            // Check if it's the RHS of a x.prototype.y = function [name]() { .... }
            if (container.kind === 201 /* FunctionExpression */ &&
                ts.isBinaryExpression(container.parent) &&
                ts.getAssignmentDeclarationKind(container.parent) === 3 /* PrototypeProperty */) {
                // Get the 'x' of 'x.prototype.y = container'
                return container.parent // x.prototype.y = container
                    .left // x.prototype.y
                    .expression // x.prototype
                    .expression; // x
            }
            // x.prototype = { method() { } }
            else if (container.kind === 161 /* MethodDeclaration */ &&
                container.parent.kind === 193 /* ObjectLiteralExpression */ &&
                ts.isBinaryExpression(container.parent.parent) &&
                ts.getAssignmentDeclarationKind(container.parent.parent) === 6 /* Prototype */) {
                return container.parent.parent.left.expression;
            }
            // x.prototype = { method: function() { } }
            else if (container.kind === 201 /* FunctionExpression */ &&
                container.parent.kind === 281 /* PropertyAssignment */ &&
                container.parent.parent.kind === 193 /* ObjectLiteralExpression */ &&
                ts.isBinaryExpression(container.parent.parent.parent) &&
                ts.getAssignmentDeclarationKind(container.parent.parent.parent) === 6 /* Prototype */) {
                return container.parent.parent.parent.left.expression;
            }
            // Object.defineProperty(x, "method", { value: function() { } });
            // Object.defineProperty(x, "method", { set: (x: () => void) => void });
            // Object.defineProperty(x, "method", { get: () => function() { }) });
            else if (container.kind === 201 /* FunctionExpression */ &&
                ts.isPropertyAssignment(container.parent) &&
                ts.isIdentifier(container.parent.name) &&
                (container.parent.name.escapedText === "value" || container.parent.name.escapedText === "get" || container.parent.name.escapedText === "set") &&
                ts.isObjectLiteralExpression(container.parent.parent) &&
                ts.isCallExpression(container.parent.parent.parent) &&
                container.parent.parent.parent.arguments[2] === container.parent.parent &&
                ts.getAssignmentDeclarationKind(container.parent.parent.parent) === 9 /* ObjectDefinePrototypeProperty */) {
                return container.parent.parent.parent.arguments[0].expression;
            }
            // Object.defineProperty(x, "method", { value() { } });
            // Object.defineProperty(x, "method", { set(x: () => void) {} });
            // Object.defineProperty(x, "method", { get() { return () => {} } });
            else if (ts.isMethodDeclaration(container) &&
                ts.isIdentifier(container.name) &&
                (container.name.escapedText === "value" || container.name.escapedText === "get" || container.name.escapedText === "set") &&
                ts.isObjectLiteralExpression(container.parent) &&
                ts.isCallExpression(container.parent.parent) &&
                container.parent.parent.arguments[2] === container.parent &&
                ts.getAssignmentDeclarationKind(container.parent.parent) === 9 /* ObjectDefinePrototypeProperty */) {
                return container.parent.parent.arguments[0].expression;
            }
        }
        function getTypeForThisExpressionFromJSDoc(node) {
            var jsdocType = ts.getJSDocType(node);
            if (jsdocType && jsdocType.kind === 300 /* JSDocFunctionType */) {
                var jsDocFunctionType = jsdocType;
                if (jsDocFunctionType.parameters.length > 0 &&
                    jsDocFunctionType.parameters[0].name &&
                    jsDocFunctionType.parameters[0].name.escapedText === "this" /* This */) {
                    return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type);
                }
            }
            var thisTag = ts.getJSDocThisTag(node);
            if (thisTag && thisTag.typeExpression) {
                return getTypeFromTypeNode(thisTag.typeExpression);
            }
        }
        function isInConstructorArgumentInitializer(node, constructorDecl) {
            return !!ts.findAncestor(node, function (n) { return ts.isFunctionLikeDeclaration(n) ? "quit" : n.kind === 156 /* Parameter */ && n.parent === constructorDecl; });
        }
        function checkSuperExpression(node) {
            var isCallExpression = node.parent.kind === 196 /* CallExpression */ && node.parent.expression === node;
            var container = ts.getSuperContainer(node, /*stopOnFunctions*/ true);
            var needToCaptureLexicalThis = false;
            // adjust the container reference in case if super is used inside arrow functions with arbitrarily deep nesting
            if (!isCallExpression) {
                while (container && container.kind === 202 /* ArrowFunction */) {
                    container = ts.getSuperContainer(container, /*stopOnFunctions*/ true);
                    needToCaptureLexicalThis = languageVersion < 2 /* ES2015 */;
                }
            }
            var canUseSuperExpression = isLegalUsageOfSuperExpression(container);
            var nodeCheckFlag = 0;
            if (!canUseSuperExpression) {
                // issue more specific error if super is used in computed property name
                // class A { foo() { return "1" }}
                // class B {
                //     [super.foo()]() {}
                // }
                var current = ts.findAncestor(node, function (n) { return n === container ? "quit" : n.kind === 154 /* ComputedPropertyName */; });
                if (current && current.kind === 154 /* ComputedPropertyName */) {
                    error(node, ts.Diagnostics.super_cannot_be_referenced_in_a_computed_property_name);
                }
                else if (isCallExpression) {
                    error(node, ts.Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors);
                }
                else if (!container || !container.parent || !(ts.isClassLike(container.parent) || container.parent.kind === 193 /* ObjectLiteralExpression */)) {
                    error(node, ts.Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions);
                }
                else {
                    error(node, ts.Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class);
                }
                return errorType;
            }
            if (!isCallExpression && container.kind === 162 /* Constructor */) {
                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
            }
            if (ts.hasModifier(container, 32 /* Static */) || isCallExpression) {
                nodeCheckFlag = 512 /* SuperStatic */;
            }
            else {
                nodeCheckFlag = 256 /* SuperInstance */;
            }
            getNodeLinks(node).flags |= nodeCheckFlag;
            // Due to how we emit async functions, we need to specialize the emit for an async method that contains a `super` reference.
            // This is due to the fact that we emit the body of an async function inside of a generator function. As generator
            // functions cannot reference `super`, we emit a helper inside of the method body, but outside of the generator. This helper
            // uses an arrow function, which is permitted to reference `super`.
            //
            // There are two primary ways we can access `super` from within an async method. The first is getting the value of a property
            // or indexed access on super, either as part of a right-hand-side expression or call expression. The second is when setting the value
            // of a property or indexed access, either as part of an assignment expression or destructuring assignment.
            //
            // The simplest case is reading a value, in which case we will emit something like the following:
            //
            //  // ts
            //  ...
            //  async asyncMethod() {
            //    let x = await super.asyncMethod();
            //    return x;
            //  }
            //  ...
            //
            //  // js
            //  ...
            //  asyncMethod() {
            //      const _super = Object.create(null, {
            //        asyncMethod: { get: () => super.asyncMethod },
            //      });
            //      return __awaiter(this, arguments, Promise, function *() {
            //          let x = yield _super.asyncMethod.call(this);
            //          return x;
            //      });
            //  }
            //  ...
            //
            // The more complex case is when we wish to assign a value, especially as part of a destructuring assignment. As both cases
            // are legal in ES6, but also likely less frequent, we only emit setters if there is an assignment:
            //
            //  // ts
            //  ...
            //  async asyncMethod(ar: Promise<any[]>) {
            //      [super.a, super.b] = await ar;
            //  }
            //  ...
            //
            //  // js
            //  ...
            //  asyncMethod(ar) {
            //      const _super = Object.create(null, {
            //        a: { get: () => super.a, set: (v) => super.a = v },
            //        b: { get: () => super.b, set: (v) => super.b = v }
            //      };
            //      return __awaiter(this, arguments, Promise, function *() {
            //          [_super.a, _super.b] = yield ar;
            //      });
            //  }
            //  ...
            //
            // Creating an object that has getter and setters instead of just an accessor function is required for destructuring assignments
            // as a call expression cannot be used as the target of a destructuring assignment while a property access can.
            //
            // For element access expressions (`super[x]`), we emit a generic helper that forwards the element access in both situations.
            if (container.kind === 161 /* MethodDeclaration */ && ts.hasModifier(container, 256 /* Async */)) {
                if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) {
                    getNodeLinks(container).flags |= 4096 /* AsyncMethodWithSuperBinding */;
                }
                else {
                    getNodeLinks(container).flags |= 2048 /* AsyncMethodWithSuper */;
                }
            }
            if (needToCaptureLexicalThis) {
                // call expressions are allowed only in constructors so they should always capture correct 'this'
                // super property access expressions can also appear in arrow functions -
                // in this case they should also use correct lexical this
                captureLexicalThis(node.parent, container);
            }
            if (container.parent.kind === 193 /* ObjectLiteralExpression */) {
                if (languageVersion < 2 /* ES2015 */) {
                    error(node, ts.Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher);
                    return errorType;
                }
                else {
                    // for object literal assume that type of 'super' is 'any'
                    return anyType;
                }
            }
            // at this point the only legal case for parent is ClassLikeDeclaration
            var classLikeDeclaration = container.parent;
            if (!ts.getClassExtendsHeritageElement(classLikeDeclaration)) {
                error(node, ts.Diagnostics.super_can_only_be_referenced_in_a_derived_class);
                return errorType;
            }
            var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration));
            var baseClassType = classType && getBaseTypes(classType)[0];
            if (!baseClassType) {
                return errorType;
            }
            if (container.kind === 162 /* Constructor */ && isInConstructorArgumentInitializer(node, container)) {
                // issue custom error message for super property access in constructor arguments (to be aligned with old compiler)
                error(node, ts.Diagnostics.super_cannot_be_referenced_in_constructor_arguments);
                return errorType;
            }
            return nodeCheckFlag === 512 /* SuperStatic */
                ? getBaseConstructorTypeOfClass(classType)
                : getTypeWithThisArgument(baseClassType, classType.thisType);
            function isLegalUsageOfSuperExpression(container) {
                if (!container) {
                    return false;
                }
                if (isCallExpression) {
                    // TS 1.0 SPEC (April 2014): 4.8.1
                    // Super calls are only permitted in constructors of derived classes
                    return container.kind === 162 /* Constructor */;
                }
                else {
                    // TS 1.0 SPEC (April 2014)
                    // 'super' property access is allowed
                    // - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance
                    // - In a static member function or static member accessor
                    // topmost container must be something that is directly nested in the class declaration\object literal expression
                    if (ts.isClassLike(container.parent) || container.parent.kind === 193 /* ObjectLiteralExpression */) {
                        if (ts.hasModifier(container, 32 /* Static */)) {
                            return container.kind === 161 /* MethodDeclaration */ ||
                                container.kind === 160 /* MethodSignature */ ||
                                container.kind === 163 /* GetAccessor */ ||
                                container.kind === 164 /* SetAccessor */;
                        }
                        else {
                            return container.kind === 161 /* MethodDeclaration */ ||
                                container.kind === 160 /* MethodSignature */ ||
                                container.kind === 163 /* GetAccessor */ ||
                                container.kind === 164 /* SetAccessor */ ||
                                container.kind === 159 /* PropertyDeclaration */ ||
                                container.kind === 158 /* PropertySignature */ ||
                                container.kind === 162 /* Constructor */;
                        }
                    }
                }
                return false;
            }
        }
        function getContainingObjectLiteral(func) {
            return (func.kind === 161 /* MethodDeclaration */ ||
                func.kind === 163 /* GetAccessor */ ||
                func.kind === 164 /* SetAccessor */) && func.parent.kind === 193 /* ObjectLiteralExpression */ ? func.parent :
                func.kind === 201 /* FunctionExpression */ && func.parent.kind === 281 /* PropertyAssignment */ ? func.parent.parent :
                    undefined;
        }
        function getThisTypeArgument(type) {
            return ts.getObjectFlags(type) & 4 /* Reference */ && type.target === globalThisType ? getTypeArguments(type)[0] : undefined;
        }
        function getThisTypeFromContextualType(type) {
            return mapType(type, function (t) {
                return t.flags & 2097152 /* Intersection */ ? ts.forEach(t.types, getThisTypeArgument) : getThisTypeArgument(t);
            });
        }
        function getContextualThisParameterType(func) {
            if (func.kind === 202 /* ArrowFunction */) {
                return undefined;
            }
            if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
                var contextualSignature = getContextualSignature(func);
                if (contextualSignature) {
                    var thisParameter = contextualSignature.thisParameter;
                    if (thisParameter) {
                        return getTypeOfSymbol(thisParameter);
                    }
                }
            }
            var inJs = ts.isInJSFile(func);
            if (noImplicitThis || inJs) {
                var containingLiteral = getContainingObjectLiteral(func);
                if (containingLiteral) {
                    // We have an object literal method. Check if the containing object literal has a contextual type
                    // that includes a ThisType<T>. If so, T is the contextual type for 'this'. We continue looking in
                    // any directly enclosing object literals.
                    var contextualType = getApparentTypeOfContextualType(containingLiteral);
                    var literal = containingLiteral;
                    var type = contextualType;
                    while (type) {
                        var thisType = getThisTypeFromContextualType(type);
                        if (thisType) {
                            return instantiateType(thisType, getMapperFromContext(getInferenceContext(containingLiteral)));
                        }
                        if (literal.parent.kind !== 281 /* PropertyAssignment */) {
                            break;
                        }
                        literal = literal.parent.parent;
                        type = getApparentTypeOfContextualType(literal);
                    }
                    // There was no contextual ThisType<T> for the containing object literal, so the contextual type
                    // for 'this' is the non-null form of the contextual type for the containing object literal or
                    // the type of the object literal itself.
                    return getWidenedType(contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral));
                }
                // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the
                // contextual type for 'this' is 'obj'.
                var parent = ts.walkUpParenthesizedExpressions(func.parent);
                if (parent.kind === 209 /* BinaryExpression */ && parent.operatorToken.kind === 62 /* EqualsToken */) {
                    var target = parent.left;
                    if (ts.isAccessExpression(target)) {
                        var expression = target.expression;
                        // Don't contextually type `this` as `exports` in `exports.Point = function(x, y) { this.x = x; this.y = y; }`
                        if (inJs && ts.isIdentifier(expression)) {
                            var sourceFile = ts.getSourceFileOfNode(parent);
                            if (sourceFile.commonJsModuleIndicator && getResolvedSymbol(expression) === sourceFile.symbol) {
                                return undefined;
                            }
                        }
                        return getWidenedType(checkExpressionCached(expression));
                    }
                }
            }
            return undefined;
        }
        // Return contextual type of parameter or undefined if no contextual type is available
        function getContextuallyTypedParameterType(parameter) {
            var func = parameter.parent;
            if (!isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
                return undefined;
            }
            var iife = ts.getImmediatelyInvokedFunctionExpression(func);
            if (iife && iife.arguments) {
                var args = getEffectiveCallArguments(iife);
                var indexOfParameter = func.parameters.indexOf(parameter);
                if (parameter.dotDotDotToken) {
                    return getSpreadArgumentType(args, indexOfParameter, args.length, anyType, /*context*/ undefined);
                }
                var links = getNodeLinks(iife);
                var cached = links.resolvedSignature;
                links.resolvedSignature = anySignature;
                var type = indexOfParameter < args.length ?
                    getWidenedLiteralType(checkExpression(args[indexOfParameter])) :
                    parameter.initializer ? undefined : undefinedWideningType;
                links.resolvedSignature = cached;
                return type;
            }
            var contextualSignature = getContextualSignature(func);
            if (contextualSignature) {
                var index = func.parameters.indexOf(parameter) - (ts.getThisParameter(func) ? 1 : 0);
                return parameter.dotDotDotToken && ts.lastOrUndefined(func.parameters) === parameter ?
                    getRestTypeAtPosition(contextualSignature, index) :
                    tryGetTypeAtPosition(contextualSignature, index);
            }
        }
        function getContextualTypeForVariableLikeDeclaration(declaration) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
            switch (declaration.kind) {
                case 156 /* Parameter */:
                    return getContextuallyTypedParameterType(declaration);
                case 191 /* BindingElement */:
                    return getContextualTypeForBindingElement(declaration);
                // By default, do nothing and return undefined - only parameters and binding elements have context implied by a parent
            }
        }
        function getContextualTypeForBindingElement(declaration) {
            var parent = declaration.parent.parent;
            var name = declaration.propertyName || declaration.name;
            var parentType = getContextualTypeForVariableLikeDeclaration(parent) ||
                parent.kind !== 191 /* BindingElement */ && parent.initializer && checkDeclarationInitializer(parent);
            if (parentType && !ts.isBindingPattern(name) && !ts.isComputedNonLiteralName(name)) {
                var nameType = getLiteralTypeFromPropertyName(name);
                if (isTypeUsableAsPropertyName(nameType)) {
                    var text = getPropertyNameFromType(nameType);
                    return getTypeOfPropertyOfType(parentType, text);
                }
            }
        }
        // In a variable, parameter or property declaration with a type annotation,
        //   the contextual type of an initializer expression is the type of the variable, parameter or property.
        // Otherwise, in a parameter declaration of a contextually typed function expression,
        //   the contextual type of an initializer expression is the contextual type of the parameter.
        // Otherwise, in a variable or parameter declaration with a binding pattern name,
        //   the contextual type of an initializer expression is the type implied by the binding pattern.
        // Otherwise, in a binding pattern inside a variable or parameter declaration,
        //   the contextual type of an initializer expression is the type annotation of the containing declaration, if present.
        function getContextualTypeForInitializerExpression(node) {
            var declaration = node.parent;
            if (ts.hasInitializer(declaration) && node === declaration.initializer) {
                var result = getContextualTypeForVariableLikeDeclaration(declaration);
                if (result) {
                    return result;
                }
                if (ts.isBindingPattern(declaration.name)) { // This is less a contextual type and more an implied shape - in some cases, this may be undesirable
                    return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
                }
            }
            return undefined;
        }
        function getContextualTypeForReturnExpression(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var functionFlags = ts.getFunctionFlags(func);
                if (functionFlags & 1 /* Generator */) { // AsyncGenerator function or Generator function
                    return undefined;
                }
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    if (functionFlags & 2 /* Async */) { // Async function
                        var contextualAwaitedType = mapType(contextualReturnType, getAwaitedTypeOfPromise);
                        return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
                    }
                    return contextualReturnType; // Regular function
                }
            }
            return undefined;
        }
        function getContextualTypeForAwaitOperand(node) {
            var contextualType = getContextualType(node);
            if (contextualType) {
                var contextualAwaitedType = getAwaitedType(contextualType);
                return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
            }
            return undefined;
        }
        function getContextualTypeForYieldOperand(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var functionFlags = ts.getFunctionFlags(func);
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    return node.asteriskToken
                        ? contextualReturnType
                        : getIterationTypeOfGeneratorFunctionReturnType(0 /* Yield */, contextualReturnType, (functionFlags & 2 /* Async */) !== 0);
                }
            }
            return undefined;
        }
        function isInParameterInitializerBeforeContainingFunction(node) {
            var inBindingInitializer = false;
            while (node.parent && !ts.isFunctionLike(node.parent)) {
                if (ts.isParameter(node.parent) && (inBindingInitializer || node.parent.initializer === node)) {
                    return true;
                }
                if (ts.isBindingElement(node.parent) && node.parent.initializer === node) {
                    inBindingInitializer = true;
                }
                node = node.parent;
            }
            return false;
        }
        function getContextualIterationType(kind, functionDecl) {
            var isAsync = !!(ts.getFunctionFlags(functionDecl) & 2 /* Async */);
            var contextualReturnType = getContextualReturnType(functionDecl);
            if (contextualReturnType) {
                return getIterationTypeOfGeneratorFunctionReturnType(kind, contextualReturnType, isAsync)
                    || undefined;
            }
            return undefined;
        }
        function getContextualReturnType(functionDecl) {
            // If the containing function has a return type annotation, is a constructor, or is a get accessor whose
            // corresponding set accessor has a type annotation, return statements in the function are contextually typed
            var returnType = getReturnTypeFromAnnotation(functionDecl);
            if (returnType) {
                return returnType;
            }
            // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
            // and that call signature is non-generic, return statements are contextually typed by the return type of the signature
            var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl);
            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                return getReturnTypeOfSignature(signature);
            }
            return undefined;
        }
        // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter.
        function getContextualTypeForArgument(callTarget, arg) {
            var args = getEffectiveCallArguments(callTarget);
            var argIndex = args.indexOf(arg); // -1 for e.g. the expression of a CallExpression, or the tag of a TaggedTemplateExpression
            return argIndex === -1 ? undefined : getContextualTypeForArgumentAtIndex(callTarget, argIndex);
        }
        function getContextualTypeForArgumentAtIndex(callTarget, argIndex) {
            // If we're already in the process of resolving the given signature, don't resolve again as
            // that could cause infinite recursion. Instead, return anySignature.
            var signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget);
            if (ts.isJsxOpeningLikeElement(callTarget) && argIndex === 0) {
                return getEffectiveFirstArgumentForJsxSignature(signature, callTarget);
            }
            return getTypeAtPosition(signature, argIndex);
        }
        function getContextualTypeForSubstitutionExpression(template, substitutionExpression) {
            if (template.parent.kind === 198 /* TaggedTemplateExpression */) {
                return getContextualTypeForArgument(template.parent, substitutionExpression);
            }
            return undefined;
        }
        function getContextualTypeForBinaryOperand(node, contextFlags) {
            var binaryExpression = node.parent;
            var left = binaryExpression.left, operatorToken = binaryExpression.operatorToken, right = binaryExpression.right;
            switch (operatorToken.kind) {
                case 62 /* EqualsToken */:
                    if (node !== right) {
                        return undefined;
                    }
                    var contextSensitive = getIsContextSensitiveAssignmentOrContextType(binaryExpression);
                    if (!contextSensitive) {
                        return undefined;
                    }
                    return contextSensitive === true ? getTypeOfExpression(left) : contextSensitive;
                case 56 /* BarBarToken */:
                case 60 /* QuestionQuestionToken */:
                    // When an || expression has a contextual type, the operands are contextually typed by that type, except
                    // when that type originates in a binding pattern, the right operand is contextually typed by the type of
                    // the left operand. When an || expression has no contextual type, the right operand is contextually typed
                    // by the type of the left operand, except for the special case of Javascript declarations of the form
                    // `namespace.prop = namespace.prop || {}`.
                    var type = getContextualType(binaryExpression, contextFlags);
                    return node === right && (type && type.pattern || !type && !ts.isDefaultedExpandoInitializer(binaryExpression)) ?
                        getTypeOfExpression(left) : type;
                case 55 /* AmpersandAmpersandToken */:
                case 27 /* CommaToken */:
                    return node === right ? getContextualType(binaryExpression, contextFlags) : undefined;
                default:
                    return undefined;
            }
        }
        // In an assignment expression, the right operand is contextually typed by the type of the left operand.
        // Don't do this for assignment declarations unless there is a type tag on the assignment, to avoid circularity from checking the right operand.
        function getIsContextSensitiveAssignmentOrContextType(binaryExpression) {
            var kind = ts.getAssignmentDeclarationKind(binaryExpression);
            switch (kind) {
                case 0 /* None */:
                    return true;
                case 5 /* Property */:
                case 1 /* ExportsProperty */:
                case 6 /* Prototype */:
                case 3 /* PrototypeProperty */:
                    // If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration.
                    // See `bindStaticPropertyAssignment` in `binder.ts`.
                    if (!binaryExpression.left.symbol) {
                        return true;
                    }
                    else {
                        var decl = binaryExpression.left.symbol.valueDeclaration;
                        if (!decl) {
                            return false;
                        }
                        var lhs = ts.cast(binaryExpression.left, ts.isAccessExpression);
                        var overallAnnotation = ts.getEffectiveTypeAnnotationNode(decl);
                        if (overallAnnotation) {
                            return getTypeFromTypeNode(overallAnnotation);
                        }
                        else if (ts.isIdentifier(lhs.expression)) {
                            var id = lhs.expression;
                            var parentSymbol = resolveName(id, id.escapedText, 111551 /* Value */, undefined, id.escapedText, /*isUse*/ true);
                            if (parentSymbol) {
                                var annotated = ts.getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration);
                                if (annotated) {
                                    var nameStr_1 = ts.getElementOrPropertyAccessName(lhs);
                                    if (nameStr_1 !== undefined) {
                                        var type = getTypeOfPropertyOfContextualType(getTypeFromTypeNode(annotated), nameStr_1);
                                        return type || false;
                                    }
                                }
                                return false;
                            }
                        }
                        return !ts.isInJSFile(decl);
                    }
                case 2 /* ModuleExports */:
                case 4 /* ThisProperty */:
                    if (!binaryExpression.symbol)
                        return true;
                    if (binaryExpression.symbol.valueDeclaration) {
                        var annotated = ts.getEffectiveTypeAnnotationNode(binaryExpression.symbol.valueDeclaration);
                        if (annotated) {
                            var type = getTypeFromTypeNode(annotated);
                            if (type) {
                                return type;
                            }
                        }
                    }
                    if (kind === 2 /* ModuleExports */)
                        return false;
                    var thisAccess = ts.cast(binaryExpression.left, ts.isAccessExpression);
                    if (!ts.isObjectLiteralMethod(ts.getThisContainer(thisAccess.expression, /*includeArrowFunctions*/ false))) {
                        return false;
                    }
                    var thisType = checkThisExpression(thisAccess.expression);
                    var nameStr = ts.getElementOrPropertyAccessName(thisAccess);
                    return nameStr !== undefined && thisType && getTypeOfPropertyOfContextualType(thisType, nameStr) || false;
                case 7 /* ObjectDefinePropertyValue */:
                case 8 /* ObjectDefinePropertyExports */:
                case 9 /* ObjectDefinePrototypeProperty */:
                    return ts.Debug.fail("Does not apply");
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function isCircularMappedProperty(symbol) {
            return !!(ts.getCheckFlags(symbol) & 262144 /* Mapped */ && !symbol.type && findResolutionCycleStartIndex(symbol, 0 /* Type */) >= 0);
        }
        function getTypeOfPropertyOfContextualType(type, name) {
            return mapType(type, function (t) {
                if (isGenericMappedType(t)) {
                    var constraint = getConstraintTypeFromMappedType(t);
                    var constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
                    var propertyNameType = getLiteralType(ts.unescapeLeadingUnderscores(name));
                    if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) {
                        return substituteIndexedMappedType(t, propertyNameType);
                    }
                }
                else if (t.flags & 3670016 /* StructuredType */) {
                    var prop = getPropertyOfType(t, name);
                    if (prop) {
                        return isCircularMappedProperty(prop) ? undefined : getTypeOfSymbol(prop);
                    }
                    if (isTupleType(t)) {
                        var restType = getRestTypeOfTupleType(t);
                        if (restType && isNumericLiteralName(name) && +name >= 0) {
                            return restType;
                        }
                    }
                    return isNumericLiteralName(name) && getIndexTypeOfContextualType(t, 1 /* Number */) ||
                        getIndexTypeOfContextualType(t, 0 /* String */);
                }
                return undefined;
            }, /*noReductions*/ true);
        }
        function getIndexTypeOfContextualType(type, kind) {
            return mapType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); }, /*noReductions*/ true);
        }
        // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of
        // the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one
        // exists. Otherwise, it is the type of the string index signature in T, if one exists.
        function getContextualTypeForObjectLiteralMethod(node, contextFlags) {
            ts.Debug.assert(ts.isObjectLiteralMethod(node));
            if (node.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            return getContextualTypeForObjectLiteralElement(node, contextFlags);
        }
        function getContextualTypeForObjectLiteralElement(element, contextFlags) {
            var objectLiteral = element.parent;
            var type = getApparentTypeOfContextualType(objectLiteral, contextFlags);
            if (type) {
                if (!hasNonBindableDynamicName(element)) {
                    // For a (non-symbol) computed property, there is no reason to look up the name
                    // in the type. It will just be "__computed", which does not appear in any
                    // SymbolTable.
                    var symbolName_3 = getSymbolOfNode(element).escapedName;
                    var propertyType = getTypeOfPropertyOfContextualType(type, symbolName_3);
                    if (propertyType) {
                        return propertyType;
                    }
                }
                return isNumericName(element.name) && getIndexTypeOfContextualType(type, 1 /* Number */) ||
                    getIndexTypeOfContextualType(type, 0 /* String */);
            }
            return undefined;
        }
        // In an array literal contextually typed by a type T, the contextual type of an element expression at index N is
        // the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature,
        // it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated
        // type of T.
        function getContextualTypeForElementExpression(arrayContextualType, index) {
            return arrayContextualType && (getTypeOfPropertyOfContextualType(arrayContextualType, "" + index)
                || getIteratedTypeOrElementType(1 /* Element */, arrayContextualType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false));
        }
        // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type.
        function getContextualTypeForConditionalOperand(node, contextFlags) {
            var conditional = node.parent;
            return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional, contextFlags) : undefined;
        }
        function getContextualTypeForChildJsxExpression(node, child) {
            var attributesType = getApparentTypeOfContextualType(node.openingElement.tagName);
            // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
            var jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
            if (!(attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "")) {
                return undefined;
            }
            var realChildren = getSemanticJsxChildren(node.children);
            var childIndex = realChildren.indexOf(child);
            var childFieldType = getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName);
            return childFieldType && (realChildren.length === 1 ? childFieldType : mapType(childFieldType, function (t) {
                if (isArrayLikeType(t)) {
                    return getIndexedAccessType(t, getLiteralType(childIndex));
                }
                else {
                    return t;
                }
            }, /*noReductions*/ true));
        }
        function getContextualTypeForJsxExpression(node) {
            var exprParent = node.parent;
            return ts.isJsxAttributeLike(exprParent)
                ? getContextualType(node)
                : ts.isJsxElement(exprParent)
                    ? getContextualTypeForChildJsxExpression(exprParent, node)
                    : undefined;
        }
        function getContextualTypeForJsxAttribute(attribute) {
            // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
            // which is a type of the parameter of the signature we are trying out.
            // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
            if (ts.isJsxAttribute(attribute)) {
                var attributesType = getApparentTypeOfContextualType(attribute.parent);
                if (!attributesType || isTypeAny(attributesType)) {
                    return undefined;
                }
                return getTypeOfPropertyOfContextualType(attributesType, attribute.name.escapedText);
            }
            else {
                return getContextualType(attribute.parent);
            }
        }
        // Return true if the given expression is possibly a discriminant value. We limit the kinds of
        // expressions we check to those that don't depend on their contextual type in order not to cause
        // recursive (and possibly infinite) invocations of getContextualType.
        function isPossiblyDiscriminantValue(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 100 /* NullKeyword */:
                case 75 /* Identifier */:
                case 146 /* UndefinedKeyword */:
                    return true;
                case 194 /* PropertyAccessExpression */:
                case 200 /* ParenthesizedExpression */:
                    return isPossiblyDiscriminantValue(node.expression);
                case 276 /* JsxExpression */:
                    return !node.expression || isPossiblyDiscriminantValue(node.expression);
            }
            return false;
        }
        function discriminateContextualTypeByObjectMembers(node, contextualType) {
            return discriminateTypeByDiscriminableItems(contextualType, ts.map(ts.filter(node.properties, function (p) { return !!p.symbol && p.kind === 281 /* PropertyAssignment */ && isPossiblyDiscriminantValue(p.initializer) && isDiscriminantProperty(contextualType, p.symbol.escapedName); }), function (prop) { return [function () { return checkExpression(prop.initializer); }, prop.symbol.escapedName]; }), isTypeAssignableTo, contextualType);
        }
        function discriminateContextualTypeByJSXAttributes(node, contextualType) {
            return discriminateTypeByDiscriminableItems(contextualType, ts.map(ts.filter(node.properties, function (p) { return !!p.symbol && p.kind === 273 /* JsxAttribute */ && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer)); }), function (prop) { return [!prop.initializer ? (function () { return trueType; }) : (function () { return checkExpression(prop.initializer); }), prop.symbol.escapedName]; }), isTypeAssignableTo, contextualType);
        }
        // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
        // be "pushed" onto a node using the contextualType property.
        function getApparentTypeOfContextualType(node, contextFlags) {
            var contextualType = ts.isObjectLiteralMethod(node) ?
                getContextualTypeForObjectLiteralMethod(node, contextFlags) :
                getContextualType(node, contextFlags);
            var instantiatedType = instantiateContextualType(contextualType, node, contextFlags);
            if (instantiatedType && !(contextFlags && contextFlags & 2 /* NoConstraints */ && instantiatedType.flags & 8650752 /* TypeVariable */)) {
                var apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true);
                if (apparentType.flags & 1048576 /* Union */) {
                    if (ts.isObjectLiteralExpression(node)) {
                        return discriminateContextualTypeByObjectMembers(node, apparentType);
                    }
                    else if (ts.isJsxAttributes(node)) {
                        return discriminateContextualTypeByJSXAttributes(node, apparentType);
                    }
                }
                return apparentType;
            }
        }
        // If the given contextual type contains instantiable types and if a mapper representing
        // return type inferences is available, instantiate those types using that mapper.
        function instantiateContextualType(contextualType, node, contextFlags) {
            if (contextualType && maybeTypeOfKind(contextualType, 63176704 /* Instantiable */)) {
                var inferenceContext = getInferenceContext(node);
                // If no inferences have been made, nothing is gained from instantiating as type parameters
                // would just be replaced with their defaults similar to the apparent type.
                if (inferenceContext && ts.some(inferenceContext.inferences, hasInferenceCandidates)) {
                    // For contextual signatures we incorporate all inferences made so far, e.g. from return
                    // types as well as arguments to the left in a function call.
                    if (contextFlags && contextFlags & 1 /* Signature */) {
                        return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
                    }
                    // For other purposes (e.g. determining whether to produce literal types) we only
                    // incorporate inferences made from the return type in a function call.
                    if (inferenceContext.returnMapper) {
                        return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
                    }
                }
            }
            return contextualType;
        }
        // This function is similar to instantiateType, except that (a) it only instantiates types that
        // are classified as instantiable (i.e. it doesn't instantiate object types), and (b) it performs
        // no reductions on instantiated union types.
        function instantiateInstantiableTypes(type, mapper) {
            if (type.flags & 63176704 /* Instantiable */) {
                return instantiateType(type, mapper);
            }
            if (type.flags & 1048576 /* Union */) {
                return getUnionType(ts.map(type.types, function (t) { return instantiateInstantiableTypes(t, mapper); }), 0 /* None */);
            }
            if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, function (t) { return instantiateInstantiableTypes(t, mapper); }));
            }
            return type;
        }
        /**
         * Whoa! Do you really want to use this function?
         *
         * Unless you're trying to get the *non-apparent* type for a
         * value-literal type or you're authoring relevant portions of this algorithm,
         * you probably meant to use 'getApparentTypeOfContextualType'.
         * Otherwise this may not be very useful.
         *
         * In cases where you *are* working on this function, you should understand
         * when it is appropriate to use 'getContextualType' and 'getApparentTypeOfContextualType'.
         *
         *   - Use 'getContextualType' when you are simply going to propagate the result to the expression.
         *   - Use 'getApparentTypeOfContextualType' when you're going to need the members of the type.
         *
         * @param node the expression whose contextual type will be returned.
         * @returns the contextual type of an expression.
         */
        function getContextualType(node, contextFlags) {
            if (node.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            if (node.contextualType) {
                return node.contextualType;
            }
            var parent = node.parent;
            switch (parent.kind) {
                case 242 /* VariableDeclaration */:
                case 156 /* Parameter */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 191 /* BindingElement */:
                    return getContextualTypeForInitializerExpression(node);
                case 202 /* ArrowFunction */:
                case 235 /* ReturnStatement */:
                    return getContextualTypeForReturnExpression(node);
                case 212 /* YieldExpression */:
                    return getContextualTypeForYieldOperand(parent);
                case 206 /* AwaitExpression */:
                    return getContextualTypeForAwaitOperand(parent);
                case 196 /* CallExpression */:
                    if (parent.expression.kind === 96 /* ImportKeyword */) {
                        return stringType;
                    }
                /* falls through */
                case 197 /* NewExpression */:
                    return getContextualTypeForArgument(parent, node);
                case 199 /* TypeAssertionExpression */:
                case 217 /* AsExpression */:
                    return ts.isConstTypeReference(parent.type) ? undefined : getTypeFromTypeNode(parent.type);
                case 209 /* BinaryExpression */:
                    return getContextualTypeForBinaryOperand(node, contextFlags);
                case 281 /* PropertyAssignment */:
                case 282 /* ShorthandPropertyAssignment */:
                    return getContextualTypeForObjectLiteralElement(parent, contextFlags);
                case 283 /* SpreadAssignment */:
                    return getApparentTypeOfContextualType(parent.parent, contextFlags);
                case 192 /* ArrayLiteralExpression */: {
                    var arrayLiteral = parent;
                    var type = getApparentTypeOfContextualType(arrayLiteral, contextFlags);
                    return getContextualTypeForElementExpression(type, ts.indexOfNode(arrayLiteral.elements, node));
                }
                case 210 /* ConditionalExpression */:
                    return getContextualTypeForConditionalOperand(node, contextFlags);
                case 221 /* TemplateSpan */:
                    ts.Debug.assert(parent.parent.kind === 211 /* TemplateExpression */);
                    return getContextualTypeForSubstitutionExpression(parent.parent, node);
                case 200 /* ParenthesizedExpression */: {
                    // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
                    var tag = ts.isInJSFile(parent) ? ts.getJSDocTypeTag(parent) : undefined;
                    return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent, contextFlags);
                }
                case 276 /* JsxExpression */:
                    return getContextualTypeForJsxExpression(parent);
                case 273 /* JsxAttribute */:
                case 275 /* JsxSpreadAttribute */:
                    return getContextualTypeForJsxAttribute(parent);
                case 268 /* JsxOpeningElement */:
                case 267 /* JsxSelfClosingElement */:
                    return getContextualJsxElementAttributesType(parent, contextFlags);
            }
            return undefined;
        }
        function getInferenceContext(node) {
            var ancestor = ts.findAncestor(node, function (n) { return !!n.inferenceContext; });
            return ancestor && ancestor.inferenceContext;
        }
        function getContextualJsxElementAttributesType(node, contextFlags) {
            if (ts.isJsxOpeningElement(node) && node.parent.contextualType && contextFlags !== 4 /* Completions */) {
                // Contextually applied type is moved from attributes up to the outer jsx attributes so when walking up from the children they get hit
                // _However_ to hit them from the _attributes_ we must look for them here; otherwise we'll used the declared type
                // (as below) instead!
                return node.parent.contextualType;
            }
            return getContextualTypeForArgumentAtIndex(node, 0);
        }
        function getEffectiveFirstArgumentForJsxSignature(signature, node) {
            return getJsxReferenceKind(node) !== 0 /* Component */
                ? getJsxPropsTypeFromCallSignature(signature, node)
                : getJsxPropsTypeFromClassType(signature, node);
        }
        function getJsxPropsTypeFromCallSignature(sig, context) {
            var propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType);
            propsType = getJsxManagedAttributesFromLocatedAttributes(context, getJsxNamespaceAt(context), propsType);
            var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
            if (intrinsicAttribs !== errorType) {
                propsType = intersectTypes(intrinsicAttribs, propsType);
            }
            return propsType;
        }
        function getJsxPropsTypeForSignatureFromMember(sig, forcedLookupLocation) {
            if (sig.unionSignatures) {
                // JSX Elements using the legacy `props`-field based lookup (eg, react class components) need to treat the `props` member as an input
                // instead of an output position when resolving the signature. We need to go back to the input signatures of the composite signature,
                // get the type of `props` on each return type individually, and then _intersect them_, rather than union them (as would normally occur
                // for a union signature). It's an unfortunate quirk of looking in the output of the signature for the type we want to use for the input.
                // The default behavior of `getTypeOfFirstParameterOfSignatureWithFallback` when no `props` member name is defined is much more sane.
                var results = [];
                for (var _i = 0, _a = sig.unionSignatures; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    var instance = getReturnTypeOfSignature(signature);
                    if (isTypeAny(instance)) {
                        return instance;
                    }
                    var propType = getTypeOfPropertyOfType(instance, forcedLookupLocation);
                    if (!propType) {
                        return;
                    }
                    results.push(propType);
                }
                return getIntersectionType(results);
            }
            var instanceType = getReturnTypeOfSignature(sig);
            return isTypeAny(instanceType) ? instanceType : getTypeOfPropertyOfType(instanceType, forcedLookupLocation);
        }
        function getStaticTypeOfReferencedJsxConstructor(context) {
            if (isJsxIntrinsicIdentifier(context.tagName)) {
                var result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(context);
                var fakeSignature = createSignatureForJSXIntrinsic(context, result);
                return getOrCreateTypeFromSignature(fakeSignature);
            }
            var tagType = checkExpressionCached(context.tagName);
            if (tagType.flags & 128 /* StringLiteral */) {
                var result = getIntrinsicAttributesTypeFromStringLiteralType(tagType, context);
                if (!result) {
                    return errorType;
                }
                var fakeSignature = createSignatureForJSXIntrinsic(context, result);
                return getOrCreateTypeFromSignature(fakeSignature);
            }
            return tagType;
        }
        function getJsxManagedAttributesFromLocatedAttributes(context, ns, attributesType) {
            var managedSym = getJsxLibraryManagedAttributes(ns);
            if (managedSym) {
                var declaredManagedType = getDeclaredTypeOfSymbol(managedSym);
                var ctorType = getStaticTypeOfReferencedJsxConstructor(context);
                if (ts.length(declaredManagedType.typeParameters) >= 2) {
                    var args = fillMissingTypeArguments([ctorType, attributesType], declaredManagedType.typeParameters, 2, ts.isInJSFile(context));
                    return createTypeReference(declaredManagedType, args);
                }
                else if (ts.length(declaredManagedType.aliasTypeArguments) >= 2) {
                    var args = fillMissingTypeArguments([ctorType, attributesType], declaredManagedType.aliasTypeArguments, 2, ts.isInJSFile(context));
                    return getTypeAliasInstantiation(declaredManagedType.aliasSymbol, args);
                }
            }
            return attributesType;
        }
        function getJsxPropsTypeFromClassType(sig, context) {
            var ns = getJsxNamespaceAt(context);
            var forcedLookupLocation = getJsxElementPropertiesName(ns);
            var attributesType = forcedLookupLocation === undefined
                // If there is no type ElementAttributesProperty, return the type of the first parameter of the signature, which should be the props type
                ? getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType)
                : forcedLookupLocation === ""
                    // If there is no e.g. 'props' member in ElementAttributesProperty, use the element class type instead
                    ? getReturnTypeOfSignature(sig)
                    // Otherwise get the type of the property on the signature return type
                    : getJsxPropsTypeForSignatureFromMember(sig, forcedLookupLocation);
            if (!attributesType) {
                // There is no property named 'props' on this instance type
                if (!!forcedLookupLocation && !!ts.length(context.attributes.properties)) {
                    error(context, ts.Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, ts.unescapeLeadingUnderscores(forcedLookupLocation));
                }
                return unknownType;
            }
            attributesType = getJsxManagedAttributesFromLocatedAttributes(context, ns, attributesType);
            if (isTypeAny(attributesType)) {
                // Props is of type 'any' or unknown
                return attributesType;
            }
            else {
                // Normal case -- add in IntrinsicClassElements<T> and IntrinsicElements
                var apparentAttributesType = attributesType;
                var intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes, context);
                if (intrinsicClassAttribs !== errorType) {
                    var typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol);
                    var hostClassType = getReturnTypeOfSignature(sig);
                    apparentAttributesType = intersectTypes(typeParams
                        ? createTypeReference(intrinsicClassAttribs, fillMissingTypeArguments([hostClassType], typeParams, getMinTypeArgumentCount(typeParams), ts.isInJSFile(context)))
                        : intrinsicClassAttribs, apparentAttributesType);
                }
                var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
                if (intrinsicAttribs !== errorType) {
                    apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType);
                }
                return apparentAttributesType;
            }
        }
        // If the given type is an object or union type with a single signature, and if that signature has at
        // least as many parameters as the given function, return the signature. Otherwise return undefined.
        function getContextualCallSignature(type, node) {
            var signatures = getSignaturesOfType(type, 0 /* Call */);
            if (signatures.length === 1) {
                var signature = signatures[0];
                if (!isAritySmaller(signature, node)) {
                    return signature;
                }
            }
        }
        /** If the contextual signature has fewer parameters than the function expression, do not use it */
        function isAritySmaller(signature, target) {
            var targetParameterCount = 0;
            for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
                var param = target.parameters[targetParameterCount];
                if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
                    break;
                }
            }
            if (target.parameters.length && ts.parameterIsThisKeyword(target.parameters[0])) {
                targetParameterCount--;
            }
            return !hasEffectiveRestParameter(signature) && getParameterCount(signature) < targetParameterCount;
        }
        function isFunctionExpressionOrArrowFunction(node) {
            return node.kind === 201 /* FunctionExpression */ || node.kind === 202 /* ArrowFunction */;
        }
        function getContextualSignatureForFunctionLikeDeclaration(node) {
            // Only function expressions, arrow functions, and object literal methods are contextually typed.
            return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node)
                ? getContextualSignature(node)
                : undefined;
        }
        // Return the contextual signature for a given expression node. A contextual type provides a
        // contextual signature if it has a single call signature and if that call signature is non-generic.
        // If the contextual type is a union type, get the signature from each type possible and if they are
        // all identical ignoring their return type, the result is same signature but with return type as
        // union type of return types from these signatures
        function getContextualSignature(node) {
            ts.Debug.assert(node.kind !== 161 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var typeTagSignature = getSignatureOfTypeTag(node);
            if (typeTagSignature) {
                return typeTagSignature;
            }
            var type = getApparentTypeOfContextualType(node, 1 /* Signature */);
            if (!type) {
                return undefined;
            }
            if (!(type.flags & 1048576 /* Union */)) {
                return getContextualCallSignature(type, node);
            }
            var signatureList;
            var types = type.types;
            for (var _i = 0, types_17 = types; _i < types_17.length; _i++) {
                var current = types_17[_i];
                var signature = getContextualCallSignature(current, node);
                if (signature) {
                    if (!signatureList) {
                        // This signature will contribute to contextual union signature
                        signatureList = [signature];
                    }
                    else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
                        // Signatures aren't identical, do not use
                        return undefined;
                    }
                    else {
                        // Use this signature for contextual union signature
                        signatureList.push(signature);
                    }
                }
            }
            // Result is union of signatures collected (return type is union of return types of this signature set)
            if (signatureList) {
                return signatureList.length === 1 ? signatureList[0] : createUnionSignature(signatureList[0], signatureList);
            }
        }
        function checkSpreadExpression(node, checkMode) {
            if (languageVersion < 2 /* ES2015 */) {
                checkExternalEmitHelpers(node, compilerOptions.downlevelIteration ? 1536 /* SpreadIncludes */ : 2048 /* SpreadArrays */);
            }
            var arrayOrIterableType = checkExpression(node.expression, checkMode);
            return checkIteratedTypeOrElementType(33 /* Spread */, arrayOrIterableType, undefinedType, node.expression);
        }
        function hasDefaultValue(node) {
            return (node.kind === 191 /* BindingElement */ && !!node.initializer) ||
                (node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 62 /* EqualsToken */);
        }
        function checkArrayLiteral(node, checkMode, forceTuple) {
            var elements = node.elements;
            var elementCount = elements.length;
            var elementTypes = [];
            var hasEndingSpreadElement = false;
            var hasNonEndingSpreadElement = false;
            var contextualType = getApparentTypeOfContextualType(node);
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            var inConstContext = isConstContext(node);
            for (var i = 0; i < elementCount; i++) {
                var e = elements[i];
                var spread = e.kind === 213 /* SpreadElement */ && e.expression;
                var spreadType = spread && checkExpression(spread, checkMode, forceTuple);
                if (spreadType && isTupleType(spreadType)) {
                    elementTypes.push.apply(elementTypes, getTypeArguments(spreadType));
                    if (spreadType.target.hasRestElement) {
                        if (i === elementCount - 1)
                            hasEndingSpreadElement = true;
                        else
                            hasNonEndingSpreadElement = true;
                    }
                }
                else {
                    if (inDestructuringPattern && spreadType) {
                        // Given the following situation:
                        //    var c: {};
                        //    [...c] = ["", 0];
                        //
                        // c is represented in the tree as a spread element in an array literal.
                        // But c really functions as a rest element, and its purpose is to provide
                        // a contextual type for the right hand side of the assignment. Therefore,
                        // instead of calling checkExpression on "...c", which will give an error
                        // if c is not iterable/array-like, we need to act as if we are trying to
                        // get the contextual element type from it. So we do something similar to
                        // getContextualTypeForElementExpression, which will crucially not error
                        // if there is no index type / iterated type.
                        var restElementType = getIndexTypeOfType(spreadType, 1 /* Number */) ||
                            getIteratedTypeOrElementType(65 /* Destructuring */, spreadType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false);
                        if (restElementType) {
                            elementTypes.push(restElementType);
                        }
                    }
                    else {
                        var elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length);
                        var type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple);
                        elementTypes.push(type);
                    }
                    if (spread) { // tuples are done above, so these are only arrays
                        if (i === elementCount - 1)
                            hasEndingSpreadElement = true;
                        else
                            hasNonEndingSpreadElement = true;
                    }
                }
            }
            if (!hasNonEndingSpreadElement) {
                var minLength = elementTypes.length - (hasEndingSpreadElement ? 1 : 0);
                // If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
                // that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
                var tupleResult = void 0;
                if (inDestructuringPattern && minLength > 0) {
                    var type = cloneTypeReference(createTupleType(elementTypes, minLength, hasEndingSpreadElement));
                    type.pattern = node;
                    return type;
                }
                else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasEndingSpreadElement, elementTypes.length, inConstContext)) {
                    return createArrayLiteralType(tupleResult);
                }
                else if (forceTuple) {
                    return createArrayLiteralType(createTupleType(elementTypes, minLength, hasEndingSpreadElement));
                }
            }
            return createArrayLiteralType(createArrayType(elementTypes.length ?
                getUnionType(elementTypes, 2 /* Subtype */) :
                strictNullChecks ? implicitNeverType : undefinedWideningType, inConstContext));
        }
        function createArrayLiteralType(type) {
            if (!(ts.getObjectFlags(type) & 4 /* Reference */)) {
                return type;
            }
            var literalType = type.literalType;
            if (!literalType) {
                literalType = type.literalType = cloneTypeReference(type);
                literalType.objectFlags |= 65536 /* ArrayLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
            }
            return literalType;
        }
        function getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasRestElement, elementCount, readonly) {
            if (elementCount === void 0) { elementCount = elementTypes.length; }
            if (readonly === void 0) { readonly = false; }
            // Infer a tuple type when the contextual type is or contains a tuple-like type
            if (readonly || (contextualType && forEachType(contextualType, isTupleLikeType))) {
                return createTupleType(elementTypes, elementCount - (hasRestElement ? 1 : 0), hasRestElement, readonly);
            }
        }
        function isNumericName(name) {
            switch (name.kind) {
                case 154 /* ComputedPropertyName */:
                    return isNumericComputedName(name);
                case 75 /* Identifier */:
                    return isNumericLiteralName(name.escapedText);
                case 8 /* NumericLiteral */:
                case 10 /* StringLiteral */:
                    return isNumericLiteralName(name.text);
                default:
                    return false;
            }
        }
        function isNumericComputedName(name) {
            // It seems odd to consider an expression of type Any to result in a numeric name,
            // but this behavior is consistent with checkIndexedAccess
            return isTypeAssignableToKind(checkComputedPropertyName(name), 296 /* NumberLike */);
        }
        function isInfinityOrNaNString(name) {
            return name === "Infinity" || name === "-Infinity" || name === "NaN";
        }
        function isNumericLiteralName(name) {
            // The intent of numeric names is that
            //     - they are names with text in a numeric form, and that
            //     - setting properties/indexing with them is always equivalent to doing so with the numeric literal 'numLit',
            //         acquired by applying the abstract 'ToNumber' operation on the name's text.
            //
            // The subtlety is in the latter portion, as we cannot reliably say that anything that looks like a numeric literal is a numeric name.
            // In fact, it is the case that the text of the name must be equal to 'ToString(numLit)' for this to hold.
            //
            // Consider the property name '"0xF00D"'. When one indexes with '0xF00D', they are actually indexing with the value of 'ToString(0xF00D)'
            // according to the ECMAScript specification, so it is actually as if the user indexed with the string '"61453"'.
            // Thus, the text of all numeric literals equivalent to '61543' such as '0xF00D', '0xf00D', '0170015', etc. are not valid numeric names
            // because their 'ToString' representation is not equal to their original text.
            // This is motivated by ECMA-262 sections 9.3.1, 9.8.1, 11.1.5, and 11.2.1.
            //
            // Here, we test whether 'ToString(ToNumber(name))' is exactly equal to 'name'.
            // The '+' prefix operator is equivalent here to applying the abstract ToNumber operation.
            // Applying the 'toString()' method on a number gives us the abstract ToString operation on a number.
            //
            // Note that this accepts the values 'Infinity', '-Infinity', and 'NaN', and that this is intentional.
            // This is desired behavior, because when indexing with them as numeric entities, you are indexing
            // with the strings '"Infinity"', '"-Infinity"', and '"NaN"' respectively.
            return (+name).toString() === name;
        }
        function checkComputedPropertyName(node) {
            var links = getNodeLinks(node.expression);
            if (!links.resolvedType) {
                links.resolvedType = checkExpression(node.expression);
                // This will allow types number, string, symbol or any. It will also allow enums, the unknown
                // type, and any union of these types (like string | number).
                if (links.resolvedType.flags & 98304 /* Nullable */ ||
                    !isTypeAssignableToKind(links.resolvedType, 132 /* StringLike */ | 296 /* NumberLike */ | 12288 /* ESSymbolLike */) &&
                        !isTypeAssignableTo(links.resolvedType, stringNumberSymbolType)) {
                    error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
                }
                else {
                    checkThatExpressionIsProperSymbolReference(node.expression, links.resolvedType, /*reportError*/ true);
                }
            }
            return links.resolvedType;
        }
        function getObjectLiteralIndexInfo(node, offset, properties, kind) {
            var propTypes = [];
            for (var i = 0; i < properties.length; i++) {
                if (kind === 0 /* String */ || isNumericName(node.properties[i + offset].name)) {
                    propTypes.push(getTypeOfSymbol(properties[i]));
                }
            }
            var unionType = propTypes.length ? getUnionType(propTypes, 2 /* Subtype */) : undefinedType;
            return createIndexInfo(unionType, isConstContext(node));
        }
        function getImmediateAliasedSymbol(symbol) {
            ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
            var links = getSymbolLinks(symbol);
            if (!links.immediateTarget) {
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true);
            }
            return links.immediateTarget;
        }
        function checkObjectLiteral(node, checkMode) {
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            // Grammar checking
            checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
            var allPropertiesTable = strictNullChecks ? ts.createSymbolTable() : undefined;
            var propertiesTable = ts.createSymbolTable();
            var propertiesArray = [];
            var spread = emptyObjectType;
            var contextualType = getApparentTypeOfContextualType(node);
            var contextualTypeHasPattern = contextualType && contextualType.pattern &&
                (contextualType.pattern.kind === 189 /* ObjectBindingPattern */ || contextualType.pattern.kind === 193 /* ObjectLiteralExpression */);
            var inConstContext = isConstContext(node);
            var checkFlags = inConstContext ? 8 /* Readonly */ : 0;
            var isInJavascript = ts.isInJSFile(node) && !ts.isInJsonFile(node);
            var enumTag = ts.getJSDocEnumTag(node);
            var isJSObjectLiteral = !contextualType && isInJavascript && !enumTag;
            var objectFlags = freshObjectLiteralFlag;
            var patternWithComputedProperties = false;
            var hasComputedStringProperty = false;
            var hasComputedNumberProperty = false;
            // Spreads may cause an early bail; ensure computed names are always checked (this is cached)
            // As otherwise they may not be checked until exports for the type at this position are retrieved,
            // which may never occur.
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var elem = _a[_i];
                if (elem.name && ts.isComputedPropertyName(elem.name) && !ts.isWellKnownSymbolSyntactically(elem.name)) {
                    checkComputedPropertyName(elem.name);
                }
            }
            var offset = 0;
            for (var i = 0; i < node.properties.length; i++) {
                var memberDecl = node.properties[i];
                var member = getSymbolOfNode(memberDecl);
                var computedNameType = memberDecl.name && memberDecl.name.kind === 154 /* ComputedPropertyName */ && !ts.isWellKnownSymbolSyntactically(memberDecl.name.expression) ?
                    checkComputedPropertyName(memberDecl.name) : undefined;
                if (memberDecl.kind === 281 /* PropertyAssignment */ ||
                    memberDecl.kind === 282 /* ShorthandPropertyAssignment */ ||
                    ts.isObjectLiteralMethod(memberDecl)) {
                    var type = memberDecl.kind === 281 /* PropertyAssignment */ ? checkPropertyAssignment(memberDecl, checkMode) :
                        memberDecl.kind === 282 /* ShorthandPropertyAssignment */ ? checkExpressionForMutableLocation(memberDecl.name, checkMode) :
                            checkObjectLiteralMethod(memberDecl, checkMode);
                    if (isInJavascript) {
                        var jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl);
                        if (jsDocType) {
                            checkTypeAssignableTo(type, jsDocType, memberDecl);
                            type = jsDocType;
                        }
                        else if (enumTag && enumTag.typeExpression) {
                            checkTypeAssignableTo(type, getTypeFromTypeNode(enumTag.typeExpression), memberDecl);
                        }
                    }
                    objectFlags |= ts.getObjectFlags(type) & 3670016 /* PropagatingFlags */;
                    var nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined;
                    var prop = nameType ?
                        createSymbol(4 /* Property */ | member.flags, getPropertyNameFromType(nameType), checkFlags | 4096 /* Late */) :
                        createSymbol(4 /* Property */ | member.flags, member.escapedName, checkFlags);
                    if (nameType) {
                        prop.nameType = nameType;
                    }
                    if (inDestructuringPattern) {
                        // If object literal is an assignment pattern and if the assignment pattern specifies a default value
                        // for the property, make the property optional.
                        var isOptional = (memberDecl.kind === 281 /* PropertyAssignment */ && hasDefaultValue(memberDecl.initializer)) ||
                            (memberDecl.kind === 282 /* ShorthandPropertyAssignment */ && memberDecl.objectAssignmentInitializer);
                        if (isOptional) {
                            prop.flags |= 16777216 /* Optional */;
                        }
                    }
                    else if (contextualTypeHasPattern && !(ts.getObjectFlags(contextualType) & 512 /* ObjectLiteralPatternWithComputedProperties */)) {
                        // If object literal is contextually typed by the implied type of a binding pattern, and if the
                        // binding pattern specifies a default value for the property, make the property optional.
                        var impliedProp = getPropertyOfType(contextualType, member.escapedName);
                        if (impliedProp) {
                            prop.flags |= impliedProp.flags & 16777216 /* Optional */;
                        }
                        else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, 0 /* String */)) {
                            error(memberDecl.name, ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType));
                        }
                    }
                    prop.declarations = member.declarations;
                    prop.parent = member.parent;
                    if (member.valueDeclaration) {
                        prop.valueDeclaration = member.valueDeclaration;
                    }
                    prop.type = type;
                    prop.target = member;
                    member = prop;
                    allPropertiesTable === null || allPropertiesTable === void 0 ? void 0 : allPropertiesTable.set(prop.escapedName, prop);
                }
                else if (memberDecl.kind === 283 /* SpreadAssignment */) {
                    if (languageVersion < 2 /* ES2015 */) {
                        checkExternalEmitHelpers(memberDecl, 2 /* Assign */);
                    }
                    if (propertiesArray.length > 0) {
                        spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
                        propertiesArray = [];
                        propertiesTable = ts.createSymbolTable();
                        hasComputedStringProperty = false;
                        hasComputedNumberProperty = false;
                    }
                    var type = getReducedType(checkExpression(memberDecl.expression));
                    if (!isValidSpreadType(type)) {
                        error(memberDecl, ts.Diagnostics.Spread_types_may_only_be_created_from_object_types);
                        return errorType;
                    }
                    if (allPropertiesTable) {
                        checkSpreadPropOverrides(type, allPropertiesTable, memberDecl);
                    }
                    spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext);
                    offset = i + 1;
                    continue;
                }
                else {
                    // TypeScript 1.0 spec (April 2014)
                    // A get accessor declaration is processed in the same manner as
                    // an ordinary function declaration(section 6.1) with no parameters.
                    // A set accessor declaration is processed in the same manner
                    // as an ordinary function declaration with a single parameter and a Void return type.
                    ts.Debug.assert(memberDecl.kind === 163 /* GetAccessor */ || memberDecl.kind === 164 /* SetAccessor */);
                    checkNodeDeferred(memberDecl);
                }
                if (computedNameType && !(computedNameType.flags & 8576 /* StringOrNumberLiteralOrUnique */)) {
                    if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) {
                        if (isTypeAssignableTo(computedNameType, numberType)) {
                            hasComputedNumberProperty = true;
                        }
                        else {
                            hasComputedStringProperty = true;
                        }
                        if (inDestructuringPattern) {
                            patternWithComputedProperties = true;
                        }
                    }
                }
                else {
                    propertiesTable.set(member.escapedName, member);
                }
                propertiesArray.push(member);
            }
            // If object literal is contextually typed by the implied type of a binding pattern, augment the result
            // type with those properties for which the binding pattern specifies a default value.
            // If the object literal is spread into another object literal, skip this step and let the top-level object
            // literal handle it instead.
            if (contextualTypeHasPattern && node.parent.kind !== 283 /* SpreadAssignment */) {
                for (var _b = 0, _c = getPropertiesOfType(contextualType); _b < _c.length; _b++) {
                    var prop = _c[_b];
                    if (!propertiesTable.get(prop.escapedName) && !getPropertyOfType(spread, prop.escapedName)) {
                        if (!(prop.flags & 16777216 /* Optional */)) {
                            error(prop.valueDeclaration || prop.bindingElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
                        }
                        propertiesTable.set(prop.escapedName, prop);
                        propertiesArray.push(prop);
                    }
                }
            }
            if (spread !== emptyObjectType) {
                if (propertiesArray.length > 0) {
                    spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
                    propertiesArray = [];
                    propertiesTable = ts.createSymbolTable();
                    hasComputedStringProperty = false;
                    hasComputedNumberProperty = false;
                }
                // remap the raw emptyObjectType fed in at the top into a fresh empty object literal type, unique to this use site
                return mapType(spread, function (t) { return t === emptyObjectType ? createObjectLiteralType() : t; });
            }
            return createObjectLiteralType();
            function createObjectLiteralType() {
                var stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, 0 /* String */) : undefined;
                var numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, 1 /* Number */) : undefined;
                var result = createAnonymousType(node.symbol, propertiesTable, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
                result.objectFlags |= objectFlags | 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
                if (isJSObjectLiteral) {
                    result.objectFlags |= 16384 /* JSLiteral */;
                }
                if (patternWithComputedProperties) {
                    result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
                }
                if (inDestructuringPattern) {
                    result.pattern = node;
                }
                return result;
            }
        }
        function isValidSpreadType(type) {
            if (type.flags & 63176704 /* Instantiable */) {
                var constraint = getBaseConstraintOfType(type);
                if (constraint !== undefined) {
                    return isValidSpreadType(constraint);
                }
            }
            return !!(type.flags & (1 /* Any */ | 67108864 /* NonPrimitive */ | 524288 /* Object */ | 58982400 /* InstantiableNonPrimitive */) ||
                getFalsyFlags(type) & 117632 /* DefinitelyFalsy */ && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
                type.flags & 3145728 /* UnionOrIntersection */ && ts.every(type.types, isValidSpreadType));
        }
        function checkJsxSelfClosingElementDeferred(node) {
            checkJsxOpeningLikeElementOrOpeningFragment(node);
            resolveUntypedCall(node); // ensure type arguments and parameters are typechecked, even if there is an arity error
        }
        function checkJsxSelfClosingElement(node, _checkMode) {
            checkNodeDeferred(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        function checkJsxElementDeferred(node) {
            // Check attributes
            checkJsxOpeningLikeElementOrOpeningFragment(node.openingElement);
            // Perform resolution on the closing tag so that rename/go to definition/etc work
            if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
                getIntrinsicTagSymbol(node.closingElement);
            }
            else {
                checkExpression(node.closingElement.tagName);
            }
            checkJsxChildren(node);
        }
        function checkJsxElement(node, _checkMode) {
            checkNodeDeferred(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        function checkJsxFragment(node) {
            checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment);
            if (compilerOptions.jsx === 2 /* React */ && (compilerOptions.jsxFactory || ts.getSourceFileOfNode(node).pragmas.has("jsx"))) {
                error(node, compilerOptions.jsxFactory
                    ? ts.Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory
                    : ts.Diagnostics.JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma);
            }
            checkJsxChildren(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        /**
         * Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
         */
        function isUnhyphenatedJsxName(name) {
            // - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers
            return !ts.stringContains(name, "-");
        }
        /**
         * Returns true iff React would emit this tag name as a string rather than an identifier or qualified name
         */
        function isJsxIntrinsicIdentifier(tagName) {
            return tagName.kind === 75 /* Identifier */ && ts.isIntrinsicJsxName(tagName.escapedText);
        }
        function checkJsxAttribute(node, checkMode) {
            return node.initializer
                ? checkExpressionForMutableLocation(node.initializer, checkMode)
                : trueType; // <Elem attr /> is sugar for <Elem attr={true} />
        }
        /**
         * Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element.
         *
         * @param openingLikeElement a JSX opening-like element
         * @param filter a function to remove attributes that will not participate in checking whether attributes are assignable
         * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property.
         * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral,
         * which also calls getSpreadType.
         */
        function createJsxAttributesTypeFromAttributesProperty(openingLikeElement, checkMode) {
            var attributes = openingLikeElement.attributes;
            var allAttributesTable = strictNullChecks ? ts.createSymbolTable() : undefined;
            var attributesTable = ts.createSymbolTable();
            var spread = emptyJsxObjectType;
            var hasSpreadAnyType = false;
            var typeToIntersect;
            var explicitlySpecifyChildrenAttribute = false;
            var objectFlags = 4096 /* JsxAttributes */;
            var jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement));
            for (var _i = 0, _a = attributes.properties; _i < _a.length; _i++) {
                var attributeDecl = _a[_i];
                var member = attributeDecl.symbol;
                if (ts.isJsxAttribute(attributeDecl)) {
                    var exprType = checkJsxAttribute(attributeDecl, checkMode);
                    objectFlags |= ts.getObjectFlags(exprType) & 3670016 /* PropagatingFlags */;
                    var attributeSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */ | member.flags, member.escapedName);
                    attributeSymbol.declarations = member.declarations;
                    attributeSymbol.parent = member.parent;
                    if (member.valueDeclaration) {
                        attributeSymbol.valueDeclaration = member.valueDeclaration;
                    }
                    attributeSymbol.type = exprType;
                    attributeSymbol.target = member;
                    attributesTable.set(attributeSymbol.escapedName, attributeSymbol);
                    allAttributesTable === null || allAttributesTable === void 0 ? void 0 : allAttributesTable.set(attributeSymbol.escapedName, attributeSymbol);
                    if (attributeDecl.name.escapedText === jsxChildrenPropertyName) {
                        explicitlySpecifyChildrenAttribute = true;
                    }
                }
                else {
                    ts.Debug.assert(attributeDecl.kind === 275 /* JsxSpreadAttribute */);
                    if (attributesTable.size > 0) {
                        spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
                        attributesTable = ts.createSymbolTable();
                    }
                    var exprType = getReducedType(checkExpressionCached(attributeDecl.expression, checkMode));
                    if (isTypeAny(exprType)) {
                        hasSpreadAnyType = true;
                    }
                    if (isValidSpreadType(exprType)) {
                        spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false);
                        if (allAttributesTable) {
                            checkSpreadPropOverrides(exprType, allAttributesTable, attributeDecl);
                        }
                    }
                    else {
                        typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
                    }
                }
            }
            if (!hasSpreadAnyType) {
                if (attributesTable.size > 0) {
                    spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
                }
            }
            // Handle children attribute
            var parent = openingLikeElement.parent.kind === 266 /* JsxElement */ ? openingLikeElement.parent : undefined;
            // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement
            if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) {
                var childrenTypes = checkJsxChildren(parent, checkMode);
                if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") {
                    // Error if there is a attribute named "children" explicitly specified and children element.
                    // This is because children element will overwrite the value from attributes.
                    // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread.
                    if (explicitlySpecifyChildrenAttribute) {
                        error(attributes, ts.Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName));
                    }
                    var contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes);
                    var childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
                    // If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process
                    var childrenPropSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */, jsxChildrenPropertyName);
                    childrenPropSymbol.type = childrenTypes.length === 1 ?
                        childrenTypes[0] :
                        (getArrayLiteralTupleTypeIfApplicable(childrenTypes, childrenContextualType, /*hasRestElement*/ false) || createArrayType(getUnionType(childrenTypes)));
                    // Fake up a property declaration for the children
                    childrenPropSymbol.valueDeclaration = ts.createPropertySignature(/*modifiers*/ undefined, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined);
                    childrenPropSymbol.valueDeclaration.parent = attributes;
                    childrenPropSymbol.valueDeclaration.symbol = childrenPropSymbol;
                    var childPropMap = ts.createSymbolTable();
                    childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
                    spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), attributes.symbol, objectFlags, /*readonly*/ false);
                }
            }
            if (hasSpreadAnyType) {
                return anyType;
            }
            if (typeToIntersect && spread !== emptyJsxObjectType) {
                return getIntersectionType([typeToIntersect, spread]);
            }
            return typeToIntersect || (spread === emptyJsxObjectType ? createJsxAttributesType() : spread);
            /**
             * Create anonymous type from given attributes symbol table.
             * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable
             * @param attributesTable a symbol table of attributes property
             */
            function createJsxAttributesType() {
                objectFlags |= freshObjectLiteralFlag;
                var result = createAnonymousType(attributes.symbol, attributesTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
                result.objectFlags |= objectFlags | 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
                return result;
            }
        }
        function checkJsxChildren(node, checkMode) {
            var childrenTypes = [];
            for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
                var child = _a[_i];
                // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that
                // because then type of children property will have constituent of string type.
                if (child.kind === 11 /* JsxText */) {
                    if (!child.containsOnlyTriviaWhiteSpaces) {
                        childrenTypes.push(stringType);
                    }
                }
                else {
                    childrenTypes.push(checkExpressionForMutableLocation(child, checkMode));
                }
            }
            return childrenTypes;
        }
        function checkSpreadPropOverrides(type, props, spread) {
            for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                var right = _a[_i];
                var left = props.get(right.escapedName);
                var rightType = getTypeOfSymbol(right);
                if (left && !maybeTypeOfKind(rightType, 98304 /* Nullable */) && !(maybeTypeOfKind(rightType, 3 /* AnyOrUnknown */) && right.flags & 16777216 /* Optional */)) {
                    var diagnostic = error(left.valueDeclaration, ts.Diagnostics._0_is_specified_more_than_once_so_this_usage_will_be_overwritten, ts.unescapeLeadingUnderscores(left.escapedName));
                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(spread, ts.Diagnostics.This_spread_always_overwrites_this_property));
                }
            }
        }
        /**
         * Check attributes property of opening-like element. This function is called during chooseOverload to get call signature of a JSX opening-like element.
         * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used)
         * @param node a JSXAttributes to be resolved of its type
         */
        function checkJsxAttributes(node, checkMode) {
            return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode);
        }
        function getJsxType(name, location) {
            var namespace = getJsxNamespaceAt(location);
            var exports = namespace && getExportsOfSymbol(namespace);
            var typeSymbol = exports && getSymbol(exports, name, 788968 /* Type */);
            return typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType;
        }
        /**
         * Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic
         * property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic
         * string index signature (in which case nodeLinks.jsxFlags will be IntrinsicIndexedElement).
         * May also return unknownSymbol if both of these lookups fail.
         */
        function getIntrinsicTagSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, node);
                if (intrinsicElementsType !== errorType) {
                    // Property case
                    if (!ts.isIdentifier(node.tagName))
                        return ts.Debug.fail();
                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText);
                    if (intrinsicProp) {
                        links.jsxFlags |= 1 /* IntrinsicNamedElement */;
                        return links.resolvedSymbol = intrinsicProp;
                    }
                    // Intrinsic string indexer case
                    var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                    if (indexSignatureType) {
                        links.jsxFlags |= 2 /* IntrinsicIndexedElement */;
                        return links.resolvedSymbol = intrinsicElementsType.symbol;
                    }
                    // Wasn't found
                    error(node, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(node.tagName), "JSX." + JsxNames.IntrinsicElements);
                    return links.resolvedSymbol = unknownSymbol;
                }
                else {
                    if (noImplicitAny) {
                        error(node, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, ts.unescapeLeadingUnderscores(JsxNames.IntrinsicElements));
                    }
                    return links.resolvedSymbol = unknownSymbol;
                }
            }
            return links.resolvedSymbol;
        }
        function getJsxNamespaceAt(location) {
            var links = location && getNodeLinks(location);
            if (links && links.jsxNamespace) {
                return links.jsxNamespace;
            }
            if (!links || links.jsxNamespace !== false) {
                var namespaceName = getJsxNamespace(location);
                var resolvedNamespace = resolveName(location, namespaceName, 1920 /* Namespace */, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false);
                if (resolvedNamespace) {
                    var candidate = resolveSymbol(getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, 1920 /* Namespace */));
                    if (candidate) {
                        if (links) {
                            links.jsxNamespace = candidate;
                        }
                        return candidate;
                    }
                    if (links) {
                        links.jsxNamespace = false;
                    }
                }
            }
            // JSX global fallback
            return getGlobalSymbol(JsxNames.JSX, 1920 /* Namespace */, /*diagnosticMessage*/ undefined); // TODO: GH#18217
        }
        /**
         * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer.
         * Get a single property from that container if existed. Report an error if there are more than one property.
         *
         * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer
         *          if other string is given or the container doesn't exist, return undefined.
         */
        function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer, jsxNamespace) {
            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol]
            var jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, 788968 /* Type */);
            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type]
            var jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym);
            // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute
            var propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType);
            if (propertiesOfJsxElementAttribPropInterface) {
                // Element Attributes has zero properties, so the element attributes type will be the class instance type
                if (propertiesOfJsxElementAttribPropInterface.length === 0) {
                    return "";
                }
                // Element Attributes has one property, so the element attributes type will be the type of the corresponding
                // property of the class instance type
                else if (propertiesOfJsxElementAttribPropInterface.length === 1) {
                    return propertiesOfJsxElementAttribPropInterface[0].escapedName;
                }
                else if (propertiesOfJsxElementAttribPropInterface.length > 1) {
                    // More than one property on ElementAttributesProperty is an error
                    error(jsxElementAttribPropInterfaceSym.declarations[0], ts.Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, ts.unescapeLeadingUnderscores(nameOfAttribPropContainer));
                }
            }
            return undefined;
        }
        function getJsxLibraryManagedAttributes(jsxNamespace) {
            // JSX.LibraryManagedAttributes [symbol]
            return jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.LibraryManagedAttributes, 788968 /* Type */);
        }
        /// e.g. "props" for React.d.ts,
        /// or 'undefined' if ElementAttributesProperty doesn't exist (which means all
        ///     non-intrinsic elements' attributes type is 'any'),
        /// or '' if it has 0 properties (which means every
        ///     non-intrinsic elements' attributes type is the element instance type)
        function getJsxElementPropertiesName(jsxNamespace) {
            return getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer, jsxNamespace);
        }
        function getJsxElementChildrenPropertyName(jsxNamespace) {
            return getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer, jsxNamespace);
        }
        function getUninstantiatedJsxSignaturesOfType(elementType, caller) {
            if (elementType.flags & 4 /* String */) {
                return [anySignature];
            }
            else if (elementType.flags & 128 /* StringLiteral */) {
                var intrinsicType = getIntrinsicAttributesTypeFromStringLiteralType(elementType, caller);
                if (!intrinsicType) {
                    error(caller, ts.Diagnostics.Property_0_does_not_exist_on_type_1, elementType.value, "JSX." + JsxNames.IntrinsicElements);
                    return ts.emptyArray;
                }
                else {
                    var fakeSignature = createSignatureForJSXIntrinsic(caller, intrinsicType);
                    return [fakeSignature];
                }
            }
            var apparentElemType = getApparentType(elementType);
            // Resolve the signatures, preferring constructor
            var signatures = getSignaturesOfType(apparentElemType, 1 /* Construct */);
            if (signatures.length === 0) {
                // No construct signatures, try call signatures
                signatures = getSignaturesOfType(apparentElemType, 0 /* Call */);
            }
            if (signatures.length === 0 && apparentElemType.flags & 1048576 /* Union */) {
                // If each member has some combination of new/call signatures; make a union signature list for those
                signatures = getUnionSignatures(ts.map(apparentElemType.types, function (t) { return getUninstantiatedJsxSignaturesOfType(t, caller); }));
            }
            return signatures;
        }
        function getIntrinsicAttributesTypeFromStringLiteralType(type, location) {
            // If the elemType is a stringLiteral type, we can then provide a check to make sure that the string literal type is one of the Jsx intrinsic element type
            // For example:
            //      var CustomTag: "h1" = "h1";
            //      <CustomTag> Hello World </CustomTag>
            var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, location);
            if (intrinsicElementsType !== errorType) {
                var stringLiteralTypeName = type.value;
                var intrinsicProp = getPropertyOfType(intrinsicElementsType, ts.escapeLeadingUnderscores(stringLiteralTypeName));
                if (intrinsicProp) {
                    return getTypeOfSymbol(intrinsicProp);
                }
                var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                if (indexSignatureType) {
                    return indexSignatureType;
                }
                return undefined;
            }
            // If we need to report an error, we already done so here. So just return any to prevent any more error downstream
            return anyType;
        }
        function checkJsxReturnAssignableToAppropriateBound(refKind, elemInstanceType, openingLikeElement) {
            if (refKind === 1 /* Function */) {
                var sfcReturnConstraint = getJsxStatelessElementTypeAt(openingLikeElement);
                if (sfcReturnConstraint) {
                    checkTypeRelatedTo(elemInstanceType, sfcReturnConstraint, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_return_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain);
                }
            }
            else if (refKind === 0 /* Component */) {
                var classConstraint = getJsxElementClassTypeAt(openingLikeElement);
                if (classConstraint) {
                    // Issue an error if this return type isn't assignable to JSX.ElementClass, failing that
                    checkTypeRelatedTo(elemInstanceType, classConstraint, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_instance_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain);
                }
            }
            else { // Mixed
                var sfcReturnConstraint = getJsxStatelessElementTypeAt(openingLikeElement);
                var classConstraint = getJsxElementClassTypeAt(openingLikeElement);
                if (!sfcReturnConstraint || !classConstraint) {
                    return;
                }
                var combined = getUnionType([sfcReturnConstraint, classConstraint]);
                checkTypeRelatedTo(elemInstanceType, combined, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_element_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain);
            }
            function generateInitialErrorChain() {
                var componentName = ts.getTextOfNode(openingLikeElement.tagName);
                return ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics._0_cannot_be_used_as_a_JSX_component, componentName);
            }
        }
        /**
         * Get attributes type of the given intrinsic opening-like Jsx element by resolving the tag name.
         * The function is intended to be called from a function which has checked that the opening element is an intrinsic element.
         * @param node an intrinsic JSX opening-like element
         */
        function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node) {
            ts.Debug.assert(isJsxIntrinsicIdentifier(node.tagName));
            var links = getNodeLinks(node);
            if (!links.resolvedJsxElementAttributesType) {
                var symbol = getIntrinsicTagSymbol(node);
                if (links.jsxFlags & 1 /* IntrinsicNamedElement */) {
                    return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol);
                }
                else if (links.jsxFlags & 2 /* IntrinsicIndexedElement */) {
                    return links.resolvedJsxElementAttributesType =
                        getIndexTypeOfType(getDeclaredTypeOfSymbol(symbol), 0 /* String */);
                }
                else {
                    return links.resolvedJsxElementAttributesType = errorType;
                }
            }
            return links.resolvedJsxElementAttributesType;
        }
        function getJsxElementClassTypeAt(location) {
            var type = getJsxType(JsxNames.ElementClass, location);
            if (type === errorType)
                return undefined;
            return type;
        }
        function getJsxElementTypeAt(location) {
            return getJsxType(JsxNames.Element, location);
        }
        function getJsxStatelessElementTypeAt(location) {
            var jsxElementType = getJsxElementTypeAt(location);
            if (jsxElementType) {
                return getUnionType([jsxElementType, nullType]);
            }
        }
        /**
         * Returns all the properties of the Jsx.IntrinsicElements interface
         */
        function getJsxIntrinsicTagNamesAt(location) {
            var intrinsics = getJsxType(JsxNames.IntrinsicElements, location);
            return intrinsics ? getPropertiesOfType(intrinsics) : ts.emptyArray;
        }
        function checkJsxPreconditions(errorNode) {
            // Preconditions for using JSX
            if ((compilerOptions.jsx || 0 /* None */) === 0 /* None */) {
                error(errorNode, ts.Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
            }
            if (getJsxElementTypeAt(errorNode) === undefined) {
                if (noImplicitAny) {
                    error(errorNode, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
                }
            }
        }
        function checkJsxOpeningLikeElementOrOpeningFragment(node) {
            var isNodeOpeningLikeElement = ts.isJsxOpeningLikeElement(node);
            if (isNodeOpeningLikeElement) {
                checkGrammarJsxElement(node);
            }
            checkJsxPreconditions(node);
            // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
            // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
            var reactRefErr = diagnostics && compilerOptions.jsx === 2 /* React */ ? ts.Diagnostics.Cannot_find_name_0 : undefined;
            var reactNamespace = getJsxNamespace(node);
            var reactLocation = isNodeOpeningLikeElement ? node.tagName : node;
            var reactSym = resolveName(reactLocation, reactNamespace, 111551 /* Value */, reactRefErr, reactNamespace, /*isUse*/ true);
            if (reactSym) {
                // Mark local symbol as referenced here because it might not have been marked
                // if jsx emit was not react as there wont be error being emitted
                reactSym.isReferenced = 67108863 /* All */;
                // If react symbol is alias, mark it as refereced
                if (reactSym.flags & 2097152 /* Alias */ && !getTypeOnlyAliasDeclaration(reactSym)) {
                    markAliasSymbolAsReferenced(reactSym);
                }
            }
            if (isNodeOpeningLikeElement) {
                var jsxOpeningLikeNode = node;
                var sig = getResolvedSignature(jsxOpeningLikeNode);
                checkJsxReturnAssignableToAppropriateBound(getJsxReferenceKind(jsxOpeningLikeNode), getReturnTypeOfSignature(sig), jsxOpeningLikeNode);
            }
        }
        /**
         * Check if a property with the given name is known anywhere in the given type. In an object type, a property
         * is considered known if
         * 1. the object type is empty and the check is for assignability, or
         * 2. if the object type has index signatures, or
         * 3. if the property is actually declared in the object type
         *    (this means that 'toString', for example, is not usually a known property).
         * 4. In a union or intersection type,
         *    a property is considered known if it is known in any constituent type.
         * @param targetType a type to search a given name in
         * @param name a property name to search
         * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType
         */
        function isKnownProperty(targetType, name, isComparingJsxAttributes) {
            if (targetType.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(targetType);
                if (resolved.stringIndexInfo ||
                    resolved.numberIndexInfo && isNumericLiteralName(name) ||
                    getPropertyOfObjectType(targetType, name) ||
                    isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
                    // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
                    return true;
                }
            }
            else if (targetType.flags & 3145728 /* UnionOrIntersection */ && isExcessPropertyCheckTarget(targetType)) {
                for (var _i = 0, _a = targetType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (isKnownProperty(t, name, isComparingJsxAttributes)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isExcessPropertyCheckTarget(type) {
            return !!(type.flags & 524288 /* Object */ && !(ts.getObjectFlags(type) & 512 /* ObjectLiteralPatternWithComputedProperties */) ||
                type.flags & 67108864 /* NonPrimitive */ ||
                type.flags & 1048576 /* Union */ && ts.some(type.types, isExcessPropertyCheckTarget) ||
                type.flags & 2097152 /* Intersection */ && ts.every(type.types, isExcessPropertyCheckTarget));
        }
        function checkJsxExpression(node, checkMode) {
            checkGrammarJsxExpression(node);
            if (node.expression) {
                var type = checkExpression(node.expression, checkMode);
                if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) {
                    error(node, ts.Diagnostics.JSX_spread_child_must_be_an_array_type);
                }
                return type;
            }
            else {
                return errorType;
            }
        }
        function getDeclarationNodeFlagsFromSymbol(s) {
            return s.valueDeclaration ? ts.getCombinedNodeFlags(s.valueDeclaration) : 0;
        }
        /**
         * Return whether this symbol is a member of a prototype somewhere
         * Note that this is not tracked well within the compiler, so the answer may be incorrect.
         */
        function isPrototypeProperty(symbol) {
            if (symbol.flags & 8192 /* Method */ || ts.getCheckFlags(symbol) & 4 /* SyntheticMethod */) {
                return true;
            }
            if (ts.isInJSFile(symbol.valueDeclaration)) {
                var parent = symbol.valueDeclaration.parent;
                return parent && ts.isBinaryExpression(parent) &&
                    ts.getAssignmentDeclarationKind(parent) === 3 /* PrototypeProperty */;
            }
        }
        /**
         * Check whether the requested property access is valid.
         * Returns true if node is a valid property access, and false otherwise.
         * @param node The node to be checked.
         * @param isSuper True if the access is from `super.`.
         * @param type The type of the object whose property is being accessed. (Not the type of the property.)
         * @param prop The symbol for the property being accessed.
         */
        function checkPropertyAccessibility(node, isSuper, type, prop) {
            var flags = ts.getDeclarationModifierFlagsFromSymbol(prop);
            var errorNode = node.kind === 153 /* QualifiedName */ ? node.right : node.kind === 188 /* ImportType */ ? node : node.name;
            if (isSuper) {
                // TS 1.0 spec (April 2014): 4.8.2
                // - In a constructor, instance member function, instance member accessor, or
                //   instance member variable initializer where this references a derived class instance,
                //   a super property access is permitted and must specify a public instance member function of the base class.
                // - In a static member function or static member accessor
                //   where this references the constructor function object of a derived class,
                //   a super property access is permitted and must specify a public static member function of the base class.
                if (languageVersion < 2 /* ES2015 */) {
                    if (symbolHasNonMethodDeclaration(prop)) {
                        error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
                        return false;
                    }
                }
                if (flags & 128 /* Abstract */) {
                    // A method cannot be accessed in a super property access if the method is abstract.
                    // This error could mask a private property access error. But, a member
                    // cannot simultaneously be private and abstract, so this will trigger an
                    // additional error elsewhere.
                    error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(getDeclaringClass(prop)));
                    return false;
                }
            }
            // Referencing abstract properties within their own constructors is not allowed
            if ((flags & 128 /* Abstract */) && ts.isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) {
                var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
                if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node)) {
                    error(errorNode, ts.Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), ts.getTextOfIdentifierOrLiteral(declaringClassDeclaration.name)); // TODO: GH#18217
                    return false;
                }
            }
            if (ts.isPropertyAccessExpression(node) && ts.isPrivateIdentifier(node.name)) {
                if (!ts.getContainingClass(node)) {
                    error(errorNode, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
                    return false;
                }
                return true;
            }
            // Public properties are otherwise accessible.
            if (!(flags & 24 /* NonPublicAccessibilityModifier */)) {
                return true;
            }
            // Property is known to be private or protected at this point
            // Private property is accessible if the property is within the declaring class
            if (flags & 8 /* Private */) {
                var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
                if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                    error(errorNode, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop)));
                    return false;
                }
                return true;
            }
            // Property is known to be protected at this point
            // All protected properties of a supertype are accessible in a super access
            if (isSuper) {
                return true;
            }
            // Find the first enclosing class that has the declaring classes of the protected constituents
            // of the property as base classes
            var enclosingClass = forEachEnclosingClass(node, function (enclosingDeclaration) {
                var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration));
                return isClassDerivedFromDeclaringClasses(enclosingClass, prop) ? enclosingClass : undefined;
            });
            // A protected property is accessible if the property is within the declaring class or classes derived from it
            if (!enclosingClass) {
                // allow PropertyAccessibility if context is in function with this parameter
                // static member access is disallow
                var thisParameter = void 0;
                if (flags & 32 /* Static */ || !(thisParameter = getThisParameterFromNodeContext(node)) || !thisParameter.type) {
                    error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(getDeclaringClass(prop) || type));
                    return false;
                }
                var thisType = getTypeFromTypeNode(thisParameter.type);
                enclosingClass = ((thisType.flags & 262144 /* TypeParameter */) ? getConstraintOfTypeParameter(thisType) : thisType).target;
            }
            // No further restrictions for static properties
            if (flags & 32 /* Static */) {
                return true;
            }
            if (type.flags & 262144 /* TypeParameter */) {
                // get the original type -- represented as the type constraint of the 'this' type
                type = type.isThisType ? getConstraintOfTypeParameter(type) : getBaseConstraintOfType(type); // TODO: GH#18217 Use a different variable that's allowed to be undefined
            }
            if (!type || !hasBaseType(type, enclosingClass)) {
                error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
                return false;
            }
            return true;
        }
        function getThisParameterFromNodeContext(node) {
            var thisContainer = ts.getThisContainer(node, /* includeArrowFunctions */ false);
            return thisContainer && ts.isFunctionLike(thisContainer) ? ts.getThisParameter(thisContainer) : undefined;
        }
        function symbolHasNonMethodDeclaration(symbol) {
            return !!forEachProperty(symbol, function (prop) { return !(prop.flags & 8192 /* Method */); });
        }
        function checkNonNullExpression(node) {
            return checkNonNullType(checkExpression(node), node);
        }
        function isNullableType(type) {
            return !!((strictNullChecks ? getFalsyFlags(type) : type.flags) & 98304 /* Nullable */);
        }
        function getNonNullableTypeIfNeeded(type) {
            return isNullableType(type) ? getNonNullableType(type) : type;
        }
        function reportObjectPossiblyNullOrUndefinedError(node, flags) {
            error(node, flags & 32768 /* Undefined */ ? flags & 65536 /* Null */ ?
                ts.Diagnostics.Object_is_possibly_null_or_undefined :
                ts.Diagnostics.Object_is_possibly_undefined :
                ts.Diagnostics.Object_is_possibly_null);
        }
        function reportCannotInvokePossiblyNullOrUndefinedError(node, flags) {
            error(node, flags & 32768 /* Undefined */ ? flags & 65536 /* Null */ ?
                ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined :
                ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined :
                ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_null);
        }
        function checkNonNullTypeWithReporter(type, node, reportError) {
            if (strictNullChecks && type.flags & 2 /* Unknown */) {
                error(node, ts.Diagnostics.Object_is_of_type_unknown);
                return errorType;
            }
            var kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & 98304 /* Nullable */;
            if (kind) {
                reportError(node, kind);
                var t = getNonNullableType(type);
                return t.flags & (98304 /* Nullable */ | 131072 /* Never */) ? errorType : t;
            }
            return type;
        }
        function checkNonNullType(type, node) {
            return checkNonNullTypeWithReporter(type, node, reportObjectPossiblyNullOrUndefinedError);
        }
        function checkNonNullNonVoidType(type, node) {
            var nonNullType = checkNonNullType(type, node);
            if (nonNullType !== errorType && nonNullType.flags & 16384 /* Void */) {
                error(node, ts.Diagnostics.Object_is_possibly_undefined);
            }
            return nonNullType;
        }
        function checkPropertyAccessExpression(node) {
            return node.flags & 32 /* OptionalChain */ ? checkPropertyAccessChain(node) :
                checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullExpression(node.expression), node.name);
        }
        function checkPropertyAccessChain(node) {
            var leftType = checkExpression(node.expression);
            var nonOptionalType = getOptionalExpressionType(leftType, node.expression);
            return propagateOptionalTypeMarker(checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullType(nonOptionalType, node.expression), node.name), node, nonOptionalType !== leftType);
        }
        function checkQualifiedName(node) {
            return checkPropertyAccessExpressionOrQualifiedName(node, node.left, checkNonNullExpression(node.left), node.right);
        }
        function isMethodAccessForCall(node) {
            while (node.parent.kind === 200 /* ParenthesizedExpression */) {
                node = node.parent;
            }
            return ts.isCallOrNewExpression(node.parent) && node.parent.expression === node;
        }
        // Lookup the private identifier lexically.
        function lookupSymbolForPrivateIdentifierDeclaration(propName, location) {
            for (var containingClass = ts.getContainingClass(location); !!containingClass; containingClass = ts.getContainingClass(containingClass)) {
                var symbol = containingClass.symbol;
                var name = ts.getSymbolNameForPrivateIdentifier(symbol, propName);
                var prop = (symbol.members && symbol.members.get(name)) || (symbol.exports && symbol.exports.get(name));
                if (prop) {
                    return prop;
                }
            }
        }
        function getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedIdentifier) {
            return getPropertyOfType(leftType, lexicallyScopedIdentifier.escapedName);
        }
        function checkPrivateIdentifierPropertyAccess(leftType, right, lexicallyScopedIdentifier) {
            // Either the identifier could not be looked up in the lexical scope OR the lexically scoped identifier did not exist on the type.
            // Find a private identifier with the same description on the type.
            var propertyOnType;
            var properties = getPropertiesOfType(leftType);
            if (properties) {
                ts.forEach(properties, function (symbol) {
                    var decl = symbol.valueDeclaration;
                    if (decl && ts.isNamedDeclaration(decl) && ts.isPrivateIdentifier(decl.name) && decl.name.escapedText === right.escapedText) {
                        propertyOnType = symbol;
                        return true;
                    }
                });
            }
            var diagName = diagnosticName(right);
            if (propertyOnType) {
                var typeValueDecl = propertyOnType.valueDeclaration;
                var typeClass_1 = ts.getContainingClass(typeValueDecl);
                ts.Debug.assert(!!typeClass_1);
                // We found a private identifier property with the same description.
                // Either:
                // - There is a lexically scoped private identifier AND it shadows the one we found on the type.
                // - It is an attempt to access the private identifier outside of the class.
                if (lexicallyScopedIdentifier) {
                    var lexicalValueDecl = lexicallyScopedIdentifier.valueDeclaration;
                    var lexicalClass = ts.getContainingClass(lexicalValueDecl);
                    ts.Debug.assert(!!lexicalClass);
                    if (ts.findAncestor(lexicalClass, function (n) { return typeClass_1 === n; })) {
                        var diagnostic = error(right, ts.Diagnostics.The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_private_identifier_with_the_same_spelling, diagName, typeToString(leftType));
                        ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(lexicalValueDecl, ts.Diagnostics.The_shadowing_declaration_of_0_is_defined_here, diagName), ts.createDiagnosticForNode(typeValueDecl, ts.Diagnostics.The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here, diagName));
                        return true;
                    }
                }
                error(right, ts.Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, diagName, diagnosticName(typeClass_1.name || anon));
                return true;
            }
            return false;
        }
        function checkPropertyAccessExpressionOrQualifiedName(node, left, leftType, right) {
            var parentSymbol = getNodeLinks(left).resolvedSymbol;
            var assignmentKind = ts.getAssignmentTargetKind(node);
            var apparentType = getApparentType(assignmentKind !== 0 /* None */ || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType);
            if (ts.isPrivateIdentifier(right)) {
                checkExternalEmitHelpers(node, 262144 /* ClassPrivateFieldGet */);
            }
            var isAnyLike = isTypeAny(apparentType) || apparentType === silentNeverType;
            var prop;
            if (ts.isPrivateIdentifier(right)) {
                var lexicallyScopedSymbol = lookupSymbolForPrivateIdentifierDeclaration(right.escapedText, right);
                if (isAnyLike) {
                    if (lexicallyScopedSymbol) {
                        return apparentType;
                    }
                    if (!ts.getContainingClass(right)) {
                        grammarErrorOnNode(right, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
                        return anyType;
                    }
                }
                prop = lexicallyScopedSymbol ? getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedSymbol) : undefined;
                // Check for private-identifier-specific shadowing and lexical-scoping errors.
                if (!prop && checkPrivateIdentifierPropertyAccess(leftType, right, lexicallyScopedSymbol)) {
                    return errorType;
                }
            }
            else {
                if (isAnyLike) {
                    if (ts.isIdentifier(left) && parentSymbol) {
                        markAliasReferenced(parentSymbol, node);
                    }
                    return apparentType;
                }
                prop = getPropertyOfType(apparentType, right.escapedText);
            }
            if (ts.isIdentifier(left) && parentSymbol && !(prop && isConstEnumOrConstEnumOnlyModule(prop))) {
                markAliasReferenced(parentSymbol, node);
            }
            var propType;
            if (!prop) {
                var indexInfo = !ts.isPrivateIdentifier(right) && (assignmentKind === 0 /* None */ || !isGenericObjectType(leftType) || isThisTypeParameter(leftType)) ? getIndexInfoOfType(apparentType, 0 /* String */) : undefined;
                if (!(indexInfo && indexInfo.type)) {
                    if (isJSLiteralType(leftType)) {
                        return anyType;
                    }
                    if (leftType.symbol === globalThisSymbol) {
                        if (globalThisSymbol.exports.has(right.escapedText) && (globalThisSymbol.exports.get(right.escapedText).flags & 418 /* BlockScoped */)) {
                            error(right, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(right.escapedText), typeToString(leftType));
                        }
                        else if (noImplicitAny) {
                            error(right, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(leftType));
                        }
                        return anyType;
                    }
                    if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
                        reportNonexistentProperty(right, isThisTypeParameter(leftType) ? apparentType : leftType);
                    }
                    return errorType;
                }
                if (indexInfo.isReadonly && (ts.isAssignmentTarget(node) || ts.isDeleteTarget(node))) {
                    error(node, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType));
                }
                propType = indexInfo.type;
            }
            else {
                checkPropertyNotUsedBeforeDeclaration(prop, node, right);
                markPropertyAsReferenced(prop, node, left.kind === 104 /* ThisKeyword */);
                getNodeLinks(node).resolvedSymbol = prop;
                checkPropertyAccessibility(node, left.kind === 102 /* SuperKeyword */, apparentType, prop);
                if (isAssignmentToReadonlyEntity(node, prop, assignmentKind)) {
                    error(right, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, ts.idText(right));
                    return errorType;
                }
                propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
            }
            return getFlowTypeOfAccessExpression(node, prop, propType, right);
        }
        function getFlowTypeOfAccessExpression(node, prop, propType, errorNode) {
            // Only compute control flow type if this is a property access expression that isn't an
            // assignment target, and the referenced property was declared as a variable, property,
            // accessor, or optional method.
            var assignmentKind = ts.getAssignmentTargetKind(node);
            if (!ts.isAccessExpression(node) ||
                assignmentKind === 1 /* Definite */ ||
                prop && !(prop.flags & (3 /* Variable */ | 4 /* Property */ | 98304 /* Accessor */)) && !(prop.flags & 8192 /* Method */ && propType.flags & 1048576 /* Union */)) {
                return propType;
            }
            // If strict null checks and strict property initialization checks are enabled, if we have
            // a this.xxx property access, if the property is an instance property without an initializer,
            // and if we are in a constructor of the same class as the property declaration, assume that
            // the property is uninitialized at the top of the control flow.
            var assumeUninitialized = false;
            if (strictNullChecks && strictPropertyInitialization && node.expression.kind === 104 /* ThisKeyword */) {
                var declaration = prop && prop.valueDeclaration;
                if (declaration && isInstancePropertyWithoutInitializer(declaration)) {
                    var flowContainer = getControlFlowContainer(node);
                    if (flowContainer.kind === 162 /* Constructor */ && flowContainer.parent === declaration.parent && !(declaration.flags & 8388608 /* Ambient */)) {
                        assumeUninitialized = true;
                    }
                }
            }
            else if (strictNullChecks && prop && prop.valueDeclaration &&
                ts.isPropertyAccessExpression(prop.valueDeclaration) &&
                ts.getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration) &&
                getControlFlowContainer(node) === getControlFlowContainer(prop.valueDeclaration)) {
                assumeUninitialized = true;
            }
            var flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
            if (assumeUninitialized && !(getFalsyFlags(propType) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) {
                error(errorNode, ts.Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop)); // TODO: GH#18217
                // Return the declared type to reduce follow-on errors
                return propType;
            }
            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
        }
        function checkPropertyNotUsedBeforeDeclaration(prop, node, right) {
            var valueDeclaration = prop.valueDeclaration;
            if (!valueDeclaration || ts.getSourceFileOfNode(node).isDeclarationFile) {
                return;
            }
            var diagnosticMessage;
            var declarationName = ts.idText(right);
            if (isInPropertyInitializer(node)
                && !(ts.isAccessExpression(node) && ts.isAccessExpression(node.expression))
                && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)
                && !isPropertyDeclaredInAncestorClass(prop)) {
                diagnosticMessage = error(right, ts.Diagnostics.Property_0_is_used_before_its_initialization, declarationName);
            }
            else if (valueDeclaration.kind === 245 /* ClassDeclaration */ &&
                node.parent.kind !== 169 /* TypeReference */ &&
                !(valueDeclaration.flags & 8388608 /* Ambient */) &&
                !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) {
                diagnosticMessage = error(right, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
            }
            if (diagnosticMessage) {
                ts.addRelatedInfo(diagnosticMessage, ts.createDiagnosticForNode(valueDeclaration, ts.Diagnostics._0_is_declared_here, declarationName));
            }
        }
        function isInPropertyInitializer(node) {
            return !!ts.findAncestor(node, function (node) {
                switch (node.kind) {
                    case 159 /* PropertyDeclaration */:
                        return true;
                    case 281 /* PropertyAssignment */:
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 283 /* SpreadAssignment */:
                    case 154 /* ComputedPropertyName */:
                    case 221 /* TemplateSpan */:
                    case 276 /* JsxExpression */:
                    case 273 /* JsxAttribute */:
                    case 274 /* JsxAttributes */:
                    case 275 /* JsxSpreadAttribute */:
                    case 268 /* JsxOpeningElement */:
                    case 216 /* ExpressionWithTypeArguments */:
                    case 279 /* HeritageClause */:
                        return false;
                    default:
                        return ts.isExpressionNode(node) ? false : "quit";
                }
            });
        }
        /**
         * It's possible that "prop.valueDeclaration" is a local declaration, but the property was also declared in a superclass.
         * In that case we won't consider it used before its declaration, because it gets its value from the superclass' declaration.
         */
        function isPropertyDeclaredInAncestorClass(prop) {
            if (!(prop.parent.flags & 32 /* Class */)) {
                return false;
            }
            var classType = getTypeOfSymbol(prop.parent);
            while (true) {
                classType = classType.symbol && getSuperClass(classType);
                if (!classType) {
                    return false;
                }
                var superProperty = getPropertyOfType(classType, prop.escapedName);
                if (superProperty && superProperty.valueDeclaration) {
                    return true;
                }
            }
        }
        function getSuperClass(classType) {
            var x = getBaseTypes(classType);
            if (x.length === 0) {
                return undefined;
            }
            return getIntersectionType(x);
        }
        function reportNonexistentProperty(propNode, containingType) {
            var errorInfo;
            var relatedInfo;
            if (!ts.isPrivateIdentifier(propNode) && containingType.flags & 1048576 /* Union */ && !(containingType.flags & 131068 /* Primitive */)) {
                for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) {
                    var subtype = _a[_i];
                    if (!getPropertyOfType(subtype, propNode.escapedText) && !getIndexInfoOfType(subtype, 0 /* String */)) {
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(subtype));
                        break;
                    }
                }
            }
            if (typeHasStaticProperty(propNode.escapedText, containingType)) {
                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_is_a_static_member_of_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
            }
            else {
                var promisedType = getPromisedTypeOfPromise(containingType);
                if (promisedType && getPropertyOfType(promisedType, propNode.escapedText)) {
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
                    relatedInfo = ts.createDiagnosticForNode(propNode, ts.Diagnostics.Did_you_forget_to_use_await);
                }
                else {
                    var suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType);
                    if (suggestion !== undefined) {
                        var suggestedName = ts.symbolName(suggestion);
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, ts.declarationNameToString(propNode), typeToString(containingType), suggestedName);
                        relatedInfo = suggestion.valueDeclaration && ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestedName);
                    }
                    else {
                        errorInfo = ts.chainDiagnosticMessages(elaborateNeverIntersection(errorInfo, containingType), ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
                    }
                }
            }
            var resultDiagnostic = ts.createDiagnosticForNodeFromMessageChain(propNode, errorInfo);
            if (relatedInfo) {
                ts.addRelatedInfo(resultDiagnostic, relatedInfo);
            }
            diagnostics.add(resultDiagnostic);
        }
        function typeHasStaticProperty(propName, containingType) {
            var prop = containingType.symbol && getPropertyOfType(getTypeOfSymbol(containingType.symbol), propName);
            return prop !== undefined && prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 32 /* Static */);
        }
        function getSuggestedSymbolForNonexistentProperty(name, containingType) {
            return getSpellingSuggestionForName(ts.isString(name) ? name : ts.idText(name), getPropertiesOfType(containingType), 111551 /* Value */);
        }
        function getSuggestionForNonexistentProperty(name, containingType) {
            var suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType);
            return suggestion && ts.symbolName(suggestion);
        }
        function getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning) {
            ts.Debug.assert(outerName !== undefined, "outername should always be defined");
            var result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, function (symbols, name, meaning) {
                ts.Debug.assertEqual(outerName, name, "name should equal outerName");
                var symbol = getSymbol(symbols, name, meaning);
                // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
                // So the table *contains* `x` but `x` isn't actually in scope.
                // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
                return symbol || getSpellingSuggestionForName(ts.unescapeLeadingUnderscores(name), ts.arrayFrom(symbols.values()), meaning);
            });
            return result;
        }
        function getSuggestionForNonexistentSymbol(location, outerName, meaning) {
            var symbolResult = getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning);
            return symbolResult && ts.symbolName(symbolResult);
        }
        function getSuggestedSymbolForNonexistentModule(name, targetModule) {
            return targetModule.exports && getSpellingSuggestionForName(ts.idText(name), getExportsOfModuleAsArray(targetModule), 2623475 /* ModuleMember */);
        }
        function getSuggestionForNonexistentExport(name, targetModule) {
            var suggestion = getSuggestedSymbolForNonexistentModule(name, targetModule);
            return suggestion && ts.symbolName(suggestion);
        }
        function getSuggestionForNonexistentIndexSignature(objectType, expr, keyedType) {
            // check if object type has setter or getter
            function hasProp(name) {
                var prop = getPropertyOfObjectType(objectType, name);
                if (prop) {
                    var s = getSingleCallSignature(getTypeOfSymbol(prop));
                    return !!s && getMinArgumentCount(s) >= 1 && isTypeAssignableTo(keyedType, getTypeAtPosition(s, 0));
                }
                return false;
            }
            ;
            var suggestedMethod = ts.isAssignmentTarget(expr) ? "set" : "get";
            if (!hasProp(suggestedMethod)) {
                return undefined;
            }
            var suggestion = ts.tryGetPropertyAccessOrIdentifierToString(expr.expression);
            if (suggestion === undefined) {
                suggestion = suggestedMethod;
            }
            else {
                suggestion += "." + suggestedMethod;
            }
            return suggestion;
        }
        /**
         * Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
         * Names less than length 3 only check for case-insensitive equality, not levenshtein distance.
         *
         * If there is a candidate that's the same except for case, return that.
         * If there is a candidate that's within one edit of the name, return that.
         * Otherwise, return the candidate with the smallest Levenshtein distance,
         *    except for candidates:
         *      * With no name
         *      * Whose meaning doesn't match the `meaning` parameter.
         *      * Whose length differs from the target name by more than 0.34 of the length of the name.
         *      * Whose levenshtein distance is more than 0.4 of the length of the name
         *        (0.4 allows 1 substitution/transposition for every 5 characters,
         *         and 1 insertion/deletion at 3 characters)
         */
        function getSpellingSuggestionForName(name, symbols, meaning) {
            return ts.getSpellingSuggestion(name, symbols, getCandidateName);
            function getCandidateName(candidate) {
                var candidateName = ts.symbolName(candidate);
                if (ts.startsWith(candidateName, "\"")) {
                    return undefined;
                }
                if (candidate.flags & meaning) {
                    return candidateName;
                }
                if (candidate.flags & 2097152 /* Alias */) {
                    var alias = tryResolveAlias(candidate);
                    if (alias && alias.flags & meaning) {
                        return candidateName;
                    }
                }
                return undefined;
            }
        }
        function markPropertyAsReferenced(prop, nodeForCheckWriteOnly, isThisAccess) {
            var valueDeclaration = prop && (prop.flags & 106500 /* ClassMember */) && prop.valueDeclaration;
            if (!valueDeclaration) {
                return;
            }
            var hasPrivateModifier = ts.hasModifier(valueDeclaration, 8 /* Private */);
            var hasPrivateIdentifier = ts.isNamedDeclaration(prop.valueDeclaration) && ts.isPrivateIdentifier(prop.valueDeclaration.name);
            if (!hasPrivateModifier && !hasPrivateIdentifier) {
                return;
            }
            if (nodeForCheckWriteOnly && ts.isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & 65536 /* SetAccessor */)) {
                return;
            }
            if (isThisAccess) {
                // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters).
                var containingMethod = ts.findAncestor(nodeForCheckWriteOnly, ts.isFunctionLikeDeclaration);
                if (containingMethod && containingMethod.symbol === prop) {
                    return;
                }
            }
            (ts.getCheckFlags(prop) & 1 /* Instantiated */ ? getSymbolLinks(prop).target : prop).isReferenced = 67108863 /* All */;
        }
        function isValidPropertyAccess(node, propertyName) {
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                    return isValidPropertyAccessWithType(node, node.expression.kind === 102 /* SuperKeyword */, propertyName, getWidenedType(checkExpression(node.expression)));
                case 153 /* QualifiedName */:
                    return isValidPropertyAccessWithType(node, /*isSuper*/ false, propertyName, getWidenedType(checkExpression(node.left)));
                case 188 /* ImportType */:
                    return isValidPropertyAccessWithType(node, /*isSuper*/ false, propertyName, getTypeFromTypeNode(node));
            }
        }
        function isValidPropertyAccessForCompletions(node, type, property) {
            return isValidPropertyAccessWithType(node, node.kind === 194 /* PropertyAccessExpression */ && node.expression.kind === 102 /* SuperKeyword */, property.escapedName, type);
            // Previously we validated the 'this' type of methods but this adversely affected performance. See #31377 for more context.
        }
        function isValidPropertyAccessWithType(node, isSuper, propertyName, type) {
            if (type === errorType || isTypeAny(type)) {
                return true;
            }
            var prop = getPropertyOfType(type, propertyName);
            if (prop) {
                if (ts.isPropertyAccessExpression(node) && prop.valueDeclaration && ts.isPrivateIdentifierPropertyDeclaration(prop.valueDeclaration)) {
                    var declClass_1 = ts.getContainingClass(prop.valueDeclaration);
                    return !ts.isOptionalChain(node) && !!ts.findAncestor(node, function (parent) { return parent === declClass_1; });
                }
                return checkPropertyAccessibility(node, isSuper, type, prop);
            }
            // In js files properties of unions are allowed in completion
            return ts.isInJSFile(node) && (type.flags & 1048576 /* Union */) !== 0 && type.types.some(function (elementType) { return isValidPropertyAccessWithType(node, isSuper, propertyName, elementType); });
        }
        /**
         * Return the symbol of the for-in variable declared or referenced by the given for-in statement.
         */
        function getForInVariableSymbol(node) {
            var initializer = node.initializer;
            if (initializer.kind === 243 /* VariableDeclarationList */) {
                var variable = initializer.declarations[0];
                if (variable && !ts.isBindingPattern(variable.name)) {
                    return getSymbolOfNode(variable);
                }
            }
            else if (initializer.kind === 75 /* Identifier */) {
                return getResolvedSymbol(initializer);
            }
            return undefined;
        }
        /**
         * Return true if the given type is considered to have numeric property names.
         */
        function hasNumericPropertyNames(type) {
            return getIndexTypeOfType(type, 1 /* Number */) && !getIndexTypeOfType(type, 0 /* String */);
        }
        /**
         * Return true if given node is an expression consisting of an identifier (possibly parenthesized)
         * that references a for-in variable for an object with numeric property names.
         */
        function isForInVariableForNumericPropertyNames(expr) {
            var e = ts.skipParentheses(expr);
            if (e.kind === 75 /* Identifier */) {
                var symbol = getResolvedSymbol(e);
                if (symbol.flags & 3 /* Variable */) {
                    var child = expr;
                    var node = expr.parent;
                    while (node) {
                        if (node.kind === 231 /* ForInStatement */ &&
                            child === node.statement &&
                            getForInVariableSymbol(node) === symbol &&
                            hasNumericPropertyNames(getTypeOfExpression(node.expression))) {
                            return true;
                        }
                        child = node;
                        node = node.parent;
                    }
                }
            }
            return false;
        }
        function checkIndexedAccess(node) {
            return node.flags & 32 /* OptionalChain */ ? checkElementAccessChain(node) :
                checkElementAccessExpression(node, checkNonNullExpression(node.expression));
        }
        function checkElementAccessChain(node) {
            var exprType = checkExpression(node.expression);
            var nonOptionalType = getOptionalExpressionType(exprType, node.expression);
            return propagateOptionalTypeMarker(checkElementAccessExpression(node, checkNonNullType(nonOptionalType, node.expression)), node, nonOptionalType !== exprType);
        }
        function checkElementAccessExpression(node, exprType) {
            var objectType = ts.getAssignmentTargetKind(node) !== 0 /* None */ || isMethodAccessForCall(node) ? getWidenedType(exprType) : exprType;
            var indexExpression = node.argumentExpression;
            var indexType = checkExpression(indexExpression);
            if (objectType === errorType || objectType === silentNeverType) {
                return objectType;
            }
            if (isConstEnumObjectType(objectType) && !ts.isStringLiteralLike(indexExpression)) {
                error(indexExpression, ts.Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
                return errorType;
            }
            var effectiveIndexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType;
            var accessFlags = ts.isAssignmentTarget(node) ?
                2 /* Writing */ | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? 1 /* NoIndexSignatures */ : 0) :
                0 /* None */;
            var indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
            return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node);
        }
        function checkThatExpressionIsProperSymbolReference(expression, expressionType, reportError) {
            if (expressionType === errorType) {
                // There is already an error, so no need to report one.
                return false;
            }
            if (!ts.isWellKnownSymbolSyntactically(expression)) {
                return false;
            }
            // Make sure the property type is the primitive symbol type
            if ((expressionType.flags & 12288 /* ESSymbolLike */) === 0) {
                if (reportError) {
                    error(expression, ts.Diagnostics.A_computed_property_name_of_the_form_0_must_be_of_type_symbol, ts.getTextOfNode(expression));
                }
                return false;
            }
            // The name is Symbol.<someName>, so make sure Symbol actually resolves to the
            // global Symbol object
            var leftHandSide = expression.expression;
            var leftHandSideSymbol = getResolvedSymbol(leftHandSide);
            if (!leftHandSideSymbol) {
                return false;
            }
            var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ true);
            if (!globalESSymbol) {
                // Already errored when we tried to look up the symbol
                return false;
            }
            if (leftHandSideSymbol !== globalESSymbol) {
                if (reportError) {
                    error(leftHandSide, ts.Diagnostics.Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object);
                }
                return false;
            }
            return true;
        }
        function callLikeExpressionMayHaveTypeArguments(node) {
            return ts.isCallOrNewExpression(node) || ts.isTaggedTemplateExpression(node) || ts.isJsxOpeningLikeElement(node);
        }
        function resolveUntypedCall(node) {
            if (callLikeExpressionMayHaveTypeArguments(node)) {
                // Check type arguments even though we will give an error that untyped calls may not accept type arguments.
                // This gets us diagnostics for the type arguments and marks them as referenced.
                ts.forEach(node.typeArguments, checkSourceElement);
            }
            if (node.kind === 198 /* TaggedTemplateExpression */) {
                checkExpression(node.template);
            }
            else if (ts.isJsxOpeningLikeElement(node)) {
                checkExpression(node.attributes);
            }
            else if (node.kind !== 157 /* Decorator */) {
                ts.forEach(node.arguments, function (argument) {
                    checkExpression(argument);
                });
            }
            return anySignature;
        }
        function resolveErrorCall(node) {
            resolveUntypedCall(node);
            return unknownSignature;
        }
        // Re-order candidate signatures into the result array. Assumes the result array to be empty.
        // The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
        // A nit here is that we reorder only signatures that belong to the same symbol,
        // so order how inherited signatures are processed is still preserved.
        // interface A { (x: string): void }
        // interface B extends A { (x: 'foo'): string }
        // const b: B;
        // b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
        function reorderCandidates(signatures, result, callChainFlags) {
            var lastParent;
            var lastSymbol;
            var cutoffIndex = 0;
            var index;
            var specializedIndex = -1;
            var spliceIndex;
            ts.Debug.assert(!result.length);
            for (var _i = 0, signatures_7 = signatures; _i < signatures_7.length; _i++) {
                var signature = signatures_7[_i];
                var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
                var parent = signature.declaration && signature.declaration.parent;
                if (!lastSymbol || symbol === lastSymbol) {
                    if (lastParent && parent === lastParent) {
                        index = index + 1;
                    }
                    else {
                        lastParent = parent;
                        index = cutoffIndex;
                    }
                }
                else {
                    // current declaration belongs to a different symbol
                    // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex
                    index = cutoffIndex = result.length;
                    lastParent = parent;
                }
                lastSymbol = symbol;
                // specialized signatures always need to be placed before non-specialized signatures regardless
                // of the cutoff position; see GH#1133
                if (signatureHasLiteralTypes(signature)) {
                    specializedIndex++;
                    spliceIndex = specializedIndex;
                    // The cutoff index always needs to be greater than or equal to the specialized signature index
                    // in order to prevent non-specialized signatures from being added before a specialized
                    // signature.
                    cutoffIndex++;
                }
                else {
                    spliceIndex = index;
                }
                result.splice(spliceIndex, 0, callChainFlags ? getOptionalCallSignature(signature, callChainFlags) : signature);
            }
        }
        function isSpreadArgument(arg) {
            return !!arg && (arg.kind === 213 /* SpreadElement */ || arg.kind === 220 /* SyntheticExpression */ && arg.isSpread);
        }
        function getSpreadArgumentIndex(args) {
            return ts.findIndex(args, isSpreadArgument);
        }
        function acceptsVoid(t) {
            return !!(t.flags & 16384 /* Void */);
        }
        function hasCorrectArity(node, args, signature, signatureHelpTrailingComma) {
            if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
            var argCount;
            var callIsIncomplete = false; // In incomplete call we want to be lenient when we have too few arguments
            var effectiveParameterCount = getParameterCount(signature);
            var effectiveMinimumArguments = getMinArgumentCount(signature);
            if (node.kind === 198 /* TaggedTemplateExpression */) {
                argCount = args.length;
                if (node.template.kind === 211 /* TemplateExpression */) {
                    // If a tagged template expression lacks a tail literal, the call is incomplete.
                    // Specifically, a template only can end in a TemplateTail or a Missing literal.
                    var lastSpan = ts.last(node.template.templateSpans); // we should always have at least one span.
                    callIsIncomplete = ts.nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated;
                }
                else {
                    // If the template didn't end in a backtick, or its beginning occurred right prior to EOF,
                    // then this might actually turn out to be a TemplateHead in the future;
                    // so we consider the call to be incomplete.
                    var templateLiteral = node.template;
                    ts.Debug.assert(templateLiteral.kind === 14 /* NoSubstitutionTemplateLiteral */);
                    callIsIncomplete = !!templateLiteral.isUnterminated;
                }
            }
            else if (node.kind === 157 /* Decorator */) {
                argCount = getDecoratorArgumentCount(node, signature);
            }
            else if (ts.isJsxOpeningLikeElement(node)) {
                callIsIncomplete = node.attributes.end === node.end;
                if (callIsIncomplete) {
                    return true;
                }
                argCount = effectiveMinimumArguments === 0 ? args.length : 1;
                effectiveParameterCount = args.length === 0 ? effectiveParameterCount : 1; // class may have argumentless ctor functions - still resolve ctor and compare vs props member type
                effectiveMinimumArguments = Math.min(effectiveMinimumArguments, 1); // sfc may specify context argument - handled by framework and not typechecked
            }
            else {
                if (!node.arguments) {
                    // This only happens when we have something of the form: 'new C'
                    ts.Debug.assert(node.kind === 197 /* NewExpression */);
                    return getMinArgumentCount(signature) === 0;
                }
                argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
                // If we are missing the close parenthesis, the call is incomplete.
                callIsIncomplete = node.arguments.end === node.end;
                // If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range.
                var spreadArgIndex = getSpreadArgumentIndex(args);
                if (spreadArgIndex >= 0) {
                    return spreadArgIndex >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || spreadArgIndex < getParameterCount(signature));
                }
            }
            // Too many arguments implies incorrect arity.
            if (!hasEffectiveRestParameter(signature) && argCount > effectiveParameterCount) {
                return false;
            }
            // If the call is incomplete, we should skip the lower bound check.
            // JSX signatures can have extra parameters provided by the library which we don't check
            if (callIsIncomplete || argCount >= effectiveMinimumArguments) {
                return true;
            }
            for (var i = argCount; i < effectiveMinimumArguments; i++) {
                var type = getTypeAtPosition(signature, i);
                if (filterType(type, acceptsVoid).flags & 131072 /* Never */) {
                    return false;
                }
            }
            return true;
        }
        function hasCorrectTypeArgumentArity(signature, typeArguments) {
            // If the user supplied type arguments, but the number of type arguments does not match
            // the declared number of type parameters, the call has an incorrect arity.
            var numTypeParameters = ts.length(signature.typeParameters);
            var minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters);
            return !ts.some(typeArguments) ||
                (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters);
        }
        // If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
        function getSingleCallSignature(type) {
            return getSingleSignature(type, 0 /* Call */, /*allowMembers*/ false);
        }
        function getSingleCallOrConstructSignature(type) {
            return getSingleSignature(type, 0 /* Call */, /*allowMembers*/ false) ||
                getSingleSignature(type, 1 /* Construct */, /*allowMembers*/ false);
        }
        function getSingleSignature(type, kind, allowMembers) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (allowMembers || resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                    if (kind === 0 /* Call */ && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) {
                        return resolved.callSignatures[0];
                    }
                    if (kind === 1 /* Construct */ && resolved.constructSignatures.length === 1 && resolved.callSignatures.length === 0) {
                        return resolved.constructSignatures[0];
                    }
                }
            }
            return undefined;
        }
        // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
        function instantiateSignatureInContextOf(signature, contextualSignature, inferenceContext, compareTypes) {
            var context = createInferenceContext(signature.typeParameters, signature, 0 /* None */, compareTypes);
            // We clone the inferenceContext to avoid fixing. For example, when the source signature is <T>(x: T) => T[] and
            // the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any')
            // for T but leave it possible to later infer '[any]' back to A.
            var restType = getEffectiveRestType(contextualSignature);
            var mapper = inferenceContext && (restType && restType.flags & 262144 /* TypeParameter */ ? inferenceContext.nonFixingMapper : inferenceContext.mapper);
            var sourceSignature = mapper ? instantiateSignature(contextualSignature, mapper) : contextualSignature;
            applyToParameterTypes(sourceSignature, signature, function (source, target) {
                // Type parameters from outer context referenced by source type are fixed by instantiation of the source type
                inferTypes(context.inferences, source, target);
            });
            if (!inferenceContext) {
                applyToReturnTypes(contextualSignature, signature, function (source, target) {
                    inferTypes(context.inferences, source, target, 32 /* ReturnType */);
                });
            }
            return getSignatureInstantiation(signature, getInferredTypes(context), ts.isInJSFile(contextualSignature.declaration));
        }
        function inferJsxTypeArguments(node, signature, checkMode, context) {
            var paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
            var checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, context, checkMode);
            inferTypes(context.inferences, checkAttrType, paramType);
            return getInferredTypes(context);
        }
        function inferTypeArguments(node, signature, args, checkMode, context) {
            if (ts.isJsxOpeningLikeElement(node)) {
                return inferJsxTypeArguments(node, signature, checkMode, context);
            }
            // If a contextual type is available, infer from that type to the return type of the call expression. For
            // example, given a 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
            // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
            // return type of 'wrap'.
            if (node.kind !== 157 /* Decorator */) {
                var contextualType = getContextualType(node);
                if (contextualType) {
                    // We clone the inference context to avoid disturbing a resolution in progress for an
                    // outer call expression. Effectively we just want a snapshot of whatever has been
                    // inferred for any outer call expression so far.
                    var outerContext = getInferenceContext(node);
                    var outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, 1 /* NoDefault */));
                    var instantiatedType = instantiateType(contextualType, outerMapper);
                    // If the contextual type is a generic function type with a single call signature, we
                    // instantiate the type with its own type parameters and type arguments. This ensures that
                    // the type parameters are not erased to type any during type inference such that they can
                    // be inferred as actual types from the contextual type. For example:
                    //   declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
                    //   const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
                    // Above, the type of the 'value' parameter is inferred to be 'A'.
                    var contextualSignature = getSingleCallSignature(instantiatedType);
                    var inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
                        getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) :
                        instantiatedType;
                    var inferenceTargetType = getReturnTypeOfSignature(signature);
                    // Inferences made from return types have lower priority than all other inferences.
                    inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, 32 /* ReturnType */);
                    // Create a type mapper for instantiating generic contextual types using the inferences made
                    // from the return type. We need a separate inference pass here because (a) instantiation of
                    // the source type uses the outer context's return mapper (which excludes inferences made from
                    // outer arguments), and (b) we don't want any further inferences going into this context.
                    var returnContext = createInferenceContext(signature.typeParameters, signature, context.flags);
                    var returnSourceType = instantiateType(contextualType, outerContext && outerContext.returnMapper);
                    inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType);
                    context.returnMapper = ts.some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(cloneInferredPartOfContext(returnContext)) : undefined;
                }
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType) {
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
                inferTypes(context.inferences, thisArgumentType, thisType);
            }
            var restType = getNonArrayRestType(signature);
            var argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
            for (var i = 0; i < argCount; i++) {
                var arg = args[i];
                if (arg.kind !== 215 /* OmittedExpression */) {
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
                    inferTypes(context.inferences, argType, paramType);
                }
            }
            if (restType) {
                var spreadType = getSpreadArgumentType(args, argCount, args.length, restType, context);
                inferTypes(context.inferences, spreadType, restType);
            }
            return getInferredTypes(context);
        }
        function getArrayifiedType(type) {
            return type.flags & 1048576 /* Union */ ? mapType(type, getArrayifiedType) :
                type.flags & (1 /* Any */ | 63176704 /* Instantiable */) || isMutableArrayOrTuple(type) ? type :
                    isTupleType(type) ? createTupleType(getTypeArguments(type), type.target.minLength, type.target.hasRestElement, /*readonly*/ false, type.target.associatedNames) :
                        createArrayType(getIndexedAccessType(type, numberType));
        }
        function getSpreadArgumentType(args, index, argCount, restType, context) {
            if (index >= argCount - 1) {
                var arg = args[argCount - 1];
                if (isSpreadArgument(arg)) {
                    // We are inferring from a spread expression in the last argument position, i.e. both the parameter
                    // and the argument are ...x forms.
                    return arg.kind === 220 /* SyntheticExpression */ ?
                        createArrayType(arg.type) :
                        getArrayifiedType(checkExpressionWithContextualType(arg.expression, restType, context, 0 /* Normal */));
                }
            }
            var types = [];
            var spreadIndex = -1;
            for (var i = index; i < argCount; i++) {
                var contextualType = getIndexedAccessType(restType, getLiteralType(i - index));
                var argType = checkExpressionWithContextualType(args[i], contextualType, context, 0 /* Normal */);
                if (spreadIndex < 0 && isSpreadArgument(args[i])) {
                    spreadIndex = i - index;
                }
                var hasPrimitiveContextualType = maybeTypeOfKind(contextualType, 131068 /* Primitive */ | 4194304 /* Index */);
                types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType));
            }
            return spreadIndex < 0 ?
                createTupleType(types) :
                createTupleType(ts.append(types.slice(0, spreadIndex), getUnionType(types.slice(spreadIndex))), spreadIndex, /*hasRestElement*/ true);
        }
        function checkTypeArguments(signature, typeArgumentNodes, reportErrors, headMessage) {
            var isJavascript = ts.isInJSFile(signature.declaration);
            var typeParameters = signature.typeParameters;
            var typeArgumentTypes = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript);
            var mapper;
            for (var i = 0; i < typeArgumentNodes.length; i++) {
                ts.Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments");
                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                if (constraint) {
                    var errorInfo = reportErrors && headMessage ? (function () { return ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1); }) : undefined;
                    var typeArgumentHeadMessage = headMessage || ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1;
                    if (!mapper) {
                        mapper = createTypeMapper(typeParameters, typeArgumentTypes);
                    }
                    var typeArgument = typeArgumentTypes[i];
                    if (!checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), reportErrors ? typeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo)) {
                        return undefined;
                    }
                }
            }
            return typeArgumentTypes;
        }
        function getJsxReferenceKind(node) {
            if (isJsxIntrinsicIdentifier(node.tagName)) {
                return 2 /* Mixed */;
            }
            var tagType = getApparentType(checkExpression(node.tagName));
            if (ts.length(getSignaturesOfType(tagType, 1 /* Construct */))) {
                return 0 /* Component */;
            }
            if (ts.length(getSignaturesOfType(tagType, 0 /* Call */))) {
                return 1 /* Function */;
            }
            return 2 /* Mixed */;
        }
        /**
         * Check if the given signature can possibly be a signature called by the JSX opening-like element.
         * @param node a JSX opening-like element we are trying to figure its call signature
         * @param signature a candidate signature we are trying whether it is a call signature
         * @param relation a relationship to check parameter and argument type
         */
        function checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer) {
            // Stateless function components can have maximum of three arguments: "props", "context", and "updater".
            // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
            // can be specified by users through attributes property.
            var paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
            var attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode);
            return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes, 
            /*headMessage*/ undefined, containingMessageChain, errorOutputContainer);
            function checkTagNameDoesNotExpectTooManyArguments() {
                var _a;
                var tagType = ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node) && !isJsxIntrinsicIdentifier(node.tagName) ? checkExpression(node.tagName) : undefined;
                if (!tagType) {
                    return true;
                }
                var tagCallSignatures = getSignaturesOfType(tagType, 0 /* Call */);
                if (!ts.length(tagCallSignatures)) {
                    return true;
                }
                var factory = getJsxFactoryEntity(node);
                if (!factory) {
                    return true;
                }
                var factorySymbol = resolveEntityName(factory, 111551 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, node);
                if (!factorySymbol) {
                    return true;
                }
                var factoryType = getTypeOfSymbol(factorySymbol);
                var callSignatures = getSignaturesOfType(factoryType, 0 /* Call */);
                if (!ts.length(callSignatures)) {
                    return true;
                }
                var hasFirstParamSignatures = false;
                var maxParamCount = 0;
                // Check that _some_ first parameter expects a FC-like thing, and that some overload of the SFC expects an acceptable number of arguments
                for (var _i = 0, callSignatures_1 = callSignatures; _i < callSignatures_1.length; _i++) {
                    var sig = callSignatures_1[_i];
                    var firstparam = getTypeAtPosition(sig, 0);
                    var signaturesOfParam = getSignaturesOfType(firstparam, 0 /* Call */);
                    if (!ts.length(signaturesOfParam))
                        continue;
                    for (var _b = 0, signaturesOfParam_1 = signaturesOfParam; _b < signaturesOfParam_1.length; _b++) {
                        var paramSig = signaturesOfParam_1[_b];
                        hasFirstParamSignatures = true;
                        if (hasEffectiveRestParameter(paramSig)) {
                            return true; // some signature has a rest param, so function components can have an arbitrary number of arguments
                        }
                        var paramCount = getParameterCount(paramSig);
                        if (paramCount > maxParamCount) {
                            maxParamCount = paramCount;
                        }
                    }
                }
                if (!hasFirstParamSignatures) {
                    // Not a single signature had a first parameter which expected a signature - for back compat, and
                    // to guard against generic factories which won't have signatures directly, do not error
                    return true;
                }
                var absoluteMinArgCount = Infinity;
                for (var _c = 0, tagCallSignatures_1 = tagCallSignatures; _c < tagCallSignatures_1.length; _c++) {
                    var tagSig = tagCallSignatures_1[_c];
                    var tagRequiredArgCount = getMinArgumentCount(tagSig);
                    if (tagRequiredArgCount < absoluteMinArgCount) {
                        absoluteMinArgCount = tagRequiredArgCount;
                    }
                }
                if (absoluteMinArgCount <= maxParamCount) {
                    return true; // some signature accepts the number of arguments the function component provides
                }
                if (reportErrors) {
                    var diag = ts.createDiagnosticForNode(node.tagName, ts.Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, ts.entityNameToString(node.tagName), absoluteMinArgCount, ts.entityNameToString(factory), maxParamCount);
                    var tagNameDeclaration = (_a = getSymbolAtLocation(node.tagName)) === null || _a === void 0 ? void 0 : _a.valueDeclaration;
                    if (tagNameDeclaration) {
                        ts.addRelatedInfo(diag, ts.createDiagnosticForNode(tagNameDeclaration, ts.Diagnostics._0_is_declared_here, ts.entityNameToString(node.tagName)));
                    }
                    if (errorOutputContainer && errorOutputContainer.skipLogging) {
                        (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                    }
                    if (!errorOutputContainer.skipLogging) {
                        diagnostics.add(diag);
                    }
                }
                return false;
            }
        }
        function getSignatureApplicabilityError(node, args, signature, relation, checkMode, reportErrors, containingMessageChain) {
            var errorOutputContainer = { errors: undefined, skipLogging: true };
            if (ts.isJsxOpeningLikeElement(node)) {
                if (!checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer)) {
                    ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "jsx should have errors when reporting errors");
                    return errorOutputContainer.errors || ts.emptyArray;
                }
                return undefined;
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType && thisType !== voidType && node.kind !== 197 /* NewExpression */) {
                // If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType
                // If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible.
                // If the expression is a new expression, then the check is skipped.
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = void 0;
                if (thisArgumentNode) {
                    thisArgumentType = checkExpression(thisArgumentNode);
                    if (ts.isOptionalChainRoot(thisArgumentNode.parent)) {
                        thisArgumentType = getNonNullableType(thisArgumentType);
                    }
                    else if (ts.isOptionalChain(thisArgumentNode.parent)) {
                        thisArgumentType = removeOptionalTypeMarker(thisArgumentType);
                    }
                }
                else {
                    thisArgumentType = voidType;
                }
                var errorNode = reportErrors ? (thisArgumentNode || node) : undefined;
                var headMessage_1 = ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1;
                if (!checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage_1, containingMessageChain, errorOutputContainer)) {
                    ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "this parameter should have errors when reporting errors");
                    return errorOutputContainer.errors || ts.emptyArray;
                }
            }
            var headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
            var restType = getNonArrayRestType(signature);
            var argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
            for (var i = 0; i < argCount; i++) {
                var arg = args[i];
                if (arg.kind !== 215 /* OmittedExpression */) {
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = checkExpressionWithContextualType(arg, paramType, /*inferenceContext*/ undefined, checkMode);
                    // If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive),
                    // we obtain the regular type of any object literal arguments because we may not have inferred complete
                    // parameter types yet and therefore excess property checks may yield false positives (see #17041).
                    var checkArgType = checkMode & 4 /* SkipContextSensitive */ ? getRegularTypeOfObjectLiteral(argType) : argType;
                    if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain, errorOutputContainer)) {
                        ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "parameter should have errors when reporting errors");
                        maybeAddMissingAwaitInfo(arg, checkArgType, paramType);
                        return errorOutputContainer.errors || ts.emptyArray;
                    }
                }
            }
            if (restType) {
                var spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined);
                var errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined;
                if (!checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, /*containingMessageChain*/ undefined, errorOutputContainer)) {
                    ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "rest parameter should have errors when reporting errors");
                    maybeAddMissingAwaitInfo(errorNode, spreadType, restType);
                    return errorOutputContainer.errors || ts.emptyArray;
                }
            }
            return undefined;
            function maybeAddMissingAwaitInfo(errorNode, source, target) {
                if (errorNode && reportErrors && errorOutputContainer.errors && errorOutputContainer.errors.length) {
                    // Bail if target is Promise-like---something else is wrong
                    if (getAwaitedTypeOfPromise(target)) {
                        return;
                    }
                    var awaitedTypeOfSource = getAwaitedTypeOfPromise(source);
                    if (awaitedTypeOfSource && isTypeRelatedTo(awaitedTypeOfSource, target, relation)) {
                        ts.addRelatedInfo(errorOutputContainer.errors[0], ts.createDiagnosticForNode(errorNode, ts.Diagnostics.Did_you_forget_to_use_await));
                    }
                }
            }
        }
        /**
         * Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise.
         */
        function getThisArgumentOfCall(node) {
            if (node.kind === 196 /* CallExpression */) {
                var callee = ts.skipOuterExpressions(node.expression);
                if (ts.isAccessExpression(callee)) {
                    return callee.expression;
                }
            }
        }
        function createSyntheticExpression(parent, type, isSpread) {
            var result = ts.createNode(220 /* SyntheticExpression */, parent.pos, parent.end);
            result.parent = parent;
            result.type = type;
            result.isSpread = isSpread || false;
            return result;
        }
        /**
         * Returns the effective arguments for an expression that works like a function invocation.
         */
        function getEffectiveCallArguments(node) {
            if (node.kind === 198 /* TaggedTemplateExpression */) {
                var template = node.template;
                var args_3 = [createSyntheticExpression(template, getGlobalTemplateStringsArrayType())];
                if (template.kind === 211 /* TemplateExpression */) {
                    ts.forEach(template.templateSpans, function (span) {
                        args_3.push(span.expression);
                    });
                }
                return args_3;
            }
            if (node.kind === 157 /* Decorator */) {
                return getEffectiveDecoratorArguments(node);
            }
            if (ts.isJsxOpeningLikeElement(node)) {
                return node.attributes.properties.length > 0 || (ts.isJsxOpeningElement(node) && node.parent.children.length > 0) ? [node.attributes] : ts.emptyArray;
            }
            var args = node.arguments || ts.emptyArray;
            var length = args.length;
            if (length && isSpreadArgument(args[length - 1]) && getSpreadArgumentIndex(args) === length - 1) {
                // We have a spread argument in the last position and no other spread arguments. If the type
                // of the argument is a tuple type, spread the tuple elements into the argument list. We can
                // call checkExpressionCached because spread expressions never have a contextual type.
                var spreadArgument_1 = args[length - 1];
                var type = flowLoopCount ? checkExpression(spreadArgument_1.expression) : checkExpressionCached(spreadArgument_1.expression);
                if (isTupleType(type)) {
                    var typeArguments = getTypeArguments(type);
                    var restIndex_2 = type.target.hasRestElement ? typeArguments.length - 1 : -1;
                    var syntheticArgs = ts.map(typeArguments, function (t, i) { return createSyntheticExpression(spreadArgument_1, t, /*isSpread*/ i === restIndex_2); });
                    return ts.concatenate(args.slice(0, length - 1), syntheticArgs);
                }
            }
            return args;
        }
        /**
         * Returns the synthetic argument list for a decorator invocation.
         */
        function getEffectiveDecoratorArguments(node) {
            var parent = node.parent;
            var expr = node.expression;
            switch (parent.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    // For a class decorator, the `target` is the type of the class (e.g. the
                    // "static" or "constructor" side of the class).
                    return [
                        createSyntheticExpression(expr, getTypeOfSymbol(getSymbolOfNode(parent)))
                    ];
                case 156 /* Parameter */:
                    // A parameter declaration decorator will have three arguments (see
                    // `ParameterDecorator` in core.d.ts).
                    var func = parent.parent;
                    return [
                        createSyntheticExpression(expr, parent.parent.kind === 162 /* Constructor */ ? getTypeOfSymbol(getSymbolOfNode(func)) : errorType),
                        createSyntheticExpression(expr, anyType),
                        createSyntheticExpression(expr, numberType)
                    ];
                case 159 /* PropertyDeclaration */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    // A method or accessor declaration decorator will have two or three arguments (see
                    // `PropertyDecorator` and `MethodDecorator` in core.d.ts). If we are emitting decorators
                    // for ES3, we will only pass two arguments.
                    var hasPropDesc = parent.kind !== 159 /* PropertyDeclaration */ && languageVersion !== 0 /* ES3 */;
                    return [
                        createSyntheticExpression(expr, getParentTypeOfClassElement(parent)),
                        createSyntheticExpression(expr, getClassElementPropertyKeyType(parent)),
                        createSyntheticExpression(expr, hasPropDesc ? createTypedPropertyDescriptorType(getTypeOfNode(parent)) : anyType)
                    ];
            }
            return ts.Debug.fail();
        }
        /**
         * Returns the argument count for a decorator node that works like a function invocation.
         */
        function getDecoratorArgumentCount(node, signature) {
            switch (node.parent.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return 1;
                case 159 /* PropertyDeclaration */:
                    return 2;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    // For ES3 or decorators with only two parameters we supply only two arguments
                    return languageVersion === 0 /* ES3 */ || signature.parameters.length <= 2 ? 2 : 3;
                case 156 /* Parameter */:
                    return 3;
                default:
                    return ts.Debug.fail();
            }
        }
        function getDiagnosticSpanForCallNode(node, doNotIncludeArguments) {
            var start;
            var length;
            var sourceFile = ts.getSourceFileOfNode(node);
            if (ts.isPropertyAccessExpression(node.expression)) {
                var nameSpan = ts.getErrorSpanForNode(sourceFile, node.expression.name);
                start = nameSpan.start;
                length = doNotIncludeArguments ? nameSpan.length : node.end - start;
            }
            else {
                var expressionSpan = ts.getErrorSpanForNode(sourceFile, node.expression);
                start = expressionSpan.start;
                length = doNotIncludeArguments ? expressionSpan.length : node.end - start;
            }
            return { start: start, length: length, sourceFile: sourceFile };
        }
        function getDiagnosticForCallNode(node, message, arg0, arg1, arg2, arg3) {
            if (ts.isCallExpression(node)) {
                var _a = getDiagnosticSpanForCallNode(node), sourceFile = _a.sourceFile, start = _a.start, length_5 = _a.length;
                return ts.createFileDiagnostic(sourceFile, start, length_5, message, arg0, arg1, arg2, arg3);
            }
            else {
                return ts.createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3);
            }
        }
        function getArgumentArityError(node, signatures, args) {
            var min = Number.POSITIVE_INFINITY;
            var max = Number.NEGATIVE_INFINITY;
            var belowArgCount = Number.NEGATIVE_INFINITY;
            var aboveArgCount = Number.POSITIVE_INFINITY;
            var argCount = args.length;
            var closestSignature;
            for (var _i = 0, signatures_8 = signatures; _i < signatures_8.length; _i++) {
                var sig = signatures_8[_i];
                var minCount = getMinArgumentCount(sig);
                var maxCount = getParameterCount(sig);
                if (minCount < argCount && minCount > belowArgCount)
                    belowArgCount = minCount;
                if (argCount < maxCount && maxCount < aboveArgCount)
                    aboveArgCount = maxCount;
                if (minCount < min) {
                    min = minCount;
                    closestSignature = sig;
                }
                max = Math.max(max, maxCount);
            }
            var hasRestParameter = ts.some(signatures, hasEffectiveRestParameter);
            var paramRange = hasRestParameter ? min :
                min < max ? min + "-" + max :
                    min;
            var hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
            if (argCount <= max && hasSpreadArgument) {
                argCount--;
            }
            var spanArray;
            var related;
            var error = hasRestParameter || hasSpreadArgument ? hasRestParameter && hasSpreadArgument ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
                hasRestParameter ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1 :
                    ts.Diagnostics.Expected_0_arguments_but_got_1_or_more : ts.Diagnostics.Expected_0_arguments_but_got_1;
            if (closestSignature && getMinArgumentCount(closestSignature) > argCount && closestSignature.declaration) {
                var paramDecl = closestSignature.declaration.parameters[closestSignature.thisParameter ? argCount + 1 : argCount];
                if (paramDecl) {
                    related = ts.createDiagnosticForNode(paramDecl, ts.isBindingPattern(paramDecl.name) ? ts.Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided : ts.Diagnostics.An_argument_for_0_was_not_provided, !paramDecl.name ? argCount : !ts.isBindingPattern(paramDecl.name) ? ts.idText(ts.getFirstIdentifier(paramDecl.name)) : undefined);
                }
            }
            if (min < argCount && argCount < max) {
                return getDiagnosticForCallNode(node, ts.Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, argCount, belowArgCount, aboveArgCount);
            }
            if (!hasSpreadArgument && argCount < min) {
                var diagnostic_1 = getDiagnosticForCallNode(node, error, paramRange, argCount);
                return related ? ts.addRelatedInfo(diagnostic_1, related) : diagnostic_1;
            }
            if (hasRestParameter || hasSpreadArgument) {
                spanArray = ts.createNodeArray(args);
                if (hasSpreadArgument && argCount) {
                    var nextArg = ts.elementAt(args, getSpreadArgumentIndex(args) + 1) || undefined;
                    spanArray = ts.createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : Math.min(max, args.length - 1)));
                }
            }
            else {
                spanArray = ts.createNodeArray(args.slice(max));
            }
            spanArray.pos = ts.first(spanArray).pos;
            spanArray.end = ts.last(spanArray).end;
            if (spanArray.end === spanArray.pos) {
                spanArray.end++;
            }
            var diagnostic = ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), spanArray, error, paramRange, argCount);
            return related ? ts.addRelatedInfo(diagnostic, related) : diagnostic;
        }
        function getTypeArgumentArityError(node, signatures, typeArguments) {
            var argCount = typeArguments.length;
            // No overloads exist
            if (signatures.length === 1) {
                var sig = signatures[0];
                var min_1 = getMinTypeArgumentCount(sig.typeParameters);
                var max = ts.length(sig.typeParameters);
                return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Expected_0_type_arguments_but_got_1, min_1 < max ? min_1 + "-" + max : min_1, argCount);
            }
            // Overloads exist
            var belowArgCount = -Infinity;
            var aboveArgCount = Infinity;
            for (var _i = 0, signatures_9 = signatures; _i < signatures_9.length; _i++) {
                var sig = signatures_9[_i];
                var min_2 = getMinTypeArgumentCount(sig.typeParameters);
                var max = ts.length(sig.typeParameters);
                if (min_2 > argCount) {
                    aboveArgCount = Math.min(aboveArgCount, min_2);
                }
                else if (max < argCount) {
                    belowArgCount = Math.max(belowArgCount, max);
                }
            }
            if (belowArgCount !== -Infinity && aboveArgCount !== Infinity) {
                return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments, argCount, belowArgCount, aboveArgCount);
            }
            return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
        }
        function resolveCall(node, signatures, candidatesOutArray, checkMode, callChainFlags, fallbackError) {
            var isTaggedTemplate = node.kind === 198 /* TaggedTemplateExpression */;
            var isDecorator = node.kind === 157 /* Decorator */;
            var isJsxOpeningOrSelfClosingElement = ts.isJsxOpeningLikeElement(node);
            var reportErrors = !candidatesOutArray;
            var typeArguments;
            if (!isDecorator) {
                typeArguments = node.typeArguments;
                // We already perform checking on the type arguments on the class declaration itself.
                if (isTaggedTemplate || isJsxOpeningOrSelfClosingElement || node.expression.kind !== 102 /* SuperKeyword */) {
                    ts.forEach(typeArguments, checkSourceElement);
                }
            }
            var candidates = candidatesOutArray || [];
            // reorderCandidates fills up the candidates array directly
            reorderCandidates(signatures, candidates, callChainFlags);
            if (!candidates.length) {
                if (reportErrors) {
                    diagnostics.add(getDiagnosticForCallNode(node, ts.Diagnostics.Call_target_does_not_contain_any_signatures));
                }
                return resolveErrorCall(node);
            }
            var args = getEffectiveCallArguments(node);
            // The excludeArgument array contains true for each context sensitive argument (an argument
            // is context sensitive it is susceptible to a one-time permanent contextual typing).
            //
            // The idea is that we will perform type argument inference & assignability checking once
            // without using the susceptible parameters that are functions, and once more for those
            // parameters, contextually typing each as we go along.
            //
            // For a tagged template, then the first argument be 'undefined' if necessary because it
            // represents a TemplateStringsArray.
            //
            // For a decorator, no arguments are susceptible to contextual typing due to the fact
            // decorators are applied to a declaration by the emitter, and not to an expression.
            var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
            var argCheckMode = !isDecorator && !isSingleNonGenericCandidate && ts.some(args, isContextSensitive) ? 4 /* SkipContextSensitive */ : 0 /* Normal */;
            // The following variables are captured and modified by calls to chooseOverload.
            // If overload resolution or type argument inference fails, we want to report the
            // best error possible. The best error is one which says that an argument was not
            // assignable to a parameter. This implies that everything else about the overload
            // was fine. So if there is any overload that is only incorrect because of an
            // argument, we will report an error on that one.
            //
            //     function foo(s: string): void;
            //     function foo(n: number): void; // Report argument error on this overload
            //     function foo(): void;
            //     foo(true);
            //
            // If none of the overloads even made it that far, there are two possibilities.
            // There was a problem with type arguments for some overload, in which case
            // report an error on that. Or none of the overloads even had correct arity,
            // in which case give an arity error.
            //
            //     function foo<T extends string>(x: T): void; // Report type argument error
            //     function foo(): void;
            //     foo<number>(0);
            //
            var candidatesForArgumentError;
            var candidateForArgumentArityError;
            var candidateForTypeArgumentError;
            var result;
            // If we are in signature help, a trailing comma indicates that we intend to provide another argument,
            // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
            var signatureHelpTrailingComma = !!(checkMode & 16 /* IsForSignatureHelp */) && node.kind === 196 /* CallExpression */ && node.arguments.hasTrailingComma;
            // Section 4.12.1:
            // if the candidate list contains one or more signatures for which the type of each argument
            // expression is a subtype of each corresponding parameter type, the return type of the first
            // of those signatures becomes the return type of the function call.
            // Otherwise, the return type of the first signature in the candidate list becomes the return
            // type of the function call.
            //
            // Whether the call is an error is determined by assignability of the arguments. The subtype pass
            // is just important for choosing the best signature. So in the case where there is only one
            // signature, the subtype pass is useless. So skipping it is an optimization.
            if (candidates.length > 1) {
                result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma);
            }
            if (!result) {
                result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma);
            }
            if (result) {
                return result;
            }
            // No signatures were applicable. Now report errors based on the last applicable signature with
            // no arguments excluded from assignability checks.
            // If candidate is undefined, it means that no candidates had a suitable arity. In that case,
            // skip the checkApplicableSignature check.
            if (reportErrors) {
                if (candidatesForArgumentError) {
                    if (candidatesForArgumentError.length === 1 || candidatesForArgumentError.length > 3) {
                        var last_2 = candidatesForArgumentError[candidatesForArgumentError.length - 1];
                        var chain_1;
                        if (candidatesForArgumentError.length > 3) {
                            chain_1 = ts.chainDiagnosticMessages(chain_1, ts.Diagnostics.The_last_overload_gave_the_following_error);
                            chain_1 = ts.chainDiagnosticMessages(chain_1, ts.Diagnostics.No_overload_matches_this_call);
                        }
                        var diags = getSignatureApplicabilityError(node, args, last_2, assignableRelation, 0 /* Normal */, /*reportErrors*/ true, function () { return chain_1; });
                        if (diags) {
                            for (var _i = 0, diags_1 = diags; _i < diags_1.length; _i++) {
                                var d = diags_1[_i];
                                if (last_2.declaration && candidatesForArgumentError.length > 3) {
                                    ts.addRelatedInfo(d, ts.createDiagnosticForNode(last_2.declaration, ts.Diagnostics.The_last_overload_is_declared_here));
                                }
                                diagnostics.add(d);
                            }
                        }
                        else {
                            ts.Debug.fail("No error for last overload signature");
                        }
                    }
                    else {
                        var allDiagnostics = [];
                        var max = 0;
                        var min_3 = Number.MAX_VALUE;
                        var minIndex = 0;
                        var i_1 = 0;
                        var _loop_17 = function (c) {
                            var chain_2 = function () { return ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Overload_0_of_1_2_gave_the_following_error, i_1 + 1, candidates.length, signatureToString(c)); };
                            var diags_2 = getSignatureApplicabilityError(node, args, c, assignableRelation, 0 /* Normal */, /*reportErrors*/ true, chain_2);
                            if (diags_2) {
                                if (diags_2.length <= min_3) {
                                    min_3 = diags_2.length;
                                    minIndex = i_1;
                                }
                                max = Math.max(max, diags_2.length);
                                allDiagnostics.push(diags_2);
                            }
                            else {
                                ts.Debug.fail("No error for 3 or fewer overload signatures");
                            }
                            i_1++;
                        };
                        for (var _a = 0, candidatesForArgumentError_1 = candidatesForArgumentError; _a < candidatesForArgumentError_1.length; _a++) {
                            var c = candidatesForArgumentError_1[_a];
                            _loop_17(c);
                        }
                        var diags_3 = max > 1 ? allDiagnostics[minIndex] : ts.flatten(allDiagnostics);
                        ts.Debug.assert(diags_3.length > 0, "No errors reported for 3 or fewer overload signatures");
                        var chain = ts.chainDiagnosticMessages(ts.map(diags_3, function (d) { return typeof d.messageText === "string" ? d : d.messageText; }), ts.Diagnostics.No_overload_matches_this_call);
                        var related = ts.flatMap(diags_3, function (d) { return d.relatedInformation; });
                        if (ts.every(diags_3, function (d) { return d.start === diags_3[0].start && d.length === diags_3[0].length && d.file === diags_3[0].file; })) {
                            var _b = diags_3[0], file = _b.file, start = _b.start, length_6 = _b.length;
                            diagnostics.add({ file: file, start: start, length: length_6, code: chain.code, category: chain.category, messageText: chain, relatedInformation: related });
                        }
                        else {
                            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(node, chain, related));
                        }
                    }
                }
                else if (candidateForArgumentArityError) {
                    diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args));
                }
                else if (candidateForTypeArgumentError) {
                    checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, /*reportErrors*/ true, fallbackError);
                }
                else {
                    var signaturesWithCorrectTypeArgumentArity = ts.filter(signatures, function (s) { return hasCorrectTypeArgumentArity(s, typeArguments); });
                    if (signaturesWithCorrectTypeArgumentArity.length === 0) {
                        diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments));
                    }
                    else if (!isDecorator) {
                        diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args));
                    }
                    else if (fallbackError) {
                        diagnostics.add(getDiagnosticForCallNode(node, fallbackError));
                    }
                }
            }
            return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray);
            function chooseOverload(candidates, relation, signatureHelpTrailingComma) {
                if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
                candidatesForArgumentError = undefined;
                candidateForArgumentArityError = undefined;
                candidateForTypeArgumentError = undefined;
                if (isSingleNonGenericCandidate) {
                    var candidate = candidates[0];
                    if (ts.some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                        return undefined;
                    }
                    if (getSignatureApplicabilityError(node, args, candidate, relation, 0 /* Normal */, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                        candidatesForArgumentError = [candidate];
                        return undefined;
                    }
                    return candidate;
                }
                for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
                    var candidate = candidates[candidateIndex];
                    if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                        continue;
                    }
                    var checkCandidate = void 0;
                    var inferenceContext = void 0;
                    if (candidate.typeParameters) {
                        var typeArgumentTypes = void 0;
                        if (ts.some(typeArguments)) {
                            typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
                            if (!typeArgumentTypes) {
                                candidateForTypeArgumentError = candidate;
                                continue;
                            }
                        }
                        else {
                            inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ ts.isInJSFile(node) ? 2 /* AnyDefault */ : 0 /* None */);
                            typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | 8 /* SkipGenericFunctions */, inferenceContext);
                            argCheckMode |= inferenceContext.flags & 4 /* SkippedGenericFunction */ ? 8 /* SkipGenericFunctions */ : 0 /* Normal */;
                        }
                        checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, ts.isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
                        // If the original signature has a generic rest type, instantiation may produce a
                        // signature with different arity and we need to perform another arity check.
                        if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
                            candidateForArgumentArityError = checkCandidate;
                            continue;
                        }
                    }
                    else {
                        checkCandidate = candidate;
                    }
                    if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                        // Give preference to error candidates that have no rest parameters (as they are more specific)
                        (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
                        continue;
                    }
                    if (argCheckMode) {
                        // If one or more context sensitive arguments were excluded, we start including
                        // them now (and keeping do so for any subsequent candidates) and perform a second
                        // round of type inference and applicability checking for this particular candidate.
                        argCheckMode = 0 /* Normal */;
                        if (inferenceContext) {
                            var typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
                            checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, ts.isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
                            // If the original signature has a generic rest type, instantiation may produce a
                            // signature with different arity and we need to perform another arity check.
                            if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
                                candidateForArgumentArityError = checkCandidate;
                                continue;
                            }
                        }
                        if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                            // Give preference to error candidates that have no rest parameters (as they are more specific)
                            (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
                            continue;
                        }
                    }
                    candidates[candidateIndex] = checkCandidate;
                    return checkCandidate;
                }
                return undefined;
            }
        }
        // No signature was applicable. We have already reported the errors for the invalid signature.
        function getCandidateForOverloadFailure(node, candidates, args, hasCandidatesOutArray) {
            ts.Debug.assert(candidates.length > 0); // Else should not have called this.
            checkNodeDeferred(node);
            // Normally we will combine overloads. Skip this if they have type parameters since that's hard to combine.
            // Don't do this if there is a `candidatesOutArray`,
            // because then we want the chosen best candidate to be one of the overloads, not a combination.
            return hasCandidatesOutArray || candidates.length === 1 || candidates.some(function (c) { return !!c.typeParameters; })
                ? pickLongestCandidateSignature(node, candidates, args)
                : createUnionOfSignaturesForOverloadFailure(candidates);
        }
        function createUnionOfSignaturesForOverloadFailure(candidates) {
            var thisParameters = ts.mapDefined(candidates, function (c) { return c.thisParameter; });
            var thisParameter;
            if (thisParameters.length) {
                thisParameter = createCombinedSymbolFromTypes(thisParameters, thisParameters.map(getTypeOfParameter));
            }
            var _a = ts.minAndMax(candidates, getNumNonRestParameters), minArgumentCount = _a.min, maxNonRestParam = _a.max;
            var parameters = [];
            var _loop_18 = function (i) {
                var symbols = ts.mapDefined(candidates, function (s) { return signatureHasRestParameter(s) ?
                    i < s.parameters.length - 1 ? s.parameters[i] : ts.last(s.parameters) :
                    i < s.parameters.length ? s.parameters[i] : undefined; });
                ts.Debug.assert(symbols.length !== 0);
                parameters.push(createCombinedSymbolFromTypes(symbols, ts.mapDefined(candidates, function (candidate) { return tryGetTypeAtPosition(candidate, i); })));
            };
            for (var i = 0; i < maxNonRestParam; i++) {
                _loop_18(i);
            }
            var restParameterSymbols = ts.mapDefined(candidates, function (c) { return signatureHasRestParameter(c) ? ts.last(c.parameters) : undefined; });
            var flags = 0 /* None */;
            if (restParameterSymbols.length !== 0) {
                var type = createArrayType(getUnionType(ts.mapDefined(candidates, tryGetRestTypeOfSignature), 2 /* Subtype */));
                parameters.push(createCombinedSymbolForOverloadFailure(restParameterSymbols, type));
                flags |= 1 /* HasRestParameter */;
            }
            if (candidates.some(signatureHasLiteralTypes)) {
                flags |= 2 /* HasLiteralTypes */;
            }
            return createSignature(candidates[0].declaration, 
            /*typeParameters*/ undefined, // Before calling this we tested for `!candidates.some(c => !!c.typeParameters)`.
            thisParameter, parameters, 
            /*resolvedReturnType*/ getIntersectionType(candidates.map(getReturnTypeOfSignature)), 
            /*typePredicate*/ undefined, minArgumentCount, flags);
        }
        function getNumNonRestParameters(signature) {
            var numParams = signature.parameters.length;
            return signatureHasRestParameter(signature) ? numParams - 1 : numParams;
        }
        function createCombinedSymbolFromTypes(sources, types) {
            return createCombinedSymbolForOverloadFailure(sources, getUnionType(types, 2 /* Subtype */));
        }
        function createCombinedSymbolForOverloadFailure(sources, type) {
            // This function is currently only used for erroneous overloads, so it's good enough to just use the first source.
            return createSymbolWithType(ts.first(sources), type);
        }
        function pickLongestCandidateSignature(node, candidates, args) {
            // Pick the longest signature. This way we can get a contextual type for cases like:
            //     declare function f(a: { xa: number; xb: number; }, b: number);
            //     f({ |
            // Also, use explicitly-supplied type arguments if they are provided, so we can get a contextual signature in cases like:
            //     declare function f<T>(k: keyof T);
            //     f<Foo>("
            var bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === undefined ? args.length : apparentArgumentCount);
            var candidate = candidates[bestIndex];
            var typeParameters = candidate.typeParameters;
            if (!typeParameters) {
                return candidate;
            }
            var typeArgumentNodes = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined;
            var instantiated = typeArgumentNodes
                ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, ts.isInJSFile(node)))
                : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args);
            candidates[bestIndex] = instantiated;
            return instantiated;
        }
        function getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isJs) {
            var typeArguments = typeArgumentNodes.map(getTypeOfNode);
            while (typeArguments.length > typeParameters.length) {
                typeArguments.pop();
            }
            while (typeArguments.length < typeParameters.length) {
                typeArguments.push(getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isJs));
            }
            return typeArguments;
        }
        function inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args) {
            var inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ ts.isInJSFile(node) ? 2 /* AnyDefault */ : 0 /* None */);
            var typeArgumentTypes = inferTypeArguments(node, candidate, args, 4 /* SkipContextSensitive */ | 8 /* SkipGenericFunctions */, inferenceContext);
            return createSignatureInstantiation(candidate, typeArgumentTypes);
        }
        function getLongestCandidateIndex(candidates, argsCount) {
            var maxParamsIndex = -1;
            var maxParams = -1;
            for (var i = 0; i < candidates.length; i++) {
                var candidate = candidates[i];
                var paramCount = getParameterCount(candidate);
                if (hasEffectiveRestParameter(candidate) || paramCount >= argsCount) {
                    return i;
                }
                if (paramCount > maxParams) {
                    maxParams = paramCount;
                    maxParamsIndex = i;
                }
            }
            return maxParamsIndex;
        }
        function resolveCallExpression(node, candidatesOutArray, checkMode) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                var superType = checkSuperExpression(node.expression);
                if (isTypeAny(superType)) {
                    for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) {
                        var arg = _a[_i];
                        checkExpression(arg); // Still visit arguments so they get marked for visibility, etc
                    }
                    return anySignature;
                }
                if (superType !== errorType) {
                    // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated
                    // with the type arguments specified in the extends clause.
                    var baseTypeNode = ts.getEffectiveBaseTypeNode(ts.getContainingClass(node));
                    if (baseTypeNode) {
                        var baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
                        return resolveCall(node, baseConstructors, candidatesOutArray, checkMode, 0 /* None */);
                    }
                }
                return resolveUntypedCall(node);
            }
            var callChainFlags;
            var funcType = checkExpression(node.expression);
            if (ts.isCallChain(node)) {
                var nonOptionalType = getOptionalExpressionType(funcType, node.expression);
                callChainFlags = nonOptionalType === funcType ? 0 /* None */ :
                    ts.isOutermostOptionalChain(node) ? 8 /* IsOuterCallChain */ :
                        4 /* IsInnerCallChain */;
                funcType = nonOptionalType;
            }
            else {
                callChainFlags = 0 /* None */;
            }
            funcType = checkNonNullTypeWithReporter(funcType, node.expression, reportCannotInvokePossiblyNullOrUndefinedError);
            if (funcType === silentNeverType) {
                return silentNeverSignature;
            }
            var apparentType = getApparentType(funcType);
            if (apparentType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            // Technically, this signatures list may be incomplete. We are taking the apparent type,
            // but we are not including call signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            // TS 1.0 Spec: 4.12
            // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
            // types are provided for the argument expressions, and the result is always of type Any.
            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
                // The unknownType indicates that an error already occurred (and was reported).  No
                // need to report another error in this case.
                if (funcType !== errorType && node.typeArguments) {
                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                }
                return resolveUntypedCall(node);
            }
            // If FuncExpr's apparent type(section 3.8.1) is a function type, the call is a typed function call.
            // TypeScript employs overload resolution in typed function calls in order to support functions
            // with multiple call signatures.
            if (!callSignatures.length) {
                if (numConstructSignatures) {
                    error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
                }
                else {
                    var relatedInformation = void 0;
                    if (node.arguments.length === 1) {
                        var text = ts.getSourceFileOfNode(node).text;
                        if (ts.isLineBreak(text.charCodeAt(ts.skipTrivia(text, node.expression.end, /* stopAfterLineBreak */ true) - 1))) {
                            relatedInformation = ts.createDiagnosticForNode(node.expression, ts.Diagnostics.Are_you_missing_a_semicolon);
                        }
                    }
                    invocationError(node.expression, apparentType, 0 /* Call */, relatedInformation);
                }
                return resolveErrorCall(node);
            }
            // When a call to a generic function is an argument to an outer call to a generic function for which
            // inference is in process, we have a choice to make. If the inner call relies on inferences made from
            // its contextual type to its return type, deferring the inner call processing allows the best possible
            // contextual type to accumulate. But if the outer call relies on inferences made from the return type of
            // the inner call, the inner call should be processed early. There's no sure way to know which choice is
            // right (only a full unification algorithm can determine that), so we resort to the following heuristic:
            // If no type arguments are specified in the inner call and at least one call signature is generic and
            // returns a function type, we choose to defer processing. This narrowly permits function composition
            // operators to flow inferences through return types, but otherwise processes calls right away. We
            // use the resolvingSignature singleton to indicate that we deferred processing. This result will be
            // propagated out and eventually turned into nonInferrableType (a type that is assignable to anything and
            // from which we never make inferences).
            if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
                skippedGenericFunction(node, checkMode);
                return resolvingSignature;
            }
            // If the function is explicitly marked with `@class`, then it must be constructed.
            if (callSignatures.some(function (sig) { return ts.isInJSFile(sig.declaration) && !!ts.getJSDocClassTag(sig.declaration); })) {
                error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags);
        }
        function isGenericFunctionReturningFunction(signature) {
            return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature)));
        }
        /**
         * TS 1.0 spec: 4.12
         * If FuncExpr is of type Any, or of an object type that has no call or construct signatures
         * but is a subtype of the Function interface, the call is an untyped function call.
         */
        function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) {
            // We exclude union types because we may have a union of function types that happen to have no common signatures.
            return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & 262144 /* TypeParameter */) ||
                !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (1048576 /* Union */ | 131072 /* Never */)) && isTypeAssignableTo(funcType, globalFunctionType);
        }
        function resolveNewExpression(node, candidatesOutArray, checkMode) {
            if (node.arguments && languageVersion < 1 /* ES5 */) {
                var spreadIndex = getSpreadArgumentIndex(node.arguments);
                if (spreadIndex >= 0) {
                    error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher);
                }
            }
            var expressionType = checkNonNullExpression(node.expression);
            if (expressionType === silentNeverType) {
                return silentNeverSignature;
            }
            // If expressionType's apparent type(section 3.8.1) is an object type with one or
            // more construct signatures, the expression is processed in the same manner as a
            // function call, but using the construct signatures as the initial set of candidate
            // signatures for overload resolution. The result type of the function call becomes
            // the result type of the operation.
            expressionType = getApparentType(expressionType);
            if (expressionType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            // TS 1.0 spec: 4.11
            // If expressionType is of type Any, Args can be any argument
            // list and the result of the operation is of type Any.
            if (isTypeAny(expressionType)) {
                if (node.typeArguments) {
                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                }
                return resolveUntypedCall(node);
            }
            // Technically, this signatures list may be incomplete. We are taking the apparent type,
            // but we are not including construct signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            var constructSignatures = getSignaturesOfType(expressionType, 1 /* Construct */);
            if (constructSignatures.length) {
                if (!isConstructorAccessible(node, constructSignatures[0])) {
                    return resolveErrorCall(node);
                }
                // If the expression is a class of abstract type, then it cannot be instantiated.
                // Note, only class declarations can be declared abstract.
                // In the case of a merged class-module or class-interface declaration,
                // only the class declaration node will have the Abstract flag set.
                var valueDecl = expressionType.symbol && ts.getClassLikeDeclarationOfSymbol(expressionType.symbol);
                if (valueDecl && ts.hasModifier(valueDecl, 128 /* Abstract */)) {
                    error(node, ts.Diagnostics.Cannot_create_an_instance_of_an_abstract_class);
                    return resolveErrorCall(node);
                }
                return resolveCall(node, constructSignatures, candidatesOutArray, checkMode, 0 /* None */);
            }
            // If expressionType's apparent type is an object type with no construct signatures but
            // one or more call signatures, the expression is processed as a function call. A compile-time
            // error occurs if the result of the function call is not Void. The type of the result of the
            // operation is Any. It is an error to have a Void this type.
            var callSignatures = getSignaturesOfType(expressionType, 0 /* Call */);
            if (callSignatures.length) {
                var signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode, 0 /* None */);
                if (!noImplicitAny) {
                    if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
                        error(node, ts.Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
                    }
                    if (getThisTypeOfSignature(signature) === voidType) {
                        error(node, ts.Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void);
                    }
                }
                return signature;
            }
            invocationError(node.expression, expressionType, 1 /* Construct */);
            return resolveErrorCall(node);
        }
        function typeHasProtectedAccessibleBase(target, type) {
            var baseTypes = getBaseTypes(type);
            if (!ts.length(baseTypes)) {
                return false;
            }
            var firstBase = baseTypes[0];
            if (firstBase.flags & 2097152 /* Intersection */) {
                var types = firstBase.types;
                var mixinFlags = findMixins(types);
                var i = 0;
                for (var _i = 0, _a = firstBase.types; _i < _a.length; _i++) {
                    var intersectionMember = _a[_i];
                    // We want to ignore mixin ctors
                    if (!mixinFlags[i]) {
                        if (ts.getObjectFlags(intersectionMember) & (1 /* Class */ | 2 /* Interface */)) {
                            if (intersectionMember.symbol === target) {
                                return true;
                            }
                            if (typeHasProtectedAccessibleBase(target, intersectionMember)) {
                                return true;
                            }
                        }
                    }
                    i++;
                }
                return false;
            }
            if (firstBase.symbol === target) {
                return true;
            }
            return typeHasProtectedAccessibleBase(target, firstBase);
        }
        function isConstructorAccessible(node, signature) {
            if (!signature || !signature.declaration) {
                return true;
            }
            var declaration = signature.declaration;
            var modifiers = ts.getSelectedModifierFlags(declaration, 24 /* NonPublicAccessibilityModifier */);
            // (1) Public constructors and (2) constructor functions are always accessible.
            if (!modifiers || declaration.kind !== 162 /* Constructor */) {
                return true;
            }
            var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(declaration.parent.symbol);
            var declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol);
            // A private or protected constructor can only be instantiated within its own class (or a subclass, for protected)
            if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                var containingClass = ts.getContainingClass(node);
                if (containingClass && modifiers & 16 /* Protected */) {
                    var containingType = getTypeOfNode(containingClass);
                    if (typeHasProtectedAccessibleBase(declaration.parent.symbol, containingType)) {
                        return true;
                    }
                }
                if (modifiers & 8 /* Private */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                if (modifiers & 16 /* Protected */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                return false;
            }
            return true;
        }
        function invocationErrorDetails(apparentType, kind) {
            var errorInfo;
            var isCall = kind === 0 /* Call */;
            var awaitedType = getAwaitedType(apparentType);
            var maybeMissingAwait = awaitedType && getSignaturesOfType(awaitedType, kind).length > 0;
            if (apparentType.flags & 1048576 /* Union */) {
                var types = apparentType.types;
                var hasSignatures = false;
                for (var _i = 0, types_18 = types; _i < types_18.length; _i++) {
                    var constituent = types_18[_i];
                    var signatures = getSignaturesOfType(constituent, kind);
                    if (signatures.length !== 0) {
                        hasSignatures = true;
                        if (errorInfo) {
                            // Bail early if we already have an error, no chance of "No constituent of type is callable"
                            break;
                        }
                    }
                    else {
                        // Error on the first non callable constituent only
                        if (!errorInfo) {
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ?
                                ts.Diagnostics.Type_0_has_no_call_signatures :
                                ts.Diagnostics.Type_0_has_no_construct_signatures, typeToString(constituent));
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ?
                                ts.Diagnostics.Not_all_constituents_of_type_0_are_callable :
                                ts.Diagnostics.Not_all_constituents_of_type_0_are_constructable, typeToString(apparentType));
                        }
                        if (hasSignatures) {
                            // Bail early if we already found a siganture, no chance of "No constituent of type is callable"
                            break;
                        }
                    }
                }
                if (!hasSignatures) {
                    errorInfo = ts.chainDiagnosticMessages(
                    /* detials */ undefined, isCall ?
                        ts.Diagnostics.No_constituent_of_type_0_is_callable :
                        ts.Diagnostics.No_constituent_of_type_0_is_constructable, typeToString(apparentType));
                }
                if (!errorInfo) {
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ?
                        ts.Diagnostics.Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_other :
                        ts.Diagnostics.Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_with_each_other, typeToString(apparentType));
                }
            }
            else {
                errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ?
                    ts.Diagnostics.Type_0_has_no_call_signatures :
                    ts.Diagnostics.Type_0_has_no_construct_signatures, typeToString(apparentType));
            }
            return {
                messageChain: ts.chainDiagnosticMessages(errorInfo, isCall ? ts.Diagnostics.This_expression_is_not_callable : ts.Diagnostics.This_expression_is_not_constructable),
                relatedMessage: maybeMissingAwait ? ts.Diagnostics.Did_you_forget_to_use_await : undefined,
            };
        }
        function invocationError(errorTarget, apparentType, kind, relatedInformation) {
            var _a = invocationErrorDetails(apparentType, kind), messageChain = _a.messageChain, relatedInfo = _a.relatedMessage;
            var diagnostic = ts.createDiagnosticForNodeFromMessageChain(errorTarget, messageChain);
            if (relatedInfo) {
                ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(errorTarget, relatedInfo));
            }
            if (ts.isCallExpression(errorTarget.parent)) {
                var _b = getDiagnosticSpanForCallNode(errorTarget.parent, /* doNotIncludeArguments */ true), start = _b.start, length_7 = _b.length;
                diagnostic.start = start;
                diagnostic.length = length_7;
            }
            diagnostics.add(diagnostic);
            invocationErrorRecovery(apparentType, kind, relatedInformation ? ts.addRelatedInfo(diagnostic, relatedInformation) : diagnostic);
        }
        function invocationErrorRecovery(apparentType, kind, diagnostic) {
            if (!apparentType.symbol) {
                return;
            }
            var importNode = getSymbolLinks(apparentType.symbol).originatingImport;
            // Create a diagnostic on the originating import if possible onto which we can attach a quickfix
            //  An import call expression cannot be rewritten into another form to correct the error - the only solution is to use `.default` at the use-site
            if (importNode && !ts.isImportCall(importNode)) {
                var sigs = getSignaturesOfType(getTypeOfSymbol(getSymbolLinks(apparentType.symbol).target), kind);
                if (!sigs || !sigs.length)
                    return;
                ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(importNode, ts.Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead));
            }
        }
        function resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode) {
            var tagType = checkExpression(node.tag);
            var apparentType = getApparentType(tagType);
            if (apparentType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, numConstructSignatures)) {
                return resolveUntypedCall(node);
            }
            if (!callSignatures.length) {
                invocationError(node.tag, apparentType, 0 /* Call */);
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode, 0 /* None */);
        }
        /**
         * Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression.
         */
        function getDiagnosticHeadMessageForDecoratorResolution(node) {
            switch (node.parent.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression;
                case 156 /* Parameter */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression;
                case 159 /* PropertyDeclaration */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression;
                default:
                    return ts.Debug.fail();
            }
        }
        /**
         * Resolves a decorator as if it were a call expression.
         */
        function resolveDecorator(node, candidatesOutArray, checkMode) {
            var funcType = checkExpression(node.expression);
            var apparentType = getApparentType(funcType);
            if (apparentType === errorType) {
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
                return resolveUntypedCall(node);
            }
            if (isPotentiallyUncalledDecorator(node, callSignatures)) {
                var nodeStr = ts.getTextOfNode(node.expression, /*includeTrivia*/ false);
                error(node, ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr);
                return resolveErrorCall(node);
            }
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            if (!callSignatures.length) {
                var errorDetails = invocationErrorDetails(apparentType, 0 /* Call */);
                var messageChain = ts.chainDiagnosticMessages(errorDetails.messageChain, headMessage);
                var diag = ts.createDiagnosticForNodeFromMessageChain(node.expression, messageChain);
                if (errorDetails.relatedMessage) {
                    ts.addRelatedInfo(diag, ts.createDiagnosticForNode(node.expression, errorDetails.relatedMessage));
                }
                diagnostics.add(diag);
                invocationErrorRecovery(apparentType, 0 /* Call */, diag);
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode, 0 /* None */, headMessage);
        }
        function createSignatureForJSXIntrinsic(node, result) {
            var namespace = getJsxNamespaceAt(node);
            var exports = namespace && getExportsOfSymbol(namespace);
            // We fake up a SFC signature for each intrinsic, however a more specific per-element signature drawn from the JSX declaration
            // file would probably be preferable.
            var typeSymbol = exports && getSymbol(exports, JsxNames.Element, 788968 /* Type */);
            var returnNode = typeSymbol && nodeBuilder.symbolToEntityName(typeSymbol, 788968 /* Type */, node);
            var declaration = ts.createFunctionTypeNode(/*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotdotdot*/ undefined, "props", /*questionMark*/ undefined, nodeBuilder.typeToTypeNode(result, node))], returnNode ? ts.createTypeReferenceNode(returnNode, /*typeArguments*/ undefined) : ts.createKeywordTypeNode(125 /* AnyKeyword */));
            var parameterSymbol = createSymbol(1 /* FunctionScopedVariable */, "props");
            parameterSymbol.type = result;
            return createSignature(declaration, 
            /*typeParameters*/ undefined, 
            /*thisParameter*/ undefined, [parameterSymbol], typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType, 
            /*returnTypePredicate*/ undefined, 1, 0 /* None */);
        }
        function resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode) {
            if (isJsxIntrinsicIdentifier(node.tagName)) {
                var result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
                var fakeSignature = createSignatureForJSXIntrinsic(node, result);
                checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined, 0 /* Normal */), result, node.tagName, node.attributes);
                return fakeSignature;
            }
            var exprTypes = checkExpression(node.tagName);
            var apparentType = getApparentType(exprTypes);
            if (apparentType === errorType) {
                return resolveErrorCall(node);
            }
            var signatures = getUninstantiatedJsxSignaturesOfType(exprTypes, node);
            if (isUntypedFunctionCall(exprTypes, apparentType, signatures.length, /*constructSignatures*/ 0)) {
                return resolveUntypedCall(node);
            }
            if (signatures.length === 0) {
                // We found no signatures at all, which is an error
                error(node.tagName, ts.Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, ts.getTextOfNode(node.tagName));
                return resolveErrorCall(node);
            }
            return resolveCall(node, signatures, candidatesOutArray, checkMode, 0 /* None */);
        }
        /**
         * Sometimes, we have a decorator that could accept zero arguments,
         * but is receiving too many arguments as part of the decorator invocation.
         * In those cases, a user may have meant to *call* the expression before using it as a decorator.
         */
        function isPotentiallyUncalledDecorator(decorator, signatures) {
            return signatures.length && ts.every(signatures, function (signature) {
                return signature.minArgumentCount === 0 &&
                    !signatureHasRestParameter(signature) &&
                    signature.parameters.length < getDecoratorArgumentCount(decorator, signature);
            });
        }
        function resolveSignature(node, candidatesOutArray, checkMode) {
            switch (node.kind) {
                case 196 /* CallExpression */:
                    return resolveCallExpression(node, candidatesOutArray, checkMode);
                case 197 /* NewExpression */:
                    return resolveNewExpression(node, candidatesOutArray, checkMode);
                case 198 /* TaggedTemplateExpression */:
                    return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode);
                case 157 /* Decorator */:
                    return resolveDecorator(node, candidatesOutArray, checkMode);
                case 268 /* JsxOpeningElement */:
                case 267 /* JsxSelfClosingElement */:
                    return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode);
            }
            throw ts.Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
        }
        /**
         * Resolve a signature of a given call-like expression.
         * @param node a call-like expression to try resolve a signature for
         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
         *                           the function will fill it up with appropriate candidate signatures
         * @return a signature of the call-like expression or undefined if one can't be found
         */
        function getResolvedSignature(node, candidatesOutArray, checkMode) {
            var links = getNodeLinks(node);
            // If getResolvedSignature has already been called, we will have cached the resolvedSignature.
            // However, it is possible that either candidatesOutArray was not passed in the first time,
            // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work
            // to correctly fill the candidatesOutArray.
            var cached = links.resolvedSignature;
            if (cached && cached !== resolvingSignature && !candidatesOutArray) {
                return cached;
            }
            links.resolvedSignature = resolvingSignature;
            var result = resolveSignature(node, candidatesOutArray, checkMode || 0 /* Normal */);
            // When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call
            // resolution should be deferred.
            if (result !== resolvingSignature) {
                // If signature resolution originated in control flow type analysis (for example to compute the
                // assigned type in a flow assignment) we don't cache the result as it may be based on temporary
                // types from the control flow analysis.
                links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
            }
            return result;
        }
        /**
         * Indicates whether a declaration can be treated as a constructor in a JavaScript
         * file.
         */
        function isJSConstructor(node) {
            if (!node || !ts.isInJSFile(node)) {
                return false;
            }
            var func = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? node :
                ts.isVariableDeclaration(node) && node.initializer && ts.isFunctionExpression(node.initializer) ? node.initializer :
                    undefined;
            if (func) {
                // If the node has a @class tag, treat it like a constructor.
                if (ts.getJSDocClassTag(node))
                    return true;
                // If the symbol of the node has members, treat it like a constructor.
                var symbol = getSymbolOfNode(func);
                return !!symbol && ts.hasEntries(symbol.members);
            }
            return false;
        }
        function mergeJSSymbols(target, source) {
            if (source) {
                var links = getSymbolLinks(source);
                if (!links.inferredClassSymbol || !links.inferredClassSymbol.has("" + getSymbolId(target))) {
                    var inferred = ts.isTransientSymbol(target) ? target : cloneSymbol(target);
                    inferred.exports = inferred.exports || ts.createSymbolTable();
                    inferred.members = inferred.members || ts.createSymbolTable();
                    inferred.flags |= source.flags & 32 /* Class */;
                    if (ts.hasEntries(source.exports)) {
                        mergeSymbolTable(inferred.exports, source.exports);
                    }
                    if (ts.hasEntries(source.members)) {
                        mergeSymbolTable(inferred.members, source.members);
                    }
                    (links.inferredClassSymbol || (links.inferredClassSymbol = ts.createMap())).set("" + getSymbolId(inferred), inferred);
                    return inferred;
                }
                return links.inferredClassSymbol.get("" + getSymbolId(target));
            }
        }
        function getAssignedClassSymbol(decl) {
            var assignmentSymbol = decl && decl.parent &&
                (ts.isFunctionDeclaration(decl) && getSymbolOfNode(decl) ||
                    ts.isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) ||
                    ts.isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
            var prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype");
            var init = prototype && prototype.valueDeclaration && getAssignedJSPrototype(prototype.valueDeclaration);
            return init ? getSymbolOfNode(init) : undefined;
        }
        function getAssignedJSPrototype(node) {
            if (!node.parent) {
                return false;
            }
            var parent = node.parent;
            while (parent && parent.kind === 194 /* PropertyAccessExpression */) {
                parent = parent.parent;
            }
            if (parent && ts.isBinaryExpression(parent) && ts.isPrototypeAccess(parent.left) && parent.operatorToken.kind === 62 /* EqualsToken */) {
                var right = ts.getInitializerOfBinaryExpression(parent);
                return ts.isObjectLiteralExpression(right) && right;
            }
        }
        /**
         * Syntactically and semantically checks a call or new expression.
         * @param node The call/new expression to be checked.
         * @returns On success, the expression's signature's return type. On failure, anyType.
         */
        function checkCallExpression(node, checkMode) {
            if (!checkGrammarTypeArguments(node, node.typeArguments))
                checkGrammarArguments(node.arguments);
            var signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
            if (signature === resolvingSignature) {
                // CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
                // returns a function type. We defer checking and return nonInferrableType.
                return nonInferrableType;
            }
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return voidType;
            }
            if (node.kind === 197 /* NewExpression */) {
                var declaration = signature.declaration;
                if (declaration &&
                    declaration.kind !== 162 /* Constructor */ &&
                    declaration.kind !== 166 /* ConstructSignature */ &&
                    declaration.kind !== 171 /* ConstructorType */ &&
                    !ts.isJSDocConstructSignature(declaration) &&
                    !isJSConstructor(declaration)) {
                    // When resolved signature is a call signature (and not a construct signature) the result type is any
                    if (noImplicitAny) {
                        error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                    }
                    return anyType;
                }
            }
            // In JavaScript files, calls to any identifier 'require' are treated as external module imports
            if (ts.isInJSFile(node) && isCommonJsRequire(node)) {
                return resolveExternalModuleTypeByLiteral(node.arguments[0]);
            }
            var returnType = getReturnTypeOfSignature(signature);
            // Treat any call to the global 'Symbol' function that is part of a const variable or readonly property
            // as a fresh unique symbol literal type.
            if (returnType.flags & 12288 /* ESSymbolLike */ && isSymbolOrSymbolForCall(node)) {
                return getESSymbolLikeTypeForNode(ts.walkUpParenthesizedExpressions(node.parent));
            }
            if (node.kind === 196 /* CallExpression */ && node.parent.kind === 226 /* ExpressionStatement */ &&
                returnType.flags & 16384 /* Void */ && getTypePredicateOfSignature(signature)) {
                if (!ts.isDottedName(node.expression)) {
                    error(node.expression, ts.Diagnostics.Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name);
                }
                else if (!getEffectsSignature(node)) {
                    var diagnostic = error(node.expression, ts.Diagnostics.Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation);
                    getTypeOfDottedName(node.expression, diagnostic);
                }
            }
            if (ts.isInJSFile(node)) {
                var decl = ts.getDeclarationOfExpando(node);
                if (decl) {
                    var jsSymbol = getSymbolOfNode(decl);
                    if (jsSymbol && ts.hasEntries(jsSymbol.exports)) {
                        var jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, ts.emptyArray, ts.emptyArray, undefined, undefined);
                        jsAssignmentType.objectFlags |= 16384 /* JSLiteral */;
                        return getIntersectionType([returnType, jsAssignmentType]);
                    }
                }
            }
            return returnType;
        }
        function isSymbolOrSymbolForCall(node) {
            if (!ts.isCallExpression(node))
                return false;
            var left = node.expression;
            if (ts.isPropertyAccessExpression(left) && left.name.escapedText === "for") {
                left = left.expression;
            }
            if (!ts.isIdentifier(left) || left.escapedText !== "Symbol") {
                return false;
            }
            // make sure `Symbol` is the global symbol
            var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ false);
            if (!globalESSymbol) {
                return false;
            }
            return globalESSymbol === resolveName(left, "Symbol", 111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
        }
        function checkImportCallExpression(node) {
            // Check grammar of dynamic import
            if (!checkGrammarArguments(node.arguments))
                checkGrammarImportCallExpression(node);
            if (node.arguments.length === 0) {
                return createPromiseReturnType(node, anyType);
            }
            var specifier = node.arguments[0];
            var specifierType = checkExpressionCached(specifier);
            // Even though multiple arguments is grammatically incorrect, type-check extra arguments for completion
            for (var i = 1; i < node.arguments.length; ++i) {
                checkExpressionCached(node.arguments[i]);
            }
            if (specifierType.flags & 32768 /* Undefined */ || specifierType.flags & 65536 /* Null */ || !isTypeAssignableTo(specifierType, stringType)) {
                error(specifier, ts.Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType));
            }
            // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
            var moduleSymbol = resolveExternalModuleName(node, specifier);
            if (moduleSymbol) {
                var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true, /*suppressUsageError*/ false);
                if (esModuleSymbol) {
                    return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol));
                }
            }
            return createPromiseReturnType(node, anyType);
        }
        function getTypeWithSyntheticDefaultImportType(type, symbol, originalSymbol) {
            if (allowSyntheticDefaultImports && type && type !== errorType) {
                var synthType = type;
                if (!synthType.syntheticType) {
                    var file = ts.find(originalSymbol.declarations, ts.isSourceFile);
                    var hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false);
                    if (hasSyntheticDefault) {
                        var memberTable = ts.createSymbolTable();
                        var newSymbol = createSymbol(2097152 /* Alias */, "default" /* Default */);
                        newSymbol.nameType = getLiteralType("default");
                        newSymbol.target = resolveSymbol(symbol);
                        memberTable.set("default" /* Default */, newSymbol);
                        var anonymousSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
                        var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
                        anonymousSymbol.type = defaultContainingObject;
                        synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
                    }
                    else {
                        synthType.syntheticType = type;
                    }
                }
                return synthType.syntheticType;
            }
            return type;
        }
        function isCommonJsRequire(node) {
            if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
                return false;
            }
            // Make sure require is not a local function
            if (!ts.isIdentifier(node.expression))
                return ts.Debug.fail();
            var resolvedRequire = resolveName(node.expression, node.expression.escapedText, 111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); // TODO: GH#18217
            if (resolvedRequire === requireSymbol) {
                return true;
            }
            // project includes symbol named 'require' - make sure that it is ambient and local non-alias
            if (resolvedRequire.flags & 2097152 /* Alias */) {
                return false;
            }
            var targetDeclarationKind = resolvedRequire.flags & 16 /* Function */
                ? 244 /* FunctionDeclaration */
                : resolvedRequire.flags & 3 /* Variable */
                    ? 242 /* VariableDeclaration */
                    : 0 /* Unknown */;
            if (targetDeclarationKind !== 0 /* Unknown */) {
                var decl = ts.getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
                // function/variable declaration should be ambient
                return !!decl && !!(decl.flags & 8388608 /* Ambient */);
            }
            return false;
        }
        function checkTaggedTemplateExpression(node) {
            if (!checkGrammarTaggedTemplateChain(node))
                checkGrammarTypeArguments(node, node.typeArguments);
            if (languageVersion < 2 /* ES2015 */) {
                checkExternalEmitHelpers(node, 131072 /* MakeTemplateObject */);
            }
            return getReturnTypeOfSignature(getResolvedSignature(node));
        }
        function checkAssertion(node) {
            return checkAssertionWorker(node, node.type, node.expression);
        }
        function isValidConstAssertionArgument(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 192 /* ArrayLiteralExpression */:
                case 193 /* ObjectLiteralExpression */:
                    return true;
                case 200 /* ParenthesizedExpression */:
                    return isValidConstAssertionArgument(node.expression);
                case 207 /* PrefixUnaryExpression */:
                    var op = node.operator;
                    var arg = node.operand;
                    return op === 40 /* MinusToken */ && (arg.kind === 8 /* NumericLiteral */ || arg.kind === 9 /* BigIntLiteral */) ||
                        op === 39 /* PlusToken */ && arg.kind === 8 /* NumericLiteral */;
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    var expr = node.expression;
                    if (ts.isIdentifier(expr)) {
                        var symbol = getSymbolAtLocation(expr);
                        if (symbol && symbol.flags & 2097152 /* Alias */) {
                            symbol = resolveAlias(symbol);
                        }
                        return !!(symbol && (symbol.flags & 384 /* Enum */) && getEnumKind(symbol) === 1 /* Literal */);
                    }
            }
            return false;
        }
        function checkAssertionWorker(errNode, type, expression, checkMode) {
            var exprType = checkExpression(expression, checkMode);
            if (ts.isConstTypeReference(type)) {
                if (!isValidConstAssertionArgument(expression)) {
                    error(expression, ts.Diagnostics.A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals);
                }
                return getRegularTypeOfLiteralType(exprType);
            }
            checkSourceElement(type);
            exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(exprType));
            var targetType = getTypeFromTypeNode(type);
            if (produceDiagnostics && targetType !== errorType) {
                var widenedType = getWidenedType(exprType);
                if (!isTypeComparableTo(targetType, widenedType)) {
                    checkTypeComparableTo(exprType, targetType, errNode, ts.Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first);
                }
            }
            return targetType;
        }
        function checkNonNullChain(node) {
            var leftType = checkExpression(node.expression);
            var nonOptionalType = getOptionalExpressionType(leftType, node.expression);
            return propagateOptionalTypeMarker(getNonNullableType(nonOptionalType), node, nonOptionalType !== leftType);
        }
        function checkNonNullAssertion(node) {
            return node.flags & 32 /* OptionalChain */ ? checkNonNullChain(node) :
                getNonNullableType(checkExpression(node.expression));
        }
        function checkMetaProperty(node) {
            checkGrammarMetaProperty(node);
            if (node.keywordToken === 99 /* NewKeyword */) {
                return checkNewTargetMetaProperty(node);
            }
            if (node.keywordToken === 96 /* ImportKeyword */) {
                return checkImportMetaProperty(node);
            }
            return ts.Debug.assertNever(node.keywordToken);
        }
        function checkNewTargetMetaProperty(node) {
            var container = ts.getNewTargetContainer(node);
            if (!container) {
                error(node, ts.Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target");
                return errorType;
            }
            else if (container.kind === 162 /* Constructor */) {
                var symbol = getSymbolOfNode(container.parent);
                return getTypeOfSymbol(symbol);
            }
            else {
                var symbol = getSymbolOfNode(container);
                return getTypeOfSymbol(symbol);
            }
        }
        function checkImportMetaProperty(node) {
            if (moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) {
                error(node, ts.Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_esnext_or_system);
            }
            var file = ts.getSourceFileOfNode(node);
            ts.Debug.assert(!!(file.flags & 2097152 /* PossiblyContainsImportMeta */), "Containing file is missing import meta node flag.");
            ts.Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module.");
            return node.name.escapedText === "meta" ? getGlobalImportMetaType() : errorType;
        }
        function getTypeOfParameter(symbol) {
            var type = getTypeOfSymbol(symbol);
            if (strictNullChecks) {
                var declaration = symbol.valueDeclaration;
                if (declaration && ts.hasInitializer(declaration)) {
                    return getOptionalType(type);
                }
            }
            return type;
        }
        function getParameterNameAtPosition(signature, pos) {
            var paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
            if (pos < paramCount) {
                return signature.parameters[pos].escapedName;
            }
            var restParameter = signature.parameters[paramCount] || unknownSymbol;
            var restType = getTypeOfSymbol(restParameter);
            if (isTupleType(restType)) {
                var associatedNames = restType.target.associatedNames;
                var index = pos - paramCount;
                return associatedNames && associatedNames[index] || restParameter.escapedName + "_" + index;
            }
            return restParameter.escapedName;
        }
        function getTypeAtPosition(signature, pos) {
            return tryGetTypeAtPosition(signature, pos) || anyType;
        }
        function tryGetTypeAtPosition(signature, pos) {
            var paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
            if (pos < paramCount) {
                return getTypeOfParameter(signature.parameters[pos]);
            }
            if (signatureHasRestParameter(signature)) {
                // We want to return the value undefined for an out of bounds parameter position,
                // so we need to check bounds here before calling getIndexedAccessType (which
                // otherwise would return the type 'undefined').
                var restType = getTypeOfSymbol(signature.parameters[paramCount]);
                var index = pos - paramCount;
                if (!isTupleType(restType) || restType.target.hasRestElement || index < getTypeArguments(restType).length) {
                    return getIndexedAccessType(restType, getLiteralType(index));
                }
            }
            return undefined;
        }
        function getRestTypeAtPosition(source, pos) {
            var paramCount = getParameterCount(source);
            var restType = getEffectiveRestType(source);
            var nonRestCount = paramCount - (restType ? 1 : 0);
            if (restType && pos === nonRestCount) {
                return restType;
            }
            var types = [];
            var names = [];
            for (var i = pos; i < nonRestCount; i++) {
                types.push(getTypeAtPosition(source, i));
                names.push(getParameterNameAtPosition(source, i));
            }
            if (restType) {
                types.push(getIndexedAccessType(restType, numberType));
                names.push(getParameterNameAtPosition(source, nonRestCount));
            }
            var minArgumentCount = getMinArgumentCount(source);
            var minLength = minArgumentCount < pos ? 0 : minArgumentCount - pos;
            return createTupleType(types, minLength, !!restType, /*readonly*/ false, names);
        }
        function getParameterCount(signature) {
            var length = signature.parameters.length;
            if (signatureHasRestParameter(signature)) {
                var restType = getTypeOfSymbol(signature.parameters[length - 1]);
                if (isTupleType(restType)) {
                    return length + getTypeArguments(restType).length - 1;
                }
            }
            return length;
        }
        function getMinArgumentCount(signature, strongArityForUntypedJS) {
            if (signatureHasRestParameter(signature)) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                if (isTupleType(restType)) {
                    var minLength = restType.target.minLength;
                    if (minLength > 0) {
                        return signature.parameters.length - 1 + minLength;
                    }
                }
            }
            if (!strongArityForUntypedJS && signature.flags & 16 /* IsUntypedSignatureInJSFile */) {
                return 0;
            }
            return signature.minArgumentCount;
        }
        function hasEffectiveRestParameter(signature) {
            if (signatureHasRestParameter(signature)) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                return !isTupleType(restType) || restType.target.hasRestElement;
            }
            return false;
        }
        function getEffectiveRestType(signature) {
            if (signatureHasRestParameter(signature)) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                return isTupleType(restType) ? getRestArrayTypeOfTupleType(restType) : restType;
            }
            return undefined;
        }
        function getNonArrayRestType(signature) {
            var restType = getEffectiveRestType(signature);
            return restType && !isArrayType(restType) && !isTypeAny(restType) && (getReducedType(restType).flags & 131072 /* Never */) === 0 ? restType : undefined;
        }
        function getTypeOfFirstParameterOfSignature(signature) {
            return getTypeOfFirstParameterOfSignatureWithFallback(signature, neverType);
        }
        function getTypeOfFirstParameterOfSignatureWithFallback(signature, fallbackType) {
            return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : fallbackType;
        }
        function inferFromAnnotatedParameters(signature, context, inferenceContext) {
            var len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var declaration = signature.parameters[i].valueDeclaration;
                if (declaration.type) {
                    var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
                    if (typeNode) {
                        inferTypes(inferenceContext.inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
                    }
                }
            }
            var restType = getEffectiveRestType(context);
            if (restType && restType.flags & 262144 /* TypeParameter */) {
                // The contextual signature has a generic rest parameter. We first instantiate the contextual
                // signature (without fixing type parameters) and assign types to contextually typed parameters.
                var instantiatedContext = instantiateSignature(context, inferenceContext.nonFixingMapper);
                assignContextualParameterTypes(signature, instantiatedContext);
                // We then infer from a tuple type representing the parameters that correspond to the contextual
                // rest parameter.
                var restPos = getParameterCount(context) - 1;
                inferTypes(inferenceContext.inferences, getRestTypeAtPosition(signature, restPos), restType);
            }
        }
        function assignContextualParameterTypes(signature, context) {
            signature.typeParameters = context.typeParameters;
            if (context.thisParameter) {
                var parameter = signature.thisParameter;
                if (!parameter || parameter.valueDeclaration && !parameter.valueDeclaration.type) {
                    if (!parameter) {
                        signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined);
                    }
                    assignParameterType(signature.thisParameter, getTypeOfSymbol(context.thisParameter));
                }
            }
            var len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var parameter = signature.parameters[i];
                if (!ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
                    var contextualParameterType = tryGetTypeAtPosition(context, i);
                    assignParameterType(parameter, contextualParameterType);
                }
            }
            if (signatureHasRestParameter(signature)) {
                // parameter might be a transient symbol generated by use of `arguments` in the function body.
                var parameter = ts.last(signature.parameters);
                if (ts.isTransientSymbol(parameter) || !ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
                    var contextualParameterType = getRestTypeAtPosition(context, len);
                    assignParameterType(parameter, contextualParameterType);
                }
            }
        }
        function assignNonContextualParameterTypes(signature) {
            if (signature.thisParameter) {
                assignParameterType(signature.thisParameter);
            }
            for (var _i = 0, _a = signature.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                assignParameterType(parameter);
            }
        }
        function assignParameterType(parameter, type) {
            var links = getSymbolLinks(parameter);
            if (!links.type) {
                var declaration = parameter.valueDeclaration;
                links.type = type || getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true);
                if (declaration.name.kind !== 75 /* Identifier */) {
                    // if inference didn't come up with anything but unknown, fall back to the binding pattern if present.
                    if (links.type === unknownType) {
                        links.type = getTypeFromBindingPattern(declaration.name);
                    }
                    assignBindingElementTypes(declaration.name);
                }
            }
        }
        // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push
        // the destructured type into the contained binding elements.
        function assignBindingElementTypes(pattern) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (!ts.isOmittedExpression(element)) {
                    if (element.name.kind === 75 /* Identifier */) {
                        getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
                    }
                    else {
                        assignBindingElementTypes(element.name);
                    }
                }
            }
        }
        function createPromiseType(promisedType) {
            // creates a `Promise<T>` type where `T` is the promisedType argument
            var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
            if (globalPromiseType !== emptyGenericType) {
                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
                promisedType = getAwaitedType(promisedType) || unknownType;
                return createTypeReference(globalPromiseType, [promisedType]);
            }
            return unknownType;
        }
        function createPromiseLikeType(promisedType) {
            // creates a `PromiseLike<T>` type where `T` is the promisedType argument
            var globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true);
            if (globalPromiseLikeType !== emptyGenericType) {
                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
                promisedType = getAwaitedType(promisedType) || unknownType;
                return createTypeReference(globalPromiseLikeType, [promisedType]);
            }
            return unknownType;
        }
        function createPromiseReturnType(func, promisedType) {
            var promiseType = createPromiseType(promisedType);
            if (promiseType === unknownType) {
                error(func, ts.isImportCall(func) ?
                    ts.Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
                    ts.Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
                return errorType;
            }
            else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
                error(func, ts.isImportCall(func) ?
                    ts.Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option :
                    ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
            }
            return promiseType;
        }
        function getReturnTypeFromBody(func, checkMode) {
            if (!func.body) {
                return errorType;
            }
            var functionFlags = ts.getFunctionFlags(func);
            var isAsync = (functionFlags & 2 /* Async */) !== 0;
            var isGenerator = (functionFlags & 1 /* Generator */) !== 0;
            var returnType;
            var yieldType;
            var nextType;
            var fallbackReturnType = voidType;
            if (func.body.kind !== 223 /* Block */) { // Async or normal arrow function
                returnType = checkExpressionCached(func.body, checkMode && checkMode & ~8 /* SkipGenericFunctions */);
                if (isAsync) {
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                    // return type of the body should be unwrapped to its awaited type, which we will wrap in
                    // the native Promise<T> type later in this function.
                    returnType = checkAwaitedType(returnType, /*errorNode*/ func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                }
            }
            else if (isGenerator) { // Generator or AsyncGenerator function
                var returnTypes = checkAndAggregateReturnExpressionTypes(func, checkMode);
                if (!returnTypes) {
                    fallbackReturnType = neverType;
                }
                else if (returnTypes.length > 0) {
                    returnType = getUnionType(returnTypes, 2 /* Subtype */);
                }
                var _a = checkAndAggregateYieldOperandTypes(func, checkMode), yieldTypes = _a.yieldTypes, nextTypes = _a.nextTypes;
                yieldType = ts.some(yieldTypes) ? getUnionType(yieldTypes, 2 /* Subtype */) : undefined;
                nextType = ts.some(nextTypes) ? getIntersectionType(nextTypes) : undefined;
            }
            else { // Async or normal function
                var types = checkAndAggregateReturnExpressionTypes(func, checkMode);
                if (!types) {
                    // For an async function, the return type will not be never, but rather a Promise for never.
                    return functionFlags & 2 /* Async */
                        ? createPromiseReturnType(func, neverType) // Async function
                        : neverType; // Normal function
                }
                if (types.length === 0) {
                    // For an async function, the return type will not be void, but rather a Promise for void.
                    return functionFlags & 2 /* Async */
                        ? createPromiseReturnType(func, voidType) // Async function
                        : voidType; // Normal function
                }
                // Return a union of the return expression types.
                returnType = getUnionType(types, 2 /* Subtype */);
            }
            if (returnType || yieldType || nextType) {
                if (yieldType)
                    reportErrorsFromWidening(func, yieldType, 3 /* GeneratorYield */);
                if (returnType)
                    reportErrorsFromWidening(func, returnType, 1 /* FunctionReturn */);
                if (nextType)
                    reportErrorsFromWidening(func, nextType, 2 /* GeneratorNext */);
                if (returnType && isUnitType(returnType) ||
                    yieldType && isUnitType(yieldType) ||
                    nextType && isUnitType(nextType)) {
                    var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
                    var contextualType = !contextualSignature ? undefined :
                        contextualSignature === getSignatureFromDeclaration(func) ? isGenerator ? undefined : returnType :
                            instantiateContextualType(getReturnTypeOfSignature(contextualSignature), func);
                    if (isGenerator) {
                        yieldType = getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(yieldType, contextualType, 0 /* Yield */, isAsync);
                        returnType = getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(returnType, contextualType, 1 /* Return */, isAsync);
                        nextType = getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(nextType, contextualType, 2 /* Next */, isAsync);
                    }
                    else {
                        returnType = getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(returnType, contextualType, isAsync);
                    }
                }
                if (yieldType)
                    yieldType = getWidenedType(yieldType);
                if (returnType)
                    returnType = getWidenedType(returnType);
                if (nextType)
                    nextType = getWidenedType(nextType);
            }
            if (isGenerator) {
                return createGeneratorReturnType(yieldType || neverType, returnType || fallbackReturnType, nextType || getContextualIterationType(2 /* Next */, func) || unknownType, isAsync);
            }
            else {
                // From within an async function you can return either a non-promise value or a promise. Any
                // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                // return type of the body is awaited type of the body, wrapped in a native Promise<T> type.
                return isAsync
                    ? createPromiseType(returnType || fallbackReturnType)
                    : returnType || fallbackReturnType;
            }
        }
        function createGeneratorReturnType(yieldType, returnType, nextType, isAsyncGenerator) {
            var resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
            var globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false);
            yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType;
            returnType = resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || unknownType;
            nextType = resolver.resolveIterationType(nextType, /*errorNode*/ undefined) || unknownType;
            if (globalGeneratorType === emptyGenericType) {
                // Fall back to the global IterableIterator if returnType is assignable to the expected return iteration
                // type of IterableIterator, and the expected next iteration type of IterableIterator is assignable to
                // nextType.
                var globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false);
                var iterationTypes = globalType !== emptyGenericType ? getIterationTypesOfGlobalIterableType(globalType, resolver) : undefined;
                var iterableIteratorReturnType = iterationTypes ? iterationTypes.returnType : anyType;
                var iterableIteratorNextType = iterationTypes ? iterationTypes.nextType : undefinedType;
                if (isTypeAssignableTo(returnType, iterableIteratorReturnType) &&
                    isTypeAssignableTo(iterableIteratorNextType, nextType)) {
                    if (globalType !== emptyGenericType) {
                        return createTypeFromGenericGlobalType(globalType, [yieldType]);
                    }
                    // The global IterableIterator type doesn't exist, so report an error
                    resolver.getGlobalIterableIteratorType(/*reportErrors*/ true);
                    return emptyObjectType;
                }
                // The global Generator type doesn't exist, so report an error
                resolver.getGlobalGeneratorType(/*reportErrors*/ true);
                return emptyObjectType;
            }
            return createTypeFromGenericGlobalType(globalGeneratorType, [yieldType, returnType, nextType]);
        }
        function checkAndAggregateYieldOperandTypes(func, checkMode) {
            var yieldTypes = [];
            var nextTypes = [];
            var isAsync = (ts.getFunctionFlags(func) & 2 /* Async */) !== 0;
            ts.forEachYieldExpression(func.body, function (yieldExpression) {
                var yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : undefinedWideningType;
                ts.pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpressionType, anyType, isAsync));
                var nextType;
                if (yieldExpression.asteriskToken) {
                    var iterationTypes = getIterationTypesOfIterable(yieldExpressionType, isAsync ? 19 /* AsyncYieldStar */ : 17 /* YieldStar */, yieldExpression.expression);
                    nextType = iterationTypes && iterationTypes.nextType;
                }
                else {
                    nextType = getContextualType(yieldExpression);
                }
                if (nextType)
                    ts.pushIfUnique(nextTypes, nextType);
            });
            return { yieldTypes: yieldTypes, nextTypes: nextTypes };
        }
        function getYieldedTypeOfYieldExpression(node, expressionType, sentType, isAsync) {
            var errorNode = node.expression || node;
            // A `yield*` expression effectively yields everything that its operand yields
            var yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(isAsync ? 19 /* AsyncYieldStar */ : 17 /* YieldStar */, expressionType, sentType, errorNode) : expressionType;
            return !isAsync ? yieldedType : getAwaitedType(yieldedType, errorNode, node.asteriskToken
                ? ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
                : ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        /**
         * Collect the TypeFacts learned from a typeof switch with
         * total clauses `witnesses`, and the active clause ranging
         * from `start` to `end`. Parameter `hasDefault` denotes
         * whether the active clause contains a default clause.
         */
        function getFactsFromTypeofSwitch(start, end, witnesses, hasDefault) {
            var facts = 0 /* None */;
            // When in the default we only collect inequality facts
            // because default is 'in theory' a set of infinite
            // equalities.
            if (hasDefault) {
                // Value is not equal to any types after the active clause.
                for (var i = end; i < witnesses.length; i++) {
                    facts |= typeofNEFacts.get(witnesses[i]) || 32768 /* TypeofNEHostObject */;
                }
                // Remove inequalities for types that appear in the
                // active clause because they appear before other
                // types collected so far.
                for (var i = start; i < end; i++) {
                    facts &= ~(typeofNEFacts.get(witnesses[i]) || 0);
                }
                // Add inequalities for types before the active clause unconditionally.
                for (var i = 0; i < start; i++) {
                    facts |= typeofNEFacts.get(witnesses[i]) || 32768 /* TypeofNEHostObject */;
                }
            }
            // When in an active clause without default the set of
            // equalities is finite.
            else {
                // Add equalities for all types in the active clause.
                for (var i = start; i < end; i++) {
                    facts |= typeofEQFacts.get(witnesses[i]) || 128 /* TypeofEQHostObject */;
                }
                // Remove equalities for types that appear before the
                // active clause.
                for (var i = 0; i < start; i++) {
                    facts &= ~(typeofEQFacts.get(witnesses[i]) || 0);
                }
            }
            return facts;
        }
        function isExhaustiveSwitchStatement(node) {
            var links = getNodeLinks(node);
            return links.isExhaustive !== undefined ? links.isExhaustive : (links.isExhaustive = computeExhaustiveSwitchStatement(node));
        }
        function computeExhaustiveSwitchStatement(node) {
            if (node.expression.kind === 204 /* TypeOfExpression */) {
                var operandType = getTypeOfExpression(node.expression.expression);
                var witnesses = getSwitchClauseTypeOfWitnesses(node, /*retainDefault*/ false);
                // notEqualFacts states that the type of the switched value is not equal to every type in the switch.
                var notEqualFacts_1 = getFactsFromTypeofSwitch(0, 0, witnesses, /*hasDefault*/ true);
                var type_3 = getBaseConstraintOfType(operandType) || operandType;
                return !!(filterType(type_3, function (t) { return (getTypeFacts(t) & notEqualFacts_1) === notEqualFacts_1; }).flags & 131072 /* Never */);
            }
            var type = getTypeOfExpression(node.expression);
            if (!isLiteralType(type)) {
                return false;
            }
            var switchTypes = getSwitchClauseTypes(node);
            if (!switchTypes.length || ts.some(switchTypes, isNeitherUnitTypeNorNever)) {
                return false;
            }
            return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
        }
        function functionHasImplicitReturn(func) {
            return func.endFlowNode && isReachableFlowNode(func.endFlowNode);
        }
        /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */
        function checkAndAggregateReturnExpressionTypes(func, checkMode) {
            var functionFlags = ts.getFunctionFlags(func);
            var aggregatedTypes = [];
            var hasReturnWithNoExpression = functionHasImplicitReturn(func);
            var hasReturnOfTypeNever = false;
            ts.forEachReturnStatement(func.body, function (returnStatement) {
                var expr = returnStatement.expression;
                if (expr) {
                    var type = checkExpressionCached(expr, checkMode && checkMode & ~8 /* SkipGenericFunctions */);
                    if (functionFlags & 2 /* Async */) {
                        // From within an async function you can return either a non-promise value or a promise. Any
                        // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                        // return type of the body should be unwrapped to its awaited type, which should be wrapped in
                        // the native Promise<T> type by the caller.
                        type = checkAwaitedType(type, func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                    }
                    if (type.flags & 131072 /* Never */) {
                        hasReturnOfTypeNever = true;
                    }
                    ts.pushIfUnique(aggregatedTypes, type);
                }
                else {
                    hasReturnWithNoExpression = true;
                }
            });
            if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || mayReturnNever(func))) {
                return undefined;
            }
            if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression &&
                !(isJSConstructor(func) && aggregatedTypes.some(function (t) { return t.symbol === func.symbol; }))) {
                // Javascript "callable constructors", containing eg `if (!(this instanceof A)) return new A()` should not add undefined
                ts.pushIfUnique(aggregatedTypes, undefinedType);
            }
            return aggregatedTypes;
        }
        function mayReturnNever(func) {
            switch (func.kind) {
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return true;
                case 161 /* MethodDeclaration */:
                    return func.parent.kind === 193 /* ObjectLiteralExpression */;
                default:
                    return false;
            }
        }
        /**
         * TypeScript Specification 1.0 (6.3) - July 2014
         *   An explicitly typed function whose return type isn't the Void type,
         *   the Any type, or a union type containing the Void or Any type as a constituent
         *   must have at least one return statement somewhere in its body.
         *   An exception to this rule is if the function implementation consists of a single 'throw' statement.
         *
         * @param returnType - return type of the function, can be undefined if return type is not explicitly specified
         */
        function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func, returnType) {
            if (!produceDiagnostics) {
                return;
            }
            var functionFlags = ts.getFunctionFlags(func);
            var type = returnType && unwrapReturnType(returnType, functionFlags);
            // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
            if (type && maybeTypeOfKind(type, 1 /* Any */ | 16384 /* Void */)) {
                return;
            }
            // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check.
            // also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw
            if (func.kind === 160 /* MethodSignature */ || ts.nodeIsMissing(func.body) || func.body.kind !== 223 /* Block */ || !functionHasImplicitReturn(func)) {
                return;
            }
            var hasExplicitReturn = func.flags & 512 /* HasExplicitReturn */;
            if (type && type.flags & 131072 /* Never */) {
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
            }
            else if (type && !hasExplicitReturn) {
                // minimal check: function has syntactic return type annotation and no explicit return statements in the body
                // this function does not conform to the specification.
                // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
            }
            else if (type && strictNullChecks && !isTypeAssignableTo(undefinedType, type)) {
                error(ts.getEffectiveReturnTypeNode(func) || func, ts.Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
            }
            else if (compilerOptions.noImplicitReturns) {
                if (!type) {
                    // If return type annotation is omitted check if function has any explicit return statements.
                    // If it does not have any - its inferred return type is void - don't do any checks.
                    // Otherwise get inferred return type from function body and report error only if it is not void / anytype
                    if (!hasExplicitReturn) {
                        return;
                    }
                    var inferredReturnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func));
                    if (isUnwrappedReturnTypeVoidOrAny(func, inferredReturnType)) {
                        return;
                    }
                }
                error(ts.getEffectiveReturnTypeNode(func) || func, ts.Diagnostics.Not_all_code_paths_return_a_value);
            }
        }
        function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) {
            ts.Debug.assert(node.kind !== 161 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            checkNodeDeferred(node);
            // The identityMapper object is used to indicate that function expressions are wildcards
            if (checkMode && checkMode & 4 /* SkipContextSensitive */ && isContextSensitive(node)) {
                // Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
                if (!ts.getEffectiveReturnTypeNode(node) && !hasContextSensitiveParameters(node)) {
                    // Return plain anyFunctionType if there is no possibility we'll make inferences from the return type
                    var contextualSignature = getContextualSignature(node);
                    if (contextualSignature && couldContainTypeVariables(getReturnTypeOfSignature(contextualSignature))) {
                        var links = getNodeLinks(node);
                        if (links.contextFreeType) {
                            return links.contextFreeType;
                        }
                        var returnType = getReturnTypeFromBody(node, checkMode);
                        var returnOnlySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
                        var returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], ts.emptyArray, undefined, undefined);
                        returnOnlyType.objectFlags |= 2097152 /* NonInferrableType */;
                        return links.contextFreeType = returnOnlyType;
                    }
                }
                return anyFunctionType;
            }
            // Grammar checking
            var hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
            if (!hasGrammarError && node.kind === 201 /* FunctionExpression */) {
                checkGrammarForGenerator(node);
            }
            contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node, checkMode);
            return getTypeOfSymbol(getSymbolOfNode(node));
        }
        function contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node, checkMode) {
            var links = getNodeLinks(node);
            // Check if function expression is contextually typed and assign parameter types if so.
            if (!(links.flags & 1024 /* ContextChecked */)) {
                var contextualSignature = getContextualSignature(node);
                // If a type check is started at a function expression that is an argument of a function call, obtaining the
                // contextual type may recursively get back to here during overload resolution of the call. If so, we will have
                // already assigned contextual types.
                if (!(links.flags & 1024 /* ContextChecked */)) {
                    links.flags |= 1024 /* ContextChecked */;
                    var signature = ts.firstOrUndefined(getSignaturesOfType(getTypeOfSymbol(getSymbolOfNode(node)), 0 /* Call */));
                    if (!signature) {
                        return;
                    }
                    if (isContextSensitive(node)) {
                        if (contextualSignature) {
                            var inferenceContext = getInferenceContext(node);
                            if (checkMode && checkMode & 2 /* Inferential */) {
                                inferFromAnnotatedParameters(signature, contextualSignature, inferenceContext);
                            }
                            var instantiatedContextualSignature = inferenceContext ?
                                instantiateSignature(contextualSignature, inferenceContext.mapper) : contextualSignature;
                            assignContextualParameterTypes(signature, instantiatedContextualSignature);
                        }
                        else {
                            // Force resolution of all parameter types such that the absence of a contextual type is consistently reflected.
                            assignNonContextualParameterTypes(signature);
                        }
                    }
                    if (contextualSignature && !getReturnTypeFromAnnotation(node) && !signature.resolvedReturnType) {
                        var returnType = getReturnTypeFromBody(node, checkMode);
                        if (!signature.resolvedReturnType) {
                            signature.resolvedReturnType = returnType;
                        }
                    }
                    checkSignatureDeclaration(node);
                }
            }
        }
        function checkFunctionExpressionOrObjectLiteralMethodDeferred(node) {
            ts.Debug.assert(node.kind !== 161 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var functionFlags = ts.getFunctionFlags(node);
            var returnType = getReturnTypeFromAnnotation(node);
            checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
            if (node.body) {
                if (!ts.getEffectiveReturnTypeNode(node)) {
                    // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors
                    // we need. An example is the noImplicitAny errors resulting from widening the return expression
                    // of a function. Because checking of function expression bodies is deferred, there was never an
                    // appropriate time to do this during the main walk of the file (see the comment at the top of
                    // checkFunctionExpressionBodies). So it must be done now.
                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
                }
                if (node.body.kind === 223 /* Block */) {
                    checkSourceElement(node.body);
                }
                else {
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so we
                    // should not be checking assignability of a promise to the return type. Instead, we need to
                    // check assignability of the awaited type of the expression body against the promised type of
                    // its return type annotation.
                    var exprType = checkExpression(node.body);
                    var returnOrPromisedType = returnType && unwrapReturnType(returnType, functionFlags);
                    if (returnOrPromisedType) {
                        if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */) { // Async function
                            var awaitedType = checkAwaitedType(exprType, node.body, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                            checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, node.body, node.body);
                        }
                        else { // Normal function
                            checkTypeAssignableToAndOptionallyElaborate(exprType, returnOrPromisedType, node.body, node.body);
                        }
                    }
                }
            }
        }
        function checkArithmeticOperandType(operand, type, diagnostic, isAwaitValid) {
            if (isAwaitValid === void 0) { isAwaitValid = false; }
            if (!isTypeAssignableTo(type, numberOrBigIntType)) {
                var awaitedType = isAwaitValid && getAwaitedTypeOfPromise(type);
                errorAndMaybeSuggestAwait(operand, !!awaitedType && isTypeAssignableTo(awaitedType, numberOrBigIntType), diagnostic);
                return false;
            }
            return true;
        }
        function isReadonlyAssignmentDeclaration(d) {
            if (!ts.isCallExpression(d)) {
                return false;
            }
            if (!ts.isBindableObjectDefinePropertyCall(d)) {
                return false;
            }
            var objectLitType = checkExpressionCached(d.arguments[2]);
            var valueType = getTypeOfPropertyOfType(objectLitType, "value");
            if (valueType) {
                var writableProp = getPropertyOfType(objectLitType, "writable");
                var writableType = writableProp && getTypeOfSymbol(writableProp);
                if (!writableType || writableType === falseType || writableType === regularFalseType) {
                    return true;
                }
                // We include this definition whereupon we walk back and check the type at the declaration because
                // The usual definition of `Object.defineProperty` will _not_ cause literal types to be preserved in the
                // argument types, should the type be contextualized by the call itself.
                if (writableProp && writableProp.valueDeclaration && ts.isPropertyAssignment(writableProp.valueDeclaration)) {
                    var initializer = writableProp.valueDeclaration.initializer;
                    var rawOriginalType = checkExpression(initializer);
                    if (rawOriginalType === falseType || rawOriginalType === regularFalseType) {
                        return true;
                    }
                }
                return false;
            }
            var setProp = getPropertyOfType(objectLitType, "set");
            return !setProp;
        }
        function isReadonlySymbol(symbol) {
            // The following symbols are considered read-only:
            // Properties with a 'readonly' modifier
            // Variables declared with 'const'
            // Get accessors without matching set accessors
            // Enum members
            // Object.defineProperty assignments with writable false or no setter
            // Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation)
            return !!(ts.getCheckFlags(symbol) & 8 /* Readonly */ ||
                symbol.flags & 4 /* Property */ && ts.getDeclarationModifierFlagsFromSymbol(symbol) & 64 /* Readonly */ ||
                symbol.flags & 3 /* Variable */ && getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */ ||
                symbol.flags & 98304 /* Accessor */ && !(symbol.flags & 65536 /* SetAccessor */) ||
                symbol.flags & 8 /* EnumMember */ ||
                ts.some(symbol.declarations, isReadonlyAssignmentDeclaration));
        }
        function isAssignmentToReadonlyEntity(expr, symbol, assignmentKind) {
            var _a, _b;
            if (assignmentKind === 0 /* None */) {
                // no assigment means it doesn't matter whether the entity is readonly
                return false;
            }
            if (isReadonlySymbol(symbol)) {
                // Allow assignments to readonly properties within constructors of the same class declaration.
                if (symbol.flags & 4 /* Property */ &&
                    ts.isAccessExpression(expr) &&
                    expr.expression.kind === 104 /* ThisKeyword */) {
                    // Look for if this is the constructor for the class that `symbol` is a property of.
                    var ctor = ts.getContainingFunction(expr);
                    if (!(ctor && ctor.kind === 162 /* Constructor */)) {
                        return true;
                    }
                    if (symbol.valueDeclaration) {
                        var isAssignmentDeclaration_1 = ts.isBinaryExpression(symbol.valueDeclaration);
                        var isLocalPropertyDeclaration = ctor.parent === symbol.valueDeclaration.parent;
                        var isLocalParameterProperty = ctor === symbol.valueDeclaration.parent;
                        var isLocalThisPropertyAssignment = isAssignmentDeclaration_1 && ((_a = symbol.parent) === null || _a === void 0 ? void 0 : _a.valueDeclaration) === ctor.parent;
                        var isLocalThisPropertyAssignmentConstructorFunction = isAssignmentDeclaration_1 && ((_b = symbol.parent) === null || _b === void 0 ? void 0 : _b.valueDeclaration) === ctor;
                        var isWriteableSymbol = isLocalPropertyDeclaration
                            || isLocalParameterProperty
                            || isLocalThisPropertyAssignment
                            || isLocalThisPropertyAssignmentConstructorFunction;
                        return !isWriteableSymbol;
                    }
                }
                return true;
            }
            if (ts.isAccessExpression(expr)) {
                // references through namespace import should be readonly
                var node = ts.skipParentheses(expr.expression);
                if (node.kind === 75 /* Identifier */) {
                    var symbol_2 = getNodeLinks(node).resolvedSymbol;
                    if (symbol_2.flags & 2097152 /* Alias */) {
                        var declaration = getDeclarationOfAliasSymbol(symbol_2);
                        return !!declaration && declaration.kind === 256 /* NamespaceImport */;
                    }
                }
            }
            return false;
        }
        function checkReferenceExpression(expr, invalidReferenceMessage, invalidOptionalChainMessage) {
            // References are combinations of identifiers, parentheses, and property accesses.
            var node = ts.skipOuterExpressions(expr, 6 /* Assertions */ | 1 /* Parentheses */);
            if (node.kind !== 75 /* Identifier */ && !ts.isAccessExpression(node)) {
                error(expr, invalidReferenceMessage);
                return false;
            }
            if (node.flags & 32 /* OptionalChain */) {
                error(expr, invalidOptionalChainMessage);
                return false;
            }
            return true;
        }
        function checkDeleteExpression(node) {
            checkExpression(node.expression);
            var expr = ts.skipParentheses(node.expression);
            if (!ts.isAccessExpression(expr)) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference);
                return booleanType;
            }
            // eslint-disable-next-line
            if (expr.kind === 194 /* PropertyAccessExpression */ && ts.isPrivateIdentifier(expr.name)) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_private_identifier);
            }
            var links = getNodeLinks(expr);
            var symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol);
            if (symbol && isReadonlySymbol(symbol)) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_read_only_property);
            }
            return booleanType;
        }
        function checkTypeOfExpression(node) {
            checkExpression(node.expression);
            return typeofType;
        }
        function checkVoidExpression(node) {
            checkExpression(node.expression);
            return undefinedWideningType;
        }
        function isTopLevelAwait(node) {
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ true);
            return ts.isSourceFile(container);
        }
        function checkAwaitExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 32768 /* AwaitContext */)) {
                    if (isTopLevelAwait(node)) {
                        var sourceFile = ts.getSourceFileOfNode(node);
                        if (!hasParseDiagnostics(sourceFile)) {
                            var span = void 0;
                            if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) {
                                if (!span)
                                    span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                                var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module);
                                diagnostics.add(diagnostic);
                            }
                            if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || languageVersion < 4 /* ES2017 */) {
                                span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                                var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher);
                                diagnostics.add(diagnostic);
                            }
                        }
                    }
                    else {
                        // use of 'await' in non-async function
                        var sourceFile = ts.getSourceFileOfNode(node);
                        if (!hasParseDiagnostics(sourceFile)) {
                            var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                            var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules);
                            var func = ts.getContainingFunction(node);
                            if (func && func.kind !== 162 /* Constructor */ && (ts.getFunctionFlags(func) & 2 /* Async */) === 0) {
                                var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async);
                                ts.addRelatedInfo(diagnostic, relatedInfo);
                            }
                            diagnostics.add(diagnostic);
                        }
                    }
                }
                if (isInParameterInitializerBeforeContainingFunction(node)) {
                    error(node, ts.Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer);
                }
            }
            var operandType = checkExpression(node.expression);
            var awaitedType = checkAwaitedType(operandType, node, ts.Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
            if (awaitedType === operandType && awaitedType !== errorType && !(operandType.flags & 3 /* AnyOrUnknown */)) {
                addErrorOrSuggestion(/*isError*/ false, ts.createDiagnosticForNode(node, ts.Diagnostics.await_has_no_effect_on_the_type_of_this_expression));
            }
            return awaitedType;
        }
        function checkPrefixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            if (operandType === silentNeverType) {
                return silentNeverType;
            }
            switch (node.operand.kind) {
                case 8 /* NumericLiteral */:
                    switch (node.operator) {
                        case 40 /* MinusToken */:
                            return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text));
                        case 39 /* PlusToken */:
                            return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text));
                    }
                    break;
                case 9 /* BigIntLiteral */:
                    if (node.operator === 40 /* MinusToken */) {
                        return getFreshTypeOfLiteralType(getLiteralType({
                            negative: true,
                            base10Value: ts.parsePseudoBigInt(node.operand.text)
                        }));
                    }
            }
            switch (node.operator) {
                case 39 /* PlusToken */:
                case 40 /* MinusToken */:
                case 54 /* TildeToken */:
                    checkNonNullType(operandType, node.operand);
                    if (maybeTypeOfKind(operandType, 12288 /* ESSymbolLike */)) {
                        error(node.operand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(node.operator));
                    }
                    if (node.operator === 39 /* PlusToken */) {
                        if (maybeTypeOfKind(operandType, 2112 /* BigIntLike */)) {
                            error(node.operand, ts.Diagnostics.Operator_0_cannot_be_applied_to_type_1, ts.tokenToString(node.operator), typeToString(getBaseTypeOfLiteralType(operandType)));
                        }
                        return numberType;
                    }
                    return getUnaryResultType(operandType);
                case 53 /* ExclamationToken */:
                    checkTruthinessExpression(node.operand);
                    var facts = getTypeFacts(operandType) & (4194304 /* Truthy */ | 8388608 /* Falsy */);
                    return facts === 4194304 /* Truthy */ ? falseType :
                        facts === 8388608 /* Falsy */ ? trueType :
                            booleanType;
                case 45 /* PlusPlusToken */:
                case 46 /* MinusMinusToken */:
                    var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
                    if (ok) {
                        // run check only if former checks succeeded to avoid reporting cascading errors
                        checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access);
                    }
                    return getUnaryResultType(operandType);
            }
            return errorType;
        }
        function checkPostfixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            if (operandType === silentNeverType) {
                return silentNeverType;
            }
            var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
            if (ok) {
                // run check only if former checks succeeded to avoid reporting cascading errors
                checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access);
            }
            return getUnaryResultType(operandType);
        }
        function getUnaryResultType(operandType) {
            if (maybeTypeOfKind(operandType, 2112 /* BigIntLike */)) {
                return isTypeAssignableToKind(operandType, 3 /* AnyOrUnknown */) || maybeTypeOfKind(operandType, 296 /* NumberLike */)
                    ? numberOrBigIntType
                    : bigintType;
            }
            // If it's not a bigint type, implicit coercion will result in a number
            return numberType;
        }
        // Return true if type might be of the given kind. A union or intersection type might be of a given
        // kind if at least one constituent type is of the given kind.
        function maybeTypeOfKind(type, kind) {
            if (type.flags & kind) {
                return true;
            }
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                var types = type.types;
                for (var _i = 0, types_19 = types; _i < types_19.length; _i++) {
                    var t = types_19[_i];
                    if (maybeTypeOfKind(t, kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isTypeAssignableToKind(source, kind, strict) {
            if (source.flags & kind) {
                return true;
            }
            if (strict && source.flags & (3 /* AnyOrUnknown */ | 16384 /* Void */ | 32768 /* Undefined */ | 65536 /* Null */)) {
                return false;
            }
            return !!(kind & 296 /* NumberLike */) && isTypeAssignableTo(source, numberType) ||
                !!(kind & 2112 /* BigIntLike */) && isTypeAssignableTo(source, bigintType) ||
                !!(kind & 132 /* StringLike */) && isTypeAssignableTo(source, stringType) ||
                !!(kind & 528 /* BooleanLike */) && isTypeAssignableTo(source, booleanType) ||
                !!(kind & 16384 /* Void */) && isTypeAssignableTo(source, voidType) ||
                !!(kind & 131072 /* Never */) && isTypeAssignableTo(source, neverType) ||
                !!(kind & 65536 /* Null */) && isTypeAssignableTo(source, nullType) ||
                !!(kind & 32768 /* Undefined */) && isTypeAssignableTo(source, undefinedType) ||
                !!(kind & 4096 /* ESSymbol */) && isTypeAssignableTo(source, esSymbolType) ||
                !!(kind & 67108864 /* NonPrimitive */) && isTypeAssignableTo(source, nonPrimitiveType);
        }
        function allTypesAssignableToKind(source, kind, strict) {
            return source.flags & 1048576 /* Union */ ?
                ts.every(source.types, function (subType) { return allTypesAssignableToKind(subType, kind, strict); }) :
                isTypeAssignableToKind(source, kind, strict);
        }
        function isConstEnumObjectType(type) {
            return !!(ts.getObjectFlags(type) & 16 /* Anonymous */) && !!type.symbol && isConstEnumSymbol(type.symbol);
        }
        function isConstEnumSymbol(symbol) {
            return (symbol.flags & 128 /* ConstEnum */) !== 0;
        }
        function checkInstanceOfExpression(left, right, leftType, rightType) {
            if (leftType === silentNeverType || rightType === silentNeverType) {
                return silentNeverType;
            }
            // TypeScript 1.0 spec (April 2014): 4.15.4
            // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
            // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature.
            // The result is always of the Boolean primitive type.
            // NOTE: do not raise error if leftType is unknown as related error was already reported
            if (!isTypeAny(leftType) &&
                allTypesAssignableToKind(leftType, 131068 /* Primitive */)) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            // NOTE: do not raise error if right is unknown as related error was already reported
            if (!(isTypeAny(rightType) || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) {
                error(right, ts.Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
            }
            return booleanType;
        }
        function checkInExpression(left, right, leftType, rightType) {
            if (leftType === silentNeverType || rightType === silentNeverType) {
                return silentNeverType;
            }
            leftType = checkNonNullType(leftType, left);
            rightType = checkNonNullType(rightType, right);
            // TypeScript 1.0 spec (April 2014): 4.15.5
            // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
            // and the right operand to be of type Any, an object type, or a type parameter type.
            // The result is always of the Boolean primitive type.
            if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 296 /* NumberLike */ | 12288 /* ESSymbolLike */))) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
            }
            if (!allTypesAssignableToKind(rightType, 67108864 /* NonPrimitive */ | 58982400 /* InstantiableNonPrimitive */)) {
                error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            return booleanType;
        }
        function checkObjectLiteralAssignment(node, sourceType, rightIsThis) {
            var properties = node.properties;
            if (strictNullChecks && properties.length === 0) {
                return checkNonNullType(sourceType, node);
            }
            for (var i = 0; i < properties.length; i++) {
                checkObjectLiteralDestructuringPropertyAssignment(node, sourceType, i, properties, rightIsThis);
            }
            return sourceType;
        }
        /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
        function checkObjectLiteralDestructuringPropertyAssignment(node, objectLiteralType, propertyIndex, allProperties, rightIsThis) {
            if (rightIsThis === void 0) { rightIsThis = false; }
            var properties = node.properties;
            var property = properties[propertyIndex];
            if (property.kind === 281 /* PropertyAssignment */ || property.kind === 282 /* ShorthandPropertyAssignment */) {
                var name = property.name;
                var exprType = getLiteralTypeFromPropertyName(name);
                if (isTypeUsableAsPropertyName(exprType)) {
                    var text = getPropertyNameFromType(exprType);
                    var prop = getPropertyOfType(objectLiteralType, text);
                    if (prop) {
                        markPropertyAsReferenced(prop, property, rightIsThis);
                        checkPropertyAccessibility(property, /*isSuper*/ false, objectLiteralType, prop);
                    }
                }
                var elementType = getIndexedAccessType(objectLiteralType, exprType, name);
                var type = getFlowTypeOfDestructuring(property, elementType);
                return checkDestructuringAssignment(property.kind === 282 /* ShorthandPropertyAssignment */ ? property : property.initializer, type);
            }
            else if (property.kind === 283 /* SpreadAssignment */) {
                if (propertyIndex < properties.length - 1) {
                    error(property, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                else {
                    if (languageVersion < 99 /* ESNext */) {
                        checkExternalEmitHelpers(property, 4 /* Rest */);
                    }
                    var nonRestNames = [];
                    if (allProperties) {
                        for (var _i = 0, allProperties_1 = allProperties; _i < allProperties_1.length; _i++) {
                            var otherProperty = allProperties_1[_i];
                            if (!ts.isSpreadAssignment(otherProperty)) {
                                nonRestNames.push(otherProperty.name);
                            }
                        }
                    }
                    var type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
                    checkGrammarForDisallowedTrailingComma(allProperties, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                    return checkDestructuringAssignment(property.expression, type);
                }
            }
            else {
                error(property, ts.Diagnostics.Property_assignment_expected);
            }
        }
        function checkArrayLiteralAssignment(node, sourceType, checkMode) {
            var elements = node.elements;
            if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                checkExternalEmitHelpers(node, 512 /* Read */);
            }
            // This elementType will be used if the specific property corresponding to this index is not
            // present (aka the tuple element property). This call also checks that the parentType is in
            // fact an iterable or array (depending on target language).
            var elementType = checkIteratedTypeOrElementType(65 /* Destructuring */, sourceType, undefinedType, node) || errorType;
            for (var i = 0; i < elements.length; i++) {
                checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode);
            }
            return sourceType;
        }
        function checkArrayLiteralDestructuringElementAssignment(node, sourceType, elementIndex, elementType, checkMode) {
            var elements = node.elements;
            var element = elements[elementIndex];
            if (element.kind !== 215 /* OmittedExpression */) {
                if (element.kind !== 213 /* SpreadElement */) {
                    var indexType = getLiteralType(elementIndex);
                    if (isArrayLikeType(sourceType)) {
                        // We create a synthetic expression so that getIndexedAccessType doesn't get confused
                        // when the element is a SyntaxKind.ElementAccessExpression.
                        var accessFlags = hasDefaultValue(element) ? 8 /* NoTupleBoundsCheck */ : 0;
                        var elementType_2 = getIndexedAccessTypeOrUndefined(sourceType, indexType, createSyntheticExpression(element, indexType), accessFlags) || errorType;
                        var assignedType = hasDefaultValue(element) ? getTypeWithFacts(elementType_2, 524288 /* NEUndefined */) : elementType_2;
                        var type = getFlowTypeOfDestructuring(element, assignedType);
                        return checkDestructuringAssignment(element, type, checkMode);
                    }
                    return checkDestructuringAssignment(element, elementType, checkMode);
                }
                if (elementIndex < elements.length - 1) {
                    error(element, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                else {
                    var restExpression = element.expression;
                    if (restExpression.kind === 209 /* BinaryExpression */ && restExpression.operatorToken.kind === 62 /* EqualsToken */) {
                        error(restExpression.operatorToken, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                    }
                    else {
                        checkGrammarForDisallowedTrailingComma(node.elements, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                        var type = everyType(sourceType, isTupleType) ?
                            mapType(sourceType, function (t) { return sliceTupleType(t, elementIndex); }) :
                            createArrayType(elementType);
                        return checkDestructuringAssignment(restExpression, type, checkMode);
                    }
                }
            }
            return undefined;
        }
        function checkDestructuringAssignment(exprOrAssignment, sourceType, checkMode, rightIsThis) {
            var target;
            if (exprOrAssignment.kind === 282 /* ShorthandPropertyAssignment */) {
                var prop = exprOrAssignment;
                if (prop.objectAssignmentInitializer) {
                    // In strict null checking mode, if a default value of a non-undefined type is specified, remove
                    // undefined from the final type.
                    if (strictNullChecks &&
                        !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & 32768 /* Undefined */)) {
                        sourceType = getTypeWithFacts(sourceType, 524288 /* NEUndefined */);
                    }
                    checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, checkMode);
                }
                target = exprOrAssignment.name;
            }
            else {
                target = exprOrAssignment;
            }
            if (target.kind === 209 /* BinaryExpression */ && target.operatorToken.kind === 62 /* EqualsToken */) {
                checkBinaryExpression(target, checkMode);
                target = target.left;
            }
            if (target.kind === 193 /* ObjectLiteralExpression */) {
                return checkObjectLiteralAssignment(target, sourceType, rightIsThis);
            }
            if (target.kind === 192 /* ArrayLiteralExpression */) {
                return checkArrayLiteralAssignment(target, sourceType, checkMode);
            }
            return checkReferenceAssignment(target, sourceType, checkMode);
        }
        function checkReferenceAssignment(target, sourceType, checkMode) {
            var targetType = checkExpression(target, checkMode);
            var error = target.parent.kind === 283 /* SpreadAssignment */ ?
                ts.Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access :
                ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access;
            var optionalError = target.parent.kind === 283 /* SpreadAssignment */ ?
                ts.Diagnostics.The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access :
                ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access;
            if (checkReferenceExpression(target, error, optionalError)) {
                checkTypeAssignableToAndOptionallyElaborate(sourceType, targetType, target, target);
            }
            if (ts.isPrivateIdentifierPropertyAccessExpression(target)) {
                checkExternalEmitHelpers(target.parent, 524288 /* ClassPrivateFieldSet */);
            }
            return sourceType;
        }
        /**
         * This is a *shallow* check: An expression is side-effect-free if the
         * evaluation of the expression *itself* cannot produce side effects.
         * For example, x++ / 3 is side-effect free because the / operator
         * does not have side effects.
         * The intent is to "smell test" an expression for correctness in positions where
         * its value is discarded (e.g. the left side of the comma operator).
         */
        function isSideEffectFree(node) {
            node = ts.skipParentheses(node);
            switch (node.kind) {
                case 75 /* Identifier */:
                case 10 /* StringLiteral */:
                case 13 /* RegularExpressionLiteral */:
                case 198 /* TaggedTemplateExpression */:
                case 211 /* TemplateExpression */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 100 /* NullKeyword */:
                case 146 /* UndefinedKeyword */:
                case 201 /* FunctionExpression */:
                case 214 /* ClassExpression */:
                case 202 /* ArrowFunction */:
                case 192 /* ArrayLiteralExpression */:
                case 193 /* ObjectLiteralExpression */:
                case 204 /* TypeOfExpression */:
                case 218 /* NonNullExpression */:
                case 267 /* JsxSelfClosingElement */:
                case 266 /* JsxElement */:
                    return true;
                case 210 /* ConditionalExpression */:
                    return isSideEffectFree(node.whenTrue) &&
                        isSideEffectFree(node.whenFalse);
                case 209 /* BinaryExpression */:
                    if (ts.isAssignmentOperator(node.operatorToken.kind)) {
                        return false;
                    }
                    return isSideEffectFree(node.left) &&
                        isSideEffectFree(node.right);
                case 207 /* PrefixUnaryExpression */:
                case 208 /* PostfixUnaryExpression */:
                    // Unary operators ~, !, +, and - have no side effects.
                    // The rest do.
                    switch (node.operator) {
                        case 53 /* ExclamationToken */:
                        case 39 /* PlusToken */:
                        case 40 /* MinusToken */:
                        case 54 /* TildeToken */:
                            return true;
                    }
                    return false;
                // Some forms listed here for clarity
                case 205 /* VoidExpression */: // Explicit opt-out
                case 199 /* TypeAssertionExpression */: // Not SEF, but can produce useful type warnings
                case 217 /* AsExpression */: // Not SEF, but can produce useful type warnings
                default:
                    return false;
            }
        }
        function isTypeEqualityComparableTo(source, target) {
            return (target.flags & 98304 /* Nullable */) !== 0 || isTypeComparableTo(source, target);
        }
        var CheckBinaryExpressionState;
        (function (CheckBinaryExpressionState) {
            CheckBinaryExpressionState[CheckBinaryExpressionState["MaybeCheckLeft"] = 0] = "MaybeCheckLeft";
            CheckBinaryExpressionState[CheckBinaryExpressionState["CheckRight"] = 1] = "CheckRight";
            CheckBinaryExpressionState[CheckBinaryExpressionState["FinishCheck"] = 2] = "FinishCheck";
        })(CheckBinaryExpressionState || (CheckBinaryExpressionState = {}));
        function checkBinaryExpression(node, checkMode) {
            var workStacks = {
                expr: [node],
                state: [0 /* MaybeCheckLeft */],
                leftType: [undefined]
            };
            var stackIndex = 0;
            var lastResult;
            while (stackIndex >= 0) {
                node = workStacks.expr[stackIndex];
                switch (workStacks.state[stackIndex]) {
                    case 0 /* MaybeCheckLeft */: {
                        if (ts.isInJSFile(node) && ts.getAssignedExpandoInitializer(node)) {
                            finishInvocation(checkExpression(node.right, checkMode));
                            break;
                        }
                        checkGrammarNullishCoalesceWithLogicalExpression(node);
                        var operator = node.operatorToken.kind;
                        if (operator === 62 /* EqualsToken */ && (node.left.kind === 193 /* ObjectLiteralExpression */ || node.left.kind === 192 /* ArrayLiteralExpression */)) {
                            finishInvocation(checkDestructuringAssignment(node.left, checkExpression(node.right, checkMode), checkMode, node.right.kind === 104 /* ThisKeyword */));
                            break;
                        }
                        advanceState(1 /* CheckRight */);
                        maybeCheckExpression(node.left);
                        break;
                    }
                    case 1 /* CheckRight */: {
                        var leftType = lastResult;
                        workStacks.leftType[stackIndex] = leftType;
                        var operator = node.operatorToken.kind;
                        if (operator === 55 /* AmpersandAmpersandToken */ || operator === 56 /* BarBarToken */ || operator === 60 /* QuestionQuestionToken */) {
                            checkTruthinessOfType(leftType, node.left);
                        }
                        advanceState(2 /* FinishCheck */);
                        maybeCheckExpression(node.right);
                        break;
                    }
                    case 2 /* FinishCheck */: {
                        var leftType = workStacks.leftType[stackIndex];
                        var rightType = lastResult;
                        finishInvocation(checkBinaryLikeExpressionWorker(node.left, node.operatorToken, node.right, leftType, rightType, node));
                        break;
                    }
                    default: return ts.Debug.fail("Invalid state " + workStacks.state[stackIndex] + " for checkBinaryExpression");
                }
            }
            return lastResult;
            function finishInvocation(result) {
                lastResult = result;
                stackIndex--;
            }
            /**
             * Note that `advanceState` sets the _current_ head state, and that `maybeCheckExpression` potentially pushes on a new
             * head state; so `advanceState` must be called before any `maybeCheckExpression` during a state's execution.
             */
            function advanceState(nextState) {
                workStacks.state[stackIndex] = nextState;
            }
            function maybeCheckExpression(node) {
                if (ts.isBinaryExpression(node)) {
                    stackIndex++;
                    workStacks.expr[stackIndex] = node;
                    workStacks.state[stackIndex] = 0 /* MaybeCheckLeft */;
                    workStacks.leftType[stackIndex] = undefined;
                }
                else {
                    lastResult = checkExpression(node, checkMode);
                }
            }
        }
        function checkGrammarNullishCoalesceWithLogicalExpression(node) {
            var left = node.left, operatorToken = node.operatorToken, right = node.right;
            if (operatorToken.kind === 60 /* QuestionQuestionToken */) {
                if (ts.isBinaryExpression(left) && (left.operatorToken.kind === 56 /* BarBarToken */ || left.operatorToken.kind === 55 /* AmpersandAmpersandToken */)) {
                    grammarErrorOnNode(left, ts.Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, ts.tokenToString(left.operatorToken.kind), ts.tokenToString(operatorToken.kind));
                }
                if (ts.isBinaryExpression(right) && (right.operatorToken.kind === 56 /* BarBarToken */ || right.operatorToken.kind === 55 /* AmpersandAmpersandToken */)) {
                    grammarErrorOnNode(right, ts.Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, ts.tokenToString(right.operatorToken.kind), ts.tokenToString(operatorToken.kind));
                }
            }
        }
        // Note that this and `checkBinaryExpression` above should behave mostly the same, except this elides some
        // expression-wide checks and does not use a work stack to fold nested binary expressions into the same callstack frame
        function checkBinaryLikeExpression(left, operatorToken, right, checkMode, errorNode) {
            var operator = operatorToken.kind;
            if (operator === 62 /* EqualsToken */ && (left.kind === 193 /* ObjectLiteralExpression */ || left.kind === 192 /* ArrayLiteralExpression */)) {
                return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode, right.kind === 104 /* ThisKeyword */);
            }
            var leftType;
            if (operator === 55 /* AmpersandAmpersandToken */ || operator === 56 /* BarBarToken */ || operator === 60 /* QuestionQuestionToken */) {
                leftType = checkTruthinessExpression(left, checkMode);
            }
            else {
                leftType = checkExpression(left, checkMode);
            }
            var rightType = checkExpression(right, checkMode);
            return checkBinaryLikeExpressionWorker(left, operatorToken, right, leftType, rightType, errorNode);
        }
        function checkBinaryLikeExpressionWorker(left, operatorToken, right, leftType, rightType, errorNode) {
            var operator = operatorToken.kind;
            switch (operator) {
                case 41 /* AsteriskToken */:
                case 42 /* AsteriskAsteriskToken */:
                case 65 /* AsteriskEqualsToken */:
                case 66 /* AsteriskAsteriskEqualsToken */:
                case 43 /* SlashToken */:
                case 67 /* SlashEqualsToken */:
                case 44 /* PercentToken */:
                case 68 /* PercentEqualsToken */:
                case 40 /* MinusToken */:
                case 64 /* MinusEqualsToken */:
                case 47 /* LessThanLessThanToken */:
                case 69 /* LessThanLessThanEqualsToken */:
                case 48 /* GreaterThanGreaterThanToken */:
                case 70 /* GreaterThanGreaterThanEqualsToken */:
                case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                case 51 /* BarToken */:
                case 73 /* BarEqualsToken */:
                case 52 /* CaretToken */:
                case 74 /* CaretEqualsToken */:
                case 50 /* AmpersandToken */:
                case 72 /* AmpersandEqualsToken */:
                    if (leftType === silentNeverType || rightType === silentNeverType) {
                        return silentNeverType;
                    }
                    leftType = checkNonNullType(leftType, left);
                    rightType = checkNonNullType(rightType, right);
                    var suggestedOperator = void 0;
                    // if a user tries to apply a bitwise operator to 2 boolean operands
                    // try and return them a helpful suggestion
                    if ((leftType.flags & 528 /* BooleanLike */) &&
                        (rightType.flags & 528 /* BooleanLike */) &&
                        (suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
                        error(errorNode || operatorToken, ts.Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, ts.tokenToString(operatorToken.kind), ts.tokenToString(suggestedOperator));
                        return numberType;
                    }
                    else {
                        // otherwise just check each operand separately and report errors as normal
                        var leftOk = checkArithmeticOperandType(left, leftType, ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true);
                        var rightOk = checkArithmeticOperandType(right, rightType, ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true);
                        var resultType_1;
                        // If both are any or unknown, allow operation; assume it will resolve to number
                        if ((isTypeAssignableToKind(leftType, 3 /* AnyOrUnknown */) && isTypeAssignableToKind(rightType, 3 /* AnyOrUnknown */)) ||
                            // Or, if neither could be bigint, implicit coercion results in a number result
                            !(maybeTypeOfKind(leftType, 2112 /* BigIntLike */) || maybeTypeOfKind(rightType, 2112 /* BigIntLike */))) {
                            resultType_1 = numberType;
                        }
                        // At least one is assignable to bigint, so check that both are
                        else if (bothAreBigIntLike(leftType, rightType)) {
                            switch (operator) {
                                case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                                case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                                    reportOperatorError();
                            }
                            resultType_1 = bigintType;
                        }
                        // Exactly one of leftType/rightType is assignable to bigint
                        else {
                            reportOperatorError(bothAreBigIntLike);
                            resultType_1 = errorType;
                        }
                        if (leftOk && rightOk) {
                            checkAssignmentOperator(resultType_1);
                        }
                        return resultType_1;
                    }
                case 39 /* PlusToken */:
                case 63 /* PlusEqualsToken */:
                    if (leftType === silentNeverType || rightType === silentNeverType) {
                        return silentNeverType;
                    }
                    if (!isTypeAssignableToKind(leftType, 132 /* StringLike */) && !isTypeAssignableToKind(rightType, 132 /* StringLike */)) {
                        leftType = checkNonNullType(leftType, left);
                        rightType = checkNonNullType(rightType, right);
                    }
                    var resultType = void 0;
                    if (isTypeAssignableToKind(leftType, 296 /* NumberLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 296 /* NumberLike */, /*strict*/ true)) {
                        // Operands of an enum type are treated as having the primitive type Number.
                        // If both operands are of the Number primitive type, the result is of the Number primitive type.
                        resultType = numberType;
                    }
                    else if (isTypeAssignableToKind(leftType, 2112 /* BigIntLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 2112 /* BigIntLike */, /*strict*/ true)) {
                        // If both operands are of the BigInt primitive type, the result is of the BigInt primitive type.
                        resultType = bigintType;
                    }
                    else if (isTypeAssignableToKind(leftType, 132 /* StringLike */, /*strict*/ true) || isTypeAssignableToKind(rightType, 132 /* StringLike */, /*strict*/ true)) {
                        // If one or both operands are of the String primitive type, the result is of the String primitive type.
                        resultType = stringType;
                    }
                    else if (isTypeAny(leftType) || isTypeAny(rightType)) {
                        // Otherwise, the result is of type Any.
                        // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
                        resultType = leftType === errorType || rightType === errorType ? errorType : anyType;
                    }
                    // Symbols are not allowed at all in arithmetic expressions
                    if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
                        return resultType;
                    }
                    if (!resultType) {
                        // Types that have a reasonably good chance of being a valid operand type.
                        // If both types have an awaited type of one of these, we'll assume the user
                        // might be missing an await without doing an exhaustive check that inserting
                        // await(s) will actually be a completely valid binary expression.
                        var closeEnoughKind_1 = 296 /* NumberLike */ | 2112 /* BigIntLike */ | 132 /* StringLike */ | 3 /* AnyOrUnknown */;
                        reportOperatorError(function (left, right) {
                            return isTypeAssignableToKind(left, closeEnoughKind_1) &&
                                isTypeAssignableToKind(right, closeEnoughKind_1);
                        });
                        return anyType;
                    }
                    if (operator === 63 /* PlusEqualsToken */) {
                        checkAssignmentOperator(resultType);
                    }
                    return resultType;
                case 29 /* LessThanToken */:
                case 31 /* GreaterThanToken */:
                case 32 /* LessThanEqualsToken */:
                case 33 /* GreaterThanEqualsToken */:
                    if (checkForDisallowedESSymbolOperand(operator)) {
                        leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left));
                        rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right));
                        reportOperatorErrorUnless(function (left, right) {
                            return isTypeComparableTo(left, right) || isTypeComparableTo(right, left) || (isTypeAssignableTo(left, numberOrBigIntType) && isTypeAssignableTo(right, numberOrBigIntType));
                        });
                    }
                    return booleanType;
                case 34 /* EqualsEqualsToken */:
                case 35 /* ExclamationEqualsToken */:
                case 36 /* EqualsEqualsEqualsToken */:
                case 37 /* ExclamationEqualsEqualsToken */:
                    reportOperatorErrorUnless(function (left, right) { return isTypeEqualityComparableTo(left, right) || isTypeEqualityComparableTo(right, left); });
                    return booleanType;
                case 98 /* InstanceOfKeyword */:
                    return checkInstanceOfExpression(left, right, leftType, rightType);
                case 97 /* InKeyword */:
                    return checkInExpression(left, right, leftType, rightType);
                case 55 /* AmpersandAmpersandToken */:
                    return getTypeFacts(leftType) & 4194304 /* Truthy */ ?
                        getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) :
                        leftType;
                case 56 /* BarBarToken */:
                    return getTypeFacts(leftType) & 8388608 /* Falsy */ ?
                        getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], 2 /* Subtype */) :
                        leftType;
                case 60 /* QuestionQuestionToken */:
                    return getTypeFacts(leftType) & 262144 /* EQUndefinedOrNull */ ?
                        getUnionType([getNonNullableType(leftType), rightType], 2 /* Subtype */) :
                        leftType;
                case 62 /* EqualsToken */:
                    var declKind = ts.isBinaryExpression(left.parent) ? ts.getAssignmentDeclarationKind(left.parent) : 0 /* None */;
                    checkAssignmentDeclaration(declKind, rightType);
                    if (isAssignmentDeclaration(declKind)) {
                        if (!(rightType.flags & 524288 /* Object */) ||
                            declKind !== 2 /* ModuleExports */ &&
                                declKind !== 6 /* Prototype */ &&
                                !isEmptyObjectType(rightType) &&
                                !isFunctionObjectType(rightType) &&
                                !(ts.getObjectFlags(rightType) & 1 /* Class */)) {
                            // don't check assignability of module.exports=, C.prototype=, or expando types because they will necessarily be incomplete
                            checkAssignmentOperator(rightType);
                        }
                        return leftType;
                    }
                    else {
                        checkAssignmentOperator(rightType);
                        return getRegularTypeOfObjectLiteral(rightType);
                    }
                case 27 /* CommaToken */:
                    if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left) && !isEvalNode(right)) {
                        error(left, ts.Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects);
                    }
                    return rightType;
                default:
                    return ts.Debug.fail();
            }
            function bothAreBigIntLike(left, right) {
                return isTypeAssignableToKind(left, 2112 /* BigIntLike */) && isTypeAssignableToKind(right, 2112 /* BigIntLike */);
            }
            function checkAssignmentDeclaration(kind, rightType) {
                if (kind === 2 /* ModuleExports */) {
                    for (var _i = 0, _a = getPropertiesOfObjectType(rightType); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        var propType = getTypeOfSymbol(prop);
                        if (propType.symbol && propType.symbol.flags & 32 /* Class */) {
                            var name = prop.escapedName;
                            var symbol = resolveName(prop.valueDeclaration, name, 788968 /* Type */, undefined, name, /*isUse*/ false);
                            if (symbol && symbol.declarations.some(ts.isJSDocTypedefTag)) {
                                addDuplicateDeclarationErrorsForSymbols(symbol, ts.Diagnostics.Duplicate_identifier_0, ts.unescapeLeadingUnderscores(name), prop);
                                addDuplicateDeclarationErrorsForSymbols(prop, ts.Diagnostics.Duplicate_identifier_0, ts.unescapeLeadingUnderscores(name), symbol);
                            }
                        }
                    }
                }
            }
            function isEvalNode(node) {
                return node.kind === 75 /* Identifier */ && node.escapedText === "eval";
            }
            // Return true if there was no error, false if there was an error.
            function checkForDisallowedESSymbolOperand(operator) {
                var offendingSymbolOperand = maybeTypeOfKind(leftType, 12288 /* ESSymbolLike */) ? left :
                    maybeTypeOfKind(rightType, 12288 /* ESSymbolLike */) ? right :
                        undefined;
                if (offendingSymbolOperand) {
                    error(offendingSymbolOperand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(operator));
                    return false;
                }
                return true;
            }
            function getSuggestedBooleanOperator(operator) {
                switch (operator) {
                    case 51 /* BarToken */:
                    case 73 /* BarEqualsToken */:
                        return 56 /* BarBarToken */;
                    case 52 /* CaretToken */:
                    case 74 /* CaretEqualsToken */:
                        return 37 /* ExclamationEqualsEqualsToken */;
                    case 50 /* AmpersandToken */:
                    case 72 /* AmpersandEqualsToken */:
                        return 55 /* AmpersandAmpersandToken */;
                    default:
                        return undefined;
                }
            }
            function checkAssignmentOperator(valueType) {
                if (produceDiagnostics && ts.isAssignmentOperator(operator)) {
                    // TypeScript 1.0 spec (April 2014): 4.17
                    // An assignment of the form
                    //    VarExpr = ValueExpr
                    // requires VarExpr to be classified as a reference
                    // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
                    // and the type of the non-compound operation to be assignable to the type of VarExpr.
                    if (checkReferenceExpression(left, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access)
                        && (!ts.isIdentifier(left) || ts.unescapeLeadingUnderscores(left.escapedText) !== "exports")) {
                        // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
                        checkTypeAssignableToAndOptionallyElaborate(valueType, leftType, left, right);
                    }
                }
            }
            function isAssignmentDeclaration(kind) {
                switch (kind) {
                    case 2 /* ModuleExports */:
                        return true;
                    case 1 /* ExportsProperty */:
                    case 5 /* Property */:
                    case 6 /* Prototype */:
                    case 3 /* PrototypeProperty */:
                    case 4 /* ThisProperty */:
                        var symbol = getSymbolOfNode(left);
                        var init = ts.getAssignedExpandoInitializer(right);
                        return init && ts.isObjectLiteralExpression(init) &&
                            symbol && ts.hasEntries(symbol.exports);
                    default:
                        return false;
                }
            }
            /**
             * Returns true if an error is reported
             */
            function reportOperatorErrorUnless(typesAreCompatible) {
                if (!typesAreCompatible(leftType, rightType)) {
                    reportOperatorError(typesAreCompatible);
                    return true;
                }
                return false;
            }
            function reportOperatorError(isRelated) {
                var _a;
                var wouldWorkWithAwait = false;
                var errNode = errorNode || operatorToken;
                if (isRelated) {
                    var awaitedLeftType = getAwaitedType(leftType);
                    var awaitedRightType = getAwaitedType(rightType);
                    wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType)
                        && !!(awaitedLeftType && awaitedRightType)
                        && isRelated(awaitedLeftType, awaitedRightType);
                }
                var effectiveLeft = leftType;
                var effectiveRight = rightType;
                if (!wouldWorkWithAwait && isRelated) {
                    _a = getBaseTypesIfUnrelated(leftType, rightType, isRelated), effectiveLeft = _a[0], effectiveRight = _a[1];
                }
                var _b = getTypeNamesForErrorDisplay(effectiveLeft, effectiveRight), leftStr = _b[0], rightStr = _b[1];
                if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) {
                    errorAndMaybeSuggestAwait(errNode, wouldWorkWithAwait, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(operatorToken.kind), leftStr, rightStr);
                }
            }
            function tryGiveBetterPrimaryError(errNode, maybeMissingAwait, leftStr, rightStr) {
                var typeName;
                switch (operatorToken.kind) {
                    case 36 /* EqualsEqualsEqualsToken */:
                    case 34 /* EqualsEqualsToken */:
                        typeName = "false";
                        break;
                    case 37 /* ExclamationEqualsEqualsToken */:
                    case 35 /* ExclamationEqualsToken */:
                        typeName = "true";
                }
                if (typeName) {
                    return errorAndMaybeSuggestAwait(errNode, maybeMissingAwait, ts.Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, typeName, leftStr, rightStr);
                }
                return undefined;
            }
        }
        function getBaseTypesIfUnrelated(leftType, rightType, isRelated) {
            var effectiveLeft = leftType;
            var effectiveRight = rightType;
            var leftBase = getBaseTypeOfLiteralType(leftType);
            var rightBase = getBaseTypeOfLiteralType(rightType);
            if (!isRelated(leftBase, rightBase)) {
                effectiveLeft = leftBase;
                effectiveRight = rightBase;
            }
            return [effectiveLeft, effectiveRight];
        }
        function checkYieldExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 8192 /* YieldContext */)) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body);
                }
                if (isInParameterInitializerBeforeContainingFunction(node)) {
                    error(node, ts.Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer);
                }
            }
            var func = ts.getContainingFunction(node);
            if (!func)
                return anyType;
            var functionFlags = ts.getFunctionFlags(func);
            if (!(functionFlags & 1 /* Generator */)) {
                // If the user's code is syntactically correct, the func should always have a star. After all, we are in a yield context.
                return anyType;
            }
            var isAsync = (functionFlags & 2 /* Async */) !== 0;
            if (node.asteriskToken) {
                // Async generator functions prior to ESNext require the __await, __asyncDelegator,
                // and __asyncValues helpers
                if (isAsync && languageVersion < 99 /* ESNext */) {
                    checkExternalEmitHelpers(node, 53248 /* AsyncDelegatorIncludes */);
                }
                // Generator functions prior to ES2015 require the __values helper
                if (!isAsync && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                    checkExternalEmitHelpers(node, 256 /* Values */);
                }
            }
            // There is no point in doing an assignability check if the function
            // has no explicit return type because the return type is directly computed
            // from the yield expressions.
            var returnType = getReturnTypeFromAnnotation(func);
            var iterationTypes = returnType && getIterationTypesOfGeneratorFunctionReturnType(returnType, isAsync);
            var signatureYieldType = iterationTypes && iterationTypes.yieldType || anyType;
            var signatureNextType = iterationTypes && iterationTypes.nextType || anyType;
            var resolvedSignatureNextType = isAsync ? getAwaitedType(signatureNextType) || anyType : signatureNextType;
            var yieldExpressionType = node.expression ? checkExpression(node.expression) : undefinedWideningType;
            var yieldedType = getYieldedTypeOfYieldExpression(node, yieldExpressionType, resolvedSignatureNextType, isAsync);
            if (returnType && yieldedType) {
                checkTypeAssignableToAndOptionallyElaborate(yieldedType, signatureYieldType, node.expression || node, node.expression);
            }
            if (node.asteriskToken) {
                var use = isAsync ? 19 /* AsyncYieldStar */ : 17 /* YieldStar */;
                return getIterationTypeOfIterable(use, 1 /* Return */, yieldExpressionType, node.expression)
                    || anyType;
            }
            else if (returnType) {
                return getIterationTypeOfGeneratorFunctionReturnType(2 /* Next */, returnType, isAsync)
                    || anyType;
            }
            return getContextualIterationType(2 /* Next */, func) || anyType;
        }
        function checkConditionalExpression(node, checkMode) {
            var type = checkTruthinessExpression(node.condition);
            checkTestingKnownTruthyCallableType(node.condition, node.whenTrue, type);
            var type1 = checkExpression(node.whenTrue, checkMode);
            var type2 = checkExpression(node.whenFalse, checkMode);
            return getUnionType([type1, type2], 2 /* Subtype */);
        }
        function checkTemplateExpression(node) {
            // We just want to check each expressions, but we are unconcerned with
            // the type of each expression, as any value may be coerced into a string.
            // It is worth asking whether this is what we really want though.
            // A place where we actually *are* concerned with the expressions' types are
            // in tagged templates.
            ts.forEach(node.templateSpans, function (templateSpan) {
                if (maybeTypeOfKind(checkExpression(templateSpan.expression), 12288 /* ESSymbolLike */)) {
                    error(templateSpan.expression, ts.Diagnostics.Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String);
                }
            });
            return stringType;
        }
        function getContextNode(node) {
            if (node.kind === 274 /* JsxAttributes */ && !ts.isJsxSelfClosingElement(node.parent)) {
                return node.parent.parent; // Needs to be the root JsxElement, so it encompasses the attributes _and_ the children (which are essentially part of the attributes)
            }
            return node;
        }
        function checkExpressionWithContextualType(node, contextualType, inferenceContext, checkMode) {
            var context = getContextNode(node);
            var saveContextualType = context.contextualType;
            var saveInferenceContext = context.inferenceContext;
            try {
                context.contextualType = contextualType;
                context.inferenceContext = inferenceContext;
                var type = checkExpression(node, checkMode | 1 /* Contextual */ | (inferenceContext ? 2 /* Inferential */ : 0));
                // We strip literal freshness when an appropriate contextual type is present such that contextually typed
                // literals always preserve their literal types (otherwise they might widen during type inference). An alternative
                // here would be to not mark contextually typed literals as fresh in the first place.
                var result = maybeTypeOfKind(type, 2944 /* Literal */) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ?
                    getRegularTypeOfLiteralType(type) : type;
                return result;
            }
            finally {
                // In the event our operation is canceled or some other exception occurs, reset the contextual type
                // so that we do not accidentally hold onto an instance of the checker, as a Type created in the services layer
                // may hold onto the checker that created it.
                context.contextualType = saveContextualType;
                context.inferenceContext = saveInferenceContext;
            }
        }
        function checkExpressionCached(node, checkMode) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                if (checkMode && checkMode !== 0 /* Normal */) {
                    return checkExpression(node, checkMode);
                }
                // When computing a type that we're going to cache, we need to ignore any ongoing control flow
                // analysis because variables may have transient types in indeterminable states. Moving flowLoopStart
                // to the top of the stack ensures all transient types are computed from a known point.
                var saveFlowLoopStart = flowLoopStart;
                var saveFlowTypeCache = flowTypeCache;
                flowLoopStart = flowLoopCount;
                flowTypeCache = undefined;
                links.resolvedType = checkExpression(node, checkMode);
                flowTypeCache = saveFlowTypeCache;
                flowLoopStart = saveFlowLoopStart;
            }
            return links.resolvedType;
        }
        function isTypeAssertion(node) {
            node = ts.skipParentheses(node);
            return node.kind === 199 /* TypeAssertionExpression */ || node.kind === 217 /* AsExpression */;
        }
        function checkDeclarationInitializer(declaration, contextualType) {
            var initializer = ts.getEffectiveInitializer(declaration);
            var type = getQuickTypeOfExpression(initializer) ||
                (contextualType ? checkExpressionWithContextualType(initializer, contextualType, /*inferenceContext*/ undefined, 0 /* Normal */) : checkExpressionCached(initializer));
            return ts.isParameter(declaration) && declaration.name.kind === 190 /* ArrayBindingPattern */ &&
                isTupleType(type) && !type.target.hasRestElement && getTypeReferenceArity(type) < declaration.name.elements.length ?
                padTupleType(type, declaration.name) : type;
        }
        function padTupleType(type, pattern) {
            var patternElements = pattern.elements;
            var arity = getTypeReferenceArity(type);
            var elementTypes = arity ? getTypeArguments(type).slice() : [];
            for (var i = arity; i < patternElements.length; i++) {
                var e = patternElements[i];
                if (i < patternElements.length - 1 || !(e.kind === 191 /* BindingElement */ && e.dotDotDotToken)) {
                    elementTypes.push(!ts.isOmittedExpression(e) && hasDefaultValue(e) ? getTypeFromBindingElement(e, /*includePatternInType*/ false, /*reportErrors*/ false) : anyType);
                    if (!ts.isOmittedExpression(e) && !hasDefaultValue(e)) {
                        reportImplicitAny(e, anyType);
                    }
                }
            }
            return createTupleType(elementTypes, type.target.minLength, /*hasRestElement*/ false, type.target.readonly);
        }
        function widenTypeInferredFromInitializer(declaration, type) {
            var widened = ts.getCombinedNodeFlags(declaration) & 2 /* Const */ || ts.isDeclarationReadonly(declaration) ? type : getWidenedLiteralType(type);
            if (ts.isInJSFile(declaration)) {
                if (widened.flags & 98304 /* Nullable */) {
                    reportImplicitAny(declaration, anyType);
                    return anyType;
                }
                else if (isEmptyArrayLiteralType(widened)) {
                    reportImplicitAny(declaration, anyArrayType);
                    return anyArrayType;
                }
            }
            return widened;
        }
        function isLiteralOfContextualType(candidateType, contextualType) {
            if (contextualType) {
                if (contextualType.flags & 3145728 /* UnionOrIntersection */) {
                    var types = contextualType.types;
                    return ts.some(types, function (t) { return isLiteralOfContextualType(candidateType, t); });
                }
                if (contextualType.flags & 58982400 /* InstantiableNonPrimitive */) {
                    // If the contextual type is a type variable constrained to a primitive type, consider
                    // this a literal context for literals of that primitive type. For example, given a
                    // type parameter 'T extends string', infer string literal types for T.
                    var constraint = getBaseConstraintOfType(contextualType) || unknownType;
                    return maybeTypeOfKind(constraint, 4 /* String */) && maybeTypeOfKind(candidateType, 128 /* StringLiteral */) ||
                        maybeTypeOfKind(constraint, 8 /* Number */) && maybeTypeOfKind(candidateType, 256 /* NumberLiteral */) ||
                        maybeTypeOfKind(constraint, 64 /* BigInt */) && maybeTypeOfKind(candidateType, 2048 /* BigIntLiteral */) ||
                        maybeTypeOfKind(constraint, 4096 /* ESSymbol */) && maybeTypeOfKind(candidateType, 8192 /* UniqueESSymbol */) ||
                        isLiteralOfContextualType(candidateType, constraint);
                }
                // If the contextual type is a literal of a particular primitive type, we consider this a
                // literal context for all literals of that primitive type.
                return !!(contextualType.flags & (128 /* StringLiteral */ | 4194304 /* Index */) && maybeTypeOfKind(candidateType, 128 /* StringLiteral */) ||
                    contextualType.flags & 256 /* NumberLiteral */ && maybeTypeOfKind(candidateType, 256 /* NumberLiteral */) ||
                    contextualType.flags & 2048 /* BigIntLiteral */ && maybeTypeOfKind(candidateType, 2048 /* BigIntLiteral */) ||
                    contextualType.flags & 512 /* BooleanLiteral */ && maybeTypeOfKind(candidateType, 512 /* BooleanLiteral */) ||
                    contextualType.flags & 8192 /* UniqueESSymbol */ && maybeTypeOfKind(candidateType, 8192 /* UniqueESSymbol */));
            }
            return false;
        }
        function isConstContext(node) {
            var parent = node.parent;
            return ts.isAssertionExpression(parent) && ts.isConstTypeReference(parent.type) ||
                (ts.isParenthesizedExpression(parent) || ts.isArrayLiteralExpression(parent) || ts.isSpreadElement(parent)) && isConstContext(parent) ||
                (ts.isPropertyAssignment(parent) || ts.isShorthandPropertyAssignment(parent)) && isConstContext(parent.parent);
        }
        function checkExpressionForMutableLocation(node, checkMode, contextualType, forceTuple) {
            var type = checkExpression(node, checkMode, forceTuple);
            return isConstContext(node) ? getRegularTypeOfLiteralType(type) :
                isTypeAssertion(node) ? type :
                    getWidenedLiteralLikeTypeForContextualType(type, instantiateContextualType(arguments.length === 2 ? getContextualType(node) : contextualType, node));
        }
        function checkPropertyAssignment(node, checkMode) {
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 154 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            return checkExpressionForMutableLocation(node.initializer, checkMode);
        }
        function checkObjectLiteralMethod(node, checkMode) {
            // Grammar checking
            checkGrammarMethod(node);
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 154 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            var uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
            return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
        }
        function instantiateTypeWithSingleGenericCallSignature(node, type, checkMode) {
            if (checkMode && checkMode & (2 /* Inferential */ | 8 /* SkipGenericFunctions */)) {
                var callSignature = getSingleSignature(type, 0 /* Call */, /*allowMembers*/ true);
                var constructSignature = getSingleSignature(type, 1 /* Construct */, /*allowMembers*/ true);
                var signature = callSignature || constructSignature;
                if (signature && signature.typeParameters) {
                    var contextualType = getApparentTypeOfContextualType(node, 2 /* NoConstraints */);
                    if (contextualType) {
                        var contextualSignature = getSingleSignature(getNonNullableType(contextualType), callSignature ? 0 /* Call */ : 1 /* Construct */, /*allowMembers*/ false);
                        if (contextualSignature && !contextualSignature.typeParameters) {
                            if (checkMode & 8 /* SkipGenericFunctions */) {
                                skippedGenericFunction(node, checkMode);
                                return anyFunctionType;
                            }
                            var context = getInferenceContext(node);
                            // We have an expression that is an argument of a generic function for which we are performing
                            // type argument inference. The expression is of a function type with a single generic call
                            // signature and a contextual function type with a single non-generic call signature. Now check
                            // if the outer function returns a function type with a single non-generic call signature and
                            // if some of the outer function type parameters have no inferences so far. If so, we can
                            // potentially add inferred type parameters to the outer function return type.
                            var returnType = context.signature && getReturnTypeOfSignature(context.signature);
                            var returnSignature = returnType && getSingleCallOrConstructSignature(returnType);
                            if (returnSignature && !returnSignature.typeParameters && !ts.every(context.inferences, hasInferenceCandidates)) {
                                // Instantiate the signature with its own type parameters as type arguments, possibly
                                // renaming the type parameters to ensure they have unique names.
                                var uniqueTypeParameters = getUniqueTypeParameters(context, signature.typeParameters);
                                var instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters);
                                // Infer from the parameters of the instantiated signature to the parameters of the
                                // contextual signature starting with an empty set of inference candidates.
                                var inferences_3 = ts.map(context.inferences, function (info) { return createInferenceInfo(info.typeParameter); });
                                applyToParameterTypes(instantiatedSignature, contextualSignature, function (source, target) {
                                    inferTypes(inferences_3, source, target, /*priority*/ 0, /*contravariant*/ true);
                                });
                                if (ts.some(inferences_3, hasInferenceCandidates)) {
                                    // We have inference candidates, indicating that one or more type parameters are referenced
                                    // in the parameter types of the contextual signature. Now also infer from the return type.
                                    applyToReturnTypes(instantiatedSignature, contextualSignature, function (source, target) {
                                        inferTypes(inferences_3, source, target);
                                    });
                                    // If the type parameters for which we produced candidates do not have any inferences yet,
                                    // we adopt the new inference candidates and add the type parameters of the expression type
                                    // to the set of inferred type parameters for the outer function return type.
                                    if (!hasOverlappingInferences(context.inferences, inferences_3)) {
                                        mergeInferences(context.inferences, inferences_3);
                                        context.inferredTypeParameters = ts.concatenate(context.inferredTypeParameters, uniqueTypeParameters);
                                        return getOrCreateTypeFromSignature(instantiatedSignature);
                                    }
                                }
                            }
                            return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context));
                        }
                    }
                }
            }
            return type;
        }
        function skippedGenericFunction(node, checkMode) {
            if (checkMode & 2 /* Inferential */) {
                // We have skipped a generic function during inferential typing. Obtain the inference context and
                // indicate this has occurred such that we know a second pass of inference is be needed.
                var context = getInferenceContext(node);
                context.flags |= 4 /* SkippedGenericFunction */;
            }
        }
        function hasInferenceCandidates(info) {
            return !!(info.candidates || info.contraCandidates);
        }
        function hasOverlappingInferences(a, b) {
            for (var i = 0; i < a.length; i++) {
                if (hasInferenceCandidates(a[i]) && hasInferenceCandidates(b[i])) {
                    return true;
                }
            }
            return false;
        }
        function mergeInferences(target, source) {
            for (var i = 0; i < target.length; i++) {
                if (!hasInferenceCandidates(target[i]) && hasInferenceCandidates(source[i])) {
                    target[i] = source[i];
                }
            }
        }
        function getUniqueTypeParameters(context, typeParameters) {
            var result = [];
            var oldTypeParameters;
            var newTypeParameters;
            for (var _i = 0, typeParameters_2 = typeParameters; _i < typeParameters_2.length; _i++) {
                var tp = typeParameters_2[_i];
                var name = tp.symbol.escapedName;
                if (hasTypeParameterByName(context.inferredTypeParameters, name) || hasTypeParameterByName(result, name)) {
                    var newName = getUniqueTypeParameterName(ts.concatenate(context.inferredTypeParameters, result), name);
                    var symbol = createSymbol(262144 /* TypeParameter */, newName);
                    var newTypeParameter = createTypeParameter(symbol);
                    newTypeParameter.target = tp;
                    oldTypeParameters = ts.append(oldTypeParameters, tp);
                    newTypeParameters = ts.append(newTypeParameters, newTypeParameter);
                    result.push(newTypeParameter);
                }
                else {
                    result.push(tp);
                }
            }
            if (newTypeParameters) {
                var mapper = createTypeMapper(oldTypeParameters, newTypeParameters);
                for (var _a = 0, newTypeParameters_1 = newTypeParameters; _a < newTypeParameters_1.length; _a++) {
                    var tp = newTypeParameters_1[_a];
                    tp.mapper = mapper;
                }
            }
            return result;
        }
        function hasTypeParameterByName(typeParameters, name) {
            return ts.some(typeParameters, function (tp) { return tp.symbol.escapedName === name; });
        }
        function getUniqueTypeParameterName(typeParameters, baseName) {
            var len = baseName.length;
            while (len > 1 && baseName.charCodeAt(len - 1) >= 48 /* _0 */ && baseName.charCodeAt(len - 1) <= 57 /* _9 */)
                len--;
            var s = baseName.slice(0, len);
            for (var index = 1; true; index++) {
                var augmentedName = (s + index);
                if (!hasTypeParameterByName(typeParameters, augmentedName)) {
                    return augmentedName;
                }
            }
        }
        function getReturnTypeOfSingleNonGenericCallSignature(funcType) {
            var signature = getSingleCallSignature(funcType);
            if (signature && !signature.typeParameters) {
                return getReturnTypeOfSignature(signature);
            }
        }
        function getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) {
            var funcType = checkExpression(expr.expression);
            var nonOptionalType = getOptionalExpressionType(funcType, expr.expression);
            var returnType = getReturnTypeOfSingleNonGenericCallSignature(funcType);
            return returnType && propagateOptionalTypeMarker(returnType, expr, nonOptionalType !== funcType);
        }
        /**
         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
         * with computing the type and may not fully check all contained sub-expressions for errors.
         */
        function getTypeOfExpression(node) {
            // Don't bother caching types that require no flow analysis and are quick to compute.
            var quickType = getQuickTypeOfExpression(node);
            if (quickType) {
                return quickType;
            }
            // If a type has been cached for the node, return it.
            if (node.flags & 67108864 /* TypeCached */ && flowTypeCache) {
                var cachedType = flowTypeCache[getNodeId(node)];
                if (cachedType) {
                    return cachedType;
                }
            }
            var startInvocationCount = flowInvocationCount;
            var type = checkExpression(node);
            // If control flow analysis was required to determine the type, it is worth caching.
            if (flowInvocationCount !== startInvocationCount) {
                var cache = flowTypeCache || (flowTypeCache = []);
                cache[getNodeId(node)] = type;
                node.flags |= 67108864 /* TypeCached */;
            }
            return type;
        }
        function getQuickTypeOfExpression(node) {
            var expr = ts.skipParentheses(node);
            // Optimize for the common case of a call to a function with a single non-generic call
            // signature where we can just fetch the return type without checking the arguments.
            if (ts.isCallExpression(expr) && expr.expression.kind !== 102 /* SuperKeyword */ && !ts.isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
                var type = ts.isCallChain(expr) ? getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) :
                    getReturnTypeOfSingleNonGenericCallSignature(checkNonNullExpression(expr.expression));
                if (type) {
                    return type;
                }
            }
            else if (ts.isAssertionExpression(expr) && !ts.isConstTypeReference(expr.type)) {
                return getTypeFromTypeNode(expr.type);
            }
            else if (node.kind === 8 /* NumericLiteral */ || node.kind === 10 /* StringLiteral */ ||
                node.kind === 106 /* TrueKeyword */ || node.kind === 91 /* FalseKeyword */) {
                return checkExpression(node);
            }
            return undefined;
        }
        /**
         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
         * with computing the type and may not fully check all contained sub-expressions for errors.
         * It is intended for uses where you know there is no contextual type,
         * and requesting the contextual type might cause a circularity or other bad behaviour.
         * It sets the contextual type of the node to any before calling getTypeOfExpression.
         */
        function getContextFreeTypeOfExpression(node) {
            var links = getNodeLinks(node);
            if (links.contextFreeType) {
                return links.contextFreeType;
            }
            var saveContextualType = node.contextualType;
            node.contextualType = anyType;
            try {
                var type = links.contextFreeType = checkExpression(node, 4 /* SkipContextSensitive */);
                return type;
            }
            finally {
                // In the event our operation is canceled or some other exception occurs, reset the contextual type
                // so that we do not accidentally hold onto an instance of the checker, as a Type created in the services layer
                // may hold onto the checker that created it.
                node.contextualType = saveContextualType;
            }
        }
        function checkExpression(node, checkMode, forceTuple) {
            var saveCurrentNode = currentNode;
            currentNode = node;
            instantiationCount = 0;
            var uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
            var type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
            if (isConstEnumObjectType(type)) {
                checkConstEnumAccess(node, type);
            }
            currentNode = saveCurrentNode;
            return type;
        }
        function checkConstEnumAccess(node, type) {
            // enum object type for const enums are only permitted in:
            // - 'left' in property access
            // - 'object' in indexed access
            // - target in rhs of import statement
            var ok = (node.parent.kind === 194 /* PropertyAccessExpression */ && node.parent.expression === node) ||
                (node.parent.kind === 195 /* ElementAccessExpression */ && node.parent.expression === node) ||
                ((node.kind === 75 /* Identifier */ || node.kind === 153 /* QualifiedName */) && isInRightSideOfImportOrExportAssignment(node) ||
                    (node.parent.kind === 172 /* TypeQuery */ && node.parent.exprName === node)) ||
                (node.parent.kind === 263 /* ExportSpecifier */); // We allow reexporting const enums
            if (!ok) {
                error(node, ts.Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query);
            }
            if (compilerOptions.isolatedModules) {
                ts.Debug.assert(!!(type.symbol.flags & 128 /* ConstEnum */));
                var constEnumDeclaration = type.symbol.valueDeclaration;
                if (constEnumDeclaration.flags & 8388608 /* Ambient */) {
                    error(node, ts.Diagnostics.Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided);
                }
            }
        }
        function checkParenthesizedExpression(node, checkMode) {
            var tag = ts.isInJSFile(node) ? ts.getJSDocTypeTag(node) : undefined;
            if (tag) {
                return checkAssertionWorker(tag, tag.typeExpression.type, node.expression, checkMode);
            }
            return checkExpression(node.expression, checkMode);
        }
        function checkExpressionWorker(node, checkMode, forceTuple) {
            var kind = node.kind;
            if (cancellationToken) {
                // Only bother checking on a few construct kinds.  We don't want to be excessively
                // hitting the cancellation token on every node we check.
                switch (kind) {
                    case 214 /* ClassExpression */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                        cancellationToken.throwIfCancellationRequested();
                }
            }
            switch (kind) {
                case 75 /* Identifier */:
                    return checkIdentifier(node);
                case 104 /* ThisKeyword */:
                    return checkThisExpression(node);
                case 102 /* SuperKeyword */:
                    return checkSuperExpression(node);
                case 100 /* NullKeyword */:
                    return nullWideningType;
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 10 /* StringLiteral */:
                    return getFreshTypeOfLiteralType(getLiteralType(node.text));
                case 8 /* NumericLiteral */:
                    checkGrammarNumericLiteral(node);
                    return getFreshTypeOfLiteralType(getLiteralType(+node.text));
                case 9 /* BigIntLiteral */:
                    checkGrammarBigIntLiteral(node);
                    return getFreshTypeOfLiteralType(getBigIntLiteralType(node));
                case 106 /* TrueKeyword */:
                    return trueType;
                case 91 /* FalseKeyword */:
                    return falseType;
                case 211 /* TemplateExpression */:
                    return checkTemplateExpression(node);
                case 13 /* RegularExpressionLiteral */:
                    return globalRegExpType;
                case 192 /* ArrayLiteralExpression */:
                    return checkArrayLiteral(node, checkMode, forceTuple);
                case 193 /* ObjectLiteralExpression */:
                    return checkObjectLiteral(node, checkMode);
                case 194 /* PropertyAccessExpression */:
                    return checkPropertyAccessExpression(node);
                case 153 /* QualifiedName */:
                    return checkQualifiedName(node);
                case 195 /* ElementAccessExpression */:
                    return checkIndexedAccess(node);
                case 196 /* CallExpression */:
                    if (node.expression.kind === 96 /* ImportKeyword */) {
                        return checkImportCallExpression(node);
                    }
                // falls through
                case 197 /* NewExpression */:
                    return checkCallExpression(node, checkMode);
                case 198 /* TaggedTemplateExpression */:
                    return checkTaggedTemplateExpression(node);
                case 200 /* ParenthesizedExpression */:
                    return checkParenthesizedExpression(node, checkMode);
                case 214 /* ClassExpression */:
                    return checkClassExpression(node);
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
                case 204 /* TypeOfExpression */:
                    return checkTypeOfExpression(node);
                case 199 /* TypeAssertionExpression */:
                case 217 /* AsExpression */:
                    return checkAssertion(node);
                case 218 /* NonNullExpression */:
                    return checkNonNullAssertion(node);
                case 219 /* MetaProperty */:
                    return checkMetaProperty(node);
                case 203 /* DeleteExpression */:
                    return checkDeleteExpression(node);
                case 205 /* VoidExpression */:
                    return checkVoidExpression(node);
                case 206 /* AwaitExpression */:
                    return checkAwaitExpression(node);
                case 207 /* PrefixUnaryExpression */:
                    return checkPrefixUnaryExpression(node);
                case 208 /* PostfixUnaryExpression */:
                    return checkPostfixUnaryExpression(node);
                case 209 /* BinaryExpression */:
                    return checkBinaryExpression(node, checkMode);
                case 210 /* ConditionalExpression */:
                    return checkConditionalExpression(node, checkMode);
                case 213 /* SpreadElement */:
                    return checkSpreadExpression(node, checkMode);
                case 215 /* OmittedExpression */:
                    return undefinedWideningType;
                case 212 /* YieldExpression */:
                    return checkYieldExpression(node);
                case 220 /* SyntheticExpression */:
                    return node.type;
                case 276 /* JsxExpression */:
                    return checkJsxExpression(node, checkMode);
                case 266 /* JsxElement */:
                    return checkJsxElement(node, checkMode);
                case 267 /* JsxSelfClosingElement */:
                    return checkJsxSelfClosingElement(node, checkMode);
                case 270 /* JsxFragment */:
                    return checkJsxFragment(node);
                case 274 /* JsxAttributes */:
                    return checkJsxAttributes(node, checkMode);
                case 268 /* JsxOpeningElement */:
                    ts.Debug.fail("Shouldn't ever directly check a JsxOpeningElement");
            }
            return errorType;
        }
        // DECLARATION AND STATEMENT TYPE CHECKING
        function checkTypeParameter(node) {
            // Grammar Checking
            if (node.expression) {
                grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected);
            }
            checkSourceElement(node.constraint);
            checkSourceElement(node.default);
            var typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node));
            // Resolve base constraint to reveal circularity errors
            getBaseConstraintOfType(typeParameter);
            if (!hasNonCircularTypeParameterDefault(typeParameter)) {
                error(node.default, ts.Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
            }
            var constraintType = getConstraintOfTypeParameter(typeParameter);
            var defaultType = getDefaultFromTypeParameter(typeParameter);
            if (constraintType && defaultType) {
                checkTypeAssignableTo(defaultType, getTypeWithThisArgument(instantiateType(constraintType, makeUnaryTypeMapper(typeParameter, defaultType)), defaultType), node.default, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
            }
            if (produceDiagnostics) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0);
            }
        }
        function checkParameter(node) {
            // Grammar checking
            // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
            // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code
            // or if its FunctionBody is strict code(11.1.5).
            checkGrammarDecoratorsAndModifiers(node);
            checkVariableLikeDeclaration(node);
            var func = ts.getContainingFunction(node);
            if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
                if (!(func.kind === 162 /* Constructor */ && ts.nodeIsPresent(func.body))) {
                    error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
                }
                if (func.kind === 162 /* Constructor */ && ts.isIdentifier(node.name) && node.name.escapedText === "constructor") {
                    error(node.name, ts.Diagnostics.constructor_cannot_be_used_as_a_parameter_property_name);
                }
            }
            if (node.questionToken && ts.isBindingPattern(node.name) && func.body) {
                error(node, ts.Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature);
            }
            if (node.name && ts.isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) {
                if (func.parameters.indexOf(node) !== 0) {
                    error(node, ts.Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText);
                }
                if (func.kind === 162 /* Constructor */ || func.kind === 166 /* ConstructSignature */ || func.kind === 171 /* ConstructorType */) {
                    error(node, ts.Diagnostics.A_constructor_cannot_have_a_this_parameter);
                }
                if (func.kind === 202 /* ArrowFunction */) {
                    error(node, ts.Diagnostics.An_arrow_function_cannot_have_a_this_parameter);
                }
                if (func.kind === 163 /* GetAccessor */ || func.kind === 164 /* SetAccessor */) {
                    error(node, ts.Diagnostics.get_and_set_accessors_cannot_declare_this_parameters);
                }
            }
            // Only check rest parameter type if it's not a binding pattern. Since binding patterns are
            // not allowed in a rest parameter, we already have an error from checkGrammarParameterList.
            if (node.dotDotDotToken && !ts.isBindingPattern(node.name) && !isTypeAssignableTo(getReducedType(getTypeOfSymbol(node.symbol)), anyReadonlyArrayType)) {
                error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type);
            }
        }
        function checkTypePredicate(node) {
            var parent = getTypePredicateParent(node);
            if (!parent) {
                // The parent must not be valid.
                error(node, ts.Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
                return;
            }
            var signature = getSignatureFromDeclaration(parent);
            var typePredicate = getTypePredicateOfSignature(signature);
            if (!typePredicate) {
                return;
            }
            checkSourceElement(node.type);
            var parameterName = node.parameterName;
            if (typePredicate.kind === 0 /* This */ || typePredicate.kind === 2 /* AssertsThis */) {
                getTypeFromThisTypeNode(parameterName);
            }
            else {
                if (typePredicate.parameterIndex >= 0) {
                    if (signatureHasRestParameter(signature) && typePredicate.parameterIndex === signature.parameters.length - 1) {
                        error(parameterName, ts.Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
                    }
                    else {
                        if (typePredicate.type) {
                            var leadingError = function () { return ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); };
                            checkTypeAssignableTo(typePredicate.type, getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]), node.type, 
                            /*headMessage*/ undefined, leadingError);
                        }
                    }
                }
                else if (parameterName) {
                    var hasReportedError = false;
                    for (var _i = 0, _a = parent.parameters; _i < _a.length; _i++) {
                        var name = _a[_i].name;
                        if (ts.isBindingPattern(name) &&
                            checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) {
                            hasReportedError = true;
                            break;
                        }
                    }
                    if (!hasReportedError) {
                        error(node.parameterName, ts.Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName);
                    }
                }
            }
        }
        function getTypePredicateParent(node) {
            switch (node.parent.kind) {
                case 202 /* ArrowFunction */:
                case 165 /* CallSignature */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 170 /* FunctionType */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    var parent = node.parent;
                    if (node === parent.type) {
                        return parent;
                    }
            }
        }
        function checkIfTypePredicateVariableIsDeclaredInBindingPattern(pattern, predicateVariableNode, predicateVariableName) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (ts.isOmittedExpression(element)) {
                    continue;
                }
                var name = element.name;
                if (name.kind === 75 /* Identifier */ && name.escapedText === predicateVariableName) {
                    error(predicateVariableNode, ts.Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, predicateVariableName);
                    return true;
                }
                else if (name.kind === 190 /* ArrayBindingPattern */ || name.kind === 189 /* ObjectBindingPattern */) {
                    if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, predicateVariableNode, predicateVariableName)) {
                        return true;
                    }
                }
            }
        }
        function checkSignatureDeclaration(node) {
            // Grammar checking
            if (node.kind === 167 /* IndexSignature */) {
                checkGrammarIndexSignature(node);
            }
            // TODO (yuisu): Remove this check in else-if when SyntaxKind.Construct is moved and ambient context is handled
            else if (node.kind === 170 /* FunctionType */ || node.kind === 244 /* FunctionDeclaration */ || node.kind === 171 /* ConstructorType */ ||
                node.kind === 165 /* CallSignature */ || node.kind === 162 /* Constructor */ ||
                node.kind === 166 /* ConstructSignature */) {
                checkGrammarFunctionLikeDeclaration(node);
            }
            var functionFlags = ts.getFunctionFlags(node);
            if (!(functionFlags & 4 /* Invalid */)) {
                // Async generators prior to ESNext require the __await and __asyncGenerator helpers
                if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ && languageVersion < 99 /* ESNext */) {
                    checkExternalEmitHelpers(node, 12288 /* AsyncGeneratorIncludes */);
                }
                // Async functions prior to ES2017 require the __awaiter helper
                if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ && languageVersion < 4 /* ES2017 */) {
                    checkExternalEmitHelpers(node, 64 /* Awaiter */);
                }
                // Generator functions, Async functions, and Async Generator functions prior to
                // ES2015 require the __generator helper
                if ((functionFlags & 3 /* AsyncGenerator */) !== 0 /* Normal */ && languageVersion < 2 /* ES2015 */) {
                    checkExternalEmitHelpers(node, 128 /* Generator */);
                }
            }
            checkTypeParameters(node.typeParameters);
            ts.forEach(node.parameters, checkParameter);
            // TODO(rbuckton): Should we start checking JSDoc types?
            if (node.type) {
                checkSourceElement(node.type);
            }
            if (produceDiagnostics) {
                checkCollisionWithArgumentsInGeneratedCode(node);
                var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
                if (noImplicitAny && !returnTypeNode) {
                    switch (node.kind) {
                        case 166 /* ConstructSignature */:
                            error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                        case 165 /* CallSignature */:
                            error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                    }
                }
                if (returnTypeNode) {
                    var functionFlags_1 = ts.getFunctionFlags(node);
                    if ((functionFlags_1 & (4 /* Invalid */ | 1 /* Generator */)) === 1 /* Generator */) {
                        var returnType = getTypeFromTypeNode(returnTypeNode);
                        if (returnType === voidType) {
                            error(returnTypeNode, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation);
                        }
                        else {
                            // Naively, one could check that Generator<any, any, any> is assignable to the return type annotation.
                            // However, that would not catch the error in the following case.
                            //
                            //    interface BadGenerator extends Iterable<number>, Iterator<string> { }
                            //    function* g(): BadGenerator { } // Iterable and Iterator have different types!
                            //
                            var generatorYieldType = getIterationTypeOfGeneratorFunctionReturnType(0 /* Yield */, returnType, (functionFlags_1 & 2 /* Async */) !== 0) || anyType;
                            var generatorReturnType = getIterationTypeOfGeneratorFunctionReturnType(1 /* Return */, returnType, (functionFlags_1 & 2 /* Async */) !== 0) || generatorYieldType;
                            var generatorNextType = getIterationTypeOfGeneratorFunctionReturnType(2 /* Next */, returnType, (functionFlags_1 & 2 /* Async */) !== 0) || unknownType;
                            var generatorInstantiation = createGeneratorReturnType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags_1 & 2 /* Async */));
                            checkTypeAssignableTo(generatorInstantiation, returnType, returnTypeNode);
                        }
                    }
                    else if ((functionFlags_1 & 3 /* AsyncGenerator */) === 2 /* Async */) {
                        checkAsyncFunctionReturnType(node, returnTypeNode);
                    }
                }
                if (node.kind !== 167 /* IndexSignature */ && node.kind !== 300 /* JSDocFunctionType */) {
                    registerForUnusedIdentifiersCheck(node);
                }
            }
        }
        function checkClassForDuplicateDeclarations(node) {
            var instanceNames = ts.createUnderscoreEscapedMap();
            var staticNames = ts.createUnderscoreEscapedMap();
            // instance and static private identifiers share the same scope
            var privateIdentifiers = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 162 /* Constructor */) {
                    for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                        var param = _c[_b];
                        if (ts.isParameterPropertyDeclaration(param, member) && !ts.isBindingPattern(param.name)) {
                            addName(instanceNames, param.name, param.name.escapedText, 3 /* GetOrSetAccessor */);
                        }
                    }
                }
                else {
                    var isStatic = ts.hasModifier(member, 32 /* Static */);
                    var name = member.name;
                    if (!name) {
                        return;
                    }
                    var names = ts.isPrivateIdentifier(name) ? privateIdentifiers :
                        isStatic ? staticNames :
                            instanceNames;
                    var memberName = name && ts.getPropertyNameForPropertyNameNode(name);
                    if (memberName) {
                        switch (member.kind) {
                            case 163 /* GetAccessor */:
                                addName(names, name, memberName, 1 /* GetAccessor */);
                                break;
                            case 164 /* SetAccessor */:
                                addName(names, name, memberName, 2 /* SetAccessor */);
                                break;
                            case 159 /* PropertyDeclaration */:
                                addName(names, name, memberName, 3 /* GetOrSetAccessor */);
                                break;
                            case 161 /* MethodDeclaration */:
                                addName(names, name, memberName, 8 /* Method */);
                                break;
                        }
                    }
                }
            }
            function addName(names, location, name, meaning) {
                var prev = names.get(name);
                if (prev) {
                    if (prev & 8 /* Method */) {
                        if (meaning !== 8 /* Method */) {
                            error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                        }
                    }
                    else if (prev & meaning) {
                        error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                    }
                    else {
                        names.set(name, prev | meaning);
                    }
                }
                else {
                    names.set(name, meaning);
                }
            }
        }
        /**
         * Static members being set on a constructor function may conflict with built-in properties
         * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable
         * built-in properties. This check issues a transpile error when a class has a static
         * member with the same name as a non-writable built-in property.
         *
         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3
         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5
         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor
         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances
         */
        function checkClassForStaticPropertyNameConflicts(node) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                var memberNameNode = member.name;
                var isStatic = ts.hasModifier(member, 32 /* Static */);
                if (isStatic && memberNameNode) {
                    var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode);
                    switch (memberName) {
                        case "name":
                        case "length":
                        case "caller":
                        case "arguments":
                        case "prototype":
                            var message = ts.Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1;
                            var className = getNameOfSymbolAsWritten(getSymbolOfNode(node));
                            error(memberNameNode, message, memberName, className);
                            break;
                    }
                }
            }
        }
        function checkObjectTypeForDuplicateDeclarations(node) {
            var names = ts.createMap();
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 158 /* PropertySignature */) {
                    var memberName = void 0;
                    var name = member.name;
                    switch (name.kind) {
                        case 10 /* StringLiteral */:
                        case 8 /* NumericLiteral */:
                            memberName = name.text;
                            break;
                        case 75 /* Identifier */:
                            memberName = ts.idText(name);
                            break;
                        default:
                            continue;
                    }
                    if (names.get(memberName)) {
                        error(ts.getNameOfDeclaration(member.symbol.valueDeclaration), ts.Diagnostics.Duplicate_identifier_0, memberName);
                        error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName);
                    }
                    else {
                        names.set(memberName, true);
                    }
                }
            }
        }
        function checkTypeForDuplicateIndexSignatures(node) {
            if (node.kind === 246 /* InterfaceDeclaration */) {
                var nodeSymbol = getSymbolOfNode(node);
                // in case of merging interface declaration it is possible that we'll enter this check procedure several times for every declaration
                // to prevent this run check only for the first declaration of a given kind
                if (nodeSymbol.declarations.length > 0 && nodeSymbol.declarations[0] !== node) {
                    return;
                }
            }
            // TypeScript 1.0 spec (April 2014)
            // 3.7.4: An object type can contain at most one string index signature and one numeric index signature.
            // 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration
            var indexSymbol = getIndexSymbol(getSymbolOfNode(node));
            if (indexSymbol) {
                var seenNumericIndexer = false;
                var seenStringIndexer = false;
                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var declaration = decl;
                    if (declaration.parameters.length === 1 && declaration.parameters[0].type) {
                        switch (declaration.parameters[0].type.kind) {
                            case 143 /* StringKeyword */:
                                if (!seenStringIndexer) {
                                    seenStringIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_string_index_signature);
                                }
                                break;
                            case 140 /* NumberKeyword */:
                                if (!seenNumericIndexer) {
                                    seenNumericIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_number_index_signature);
                                }
                                break;
                        }
                    }
                }
            }
        }
        function checkPropertyDeclaration(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node))
                checkGrammarComputedPropertyName(node.name);
            checkVariableLikeDeclaration(node);
            // Private class fields transformation relies on WeakMaps.
            if (ts.isPrivateIdentifier(node.name) && languageVersion < 99 /* ESNext */) {
                for (var lexicalScope = ts.getEnclosingBlockScopeContainer(node); !!lexicalScope; lexicalScope = ts.getEnclosingBlockScopeContainer(lexicalScope)) {
                    getNodeLinks(lexicalScope).flags |= 67108864 /* ContainsClassWithPrivateIdentifiers */;
                }
            }
        }
        function checkPropertySignature(node) {
            if (ts.isPrivateIdentifier(node.name)) {
                error(node, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
            }
            return checkPropertyDeclaration(node);
        }
        function checkMethodDeclaration(node) {
            // Grammar checking
            if (!checkGrammarMethod(node))
                checkGrammarComputedPropertyName(node.name);
            if (ts.isPrivateIdentifier(node.name)) {
                error(node, ts.Diagnostics.A_method_cannot_be_named_with_a_private_identifier);
            }
            // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration
            checkFunctionOrMethodDeclaration(node);
            // Abstract methods cannot have an implementation.
            // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node.
            if (ts.hasModifier(node, 128 /* Abstract */) && node.kind === 161 /* MethodDeclaration */ && node.body) {
                error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name));
            }
        }
        function checkConstructorDeclaration(node) {
            // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function.
            checkSignatureDeclaration(node);
            // Grammar check for checking only related to constructorDeclaration
            if (!checkGrammarConstructorTypeParameters(node))
                checkGrammarConstructorTypeAnnotation(node);
            checkSourceElement(node.body);
            var symbol = getSymbolOfNode(node);
            var firstDeclaration = ts.getDeclarationOfKind(symbol, node.kind);
            // Only type check the symbol once
            if (node === firstDeclaration) {
                checkFunctionOrConstructorSymbol(symbol);
            }
            // exit early in the case of signature - super checks are not relevant to them
            if (ts.nodeIsMissing(node.body)) {
                return;
            }
            if (!produceDiagnostics) {
                return;
            }
            function isInstancePropertyWithInitializerOrPrivateIdentifierProperty(n) {
                if (ts.isPrivateIdentifierPropertyDeclaration(n)) {
                    return true;
                }
                return n.kind === 159 /* PropertyDeclaration */ &&
                    !ts.hasModifier(n, 32 /* Static */) &&
                    !!n.initializer;
            }
            // TS 1.0 spec (April 2014): 8.3.2
            // Constructors of classes with no extends clause may not contain super calls, whereas
            // constructors of derived classes must contain at least one super call somewhere in their function body.
            var containingClassDecl = node.parent;
            if (ts.getClassExtendsHeritageElement(containingClassDecl)) {
                captureLexicalThis(node.parent, containingClassDecl);
                var classExtendsNull = classDeclarationExtendsNull(containingClassDecl);
                var superCall = getSuperCallInConstructor(node);
                if (superCall) {
                    if (classExtendsNull) {
                        error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
                    }
                    // The first statement in the body of a constructor (excluding prologue directives) must be a super call
                    // if both of the following are true:
                    // - The containing class is a derived class.
                    // - The constructor declares parameter properties
                    //   or the containing class declares instance member variables with initializers.
                    var superCallShouldBeFirst = (compilerOptions.target !== 99 /* ESNext */ || !compilerOptions.useDefineForClassFields) &&
                        (ts.some(node.parent.members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) ||
                            ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92 /* ParameterPropertyModifier */); }));
                    // Skip past any prologue directives to find the first statement
                    // to ensure that it was a super call.
                    if (superCallShouldBeFirst) {
                        var statements = node.body.statements;
                        var superCallStatement = void 0;
                        for (var _i = 0, statements_3 = statements; _i < statements_3.length; _i++) {
                            var statement = statements_3[_i];
                            if (statement.kind === 226 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) {
                                superCallStatement = statement;
                                break;
                            }
                            if (!ts.isPrologueDirective(statement)) {
                                break;
                            }
                        }
                        if (!superCallStatement) {
                            error(node, ts.Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_parameter_properties_or_private_identifiers);
                        }
                    }
                }
                else if (!classExtendsNull) {
                    error(node, ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);
                }
            }
        }
        function checkAccessorDeclaration(node) {
            if (produceDiagnostics) {
                // Grammar checking accessors
                if (!checkGrammarFunctionLikeDeclaration(node) && !checkGrammarAccessor(node))
                    checkGrammarComputedPropertyName(node.name);
                checkDecorators(node);
                checkSignatureDeclaration(node);
                if (node.kind === 163 /* GetAccessor */) {
                    if (!(node.flags & 8388608 /* Ambient */) && ts.nodeIsPresent(node.body) && (node.flags & 256 /* HasImplicitReturn */)) {
                        if (!(node.flags & 512 /* HasExplicitReturn */)) {
                            error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value);
                        }
                    }
                }
                // Do not use hasDynamicName here, because that returns false for well known symbols.
                // We want to perform checkComputedPropertyName for all computed properties, including
                // well known symbols.
                if (node.name.kind === 154 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.name);
                }
                if (ts.isPrivateIdentifier(node.name)) {
                    error(node.name, ts.Diagnostics.An_accessor_cannot_be_named_with_a_private_identifier);
                }
                if (!hasNonBindableDynamicName(node)) {
                    // TypeScript 1.0 spec (April 2014): 8.4.3
                    // Accessors for the same member name must specify the same accessibility.
                    var otherKind = node.kind === 163 /* GetAccessor */ ? 164 /* SetAccessor */ : 163 /* GetAccessor */;
                    var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(node), otherKind);
                    if (otherAccessor) {
                        var nodeFlags = ts.getModifierFlags(node);
                        var otherFlags = ts.getModifierFlags(otherAccessor);
                        if ((nodeFlags & 28 /* AccessibilityModifier */) !== (otherFlags & 28 /* AccessibilityModifier */)) {
                            error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
                        }
                        if ((nodeFlags & 128 /* Abstract */) !== (otherFlags & 128 /* Abstract */)) {
                            error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract);
                        }
                        // TypeScript 1.0 spec (April 2014): 4.5
                        // If both accessors include type annotations, the specified types must be identical.
                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type);
                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
                    }
                }
                var returnType = getTypeOfAccessors(getSymbolOfNode(node));
                if (node.kind === 163 /* GetAccessor */) {
                    checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
                }
            }
            checkSourceElement(node.body);
        }
        function checkAccessorDeclarationTypesIdentical(first, second, getAnnotatedType, message) {
            var firstType = getAnnotatedType(first);
            var secondType = getAnnotatedType(second);
            if (firstType && secondType && !isTypeIdenticalTo(firstType, secondType)) {
                error(first, message);
            }
        }
        function checkMissingDeclaration(node) {
            checkDecorators(node);
        }
        function getEffectiveTypeArguments(node, typeParameters) {
            return fillMissingTypeArguments(ts.map(node.typeArguments, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJSFile(node));
        }
        function checkTypeArgumentConstraints(node, typeParameters) {
            var typeArguments;
            var mapper;
            var result = true;
            for (var i = 0; i < typeParameters.length; i++) {
                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                if (constraint) {
                    if (!typeArguments) {
                        typeArguments = getEffectiveTypeArguments(node, typeParameters);
                        mapper = createTypeMapper(typeParameters, typeArguments);
                    }
                    result = result && checkTypeAssignableTo(typeArguments[i], instantiateType(constraint, mapper), node.typeArguments[i], ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
                }
            }
            return result;
        }
        function getTypeParametersForTypeReference(node) {
            var type = getTypeFromTypeReference(node);
            if (type !== errorType) {
                var symbol = getNodeLinks(node).resolvedSymbol;
                if (symbol) {
                    return symbol.flags & 524288 /* TypeAlias */ && getSymbolLinks(symbol).typeParameters ||
                        (ts.getObjectFlags(type) & 4 /* Reference */ ? type.target.localTypeParameters : undefined);
                }
            }
            return undefined;
        }
        function checkTypeReferenceNode(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            if (node.kind === 169 /* TypeReference */ && node.typeName.jsdocDotPos !== undefined && !ts.isInJSFile(node) && !ts.isInJSDoc(node)) {
                grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
            }
            ts.forEach(node.typeArguments, checkSourceElement);
            var type = getTypeFromTypeReference(node);
            if (type !== errorType) {
                if (node.typeArguments && produceDiagnostics) {
                    var typeParameters = getTypeParametersForTypeReference(node);
                    if (typeParameters) {
                        checkTypeArgumentConstraints(node, typeParameters);
                    }
                }
                if (type.flags & 32 /* Enum */ && getNodeLinks(node).resolvedSymbol.flags & 8 /* EnumMember */) {
                    error(node, ts.Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));
                }
            }
        }
        function getTypeArgumentConstraint(node) {
            var typeReferenceNode = ts.tryCast(node.parent, ts.isTypeReferenceType);
            if (!typeReferenceNode)
                return undefined;
            var typeParameters = getTypeParametersForTypeReference(typeReferenceNode); // TODO: GH#18217
            var constraint = getConstraintOfTypeParameter(typeParameters[typeReferenceNode.typeArguments.indexOf(node)]);
            return constraint && instantiateType(constraint, createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReferenceNode, typeParameters)));
        }
        function checkTypeQuery(node) {
            getTypeFromTypeQueryNode(node);
        }
        function checkTypeLiteral(node) {
            ts.forEach(node.members, checkSourceElement);
            if (produceDiagnostics) {
                var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                checkIndexConstraints(type);
                checkTypeForDuplicateIndexSignatures(node);
                checkObjectTypeForDuplicateDeclarations(node);
            }
        }
        function checkArrayType(node) {
            checkSourceElement(node.elementType);
        }
        function checkTupleType(node) {
            var elementTypes = node.elementTypes;
            var seenOptionalElement = false;
            for (var i = 0; i < elementTypes.length; i++) {
                var e = elementTypes[i];
                if (e.kind === 177 /* RestType */) {
                    if (i !== elementTypes.length - 1) {
                        grammarErrorOnNode(e, ts.Diagnostics.A_rest_element_must_be_last_in_a_tuple_type);
                        break;
                    }
                    if (!isArrayType(getTypeFromTypeNode(e.type))) {
                        error(e, ts.Diagnostics.A_rest_element_type_must_be_an_array_type);
                    }
                }
                else if (e.kind === 176 /* OptionalType */) {
                    seenOptionalElement = true;
                }
                else if (seenOptionalElement) {
                    grammarErrorOnNode(e, ts.Diagnostics.A_required_element_cannot_follow_an_optional_element);
                    break;
                }
            }
            ts.forEach(node.elementTypes, checkSourceElement);
        }
        function checkUnionOrIntersectionType(node) {
            ts.forEach(node.types, checkSourceElement);
        }
        function checkIndexedAccessIndexType(type, accessNode) {
            if (!(type.flags & 8388608 /* IndexedAccess */)) {
                return type;
            }
            // Check if the index type is assignable to 'keyof T' for the object type.
            var objectType = type.objectType;
            var indexType = type.indexType;
            if (isTypeAssignableTo(indexType, getIndexType(objectType, /*stringsOnly*/ false))) {
                if (accessNode.kind === 195 /* ElementAccessExpression */ && ts.isAssignmentTarget(accessNode) &&
                    ts.getObjectFlags(objectType) & 32 /* Mapped */ && getMappedTypeModifiers(objectType) & 1 /* IncludeReadonly */) {
                    error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
                }
                return type;
            }
            // Check if we're indexing with a numeric type and if either object or index types
            // is a generic type with a constraint that has a numeric index signature.
            var apparentObjectType = getApparentType(objectType);
            if (getIndexInfoOfType(apparentObjectType, 1 /* Number */) && isTypeAssignableToKind(indexType, 296 /* NumberLike */)) {
                return type;
            }
            if (isGenericObjectType(objectType)) {
                var propertyName_1 = getPropertyNameFromIndex(indexType, accessNode);
                if (propertyName_1) {
                    var propertySymbol = forEachType(apparentObjectType, function (t) { return getPropertyOfType(t, propertyName_1); });
                    if (propertySymbol && ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & 24 /* NonPublicAccessibilityModifier */) {
                        error(accessNode, ts.Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, ts.unescapeLeadingUnderscores(propertyName_1));
                        return errorType;
                    }
                }
            }
            error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
            return errorType;
        }
        function checkIndexedAccessType(node) {
            checkSourceElement(node.objectType);
            checkSourceElement(node.indexType);
            checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node);
        }
        function checkMappedType(node) {
            checkSourceElement(node.typeParameter);
            checkSourceElement(node.type);
            if (!node.type) {
                reportImplicitAny(node, anyType);
            }
            var type = getTypeFromMappedTypeNode(node);
            var constraintType = getConstraintTypeFromMappedType(type);
            checkTypeAssignableTo(constraintType, keyofConstraintType, ts.getEffectiveConstraintOfTypeParameter(node.typeParameter));
        }
        function checkThisType(node) {
            getTypeFromThisTypeNode(node);
        }
        function checkTypeOperator(node) {
            checkGrammarTypeOperatorNode(node);
            checkSourceElement(node.type);
        }
        function checkConditionalType(node) {
            ts.forEachChild(node, checkSourceElement);
        }
        function checkInferType(node) {
            if (!ts.findAncestor(node, function (n) { return n.parent && n.parent.kind === 180 /* ConditionalType */ && n.parent.extendsType === n; })) {
                grammarErrorOnNode(node, ts.Diagnostics.infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type);
            }
            checkSourceElement(node.typeParameter);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkImportType(node) {
            checkSourceElement(node.argument);
            getTypeFromTypeNode(node);
        }
        function isPrivateWithinAmbient(node) {
            return (ts.hasModifier(node, 8 /* Private */) || ts.isPrivateIdentifierPropertyDeclaration(node)) && !!(node.flags & 8388608 /* Ambient */);
        }
        function getEffectiveDeclarationFlags(n, flagsToCheck) {
            var flags = ts.getCombinedModifierFlags(n);
            // children of classes (even ambient classes) should not be marked as ambient or export
            // because those flags have no useful semantics there.
            if (n.parent.kind !== 246 /* InterfaceDeclaration */ &&
                n.parent.kind !== 245 /* ClassDeclaration */ &&
                n.parent.kind !== 214 /* ClassExpression */ &&
                n.flags & 8388608 /* Ambient */) {
                if (!(flags & 2 /* Ambient */) && !(ts.isModuleBlock(n.parent) && ts.isModuleDeclaration(n.parent.parent) && ts.isGlobalScopeAugmentation(n.parent.parent))) {
                    // It is nested in an ambient context, which means it is automatically exported
                    flags |= 1 /* Export */;
                }
                flags |= 2 /* Ambient */;
            }
            return flags & flagsToCheck;
        }
        function checkFunctionOrConstructorSymbol(symbol) {
            if (!produceDiagnostics) {
                return;
            }
            function getCanonicalOverload(overloads, implementation) {
                // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
                // Error on all deviations from this canonical set of flags
                // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
                // report the errors on those. To achieve this, we will say that the implementation is
                // the canonical signature only if it is in the same container as the first overload
                var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent;
                return implementationSharesContainerWithFirstOverload ? implementation : overloads[0];
            }
            function checkFlagAgreementBetweenOverloads(overloads, implementation, flagsToCheck, someOverloadFlags, allOverloadFlags) {
                // Error if some overloads have a flag that is not shared by all overloads. To find the
                // deviations, we XOR someOverloadFlags with allOverloadFlags
                var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
                if (someButNotAllOverloadFlags !== 0) {
                    var canonicalFlags_1 = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck);
                    ts.forEach(overloads, function (o) {
                        var deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags_1;
                        if (deviation & 1 /* Export */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
                        }
                        else if (deviation & 2 /* Ambient */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
                        }
                        else if (deviation & (8 /* Private */ | 16 /* Protected */)) {
                            error(ts.getNameOfDeclaration(o) || o, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
                        }
                        else if (deviation & 128 /* Abstract */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
                        }
                    });
                }
            }
            function checkQuestionTokenAgreementBetweenOverloads(overloads, implementation, someHaveQuestionToken, allHaveQuestionToken) {
                if (someHaveQuestionToken !== allHaveQuestionToken) {
                    var canonicalHasQuestionToken_1 = ts.hasQuestionToken(getCanonicalOverload(overloads, implementation));
                    ts.forEach(overloads, function (o) {
                        var deviation = ts.hasQuestionToken(o) !== canonicalHasQuestionToken_1;
                        if (deviation) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_optional_or_required);
                        }
                    });
                }
            }
            var flagsToCheck = 1 /* Export */ | 2 /* Ambient */ | 8 /* Private */ | 16 /* Protected */ | 128 /* Abstract */;
            var someNodeFlags = 0 /* None */;
            var allNodeFlags = flagsToCheck;
            var someHaveQuestionToken = false;
            var allHaveQuestionToken = true;
            var hasOverloads = false;
            var bodyDeclaration;
            var lastSeenNonAmbientDeclaration;
            var previousDeclaration;
            var declarations = symbol.declarations;
            var isConstructor = (symbol.flags & 16384 /* Constructor */) !== 0;
            function reportImplementationExpectedError(node) {
                if (node.name && ts.nodeIsMissing(node.name)) {
                    return;
                }
                var seen = false;
                var subsequentNode = ts.forEachChild(node.parent, function (c) {
                    if (seen) {
                        return c;
                    }
                    else {
                        seen = c === node;
                    }
                });
                // We may be here because of some extra nodes between overloads that could not be parsed into a valid node.
                // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here.
                if (subsequentNode && subsequentNode.pos === node.end) {
                    if (subsequentNode.kind === node.kind) {
                        var errorNode_1 = subsequentNode.name || subsequentNode;
                        var subsequentName = subsequentNode.name;
                        if (node.name && subsequentName && (
                        // both are private identifiers
                        ts.isPrivateIdentifier(node.name) && ts.isPrivateIdentifier(subsequentName) && node.name.escapedText === subsequentName.escapedText ||
                            // Both are computed property names
                            // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!)
                            ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) ||
                            // Both are literal property names that are the same.
                            ts.isPropertyNameLiteral(node.name) && ts.isPropertyNameLiteral(subsequentName) &&
                                ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) {
                            var reportError = (node.kind === 161 /* MethodDeclaration */ || node.kind === 160 /* MethodSignature */) &&
                                ts.hasModifier(node, 32 /* Static */) !== ts.hasModifier(subsequentNode, 32 /* Static */);
                            // we can get here in two cases
                            // 1. mixed static and instance class members
                            // 2. something with the same name was defined before the set of overloads that prevents them from merging
                            // here we'll report error only for the first case since for second we should already report error in binder
                            if (reportError) {
                                var diagnostic = ts.hasModifier(node, 32 /* Static */) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static;
                                error(errorNode_1, diagnostic);
                            }
                            return;
                        }
                        if (ts.nodeIsPresent(subsequentNode.body)) {
                            error(errorNode_1, ts.Diagnostics.Function_implementation_name_must_be_0, ts.declarationNameToString(node.name));
                            return;
                        }
                    }
                }
                var errorNode = node.name || node;
                if (isConstructor) {
                    error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing);
                }
                else {
                    // Report different errors regarding non-consecutive blocks of declarations depending on whether
                    // the node in question is abstract.
                    if (ts.hasModifier(node, 128 /* Abstract */)) {
                        error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive);
                    }
                    else {
                        error(errorNode, ts.Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration);
                    }
                }
            }
            var duplicateFunctionDeclaration = false;
            var multipleConstructorImplementation = false;
            var hasNonAmbientClass = false;
            for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) {
                var current = declarations_4[_i];
                var node = current;
                var inAmbientContext = node.flags & 8388608 /* Ambient */;
                var inAmbientContextOrInterface = node.parent.kind === 246 /* InterfaceDeclaration */ || node.parent.kind === 173 /* TypeLiteral */ || inAmbientContext;
                if (inAmbientContextOrInterface) {
                    // check if declarations are consecutive only if they are non-ambient
                    // 1. ambient declarations can be interleaved
                    // i.e. this is legal
                    //     declare function foo();
                    //     declare function bar();
                    //     declare function foo();
                    // 2. mixing ambient and non-ambient declarations is a separate error that will be reported - do not want to report an extra one
                    previousDeclaration = undefined;
                }
                if ((node.kind === 245 /* ClassDeclaration */ || node.kind === 214 /* ClassExpression */) && !inAmbientContext) {
                    hasNonAmbientClass = true;
                }
                if (node.kind === 244 /* FunctionDeclaration */ || node.kind === 161 /* MethodDeclaration */ || node.kind === 160 /* MethodSignature */ || node.kind === 162 /* Constructor */) {
                    var currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
                    someNodeFlags |= currentNodeFlags;
                    allNodeFlags &= currentNodeFlags;
                    someHaveQuestionToken = someHaveQuestionToken || ts.hasQuestionToken(node);
                    allHaveQuestionToken = allHaveQuestionToken && ts.hasQuestionToken(node);
                    if (ts.nodeIsPresent(node.body) && bodyDeclaration) {
                        if (isConstructor) {
                            multipleConstructorImplementation = true;
                        }
                        else {
                            duplicateFunctionDeclaration = true;
                        }
                    }
                    else if (previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
                        reportImplementationExpectedError(previousDeclaration);
                    }
                    if (ts.nodeIsPresent(node.body)) {
                        if (!bodyDeclaration) {
                            bodyDeclaration = node;
                        }
                    }
                    else {
                        hasOverloads = true;
                    }
                    previousDeclaration = node;
                    if (!inAmbientContextOrInterface) {
                        lastSeenNonAmbientDeclaration = node;
                    }
                }
            }
            if (multipleConstructorImplementation) {
                ts.forEach(declarations, function (declaration) {
                    error(declaration, ts.Diagnostics.Multiple_constructor_implementations_are_not_allowed);
                });
            }
            if (duplicateFunctionDeclaration) {
                ts.forEach(declarations, function (declaration) {
                    error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Duplicate_function_implementation);
                });
            }
            if (hasNonAmbientClass && !isConstructor && symbol.flags & 16 /* Function */) {
                // A non-ambient class cannot be an implementation for a non-constructor function/class merge
                // TODO: The below just replicates our older error from when classes and functions were
                // entirely unable to merge - a more helpful message like "Class declaration cannot implement overload list"
                // might be warranted. :shrug:
                ts.forEach(declarations, function (declaration) {
                    addDuplicateDeclarationError(declaration, ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(symbol), declarations);
                });
            }
            // Abstract methods can't have an implementation -- in particular, they don't need one.
            if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
                !ts.hasModifier(lastSeenNonAmbientDeclaration, 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) {
                reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
            }
            if (hasOverloads) {
                checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags);
                checkQuestionTokenAgreementBetweenOverloads(declarations, bodyDeclaration, someHaveQuestionToken, allHaveQuestionToken);
                if (bodyDeclaration) {
                    var signatures = getSignaturesOfSymbol(symbol);
                    var bodySignature = getSignatureFromDeclaration(bodyDeclaration);
                    for (var _a = 0, signatures_10 = signatures; _a < signatures_10.length; _a++) {
                        var signature = signatures_10[_a];
                        if (!isImplementationCompatibleWithOverload(bodySignature, signature)) {
                            ts.addRelatedInfo(error(signature.declaration, ts.Diagnostics.This_overload_signature_is_not_compatible_with_its_implementation_signature), ts.createDiagnosticForNode(bodyDeclaration, ts.Diagnostics.The_implementation_signature_is_declared_here));
                            break;
                        }
                    }
                }
            }
        }
        function checkExportsOnMergedDeclarations(node) {
            if (!produceDiagnostics) {
                return;
            }
            // if localSymbol is defined on node then node itself is exported - check is required
            var symbol = node.localSymbol;
            if (!symbol) {
                // local symbol is undefined => this declaration is non-exported.
                // however symbol might contain other declarations that are exported
                symbol = getSymbolOfNode(node);
                if (!symbol.exportSymbol) {
                    // this is a pure local symbol (all declarations are non-exported) - no need to check anything
                    return;
                }
            }
            // run the check only for the first declaration in the list
            if (ts.getDeclarationOfKind(symbol, node.kind) !== node) {
                return;
            }
            var exportedDeclarationSpaces = 0 /* None */;
            var nonExportedDeclarationSpaces = 0 /* None */;
            var defaultExportedDeclarationSpaces = 0 /* None */;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var d = _a[_i];
                var declarationSpaces = getDeclarationSpaces(d);
                var effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, 1 /* Export */ | 512 /* Default */);
                if (effectiveDeclarationFlags & 1 /* Export */) {
                    if (effectiveDeclarationFlags & 512 /* Default */) {
                        defaultExportedDeclarationSpaces |= declarationSpaces;
                    }
                    else {
                        exportedDeclarationSpaces |= declarationSpaces;
                    }
                }
                else {
                    nonExportedDeclarationSpaces |= declarationSpaces;
                }
            }
            // Spaces for anything not declared a 'default export'.
            var nonDefaultExportedDeclarationSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces;
            var commonDeclarationSpacesForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces;
            var commonDeclarationSpacesForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationSpaces;
            if (commonDeclarationSpacesForExportsAndLocals || commonDeclarationSpacesForDefaultAndNonDefault) {
                // declaration spaces for exported and non-exported declarations intersect
                for (var _b = 0, _c = symbol.declarations; _b < _c.length; _b++) {
                    var d = _c[_b];
                    var declarationSpaces = getDeclarationSpaces(d);
                    var name = ts.getNameOfDeclaration(d);
                    // Only error on the declarations that contributed to the intersecting spaces.
                    if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) {
                        error(name, ts.Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, ts.declarationNameToString(name));
                    }
                    else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) {
                        error(name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(name));
                    }
                }
            }
            function getDeclarationSpaces(decl) {
                var d = decl;
                switch (d.kind) {
                    case 246 /* InterfaceDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                    // A jsdoc typedef and callback are, by definition, type aliases.
                    // falls through
                    case 322 /* JSDocTypedefTag */:
                    case 315 /* JSDocCallbackTag */:
                    case 316 /* JSDocEnumTag */:
                        return 2 /* ExportType */;
                    case 249 /* ModuleDeclaration */:
                        return ts.isAmbientModule(d) || ts.getModuleInstanceState(d) !== 0 /* NonInstantiated */
                            ? 4 /* ExportNamespace */ | 1 /* ExportValue */
                            : 4 /* ExportNamespace */;
                    case 245 /* ClassDeclaration */:
                    case 248 /* EnumDeclaration */:
                    case 284 /* EnumMember */:
                        return 2 /* ExportType */ | 1 /* ExportValue */;
                    case 290 /* SourceFile */:
                        return 2 /* ExportType */ | 1 /* ExportValue */ | 4 /* ExportNamespace */;
                    case 259 /* ExportAssignment */:
                        // Export assigned entity name expressions act as aliases and should fall through, otherwise they export values
                        if (!ts.isEntityNameExpression(d.expression)) {
                            return 1 /* ExportValue */;
                        }
                        d = d.expression;
                    // The below options all declare an Alias, which is allowed to merge with other values within the importing module.
                    // falls through
                    case 253 /* ImportEqualsDeclaration */:
                    case 256 /* NamespaceImport */:
                    case 255 /* ImportClause */:
                        var result_10 = 0 /* None */;
                        var target = resolveAlias(getSymbolOfNode(d));
                        ts.forEach(target.declarations, function (d) { result_10 |= getDeclarationSpaces(d); });
                        return result_10;
                    case 242 /* VariableDeclaration */:
                    case 191 /* BindingElement */:
                    case 244 /* FunctionDeclaration */:
                    case 258 /* ImportSpecifier */: // https://github.com/Microsoft/TypeScript/pull/7591
                    case 75 /* Identifier */: // https://github.com/microsoft/TypeScript/issues/36098
                        // Identifiers are used as declarations of assignment declarations whose parents may be
                        // SyntaxKind.CallExpression - `Object.defineProperty(thing, "aField", {value: 42});`
                        // SyntaxKind.ElementAccessExpression - `thing["aField"] = 42;` or `thing["aField"];` (with a doc comment on it)
                        // or SyntaxKind.PropertyAccessExpression - `thing.aField = 42;`
                        // all of which are pretty much always values, or at least imply a value meaning.
                        // It may be apprpriate to treat these as aliases in the future.
                        return 1 /* ExportValue */;
                    default:
                        return ts.Debug.failBadSyntaxKind(d);
                }
            }
        }
        function getAwaitedTypeOfPromise(type, errorNode, diagnosticMessage, arg0) {
            var promisedType = getPromisedTypeOfPromise(type, errorNode);
            return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0);
        }
        /**
         * Gets the "promised type" of a promise.
         * @param type The type of the promise.
         * @remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback.
         */
        function getPromisedTypeOfPromise(type, errorNode) {
            //
            //  { // type
            //      then( // thenFunction
            //          onfulfilled: ( // onfulfilledParameterType
            //              value: T // valueParameterType
            //          ) => any
            //      ): any;
            //  }
            //
            if (isTypeAny(type)) {
                return undefined;
            }
            var typeAsPromise = type;
            if (typeAsPromise.promisedTypeOfPromise) {
                return typeAsPromise.promisedTypeOfPromise;
            }
            if (isReferenceToType(type, getGlobalPromiseType(/*reportErrors*/ false))) {
                return typeAsPromise.promisedTypeOfPromise = getTypeArguments(type)[0];
            }
            var thenFunction = getTypeOfPropertyOfType(type, "then"); // TODO: GH#18217
            if (isTypeAny(thenFunction)) {
                return undefined;
            }
            var thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, 0 /* Call */) : ts.emptyArray;
            if (thenSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, ts.Diagnostics.A_promise_must_have_a_then_method);
                }
                return undefined;
            }
            var onfulfilledParameterType = getTypeWithFacts(getUnionType(ts.map(thenSignatures, getTypeOfFirstParameterOfSignature)), 2097152 /* NEUndefinedOrNull */);
            if (isTypeAny(onfulfilledParameterType)) {
                return undefined;
            }
            var onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, 0 /* Call */);
            if (onfulfilledParameterSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, ts.Diagnostics.The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback);
                }
                return undefined;
            }
            return typeAsPromise.promisedTypeOfPromise = getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), 2 /* Subtype */);
        }
        /**
         * Gets the "awaited type" of a type.
         * @param type The type to await.
         * @remarks The "awaited type" of an expression is its "promised type" if the expression is a
         * Promise-like type; otherwise, it is the type of the expression. This is used to reflect
         * The runtime behavior of the `await` keyword.
         */
        function checkAwaitedType(type, errorNode, diagnosticMessage, arg0) {
            var awaitedType = getAwaitedType(type, errorNode, diagnosticMessage, arg0);
            return awaitedType || errorType;
        }
        /**
         * Determines whether a type has a callable `then` member.
         */
        function isThenableType(type) {
            var thenFunction = getTypeOfPropertyOfType(type, "then");
            return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, 2097152 /* NEUndefinedOrNull */), 0 /* Call */).length > 0;
        }
        /**
         * Gets the "awaited type" of a type.
         *
         * The "awaited type" of an expression is its "promised type" if the expression is a
         * Promise-like type; otherwise, it is the type of the expression. If the "promised
         * type" is itself a Promise-like, the "promised type" is recursively unwrapped until a
         * non-promise type is found.
         *
         * This is used to reflect the runtime behavior of the `await` keyword.
         */
        function getAwaitedType(type, errorNode, diagnosticMessage, arg0) {
            if (isTypeAny(type)) {
                return type;
            }
            var typeAsAwaitable = type;
            if (typeAsAwaitable.awaitedTypeOfType) {
                return typeAsAwaitable.awaitedTypeOfType;
            }
            // For a union, get a union of the awaited types of each constituent.
            //
            return typeAsAwaitable.awaitedTypeOfType =
                mapType(type, errorNode ? function (constituentType) { return getAwaitedTypeWorker(constituentType, errorNode, diagnosticMessage, arg0); } : getAwaitedTypeWorker);
        }
        function getAwaitedTypeWorker(type, errorNode, diagnosticMessage, arg0) {
            var typeAsAwaitable = type;
            if (typeAsAwaitable.awaitedTypeOfType) {
                return typeAsAwaitable.awaitedTypeOfType;
            }
            var promisedType = getPromisedTypeOfPromise(type);
            if (promisedType) {
                if (type.id === promisedType.id || awaitedTypeStack.lastIndexOf(promisedType.id) >= 0) {
                    // Verify that we don't have a bad actor in the form of a promise whose
                    // promised type is the same as the promise type, or a mutually recursive
                    // promise. If so, we return undefined as we cannot guess the shape. If this
                    // were the actual case in the JavaScript, this Promise would never resolve.
                    //
                    // An example of a bad actor with a singly-recursive promise type might
                    // be:
                    //
                    //  interface BadPromise {
                    //      then(
                    //          onfulfilled: (value: BadPromise) => any,
                    //          onrejected: (error: any) => any): BadPromise;
                    //  }
                    //
                    // The above interface will pass the PromiseLike check, and return a
                    // promised type of `BadPromise`. Since this is a self reference, we
                    // don't want to keep recursing ad infinitum.
                    //
                    // An example of a bad actor in the form of a mutually-recursive
                    // promise type might be:
                    //
                    //  interface BadPromiseA {
                    //      then(
                    //          onfulfilled: (value: BadPromiseB) => any,
                    //          onrejected: (error: any) => any): BadPromiseB;
                    //  }
                    //
                    //  interface BadPromiseB {
                    //      then(
                    //          onfulfilled: (value: BadPromiseA) => any,
                    //          onrejected: (error: any) => any): BadPromiseA;
                    //  }
                    //
                    if (errorNode) {
                        error(errorNode, ts.Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
                    }
                    return undefined;
                }
                // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
                // See the comments above for more information.
                awaitedTypeStack.push(type.id);
                var awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0);
                awaitedTypeStack.pop();
                if (!awaitedType) {
                    return undefined;
                }
                return typeAsAwaitable.awaitedTypeOfType = awaitedType;
            }
            // The type was not a promise, so it could not be unwrapped any further.
            // As long as the type does not have a callable "then" property, it is
            // safe to return the type; otherwise, an error is reported and we return
            // undefined.
            //
            // An example of a non-promise "thenable" might be:
            //
            //  await { then(): void {} }
            //
            // The "thenable" does not match the minimal definition for a promise. When
            // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
            // will never settle. We treat this as an error to help flag an early indicator
            // of a runtime problem. If the user wants to return this value from an async
            // function, they would need to wrap it in some other value. If they want it to
            // be treated as a promise, they can cast to <any>.
            if (isThenableType(type)) {
                if (errorNode) {
                    if (!diagnosticMessage)
                        return ts.Debug.fail();
                    error(errorNode, diagnosticMessage, arg0);
                }
                return undefined;
            }
            return typeAsAwaitable.awaitedTypeOfType = type;
        }
        /**
         * Checks the return type of an async function to ensure it is a compatible
         * Promise implementation.
         *
         * This checks that an async function has a valid Promise-compatible return type.
         * An async function has a valid Promise-compatible return type if the resolved value
         * of the return type has a construct signature that takes in an `initializer` function
         * that in turn supplies a `resolve` function as one of its arguments and results in an
         * object with a callable `then` signature.
         *
         * @param node The signature to check
         */
        function checkAsyncFunctionReturnType(node, returnTypeNode) {
            // As part of our emit for an async function, we will need to emit the entity name of
            // the return type annotation as an expression. To meet the necessary runtime semantics
            // for __awaiter, we must also check that the type of the declaration (e.g. the static
            // side or "constructor" of the promise type) is compatible `PromiseConstructorLike`.
            //
            // An example might be (from lib.es6.d.ts):
            //
            //  interface Promise<T> { ... }
            //  interface PromiseConstructor {
            //      new <T>(...): Promise<T>;
            //  }
            //  declare var Promise: PromiseConstructor;
            //
            // When an async function declares a return type annotation of `Promise<T>`, we
            // need to get the type of the `Promise` variable declaration above, which would
            // be `PromiseConstructor`.
            //
            // The same case applies to a class:
            //
            //  declare class Promise<T> {
            //      constructor(...);
            //      then<U>(...): Promise<U>;
            //  }
            //
            var returnType = getTypeFromTypeNode(returnTypeNode);
            if (languageVersion >= 2 /* ES2015 */) {
                if (returnType === errorType) {
                    return;
                }
                var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
                if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
                    // The promise type was not a valid type reference to the global promise type, so we
                    // report an error and return the unknown type.
                    error(returnTypeNode, ts.Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
                    return;
                }
            }
            else {
                // Always mark the type node as referenced if it points to a value
                markTypeNodeAsReferenced(returnTypeNode);
                if (returnType === errorType) {
                    return;
                }
                var promiseConstructorName = ts.getEntityNameFromTypeNode(returnTypeNode);
                if (promiseConstructorName === undefined) {
                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
                    return;
                }
                var promiseConstructorSymbol = resolveEntityName(promiseConstructorName, 111551 /* Value */, /*ignoreErrors*/ true);
                var promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : errorType;
                if (promiseConstructorType === errorType) {
                    if (promiseConstructorName.kind === 75 /* Identifier */ && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) {
                        error(returnTypeNode, ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
                    }
                    else {
                        error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
                    }
                    return;
                }
                var globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(/*reportErrors*/ true);
                if (globalPromiseConstructorLikeType === emptyObjectType) {
                    // If we couldn't resolve the global PromiseConstructorLike type we cannot verify
                    // compatibility with __awaiter.
                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
                    return;
                }
                if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) {
                    return;
                }
                // Verify there is no local declaration that could collide with the promise constructor.
                var rootName = promiseConstructorName && ts.getFirstIdentifier(promiseConstructorName);
                var collidingSymbol = getSymbol(node.locals, rootName.escapedText, 111551 /* Value */);
                if (collidingSymbol) {
                    error(collidingSymbol.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, ts.idText(rootName), ts.entityNameToString(promiseConstructorName));
                    return;
                }
            }
            checkAwaitedType(returnType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        /** Check a decorator */
        function checkDecorator(node) {
            var signature = getResolvedSignature(node);
            var returnType = getReturnTypeOfSignature(signature);
            if (returnType.flags & 1 /* Any */) {
                return;
            }
            var expectedReturnType;
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            var errorInfo;
            switch (node.parent.kind) {
                case 245 /* ClassDeclaration */:
                    var classSymbol = getSymbolOfNode(node.parent);
                    var classConstructorType = getTypeOfSymbol(classSymbol);
                    expectedReturnType = getUnionType([classConstructorType, voidType]);
                    break;
                case 156 /* Parameter */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any);
                    break;
                case 159 /* PropertyDeclaration */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.The_return_type_of_a_property_decorator_function_must_be_either_void_or_any);
                    break;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    var methodType = getTypeOfNode(node.parent);
                    var descriptorType = createTypedPropertyDescriptorType(methodType);
                    expectedReturnType = getUnionType([descriptorType, voidType]);
                    break;
                default:
                    return ts.Debug.fail();
            }
            checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage, function () { return errorInfo; });
        }
        /**
         * If a TypeNode can be resolved to a value symbol imported from an external module, it is
         * marked as referenced to prevent import elision.
         */
        function markTypeNodeAsReferenced(node) {
            markEntityNameOrEntityExpressionAsReference(node && ts.getEntityNameFromTypeNode(node));
        }
        function markEntityNameOrEntityExpressionAsReference(typeName) {
            if (!typeName)
                return;
            var rootName = ts.getFirstIdentifier(typeName);
            var meaning = (typeName.kind === 75 /* Identifier */ ? 788968 /* Type */ : 1920 /* Namespace */) | 2097152 /* Alias */;
            var rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isRefernce*/ true);
            if (rootSymbol
                && rootSymbol.flags & 2097152 /* Alias */
                && symbolIsValue(rootSymbol)
                && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))
                && !getTypeOnlyAliasDeclaration(rootSymbol)) {
                markAliasSymbolAsReferenced(rootSymbol);
            }
        }
        /**
         * This function marks the type used for metadata decorator as referenced if it is import
         * from external module.
         * This is different from markTypeNodeAsReferenced because it tries to simplify type nodes in
         * union and intersection type
         * @param node
         */
        function markDecoratorMedataDataTypeNodeAsReferenced(node) {
            var entityName = getEntityNameForDecoratorMetadata(node);
            if (entityName && ts.isEntityName(entityName)) {
                markEntityNameOrEntityExpressionAsReference(entityName);
            }
        }
        function getEntityNameForDecoratorMetadata(node) {
            if (node) {
                switch (node.kind) {
                    case 179 /* IntersectionType */:
                    case 178 /* UnionType */:
                        return getEntityNameForDecoratorMetadataFromTypeList(node.types);
                    case 180 /* ConditionalType */:
                        return getEntityNameForDecoratorMetadataFromTypeList([node.trueType, node.falseType]);
                    case 182 /* ParenthesizedType */:
                        return getEntityNameForDecoratorMetadata(node.type);
                    case 169 /* TypeReference */:
                        return node.typeName;
                }
            }
        }
        function getEntityNameForDecoratorMetadataFromTypeList(types) {
            var commonEntityName;
            for (var _i = 0, types_20 = types; _i < types_20.length; _i++) {
                var typeNode = types_20[_i];
                while (typeNode.kind === 182 /* ParenthesizedType */) {
                    typeNode = typeNode.type; // Skip parens if need be
                }
                if (typeNode.kind === 137 /* NeverKeyword */) {
                    continue; // Always elide `never` from the union/intersection if possible
                }
                if (!strictNullChecks && (typeNode.kind === 100 /* NullKeyword */ || typeNode.kind === 146 /* UndefinedKeyword */)) {
                    continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
                }
                var individualEntityName = getEntityNameForDecoratorMetadata(typeNode);
                if (!individualEntityName) {
                    // Individual is something like string number
                    // So it would be serialized to either that type or object
                    // Safe to return here
                    return undefined;
                }
                if (commonEntityName) {
                    // Note this is in sync with the transformation that happens for type node.
                    // Keep this in sync with serializeUnionOrIntersectionType
                    // Verify if they refer to same entity and is identifier
                    // return undefined if they dont match because we would emit object
                    if (!ts.isIdentifier(commonEntityName) ||
                        !ts.isIdentifier(individualEntityName) ||
                        commonEntityName.escapedText !== individualEntityName.escapedText) {
                        return undefined;
                    }
                }
                else {
                    commonEntityName = individualEntityName;
                }
            }
            return commonEntityName;
        }
        function getParameterTypeNodeForDecoratorCheck(node) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
            return ts.isRestParameter(node) ? ts.getRestParameterElementType(typeNode) : typeNode;
        }
        /** Check the decorators of a node */
        function checkDecorators(node) {
            if (!node.decorators) {
                return;
            }
            // skip this check for nodes that cannot have decorators. These should have already had an error reported by
            // checkGrammarDecorators.
            if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) {
                return;
            }
            if (!compilerOptions.experimentalDecorators) {
                error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning);
            }
            var firstDecorator = node.decorators[0];
            checkExternalEmitHelpers(firstDecorator, 8 /* Decorate */);
            if (node.kind === 156 /* Parameter */) {
                checkExternalEmitHelpers(firstDecorator, 32 /* Param */);
            }
            if (compilerOptions.emitDecoratorMetadata) {
                checkExternalEmitHelpers(firstDecorator, 16 /* Metadata */);
                // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
                switch (node.kind) {
                    case 245 /* ClassDeclaration */:
                        var constructor = ts.getFirstConstructorWithBody(node);
                        if (constructor) {
                            for (var _i = 0, _a = constructor.parameters; _i < _a.length; _i++) {
                                var parameter = _a[_i];
                                markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                            }
                        }
                        break;
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        var otherKind = node.kind === 163 /* GetAccessor */ ? 164 /* SetAccessor */ : 163 /* GetAccessor */;
                        var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(node), otherKind);
                        markDecoratorMedataDataTypeNodeAsReferenced(getAnnotatedAccessorTypeNode(node) || otherAccessor && getAnnotatedAccessorTypeNode(otherAccessor));
                        break;
                    case 161 /* MethodDeclaration */:
                        for (var _b = 0, _c = node.parameters; _b < _c.length; _b++) {
                            var parameter = _c[_b];
                            markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                        }
                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveReturnTypeNode(node));
                        break;
                    case 159 /* PropertyDeclaration */:
                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveTypeAnnotationNode(node));
                        break;
                    case 156 /* Parameter */:
                        markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node));
                        var containingSignature = node.parent;
                        for (var _d = 0, _e = containingSignature.parameters; _d < _e.length; _d++) {
                            var parameter = _e[_d];
                            markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                        }
                        break;
                }
            }
            ts.forEach(node.decorators, checkDecorator);
        }
        function checkFunctionDeclaration(node) {
            if (produceDiagnostics) {
                checkFunctionOrMethodDeclaration(node);
                checkGrammarForGenerator(node);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
        }
        function checkJSDocTypeAliasTag(node) {
            if (!node.typeExpression) {
                // If the node had `@property` tags, `typeExpression` would have been set to the first property tag.
                error(node.name, ts.Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags);
            }
            if (node.name) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
            }
            checkSourceElement(node.typeExpression);
        }
        function checkJSDocTemplateTag(node) {
            checkSourceElement(node.constraint);
            for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) {
                var tp = _a[_i];
                checkSourceElement(tp);
            }
        }
        function checkJSDocTypeTag(node) {
            checkSourceElement(node.typeExpression);
        }
        function checkJSDocParameterTag(node) {
            checkSourceElement(node.typeExpression);
            if (!ts.getParameterSymbolFromJSDoc(node)) {
                var decl = ts.getHostSignatureFromJSDoc(node);
                // don't issue an error for invalid hosts -- just functions --
                // and give a better error message when the host function mentions `arguments`
                // but the tag doesn't have an array type
                if (decl) {
                    var i = ts.getJSDocTags(decl).filter(ts.isJSDocParameterTag).indexOf(node);
                    if (i > -1 && i < decl.parameters.length && ts.isBindingPattern(decl.parameters[i].name)) {
                        return;
                    }
                    if (!containsArgumentsReference(decl)) {
                        if (ts.isQualifiedName(node.name)) {
                            error(node.name, ts.Diagnostics.Qualified_name_0_is_not_allowed_without_a_leading_param_object_1, ts.entityNameToString(node.name), ts.entityNameToString(node.name.left));
                        }
                        else {
                            error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name));
                        }
                    }
                    else if (ts.findLast(ts.getJSDocTags(decl), ts.isJSDocParameterTag) === node &&
                        node.typeExpression && node.typeExpression.type &&
                        !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) {
                        error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(node.name.kind === 153 /* QualifiedName */ ? node.name.right : node.name));
                    }
                }
            }
        }
        function checkJSDocPropertyTag(node) {
            checkSourceElement(node.typeExpression);
        }
        function checkJSDocFunctionType(node) {
            if (produceDiagnostics && !node.type && !ts.isJSDocConstructSignature(node)) {
                reportImplicitAny(node, anyType);
            }
            checkSignatureDeclaration(node);
        }
        function checkJSDocImplementsTag(node) {
            var classLike = ts.getEffectiveJSDocHost(node);
            if (!classLike || !ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) {
                error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName));
            }
        }
        function checkJSDocAugmentsTag(node) {
            var classLike = ts.getEffectiveJSDocHost(node);
            if (!classLike || !ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) {
                error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName));
                return;
            }
            var augmentsTags = ts.getJSDocTags(classLike).filter(ts.isJSDocAugmentsTag);
            ts.Debug.assert(augmentsTags.length > 0);
            if (augmentsTags.length > 1) {
                error(augmentsTags[1], ts.Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag);
            }
            var name = getIdentifierFromEntityNameExpression(node.class.expression);
            var extend = ts.getClassExtendsHeritageElement(classLike);
            if (extend) {
                var className = getIdentifierFromEntityNameExpression(extend.expression);
                if (className && name.escapedText !== className.escapedText) {
                    error(name, ts.Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, ts.idText(node.tagName), ts.idText(name), ts.idText(className));
                }
            }
        }
        function getIdentifierFromEntityNameExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return node;
                case 194 /* PropertyAccessExpression */:
                    return node.name;
                default:
                    return undefined;
            }
        }
        function checkFunctionOrMethodDeclaration(node) {
            checkDecorators(node);
            checkSignatureDeclaration(node);
            var functionFlags = ts.getFunctionFlags(node);
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name && node.name.kind === 154 /* ComputedPropertyName */) {
                // This check will account for methods in class/interface declarations,
                // as well as accessors in classes/object literals
                checkComputedPropertyName(node.name);
            }
            if (!hasNonBindableDynamicName(node)) {
                // first we want to check the local symbol that contain this declaration
                // - if node.localSymbol !== undefined - this is current declaration is exported and localSymbol points to the local symbol
                // - if node.localSymbol === undefined - this node is non-exported so we can just pick the result of getSymbolOfNode
                var symbol = getSymbolOfNode(node);
                var localSymbol = node.localSymbol || symbol;
                // Since the javascript won't do semantic analysis like typescript,
                // if the javascript file comes before the typescript file and both contain same name functions,
                // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function.
                var firstDeclaration = ts.find(localSymbol.declarations, 
                // Get first non javascript function declaration
                function (declaration) { return declaration.kind === node.kind && !(declaration.flags & 131072 /* JavaScriptFile */); });
                // Only type check the symbol once
                if (node === firstDeclaration) {
                    checkFunctionOrConstructorSymbol(localSymbol);
                }
                if (symbol.parent) {
                    // run check once for the first declaration
                    if (ts.getDeclarationOfKind(symbol, node.kind) === node) {
                        // run check on export symbol to check that modifiers agree across all exported declarations
                        checkFunctionOrConstructorSymbol(symbol);
                    }
                }
            }
            var body = node.kind === 160 /* MethodSignature */ ? undefined : node.body;
            checkSourceElement(body);
            checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, getReturnTypeFromAnnotation(node));
            if (produceDiagnostics && !ts.getEffectiveReturnTypeNode(node)) {
                // Report an implicit any error if there is no body, no explicit return type, and node is not a private method
                // in an ambient context
                if (ts.nodeIsMissing(body) && !isPrivateWithinAmbient(node)) {
                    reportImplicitAny(node, anyType);
                }
                if (functionFlags & 1 /* Generator */ && ts.nodeIsPresent(body)) {
                    // A generator with a body and no type annotation can still cause errors. It can error if the
                    // yielded values have no common supertype, or it can give an implicit any error if it has no
                    // yielded values. The only way to trigger these errors is to try checking its return type.
                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
                }
            }
            // A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
            if (ts.isInJSFile(node)) {
                var typeTag = ts.getJSDocTypeTag(node);
                if (typeTag && typeTag.typeExpression && !getContextualCallSignature(getTypeFromTypeNode(typeTag.typeExpression), node)) {
                    error(typeTag, ts.Diagnostics.The_type_of_a_function_declaration_must_match_the_function_s_signature);
                }
            }
        }
        function registerForUnusedIdentifiersCheck(node) {
            // May be in a call such as getTypeOfNode that happened to call this. But potentiallyUnusedIdentifiers is only defined in the scope of `checkSourceFile`.
            if (produceDiagnostics) {
                var sourceFile = ts.getSourceFileOfNode(node);
                var potentiallyUnusedIdentifiers = allPotentiallyUnusedIdentifiers.get(sourceFile.path);
                if (!potentiallyUnusedIdentifiers) {
                    potentiallyUnusedIdentifiers = [];
                    allPotentiallyUnusedIdentifiers.set(sourceFile.path, potentiallyUnusedIdentifiers);
                }
                // TODO: GH#22580
                // Debug.assert(addToSeen(seenPotentiallyUnusedIdentifiers, getNodeId(node)), "Adding potentially-unused identifier twice");
                potentiallyUnusedIdentifiers.push(node);
            }
        }
        function checkUnusedIdentifiers(potentiallyUnusedIdentifiers, addDiagnostic) {
            for (var _i = 0, potentiallyUnusedIdentifiers_1 = potentiallyUnusedIdentifiers; _i < potentiallyUnusedIdentifiers_1.length; _i++) {
                var node = potentiallyUnusedIdentifiers_1[_i];
                switch (node.kind) {
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                        checkUnusedClassMembers(node, addDiagnostic);
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 290 /* SourceFile */:
                    case 249 /* ModuleDeclaration */:
                    case 223 /* Block */:
                    case 251 /* CaseBlock */:
                    case 230 /* ForStatement */:
                    case 231 /* ForInStatement */:
                    case 232 /* ForOfStatement */:
                        checkUnusedLocalsAndParameters(node, addDiagnostic);
                        break;
                    case 162 /* Constructor */:
                    case 201 /* FunctionExpression */:
                    case 244 /* FunctionDeclaration */:
                    case 202 /* ArrowFunction */:
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        if (node.body) { // Don't report unused parameters in overloads
                            checkUnusedLocalsAndParameters(node, addDiagnostic);
                        }
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 160 /* MethodSignature */:
                    case 165 /* CallSignature */:
                    case 166 /* ConstructSignature */:
                    case 170 /* FunctionType */:
                    case 171 /* ConstructorType */:
                    case 247 /* TypeAliasDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 181 /* InferType */:
                        checkUnusedInferTypeParameter(node, addDiagnostic);
                        break;
                    default:
                        ts.Debug.assertNever(node, "Node should not have been registered for unused identifiers check");
                }
            }
        }
        function errorUnusedLocal(declaration, name, addDiagnostic) {
            var node = ts.getNameOfDeclaration(declaration) || declaration;
            var message = isTypeDeclaration(declaration) ? ts.Diagnostics._0_is_declared_but_never_used : ts.Diagnostics._0_is_declared_but_its_value_is_never_read;
            addDiagnostic(declaration, 0 /* Local */, ts.createDiagnosticForNode(node, message, name));
        }
        function isIdentifierThatStartsWithUnderscore(node) {
            return ts.isIdentifier(node) && ts.idText(node).charCodeAt(0) === 95 /* _ */;
        }
        function checkUnusedClassMembers(node, addDiagnostic) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                switch (member.kind) {
                    case 161 /* MethodDeclaration */:
                    case 159 /* PropertyDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        if (member.kind === 164 /* SetAccessor */ && member.symbol.flags & 32768 /* GetAccessor */) {
                            // Already would have reported an error on the getter.
                            break;
                        }
                        var symbol = getSymbolOfNode(member);
                        if (!symbol.isReferenced
                            && (ts.hasModifier(member, 8 /* Private */) || ts.isNamedDeclaration(member) && ts.isPrivateIdentifier(member.name))
                            && !(member.flags & 8388608 /* Ambient */)) {
                            addDiagnostic(member, 0 /* Local */, ts.createDiagnosticForNode(member.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
                        }
                        break;
                    case 162 /* Constructor */:
                        for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                            var parameter = _c[_b];
                            if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8 /* Private */)) {
                                addDiagnostic(parameter, 0 /* Local */, ts.createDiagnosticForNode(parameter.name, ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read, ts.symbolName(parameter.symbol)));
                            }
                        }
                        break;
                    case 167 /* IndexSignature */:
                    case 222 /* SemicolonClassElement */:
                        // Can't be private
                        break;
                    default:
                        ts.Debug.fail();
                }
            }
        }
        function checkUnusedInferTypeParameter(node, addDiagnostic) {
            var typeParameter = node.typeParameter;
            if (isTypeParameterUnused(typeParameter)) {
                addDiagnostic(node, 1 /* Parameter */, ts.createDiagnosticForNode(node, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.idText(typeParameter.name)));
            }
        }
        function checkUnusedTypeParameters(node, addDiagnostic) {
            // Only report errors on the last declaration for the type parameter container;
            // this ensures that all uses have been accounted for.
            if (ts.last(getSymbolOfNode(node).declarations) !== node)
                return;
            var typeParameters = ts.getEffectiveTypeParameterDeclarations(node);
            var seenParentsWithEveryUnused = new ts.NodeSet();
            for (var _i = 0, typeParameters_3 = typeParameters; _i < typeParameters_3.length; _i++) {
                var typeParameter = typeParameters_3[_i];
                if (!isTypeParameterUnused(typeParameter))
                    continue;
                var name = ts.idText(typeParameter.name);
                var parent = typeParameter.parent;
                if (parent.kind !== 181 /* InferType */ && parent.typeParameters.every(isTypeParameterUnused)) {
                    if (seenParentsWithEveryUnused.tryAdd(parent)) {
                        var range = ts.isJSDocTemplateTag(parent)
                            // Whole @template tag
                            ? ts.rangeOfNode(parent)
                            // Include the `<>` in the error message
                            : ts.rangeOfTypeParameters(parent.typeParameters);
                        var only = parent.typeParameters.length === 1;
                        var message = only ? ts.Diagnostics._0_is_declared_but_its_value_is_never_read : ts.Diagnostics.All_type_parameters_are_unused;
                        var arg0 = only ? name : undefined;
                        addDiagnostic(typeParameter, 1 /* Parameter */, ts.createFileDiagnostic(ts.getSourceFileOfNode(parent), range.pos, range.end - range.pos, message, arg0));
                    }
                }
                else {
                    addDiagnostic(typeParameter, 1 /* Parameter */, ts.createDiagnosticForNode(typeParameter, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, name));
                }
            }
        }
        function isTypeParameterUnused(typeParameter) {
            return !(getMergedSymbol(typeParameter.symbol).isReferenced & 262144 /* TypeParameter */) && !isIdentifierThatStartsWithUnderscore(typeParameter.name);
        }
        function addToGroup(map, key, value, getKey) {
            var keyString = String(getKey(key));
            var group = map.get(keyString);
            if (group) {
                group[1].push(value);
            }
            else {
                map.set(keyString, [key, [value]]);
            }
        }
        function tryGetRootParameterDeclaration(node) {
            return ts.tryCast(ts.getRootDeclaration(node), ts.isParameter);
        }
        function isValidUnusedLocalDeclaration(declaration) {
            if (ts.isBindingElement(declaration) && isIdentifierThatStartsWithUnderscore(declaration.name)) {
                return !!ts.findAncestor(declaration.parent, function (ancestor) {
                    return ts.isArrayBindingPattern(ancestor) || ts.isVariableDeclaration(ancestor) || ts.isVariableDeclarationList(ancestor) ? false :
                        ts.isForOfStatement(ancestor) ? true : "quit";
                });
            }
            return ts.isAmbientModule(declaration) ||
                (ts.isVariableDeclaration(declaration) && ts.isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name);
        }
        function checkUnusedLocalsAndParameters(nodeWithLocals, addDiagnostic) {
            // Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value.
            var unusedImports = ts.createMap();
            var unusedDestructures = ts.createMap();
            var unusedVariables = ts.createMap();
            nodeWithLocals.locals.forEach(function (local) {
                // If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`.
                // If it's a type parameter merged with a parameter, check if the parameter-side is used.
                if (local.flags & 262144 /* TypeParameter */ ? !(local.flags & 3 /* Variable */ && !(local.isReferenced & 3 /* Variable */)) : local.isReferenced || local.exportSymbol) {
                    return;
                }
                for (var _i = 0, _a = local.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (isValidUnusedLocalDeclaration(declaration)) {
                        continue;
                    }
                    if (isImportedDeclaration(declaration)) {
                        addToGroup(unusedImports, importClauseFromImported(declaration), declaration, getNodeId);
                    }
                    else if (ts.isBindingElement(declaration) && ts.isObjectBindingPattern(declaration.parent)) {
                        // In `{ a, ...b }, `a` is considered used since it removes a property from `b`. `b` may still be unused though.
                        var lastElement = ts.last(declaration.parent.elements);
                        if (declaration === lastElement || !ts.last(declaration.parent.elements).dotDotDotToken) {
                            addToGroup(unusedDestructures, declaration.parent, declaration, getNodeId);
                        }
                    }
                    else if (ts.isVariableDeclaration(declaration)) {
                        addToGroup(unusedVariables, declaration.parent, declaration, getNodeId);
                    }
                    else {
                        var parameter = local.valueDeclaration && tryGetRootParameterDeclaration(local.valueDeclaration);
                        var name = local.valueDeclaration && ts.getNameOfDeclaration(local.valueDeclaration);
                        if (parameter && name) {
                            if (!ts.isParameterPropertyDeclaration(parameter, parameter.parent) && !ts.parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) {
                                addDiagnostic(parameter, 1 /* Parameter */, ts.createDiagnosticForNode(name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(local)));
                            }
                        }
                        else {
                            errorUnusedLocal(declaration, ts.symbolName(local), addDiagnostic);
                        }
                    }
                }
            });
            unusedImports.forEach(function (_a) {
                var importClause = _a[0], unuseds = _a[1];
                var importDecl = importClause.parent;
                var nDeclarations = (importClause.name ? 1 : 0) +
                    (importClause.namedBindings ?
                        (importClause.namedBindings.kind === 256 /* NamespaceImport */ ? 1 : importClause.namedBindings.elements.length)
                        : 0);
                if (nDeclarations === unuseds.length) {
                    addDiagnostic(importDecl, 0 /* Local */, unuseds.length === 1
                        ? ts.createDiagnosticForNode(importDecl, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.idText(ts.first(unuseds).name))
                        : ts.createDiagnosticForNode(importDecl, ts.Diagnostics.All_imports_in_import_declaration_are_unused));
                }
                else {
                    for (var _i = 0, unuseds_1 = unuseds; _i < unuseds_1.length; _i++) {
                        var unused = unuseds_1[_i];
                        errorUnusedLocal(unused, ts.idText(unused.name), addDiagnostic);
                    }
                }
            });
            unusedDestructures.forEach(function (_a) {
                var bindingPattern = _a[0], bindingElements = _a[1];
                var kind = tryGetRootParameterDeclaration(bindingPattern.parent) ? 1 /* Parameter */ : 0 /* Local */;
                if (bindingPattern.elements.length === bindingElements.length) {
                    if (bindingElements.length === 1 && bindingPattern.parent.kind === 242 /* VariableDeclaration */ && bindingPattern.parent.parent.kind === 243 /* VariableDeclarationList */) {
                        addToGroup(unusedVariables, bindingPattern.parent.parent, bindingPattern.parent, getNodeId);
                    }
                    else {
                        addDiagnostic(bindingPattern, kind, bindingElements.length === 1
                            ? ts.createDiagnosticForNode(bindingPattern, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(ts.first(bindingElements).name))
                            : ts.createDiagnosticForNode(bindingPattern, ts.Diagnostics.All_destructured_elements_are_unused));
                    }
                }
                else {
                    for (var _i = 0, bindingElements_1 = bindingElements; _i < bindingElements_1.length; _i++) {
                        var e = bindingElements_1[_i];
                        addDiagnostic(e, kind, ts.createDiagnosticForNode(e, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(e.name)));
                    }
                }
            });
            unusedVariables.forEach(function (_a) {
                var declarationList = _a[0], declarations = _a[1];
                if (declarationList.declarations.length === declarations.length) {
                    addDiagnostic(declarationList, 0 /* Local */, declarations.length === 1
                        ? ts.createDiagnosticForNode(ts.first(declarations).name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(ts.first(declarations).name))
                        : ts.createDiagnosticForNode(declarationList.parent.kind === 225 /* VariableStatement */ ? declarationList.parent : declarationList, ts.Diagnostics.All_variables_are_unused));
                }
                else {
                    for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) {
                        var decl = declarations_5[_i];
                        addDiagnostic(decl, 0 /* Local */, ts.createDiagnosticForNode(decl, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(decl.name)));
                    }
                }
            });
        }
        function bindingNameText(name) {
            switch (name.kind) {
                case 75 /* Identifier */:
                    return ts.idText(name);
                case 190 /* ArrayBindingPattern */:
                case 189 /* ObjectBindingPattern */:
                    return bindingNameText(ts.cast(ts.first(name.elements), ts.isBindingElement).name);
                default:
                    return ts.Debug.assertNever(name);
            }
        }
        function isImportedDeclaration(node) {
            return node.kind === 255 /* ImportClause */ || node.kind === 258 /* ImportSpecifier */ || node.kind === 256 /* NamespaceImport */;
        }
        function importClauseFromImported(decl) {
            return decl.kind === 255 /* ImportClause */ ? decl : decl.kind === 256 /* NamespaceImport */ ? decl.parent : decl.parent.parent;
        }
        function checkBlock(node) {
            // Grammar checking for SyntaxKind.Block
            if (node.kind === 223 /* Block */) {
                checkGrammarStatementInAmbientContext(node);
            }
            if (ts.isFunctionOrModuleBlock(node)) {
                var saveFlowAnalysisDisabled = flowAnalysisDisabled;
                ts.forEach(node.statements, checkSourceElement);
                flowAnalysisDisabled = saveFlowAnalysisDisabled;
            }
            else {
                ts.forEach(node.statements, checkSourceElement);
            }
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkCollisionWithArgumentsInGeneratedCode(node) {
            // no rest parameters \ declaration context \ overload - no codegen impact
            if (languageVersion >= 2 /* ES2015 */ || compilerOptions.noEmit || !ts.hasRestParameter(node) || node.flags & 8388608 /* Ambient */ || ts.nodeIsMissing(node.body)) {
                return;
            }
            ts.forEach(node.parameters, function (p) {
                if (p.name && !ts.isBindingPattern(p.name) && p.name.escapedText === argumentsSymbol.escapedName) {
                    error(p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters);
                }
            });
        }
        function needCollisionCheckForIdentifier(node, identifier, name) {
            if (!(identifier && identifier.escapedText === name)) {
                return false;
            }
            if (node.kind === 159 /* PropertyDeclaration */ ||
                node.kind === 158 /* PropertySignature */ ||
                node.kind === 161 /* MethodDeclaration */ ||
                node.kind === 160 /* MethodSignature */ ||
                node.kind === 163 /* GetAccessor */ ||
                node.kind === 164 /* SetAccessor */) {
                // it is ok to have member named '_super' or '_this' - member access is always qualified
                return false;
            }
            if (node.flags & 8388608 /* Ambient */) {
                // ambient context - no codegen impact
                return false;
            }
            var root = ts.getRootDeclaration(node);
            if (root.kind === 156 /* Parameter */ && ts.nodeIsMissing(root.parent.body)) {
                // just an overload - no codegen impact
                return false;
            }
            return true;
        }
        // this function will run after checking the source file so 'CaptureThis' is correct for all nodes
        function checkIfThisIsCapturedInEnclosingScope(node) {
            ts.findAncestor(node, function (current) {
                if (getNodeCheckFlags(current) & 4 /* CaptureThis */) {
                    var isDeclaration_1 = node.kind !== 75 /* Identifier */;
                    if (isDeclaration_1) {
                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference);
                    }
                    return true;
                }
                return false;
            });
        }
        function checkIfNewTargetIsCapturedInEnclosingScope(node) {
            ts.findAncestor(node, function (current) {
                if (getNodeCheckFlags(current) & 8 /* CaptureNewTarget */) {
                    var isDeclaration_2 = node.kind !== 75 /* Identifier */;
                    if (isDeclaration_2) {
                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference);
                    }
                    return true;
                }
                return false;
            });
        }
        function checkWeakMapCollision(node) {
            var enclosingBlockScope = ts.getEnclosingBlockScopeContainer(node);
            if (getNodeCheckFlags(enclosingBlockScope) & 67108864 /* ContainsClassWithPrivateIdentifiers */) {
                error(node, ts.Diagnostics.Compiler_reserves_name_0_when_emitting_private_identifier_downlevel, "WeakMap");
            }
        }
        function checkCollisionWithRequireExportsInGeneratedCode(node, name) {
            // No need to check for require or exports for ES6 modules and later
            if (moduleKind >= ts.ModuleKind.ES2015 || compilerOptions.noEmit) {
                return;
            }
            if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (ts.isModuleDeclaration(node) && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                return;
            }
            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
            var parent = getDeclarationContainer(node);
            if (parent.kind === 290 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent)) {
                // If the declaration happens to be in external module, report error that require and exports are reserved keywords
                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
            }
        }
        function checkCollisionWithGlobalPromiseInGeneratedCode(node, name) {
            if (languageVersion >= 4 /* ES2017 */ || compilerOptions.noEmit || !needCollisionCheckForIdentifier(node, name, "Promise")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (ts.isModuleDeclaration(node) && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                return;
            }
            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
            var parent = getDeclarationContainer(node);
            if (parent.kind === 290 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent) && parent.flags & 2048 /* HasAsyncFunctions */) {
                // If the declaration happens to be in external module, report error that Promise is a reserved identifier.
                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions, ts.declarationNameToString(name), ts.declarationNameToString(name));
            }
        }
        function checkVarDeclaredNamesNotShadowed(node) {
            // - ScriptBody : StatementList
            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
            // also occurs in the VarDeclaredNames of StatementList.
            // - Block : { StatementList }
            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
            // also occurs in the VarDeclaredNames of StatementList.
            // Variable declarations are hoisted to the top of their function scope. They can shadow
            // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition
            // by the binder as the declaration scope is different.
            // A non-initialized declaration is a no-op as the block declaration will resolve before the var
            // declaration. the problem is if the declaration has an initializer. this will act as a write to the
            // block declared value. this is fine for let, but not const.
            // Only consider declarations with initializers, uninitialized const declarations will not
            // step on a let/const variable.
            // Do not consider const and const declarations, as duplicate block-scoped declarations
            // are handled by the binder.
            // We are only looking for const declarations that step on let\const declarations from a
            // different scope. e.g.:
            //      {
            //          const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
            //          const x = 0; // symbol for this declaration will be 'symbol'
            //      }
            // skip block-scoped variables and parameters
            if ((ts.getCombinedNodeFlags(node) & 3 /* BlockScoped */) !== 0 || ts.isParameterDeclaration(node)) {
                return;
            }
            // skip variable declarations that don't have initializers
            // NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern
            // so we'll always treat binding elements as initialized
            if (node.kind === 242 /* VariableDeclaration */ && !node.initializer) {
                return;
            }
            var symbol = getSymbolOfNode(node);
            if (symbol.flags & 1 /* FunctionScopedVariable */) {
                if (!ts.isIdentifier(node.name))
                    return ts.Debug.fail();
                var localDeclarationSymbol = resolveName(node, node.name.escapedText, 3 /* Variable */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
                if (localDeclarationSymbol &&
                    localDeclarationSymbol !== symbol &&
                    localDeclarationSymbol.flags & 2 /* BlockScopedVariable */) {
                    if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & 3 /* BlockScoped */) {
                        var varDeclList = ts.getAncestor(localDeclarationSymbol.valueDeclaration, 243 /* VariableDeclarationList */);
                        var container = varDeclList.parent.kind === 225 /* VariableStatement */ && varDeclList.parent.parent
                            ? varDeclList.parent.parent
                            : undefined;
                        // names of block-scoped and function scoped variables can collide only
                        // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
                        var namesShareScope = container &&
                            (container.kind === 223 /* Block */ && ts.isFunctionLike(container.parent) ||
                                container.kind === 250 /* ModuleBlock */ ||
                                container.kind === 249 /* ModuleDeclaration */ ||
                                container.kind === 290 /* SourceFile */);
                        // here we know that function scoped variable is shadowed by block scoped one
                        // if they are defined in the same scope - binder has already reported redeclaration error
                        // otherwise if variable has an initializer - show error that initialization will fail
                        // since LHS will be block scoped name instead of function scoped
                        if (!namesShareScope) {
                            var name = symbolToString(localDeclarationSymbol);
                            error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
                        }
                    }
                }
            }
        }
        function convertAutoToAny(type) {
            return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type;
        }
        // Check variable, parameter, or property declaration
        function checkVariableLikeDeclaration(node) {
            checkDecorators(node);
            if (!ts.isBindingElement(node)) {
                checkSourceElement(node.type);
            }
            // JSDoc `function(string, string): string` syntax results in parameters with no name
            if (!node.name) {
                return;
            }
            // For a computed property, just check the initializer and exit
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 154 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
                if (node.initializer) {
                    checkExpressionCached(node.initializer);
                }
            }
            if (node.kind === 191 /* BindingElement */) {
                if (node.parent.kind === 189 /* ObjectBindingPattern */ && languageVersion < 99 /* ESNext */) {
                    checkExternalEmitHelpers(node, 4 /* Rest */);
                }
                // check computed properties inside property names of binding elements
                if (node.propertyName && node.propertyName.kind === 154 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.propertyName);
                }
                // check private/protected variable access
                var parent = node.parent.parent;
                var parentType = getTypeForBindingElementParent(parent);
                var name = node.propertyName || node.name;
                if (parentType && !ts.isBindingPattern(name)) {
                    var exprType = getLiteralTypeFromPropertyName(name);
                    if (isTypeUsableAsPropertyName(exprType)) {
                        var nameText = getPropertyNameFromType(exprType);
                        var property = getPropertyOfType(parentType, nameText);
                        if (property) {
                            markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
                            checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === 102 /* SuperKeyword */, parentType, property);
                        }
                    }
                }
            }
            // For a binding pattern, check contained binding elements
            if (ts.isBindingPattern(node.name)) {
                if (node.name.kind === 190 /* ArrayBindingPattern */ && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                    checkExternalEmitHelpers(node, 512 /* Read */);
                }
                ts.forEach(node.name.elements, checkSourceElement);
            }
            // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body
            if (node.initializer && ts.getRootDeclaration(node).kind === 156 /* Parameter */ && ts.nodeIsMissing(ts.getContainingFunction(node).body)) {
                error(node, ts.Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation);
                return;
            }
            // For a binding pattern, validate the initializer and exit
            if (ts.isBindingPattern(node.name)) {
                var needCheckInitializer = node.initializer && node.parent.parent.kind !== 231 /* ForInStatement */;
                var needCheckWidenedType = node.name.elements.length === 0;
                if (needCheckInitializer || needCheckWidenedType) {
                    // Don't validate for-in initializer as it is already an error
                    var widenedType = getWidenedTypeForVariableLikeDeclaration(node);
                    if (needCheckInitializer) {
                        var initializerType = checkExpressionCached(node.initializer);
                        if (strictNullChecks && needCheckWidenedType) {
                            checkNonNullNonVoidType(initializerType, node);
                        }
                        else {
                            checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
                        }
                    }
                    // check the binding pattern with empty elements
                    if (needCheckWidenedType) {
                        if (ts.isArrayBindingPattern(node.name)) {
                            checkIteratedTypeOrElementType(65 /* Destructuring */, widenedType, undefinedType, node);
                        }
                        else if (strictNullChecks) {
                            checkNonNullNonVoidType(widenedType, node);
                        }
                    }
                }
                return;
            }
            var symbol = getSymbolOfNode(node);
            var type = convertAutoToAny(getTypeOfSymbol(symbol));
            if (node === symbol.valueDeclaration) {
                // Node is the primary declaration of the symbol, just validate the initializer
                // Don't validate for-in initializer as it is already an error
                var initializer = ts.getEffectiveInitializer(node);
                if (initializer) {
                    var isJSObjectLiteralInitializer = ts.isInJSFile(node) &&
                        ts.isObjectLiteralExpression(initializer) &&
                        (initializer.properties.length === 0 || ts.isPrototypeAccess(node.name)) &&
                        ts.hasEntries(symbol.exports);
                    if (!isJSObjectLiteralInitializer && node.parent.parent.kind !== 231 /* ForInStatement */) {
                        checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(initializer), type, node, initializer, /*headMessage*/ undefined);
                    }
                }
                if (symbol.declarations.length > 1) {
                    if (ts.some(symbol.declarations, function (d) { return d !== node && ts.isVariableLike(d) && !areDeclarationFlagsIdentical(d, node); })) {
                        error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
                    }
                }
            }
            else {
                // Node is a secondary declaration, check that type is identical to primary declaration and check that
                // initializer is consistent with type associated with the node
                var declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
                if (type !== errorType && declarationType !== errorType &&
                    !isTypeIdenticalTo(type, declarationType) &&
                    !(symbol.flags & 67108864 /* Assignment */)) {
                    errorNextVariableOrPropertyDeclarationMustHaveSameType(symbol.valueDeclaration, type, node, declarationType);
                }
                if (node.initializer) {
                    checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(node.initializer), declarationType, node, node.initializer, /*headMessage*/ undefined);
                }
                if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) {
                    error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
                }
            }
            if (node.kind !== 159 /* PropertyDeclaration */ && node.kind !== 158 /* PropertySignature */) {
                // We know we don't have a binding pattern or computed name here
                checkExportsOnMergedDeclarations(node);
                if (node.kind === 242 /* VariableDeclaration */ || node.kind === 191 /* BindingElement */) {
                    checkVarDeclaredNamesNotShadowed(node);
                }
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                if (!compilerOptions.noEmit && languageVersion < 99 /* ESNext */ && needCollisionCheckForIdentifier(node, node.name, "WeakMap")) {
                    potentialWeakMapCollisions.push(node);
                }
            }
        }
        function errorNextVariableOrPropertyDeclarationMustHaveSameType(firstDeclaration, firstType, nextDeclaration, nextType) {
            var nextDeclarationName = ts.getNameOfDeclaration(nextDeclaration);
            var message = nextDeclaration.kind === 159 /* PropertyDeclaration */ || nextDeclaration.kind === 158 /* PropertySignature */
                ? ts.Diagnostics.Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2
                : ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2;
            var declName = ts.declarationNameToString(nextDeclarationName);
            var err = error(nextDeclarationName, message, declName, typeToString(firstType), typeToString(nextType));
            if (firstDeclaration) {
                ts.addRelatedInfo(err, ts.createDiagnosticForNode(firstDeclaration, ts.Diagnostics._0_was_also_declared_here, declName));
            }
        }
        function areDeclarationFlagsIdentical(left, right) {
            if ((left.kind === 156 /* Parameter */ && right.kind === 242 /* VariableDeclaration */) ||
                (left.kind === 242 /* VariableDeclaration */ && right.kind === 156 /* Parameter */)) {
                // Differences in optionality between parameters and variables are allowed.
                return true;
            }
            if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) {
                return false;
            }
            var interestingFlags = 8 /* Private */ |
                16 /* Protected */ |
                256 /* Async */ |
                128 /* Abstract */ |
                64 /* Readonly */ |
                32 /* Static */;
            return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags);
        }
        function checkVariableDeclaration(node) {
            checkGrammarVariableDeclaration(node);
            return checkVariableLikeDeclaration(node);
        }
        function checkBindingElement(node) {
            checkGrammarBindingElement(node);
            return checkVariableLikeDeclaration(node);
        }
        function checkVariableStatement(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarVariableDeclarationList(node.declarationList))
                checkGrammarForDisallowedLetOrConstStatement(node);
            ts.forEach(node.declarationList.declarations, checkSourceElement);
        }
        function checkExpressionStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkExpression(node.expression);
        }
        function checkIfStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            var type = checkTruthinessExpression(node.expression);
            checkTestingKnownTruthyCallableType(node.expression, node.thenStatement, type);
            checkSourceElement(node.thenStatement);
            if (node.thenStatement.kind === 224 /* EmptyStatement */) {
                error(node.thenStatement, ts.Diagnostics.The_body_of_an_if_statement_cannot_be_the_empty_statement);
            }
            checkSourceElement(node.elseStatement);
        }
        function checkTestingKnownTruthyCallableType(condExpr, body, type) {
            if (!strictNullChecks) {
                return;
            }
            var testedNode = ts.isIdentifier(condExpr)
                ? condExpr
                : ts.isPropertyAccessExpression(condExpr)
                    ? condExpr.name
                    : undefined;
            if (!testedNode) {
                return;
            }
            var possiblyFalsy = getFalsyFlags(type);
            if (possiblyFalsy) {
                return;
            }
            // While it technically should be invalid for any known-truthy value
            // to be tested, we de-scope to functions unrefenced in the block as a
            // heuristic to identify the most common bugs. There are too many
            // false positives for values sourced from type definitions without
            // strictNullChecks otherwise.
            var callSignatures = getSignaturesOfType(type, 0 /* Call */);
            if (callSignatures.length === 0) {
                return;
            }
            var testedFunctionSymbol = getSymbolAtLocation(testedNode);
            if (!testedFunctionSymbol) {
                return;
            }
            var functionIsUsedInBody = ts.forEachChild(body, function check(childNode) {
                if (ts.isIdentifier(childNode)) {
                    var childSymbol = getSymbolAtLocation(childNode);
                    if (childSymbol && childSymbol === testedFunctionSymbol) {
                        // If the test was a simple identifier, the above check is sufficient
                        if (ts.isIdentifier(condExpr)) {
                            return true;
                        }
                        // Otherwise we need to ensure the symbol is called on the same target
                        var testedExpression = testedNode.parent;
                        var childExpression = childNode.parent;
                        while (testedExpression && childExpression) {
                            if (ts.isIdentifier(testedExpression) && ts.isIdentifier(childExpression) ||
                                testedExpression.kind === 104 /* ThisKeyword */ && childExpression.kind === 104 /* ThisKeyword */) {
                                return getSymbolAtLocation(testedExpression) === getSymbolAtLocation(childExpression);
                            }
                            if (ts.isPropertyAccessExpression(testedExpression) && ts.isPropertyAccessExpression(childExpression)) {
                                if (getSymbolAtLocation(testedExpression.name) !== getSymbolAtLocation(childExpression.name)) {
                                    return false;
                                }
                                childExpression = childExpression.expression;
                                testedExpression = testedExpression.expression;
                            }
                            else {
                                return false;
                            }
                        }
                    }
                }
                return ts.forEachChild(childNode, check);
            });
            if (!functionIsUsedInBody) {
                error(condExpr, ts.Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead);
            }
        }
        function checkDoStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkSourceElement(node.statement);
            checkTruthinessExpression(node.expression);
        }
        function checkWhileStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkTruthinessExpression(node.expression);
            checkSourceElement(node.statement);
        }
        function checkTruthinessOfType(type, node) {
            if (type.flags & 16384 /* Void */) {
                error(node, ts.Diagnostics.An_expression_of_type_void_cannot_be_tested_for_truthiness);
            }
            return type;
        }
        function checkTruthinessExpression(node, checkMode) {
            return checkTruthinessOfType(checkExpression(node, checkMode), node);
        }
        function checkForStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.initializer && node.initializer.kind === 243 /* VariableDeclarationList */) {
                    checkGrammarVariableDeclarationList(node.initializer);
                }
            }
            if (node.initializer) {
                if (node.initializer.kind === 243 /* VariableDeclarationList */) {
                    ts.forEach(node.initializer.declarations, checkVariableDeclaration);
                }
                else {
                    checkExpression(node.initializer);
                }
            }
            if (node.condition)
                checkTruthinessExpression(node.condition);
            if (node.incrementor)
                checkExpression(node.incrementor);
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForOfStatement(node) {
            checkGrammarForInOrForOfStatement(node);
            if (node.awaitModifier) {
                var functionFlags = ts.getFunctionFlags(ts.getContainingFunction(node));
                if ((functionFlags & (4 /* Invalid */ | 2 /* Async */)) === 2 /* Async */ && languageVersion < 99 /* ESNext */) {
                    // for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper
                    checkExternalEmitHelpers(node, 32768 /* ForAwaitOfIncludes */);
                }
            }
            else if (compilerOptions.downlevelIteration && languageVersion < 2 /* ES2015 */) {
                // for..of prior to ES2015 requires the __values helper when downlevelIteration is enabled
                checkExternalEmitHelpers(node, 256 /* ForOfIncludes */);
            }
            // Check the LHS and RHS
            // If the LHS is a declaration, just check it as a variable declaration, which will in turn check the RHS
            // via checkRightHandSideOfForOf.
            // If the LHS is an expression, check the LHS, as a destructuring assignment or as a reference.
            // Then check that the RHS is assignable to it.
            if (node.initializer.kind === 243 /* VariableDeclarationList */) {
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                var varExpr = node.initializer;
                var iteratedType = checkRightHandSideOfForOf(node);
                // There may be a destructuring assignment on the left side
                if (varExpr.kind === 192 /* ArrayLiteralExpression */ || varExpr.kind === 193 /* ObjectLiteralExpression */) {
                    // iteratedType may be undefined. In this case, we still want to check the structure of
                    // varExpr, in particular making sure it's a valid LeftHandSideExpression. But we'd like
                    // to short circuit the type relation checking as much as possible, so we pass the unknownType.
                    checkDestructuringAssignment(varExpr, iteratedType || errorType);
                }
                else {
                    var leftType = checkExpression(varExpr);
                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access);
                    // iteratedType will be undefined if the rightType was missing properties/signatures
                    // required to get its iteratedType (like [Symbol.iterator] or next). This may be
                    // because we accessed properties from anyType, or it may have led to an error inside
                    // getElementTypeOfIterable.
                    if (iteratedType) {
                        checkTypeAssignableToAndOptionallyElaborate(iteratedType, leftType, varExpr, node.expression);
                    }
                }
            }
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForInStatement(node) {
            // Grammar checking
            checkGrammarForInOrForOfStatement(node);
            var rightType = getNonNullableTypeIfNeeded(checkExpression(node.expression));
            // TypeScript 1.0 spec (April 2014): 5.4
            // In a 'for-in' statement of the form
            // for (let VarDecl in Expr) Statement
            //   VarDecl must be a variable declaration without a type annotation that declares a variable of type Any,
            //   and Expr must be an expression of type Any, an object type, or a type parameter type.
            if (node.initializer.kind === 243 /* VariableDeclarationList */) {
                var variable = node.initializer.declarations[0];
                if (variable && ts.isBindingPattern(variable.name)) {
                    error(variable.name, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                // In a 'for-in' statement of the form
                // for (Var in Expr) Statement
                //   Var must be an expression classified as a reference of type Any or the String primitive type,
                //   and Expr must be an expression of type Any, an object type, or a type parameter type.
                var varExpr = node.initializer;
                var leftType = checkExpression(varExpr);
                if (varExpr.kind === 192 /* ArrayLiteralExpression */ || varExpr.kind === 193 /* ObjectLiteralExpression */) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
                }
                else {
                    // run check only former check succeeded to avoid cascading errors
                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access);
                }
            }
            // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
            // in this case error about missing name is already reported - do not report extra one
            if (rightType === neverType || !isTypeAssignableToKind(rightType, 67108864 /* NonPrimitive */ | 58982400 /* InstantiableNonPrimitive */)) {
                error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0, typeToString(rightType));
            }
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForInOrForOfVariableDeclaration(iterationStatement) {
            var variableDeclarationList = iterationStatement.initializer;
            // checkGrammarForInOrForOfStatement will check that there is exactly one declaration.
            if (variableDeclarationList.declarations.length >= 1) {
                var decl = variableDeclarationList.declarations[0];
                checkVariableDeclaration(decl);
            }
        }
        function checkRightHandSideOfForOf(statement) {
            var use = statement.awaitModifier ? 15 /* ForAwaitOf */ : 13 /* ForOf */;
            return checkIteratedTypeOrElementType(use, checkNonNullExpression(statement.expression), undefinedType, statement.expression);
        }
        function checkIteratedTypeOrElementType(use, inputType, sentType, errorNode) {
            if (isTypeAny(inputType)) {
                return inputType;
            }
            return getIteratedTypeOrElementType(use, inputType, sentType, errorNode, /*checkAssignability*/ true) || anyType;
        }
        /**
         * When consuming an iterable type in a for..of, spread, or iterator destructuring assignment
         * we want to get the iterated type of an iterable for ES2015 or later, or the iterated type
         * of a iterable (if defined globally) or element type of an array like for ES2015 or earlier.
         */
        function getIteratedTypeOrElementType(use, inputType, sentType, errorNode, checkAssignability) {
            var allowAsyncIterables = (use & 2 /* AllowsAsyncIterablesFlag */) !== 0;
            if (inputType === neverType) {
                reportTypeNotIterableError(errorNode, inputType, allowAsyncIterables); // TODO: GH#18217
                return undefined;
            }
            var uplevelIteration = languageVersion >= 2 /* ES2015 */;
            var downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration;
            // Get the iterated type of an `Iterable<T>` or `IterableIterator<T>` only in ES2015
            // or higher, when inside of an async generator or for-await-if, or when
            // downlevelIteration is requested.
            if (uplevelIteration || downlevelIteration || allowAsyncIterables) {
                // We only report errors for an invalid iterable type in ES2015 or higher.
                var iterationTypes = getIterationTypesOfIterable(inputType, use, uplevelIteration ? errorNode : undefined);
                if (checkAssignability) {
                    if (iterationTypes) {
                        var diagnostic = use & 8 /* ForOfFlag */ ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_send_0 :
                            use & 32 /* SpreadFlag */ ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_always_send_0 :
                                use & 64 /* DestructuringFlag */ ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring_will_always_send_0 :
                                    use & 16 /* YieldStarFlag */ ? ts.Diagnostics.Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_containing_generator_will_always_send_0 :
                                        undefined;
                        if (diagnostic) {
                            checkTypeAssignableTo(sentType, iterationTypes.nextType, errorNode, diagnostic);
                        }
                    }
                }
                if (iterationTypes || uplevelIteration) {
                    return iterationTypes && iterationTypes.yieldType;
                }
            }
            var arrayType = inputType;
            var reportedError = false;
            var hasStringConstituent = false;
            // If strings are permitted, remove any string-like constituents from the array type.
            // This allows us to find other non-string element types from an array unioned with
            // a string.
            if (use & 4 /* AllowsStringInputFlag */) {
                if (arrayType.flags & 1048576 /* Union */) {
                    // After we remove all types that are StringLike, we will know if there was a string constituent
                    // based on whether the result of filter is a new array.
                    var arrayTypes = inputType.types;
                    var filteredTypes = ts.filter(arrayTypes, function (t) { return !(t.flags & 132 /* StringLike */); });
                    if (filteredTypes !== arrayTypes) {
                        arrayType = getUnionType(filteredTypes, 2 /* Subtype */);
                    }
                }
                else if (arrayType.flags & 132 /* StringLike */) {
                    arrayType = neverType;
                }
                hasStringConstituent = arrayType !== inputType;
                if (hasStringConstituent) {
                    if (languageVersion < 1 /* ES5 */) {
                        if (errorNode) {
                            error(errorNode, ts.Diagnostics.Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher);
                            reportedError = true;
                        }
                    }
                    // Now that we've removed all the StringLike types, if no constituents remain, then the entire
                    // arrayOrStringType was a string.
                    if (arrayType.flags & 131072 /* Never */) {
                        return stringType;
                    }
                }
            }
            if (!isArrayLikeType(arrayType)) {
                if (errorNode && !reportedError) {
                    // Which error we report depends on whether we allow strings or if there was a
                    // string constituent. For example, if the input type is number | string, we
                    // want to say that number is not an array type. But if the input was just
                    // number and string input is allowed, we want to say that number is not an
                    // array type or a string type.
                    var yieldType = getIterationTypeOfIterable(use, 0 /* Yield */, inputType, /*errorNode*/ undefined);
                    var _a = !(use & 4 /* AllowsStringInputFlag */) || hasStringConstituent
                        ? downlevelIteration
                            ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]
                            : yieldType
                                ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false]
                                : [ts.Diagnostics.Type_0_is_not_an_array_type, true]
                        : downlevelIteration
                            ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]
                            : yieldType
                                ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false]
                                : [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, true], defaultDiagnostic = _a[0], maybeMissingAwait = _a[1];
                    errorAndMaybeSuggestAwait(errorNode, maybeMissingAwait && !!getAwaitedTypeOfPromise(arrayType), defaultDiagnostic, typeToString(arrayType));
                }
                return hasStringConstituent ? stringType : undefined;
            }
            var arrayElementType = getIndexTypeOfType(arrayType, 1 /* Number */);
            if (hasStringConstituent && arrayElementType) {
                // This is just an optimization for the case where arrayOrStringType is string | string[]
                if (arrayElementType.flags & 132 /* StringLike */) {
                    return stringType;
                }
                return getUnionType([arrayElementType, stringType], 2 /* Subtype */);
            }
            return arrayElementType;
        }
        /**
         * Gets the requested "iteration type" from an `Iterable`-like or `AsyncIterable`-like type.
         */
        function getIterationTypeOfIterable(use, typeKind, inputType, errorNode) {
            if (isTypeAny(inputType)) {
                return undefined;
            }
            var iterationTypes = getIterationTypesOfIterable(inputType, use, errorNode);
            return iterationTypes && iterationTypes[getIterationTypesKeyFromIterationTypeKind(typeKind)];
        }
        function createIterationTypes(yieldType, returnType, nextType) {
            // `yieldType` and `returnType` are defaulted to `neverType` they each will be combined
            // via `getUnionType` when merging iteration types. `nextType` is defined as `unknownType`
            // as it is combined via `getIntersectionType` when merging iteration types.
            if (yieldType === void 0) { yieldType = neverType; }
            if (returnType === void 0) { returnType = neverType; }
            if (nextType === void 0) { nextType = unknownType; }
            // Use the cache only for intrinsic types to keep it small as they are likely to be
            // more frequently created (i.e. `Iterator<number, void, unknown>`). Iteration types
            // are also cached on the type they are requested for, so we shouldn't need to maintain
            // the cache for less-frequently used types.
            if (yieldType.flags & 67359327 /* Intrinsic */ &&
                returnType.flags & (1 /* Any */ | 131072 /* Never */ | 2 /* Unknown */ | 16384 /* Void */ | 32768 /* Undefined */) &&
                nextType.flags & (1 /* Any */ | 131072 /* Never */ | 2 /* Unknown */ | 16384 /* Void */ | 32768 /* Undefined */)) {
                var id = getTypeListId([yieldType, returnType, nextType]);
                var iterationTypes = iterationTypesCache.get(id);
                if (!iterationTypes) {
                    iterationTypes = { yieldType: yieldType, returnType: returnType, nextType: nextType };
                    iterationTypesCache.set(id, iterationTypes);
                }
                return iterationTypes;
            }
            return { yieldType: yieldType, returnType: returnType, nextType: nextType };
        }
        /**
         * Combines multiple `IterationTypes` records.
         *
         * If `array` is empty or all elements are missing or are references to `noIterationTypes`,
         * then `noIterationTypes` is returned. Otherwise, an `IterationTypes` record is returned
         * for the combined iteration types.
         */
        function combineIterationTypes(array) {
            var yieldTypes;
            var returnTypes;
            var nextTypes;
            for (var _i = 0, array_10 = array; _i < array_10.length; _i++) {
                var iterationTypes = array_10[_i];
                if (iterationTypes === undefined || iterationTypes === noIterationTypes) {
                    continue;
                }
                if (iterationTypes === anyIterationTypes) {
                    return anyIterationTypes;
                }
                yieldTypes = ts.append(yieldTypes, iterationTypes.yieldType);
                returnTypes = ts.append(returnTypes, iterationTypes.returnType);
                nextTypes = ts.append(nextTypes, iterationTypes.nextType);
            }
            if (yieldTypes || returnTypes || nextTypes) {
                return createIterationTypes(yieldTypes && getUnionType(yieldTypes), returnTypes && getUnionType(returnTypes), nextTypes && getIntersectionType(nextTypes));
            }
            return noIterationTypes;
        }
        function getCachedIterationTypes(type, cacheKey) {
            return type[cacheKey];
        }
        function setCachedIterationTypes(type, cacheKey, cachedTypes) {
            return type[cacheKey] = cachedTypes;
        }
        /**
         * Gets the *yield*, *return*, and *next* types from an `Iterable`-like or `AsyncIterable`-like type.
         *
         * At every level that involves analyzing return types of signatures, we union the return types of all the signatures.
         *
         * Another thing to note is that at any step of this process, we could run into a dead end,
         * meaning either the property is missing, or we run into the anyType. If either of these things
         * happens, we return `undefined` to signal that we could not find the iteration type. If a property
         * is missing, and the previous step did not result in `any`, then we also give an error if the
         * caller requested it. Then the caller can decide what to do in the case where there is no iterated
         * type.
         *
         * For a **for-of** statement, `yield*` (in a normal generator), spread, array
         * destructuring, or normal generator we will only ever look for a `[Symbol.iterator]()`
         * method.
         *
         * For an async generator we will only ever look at the `[Symbol.asyncIterator]()` method.
         *
         * For a **for-await-of** statement or a `yield*` in an async generator we will look for
         * the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method.
         */
        function getIterationTypesOfIterable(type, use, errorNode) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            if (!(type.flags & 1048576 /* Union */)) {
                var iterationTypes_1 = getIterationTypesOfIterableWorker(type, use, errorNode);
                if (iterationTypes_1 === noIterationTypes) {
                    if (errorNode) {
                        reportTypeNotIterableError(errorNode, type, !!(use & 2 /* AllowsAsyncIterablesFlag */));
                    }
                    return undefined;
                }
                return iterationTypes_1;
            }
            var cacheKey = use & 2 /* AllowsAsyncIterablesFlag */ ? "iterationTypesOfAsyncIterable" : "iterationTypesOfIterable";
            var cachedTypes = getCachedIterationTypes(type, cacheKey);
            if (cachedTypes)
                return cachedTypes === noIterationTypes ? undefined : cachedTypes;
            var allIterationTypes;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var constituent = _a[_i];
                var iterationTypes_2 = getIterationTypesOfIterableWorker(constituent, use, errorNode);
                if (iterationTypes_2 === noIterationTypes) {
                    if (errorNode) {
                        reportTypeNotIterableError(errorNode, type, !!(use & 2 /* AllowsAsyncIterablesFlag */));
                        errorNode = undefined;
                    }
                }
                else {
                    allIterationTypes = ts.append(allIterationTypes, iterationTypes_2);
                }
            }
            var iterationTypes = allIterationTypes ? combineIterationTypes(allIterationTypes) : noIterationTypes;
            setCachedIterationTypes(type, cacheKey, iterationTypes);
            return iterationTypes === noIterationTypes ? undefined : iterationTypes;
        }
        function getAsyncFromSyncIterationTypes(iterationTypes, errorNode) {
            if (iterationTypes === noIterationTypes)
                return noIterationTypes;
            if (iterationTypes === anyIterationTypes)
                return anyIterationTypes;
            var yieldType = iterationTypes.yieldType, returnType = iterationTypes.returnType, nextType = iterationTypes.nextType;
            return createIterationTypes(getAwaitedType(yieldType, errorNode) || anyType, getAwaitedType(returnType, errorNode) || anyType, nextType);
        }
        /**
         * Gets the *yield*, *return*, and *next* types from a non-union type.
         *
         * If we are unable to find the *yield*, *return*, and *next* types, `noIterationTypes` is
         * returned to indicate to the caller that it should report an error. Otherwise, an
         * `IterationTypes` record is returned.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterable` instead.
         */
        function getIterationTypesOfIterableWorker(type, use, errorNode) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            if (use & 2 /* AllowsAsyncIterablesFlag */) {
                var iterationTypes = getIterationTypesOfIterableCached(type, asyncIterationTypesResolver) ||
                    getIterationTypesOfIterableFast(type, asyncIterationTypesResolver);
                if (iterationTypes) {
                    return iterationTypes;
                }
            }
            if (use & 1 /* AllowsSyncIterablesFlag */) {
                var iterationTypes = getIterationTypesOfIterableCached(type, syncIterationTypesResolver) ||
                    getIterationTypesOfIterableFast(type, syncIterationTypesResolver);
                if (iterationTypes) {
                    if (use & 2 /* AllowsAsyncIterablesFlag */) {
                        // for a sync iterable in an async context, only use the cached types if they are valid.
                        if (iterationTypes !== noIterationTypes) {
                            return setCachedIterationTypes(type, "iterationTypesOfAsyncIterable", getAsyncFromSyncIterationTypes(iterationTypes, errorNode));
                        }
                    }
                    else {
                        return iterationTypes;
                    }
                }
            }
            if (use & 2 /* AllowsAsyncIterablesFlag */) {
                var iterationTypes = getIterationTypesOfIterableSlow(type, asyncIterationTypesResolver, errorNode);
                if (iterationTypes !== noIterationTypes) {
                    return iterationTypes;
                }
            }
            if (use & 1 /* AllowsSyncIterablesFlag */) {
                var iterationTypes = getIterationTypesOfIterableSlow(type, syncIterationTypesResolver, errorNode);
                if (iterationTypes !== noIterationTypes) {
                    if (use & 2 /* AllowsAsyncIterablesFlag */) {
                        return setCachedIterationTypes(type, "iterationTypesOfAsyncIterable", iterationTypes
                            ? getAsyncFromSyncIterationTypes(iterationTypes, errorNode)
                            : noIterationTypes);
                    }
                    else {
                        return iterationTypes;
                    }
                }
            }
            return noIterationTypes;
        }
        /**
         * Gets the *yield*, *return*, and *next* types of an `Iterable`-like or
         * `AsyncIterable`-like type from the cache.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterable` instead.
         */
        function getIterationTypesOfIterableCached(type, resolver) {
            return getCachedIterationTypes(type, resolver.iterableCacheKey);
        }
        function getIterationTypesOfGlobalIterableType(globalType, resolver) {
            var globalIterationTypes = getIterationTypesOfIterableCached(globalType, resolver) ||
                getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
            return globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
        }
        /**
         * Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
         * type from from common heuristics.
         *
         * If we previously analyzed this type and found no iteration types, `noIterationTypes` is
         * returned. If we found iteration types, an `IterationTypes` record is returned.
         * Otherwise, we return `undefined` to indicate to the caller it should perform a more
         * exhaustive analysis.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterable` instead.
         */
        function getIterationTypesOfIterableFast(type, resolver) {
            // As an optimization, if the type is an instantiation of one of the following global types, then
            // just grab its related type argument:
            // - `Iterable<T>` or `AsyncIterable<T>`
            // - `IterableIterator<T>` or `AsyncIterableIterator<T>`
            var globalType;
            if (isReferenceToType(type, globalType = resolver.getGlobalIterableType(/*reportErrors*/ false)) ||
                isReferenceToType(type, globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false))) {
                var yieldType = getTypeArguments(type)[0];
                // The "return" and "next" types of `Iterable` and `IterableIterator` are defined by the
                // iteration types of their `[Symbol.iterator]()` method. The same is true for their async cousins.
                // While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use
                // different definitions.
                var _a = getIterationTypesOfGlobalIterableType(globalType, resolver), returnType = _a.returnType, nextType = _a.nextType;
                return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(yieldType, returnType, nextType));
            }
            // As an optimization, if the type is an instantiation of the following global type, then
            // just grab its related type arguments:
            // - `Generator<T, TReturn, TNext>` or `AsyncGenerator<T, TReturn, TNext>`
            if (isReferenceToType(type, resolver.getGlobalGeneratorType(/*reportErrors*/ false))) {
                var _b = getTypeArguments(type), yieldType = _b[0], returnType = _b[1], nextType = _b[2];
                return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(yieldType, returnType, nextType));
            }
        }
        /**
         * Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
         * type from its members.
         *
         * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
         * record is returned. Otherwise, `noIterationTypes` is returned.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterable` instead.
         */
        function getIterationTypesOfIterableSlow(type, resolver, errorNode) {
            var _a;
            var method = getPropertyOfType(type, ts.getPropertyNameForKnownSymbolName(resolver.iteratorSymbolName));
            var methodType = method && !(method.flags & 16777216 /* Optional */) ? getTypeOfSymbol(method) : undefined;
            if (isTypeAny(methodType)) {
                return setCachedIterationTypes(type, resolver.iterableCacheKey, anyIterationTypes);
            }
            var signatures = methodType ? getSignaturesOfType(methodType, 0 /* Call */) : undefined;
            if (!ts.some(signatures)) {
                return setCachedIterationTypes(type, resolver.iterableCacheKey, noIterationTypes);
            }
            var iteratorType = getUnionType(ts.map(signatures, getReturnTypeOfSignature), 2 /* Subtype */);
            var iterationTypes = (_a = getIterationTypesOfIterator(iteratorType, resolver, errorNode)) !== null && _a !== void 0 ? _a : noIterationTypes;
            return setCachedIterationTypes(type, resolver.iterableCacheKey, iterationTypes);
        }
        function reportTypeNotIterableError(errorNode, type, allowAsyncIterables) {
            var message = allowAsyncIterables
                ? ts.Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
                : ts.Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator;
            errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), message, typeToString(type));
        }
        /**
         * Gets the *yield*, *return*, and *next* types from an `Iterator`-like or `AsyncIterator`-like type.
         *
         * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
         * record is returned. Otherwise, `undefined` is returned.
         */
        function getIterationTypesOfIterator(type, resolver, errorNode) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            var iterationTypes = getIterationTypesOfIteratorCached(type, resolver) ||
                getIterationTypesOfIteratorFast(type, resolver) ||
                getIterationTypesOfIteratorSlow(type, resolver, errorNode);
            return iterationTypes === noIterationTypes ? undefined : iterationTypes;
        }
        /**
         * Gets the iteration types of an `Iterator`-like or `AsyncIterator`-like type from the
         * cache.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterator` instead.
         */
        function getIterationTypesOfIteratorCached(type, resolver) {
            return getCachedIterationTypes(type, resolver.iteratorCacheKey);
        }
        /**
         * Gets the iteration types of an `Iterator`-like or `AsyncIterator`-like type from the
         * cache or from common heuristics.
         *
         * If we previously analyzed this type and found no iteration types, `noIterationTypes` is
         * returned. If we found iteration types, an `IterationTypes` record is returned.
         * Otherwise, we return `undefined` to indicate to the caller it should perform a more
         * exhaustive analysis.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterator` instead.
         */
        function getIterationTypesOfIteratorFast(type, resolver) {
            // As an optimization, if the type is an instantiation of one of the following global types,
            // then just grab its related type argument:
            // - `IterableIterator<T>` or `AsyncIterableIterator<T>`
            // - `Iterator<T, TReturn, TNext>` or `AsyncIterator<T, TReturn, TNext>`
            // - `Generator<T, TReturn, TNext>` or `AsyncGenerator<T, TReturn, TNext>`
            var globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false);
            if (isReferenceToType(type, globalType)) {
                var yieldType = getTypeArguments(type)[0];
                // The "return" and "next" types of `IterableIterator` and `AsyncIterableIterator` are defined by the
                // iteration types of their `next`, `return`, and `throw` methods. While we define these as `any`
                // and `undefined` in our libs by default, a custom lib *could* use different definitions.
                var globalIterationTypes = getIterationTypesOfIteratorCached(globalType, resolver) ||
                    getIterationTypesOfIteratorSlow(globalType, resolver, /*errorNode*/ undefined);
                var _a = globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes, returnType = _a.returnType, nextType = _a.nextType;
                return setCachedIterationTypes(type, resolver.iteratorCacheKey, createIterationTypes(yieldType, returnType, nextType));
            }
            if (isReferenceToType(type, resolver.getGlobalIteratorType(/*reportErrors*/ false)) ||
                isReferenceToType(type, resolver.getGlobalGeneratorType(/*reportErrors*/ false))) {
                var _b = getTypeArguments(type), yieldType = _b[0], returnType = _b[1], nextType = _b[2];
                return setCachedIterationTypes(type, resolver.iteratorCacheKey, createIterationTypes(yieldType, returnType, nextType));
            }
        }
        function isIteratorResult(type, kind) {
            // From https://tc39.github.io/ecma262/#sec-iteratorresult-interface:
            // > [done] is the result status of an iterator `next` method call. If the end of the iterator was reached `done` is `true`.
            // > If the end was not reached `done` is `false` and a value is available.
            // > If a `done` property (either own or inherited) does not exist, it is consider to have the value `false`.
            var doneType = getTypeOfPropertyOfType(type, "done") || falseType;
            return isTypeAssignableTo(kind === 0 /* Yield */ ? falseType : trueType, doneType);
        }
        function isYieldIteratorResult(type) {
            return isIteratorResult(type, 0 /* Yield */);
        }
        function isReturnIteratorResult(type) {
            return isIteratorResult(type, 1 /* Return */);
        }
        /**
         * Gets the *yield* and *return* types of an `IteratorResult`-like type.
         *
         * If we are unable to determine a *yield* or a *return* type, `noIterationTypes` is
         * returned to indicate to the caller that it should handle the error. Otherwise, an
         * `IterationTypes` record is returned.
         */
        function getIterationTypesOfIteratorResult(type) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            var cachedTypes = getCachedIterationTypes(type, "iterationTypesOfIteratorResult");
            if (cachedTypes) {
                return cachedTypes;
            }
            // As an optimization, if the type is an instantiation of one of the global `IteratorYieldResult<T>`
            // or `IteratorReturnResult<TReturn>` types, then just grab its type argument.
            if (isReferenceToType(type, getGlobalIteratorYieldResultType(/*reportErrors*/ false))) {
                var yieldType_1 = getTypeArguments(type)[0];
                return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", createIterationTypes(yieldType_1, /*returnType*/ undefined, /*nextType*/ undefined));
            }
            if (isReferenceToType(type, getGlobalIteratorReturnResultType(/*reportErrors*/ false))) {
                var returnType_1 = getTypeArguments(type)[0];
                return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", createIterationTypes(/*yieldType*/ undefined, returnType_1, /*nextType*/ undefined));
            }
            // Choose any constituents that can produce the requested iteration type.
            var yieldIteratorResult = filterType(type, isYieldIteratorResult);
            var yieldType = yieldIteratorResult !== neverType ? getTypeOfPropertyOfType(yieldIteratorResult, "value") : undefined;
            var returnIteratorResult = filterType(type, isReturnIteratorResult);
            var returnType = returnIteratorResult !== neverType ? getTypeOfPropertyOfType(returnIteratorResult, "value") : undefined;
            if (!yieldType && !returnType) {
                return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", noIterationTypes);
            }
            // From https://tc39.github.io/ecma262/#sec-iteratorresult-interface
            // > ... If the iterator does not have a return value, `value` is `undefined`. In that case, the
            // > `value` property may be absent from the conforming object if it does not inherit an explicit
            // > `value` property.
            return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", createIterationTypes(yieldType, returnType || voidType, /*nextType*/ undefined));
        }
        /**
         * Gets the *yield*, *return*, and *next* types of a the `next()`, `return()`, or
         * `throw()` method of an `Iterator`-like or `AsyncIterator`-like type.
         *
         * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
         * record is returned. Otherwise, we return `undefined`.
         */
        function getIterationTypesOfMethod(type, resolver, methodName, errorNode) {
            var method = getPropertyOfType(type, methodName);
            // Ignore 'return' or 'throw' if they are missing.
            if (!method && methodName !== "next") {
                return undefined;
            }
            var methodType = method && !(methodName === "next" && (method.flags & 16777216 /* Optional */))
                ? methodName === "next" ? getTypeOfSymbol(method) : getTypeWithFacts(getTypeOfSymbol(method), 2097152 /* NEUndefinedOrNull */)
                : undefined;
            if (isTypeAny(methodType)) {
                // `return()` and `throw()` don't provide a *next* type.
                return methodName === "next" ? anyIterationTypes : anyIterationTypesExceptNext;
            }
            // Both async and non-async iterators *must* have a `next` method.
            var methodSignatures = methodType ? getSignaturesOfType(methodType, 0 /* Call */) : ts.emptyArray;
            if (methodSignatures.length === 0) {
                if (errorNode) {
                    var diagnostic = methodName === "next"
                        ? resolver.mustHaveANextMethodDiagnostic
                        : resolver.mustBeAMethodDiagnostic;
                    error(errorNode, diagnostic, methodName);
                }
                return methodName === "next" ? anyIterationTypes : undefined;
            }
            // Extract the first parameter and return type of each signature.
            var methodParameterTypes;
            var methodReturnTypes;
            for (var _i = 0, methodSignatures_1 = methodSignatures; _i < methodSignatures_1.length; _i++) {
                var signature = methodSignatures_1[_i];
                if (methodName !== "throw" && ts.some(signature.parameters)) {
                    methodParameterTypes = ts.append(methodParameterTypes, getTypeAtPosition(signature, 0));
                }
                methodReturnTypes = ts.append(methodReturnTypes, getReturnTypeOfSignature(signature));
            }
            // Resolve the *next* or *return* type from the first parameter of a `next()` or
            // `return()` method, respectively.
            var returnTypes;
            var nextType;
            if (methodName !== "throw") {
                var methodParameterType = methodParameterTypes ? getUnionType(methodParameterTypes) : unknownType;
                if (methodName === "next") {
                    // The value of `next(value)` is *not* awaited by async generators
                    nextType = methodParameterType;
                }
                else if (methodName === "return") {
                    // The value of `return(value)` *is* awaited by async generators
                    var resolvedMethodParameterType = resolver.resolveIterationType(methodParameterType, errorNode) || anyType;
                    returnTypes = ts.append(returnTypes, resolvedMethodParameterType);
                }
            }
            // Resolve the *yield* and *return* types from the return type of the method (i.e. `IteratorResult`)
            var yieldType;
            var methodReturnType = methodReturnTypes ? getUnionType(methodReturnTypes, 2 /* Subtype */) : neverType;
            var resolvedMethodReturnType = resolver.resolveIterationType(methodReturnType, errorNode) || anyType;
            var iterationTypes = getIterationTypesOfIteratorResult(resolvedMethodReturnType);
            if (iterationTypes === noIterationTypes) {
                if (errorNode) {
                    error(errorNode, resolver.mustHaveAValueDiagnostic, methodName);
                }
                yieldType = anyType;
                returnTypes = ts.append(returnTypes, anyType);
            }
            else {
                yieldType = iterationTypes.yieldType;
                returnTypes = ts.append(returnTypes, iterationTypes.returnType);
            }
            return createIterationTypes(yieldType, getUnionType(returnTypes), nextType);
        }
        /**
         * Gets the *yield*, *return*, and *next* types of an `Iterator`-like or `AsyncIterator`-like
         * type from its members.
         *
         * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
         * record is returned. Otherwise, `noIterationTypes` is returned.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterator` instead.
         */
        function getIterationTypesOfIteratorSlow(type, resolver, errorNode) {
            var iterationTypes = combineIterationTypes([
                getIterationTypesOfMethod(type, resolver, "next", errorNode),
                getIterationTypesOfMethod(type, resolver, "return", errorNode),
                getIterationTypesOfMethod(type, resolver, "throw", errorNode),
            ]);
            return setCachedIterationTypes(type, resolver.iteratorCacheKey, iterationTypes);
        }
        /**
         * Gets the requested "iteration type" from a type that is either `Iterable`-like, `Iterator`-like,
         * `IterableIterator`-like, or `Generator`-like (for a non-async generator); or `AsyncIterable`-like,
         * `AsyncIterator`-like, `AsyncIterableIterator`-like, or `AsyncGenerator`-like (for an async generator).
         */
        function getIterationTypeOfGeneratorFunctionReturnType(kind, returnType, isAsyncGenerator) {
            if (isTypeAny(returnType)) {
                return undefined;
            }
            var iterationTypes = getIterationTypesOfGeneratorFunctionReturnType(returnType, isAsyncGenerator);
            return iterationTypes && iterationTypes[getIterationTypesKeyFromIterationTypeKind(kind)];
        }
        function getIterationTypesOfGeneratorFunctionReturnType(type, isAsyncGenerator) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            var use = isAsyncGenerator ? 2 /* AsyncGeneratorReturnType */ : 1 /* GeneratorReturnType */;
            var resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
            return getIterationTypesOfIterable(type, use, /*errorNode*/ undefined) ||
                getIterationTypesOfIterator(type, resolver, /*errorNode*/ undefined);
        }
        function checkBreakOrContinueStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node))
                checkGrammarBreakOrContinueStatement(node);
            // TODO: Check that target label is valid
        }
        function unwrapReturnType(returnType, functionFlags) {
            var _a, _b;
            var isGenerator = !!(functionFlags & 1 /* Generator */);
            var isAsync = !!(functionFlags & 2 /* Async */);
            return isGenerator ? (_a = getIterationTypeOfGeneratorFunctionReturnType(1 /* Return */, returnType, isAsync)) !== null && _a !== void 0 ? _a : errorType :
                isAsync ? (_b = getAwaitedType(returnType)) !== null && _b !== void 0 ? _b : errorType :
                    returnType;
        }
        function isUnwrappedReturnTypeVoidOrAny(func, returnType) {
            var unwrappedReturnType = unwrapReturnType(returnType, ts.getFunctionFlags(func));
            return !!unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, 16384 /* Void */ | 3 /* AnyOrUnknown */);
        }
        function checkReturnStatement(node) {
            var _a;
            // Grammar checking
            if (checkGrammarStatementInAmbientContext(node)) {
                return;
            }
            var func = ts.getContainingFunction(node);
            if (!func) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
                return;
            }
            var signature = getSignatureFromDeclaration(func);
            var returnType = getReturnTypeOfSignature(signature);
            var functionFlags = ts.getFunctionFlags(func);
            if (strictNullChecks || node.expression || returnType.flags & 131072 /* Never */) {
                var exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
                if (func.kind === 164 /* SetAccessor */) {
                    if (node.expression) {
                        error(node, ts.Diagnostics.Setters_cannot_return_a_value);
                    }
                }
                else if (func.kind === 162 /* Constructor */) {
                    if (node.expression && !checkTypeAssignableToAndOptionallyElaborate(exprType, returnType, node, node.expression)) {
                        error(node, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
                    }
                }
                else if (getReturnTypeFromAnnotation(func)) {
                    var unwrappedReturnType = (_a = unwrapReturnType(returnType, functionFlags)) !== null && _a !== void 0 ? _a : returnType;
                    var unwrappedExprType = functionFlags & 2 /* Async */
                        ? checkAwaitedType(exprType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
                        : exprType;
                    if (unwrappedReturnType) {
                        // If the function has a return type, but promisedType is
                        // undefined, an error will be reported in checkAsyncFunctionReturnType
                        // so we don't need to report one here.
                        checkTypeAssignableToAndOptionallyElaborate(unwrappedExprType, unwrappedReturnType, node, node.expression);
                    }
                }
            }
            else if (func.kind !== 162 /* Constructor */ && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(func, returnType)) {
                // The function has a return type, but the return statement doesn't have an expression.
                error(node, ts.Diagnostics.Not_all_code_paths_return_a_value);
            }
        }
        function checkWithStatement(node) {
            // Grammar checking for withStatement
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.flags & 32768 /* AwaitContext */) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_an_async_function_block);
                }
            }
            checkExpression(node.expression);
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var start = ts.getSpanOfTokenAtPosition(sourceFile, node.pos).start;
                var end = node.statement.pos;
                grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any);
            }
        }
        function checkSwitchStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            var firstDefaultClause;
            var hasDuplicateDefaultClause = false;
            var expressionType = checkExpression(node.expression);
            var expressionIsLiteral = isLiteralType(expressionType);
            ts.forEach(node.caseBlock.clauses, function (clause) {
                // Grammar check for duplicate default clauses, skip if we already report duplicate default clause
                if (clause.kind === 278 /* DefaultClause */ && !hasDuplicateDefaultClause) {
                    if (firstDefaultClause === undefined) {
                        firstDefaultClause = clause;
                    }
                    else {
                        grammarErrorOnNode(clause, ts.Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement);
                        hasDuplicateDefaultClause = true;
                    }
                }
                if (produceDiagnostics && clause.kind === 277 /* CaseClause */) {
                    // TypeScript 1.0 spec (April 2014): 5.9
                    // In a 'switch' statement, each 'case' expression must be of a type that is comparable
                    // to or from the type of the 'switch' expression.
                    var caseType = checkExpression(clause.expression);
                    var caseIsLiteral = isLiteralType(caseType);
                    var comparedExpressionType = expressionType;
                    if (!caseIsLiteral || !expressionIsLiteral) {
                        caseType = caseIsLiteral ? getBaseTypeOfLiteralType(caseType) : caseType;
                        comparedExpressionType = getBaseTypeOfLiteralType(expressionType);
                    }
                    if (!isTypeEqualityComparableTo(comparedExpressionType, caseType)) {
                        // expressionType is not comparable to caseType, try the reversed check and report errors if it fails
                        checkTypeComparableTo(caseType, comparedExpressionType, clause.expression, /*headMessage*/ undefined);
                    }
                }
                ts.forEach(clause.statements, checkSourceElement);
                if (compilerOptions.noFallthroughCasesInSwitch && clause.fallthroughFlowNode && isReachableFlowNode(clause.fallthroughFlowNode)) {
                    error(clause, ts.Diagnostics.Fallthrough_case_in_switch);
                }
            });
            if (node.caseBlock.locals) {
                registerForUnusedIdentifiersCheck(node.caseBlock);
            }
        }
        function checkLabeledStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                ts.findAncestor(node.parent, function (current) {
                    if (ts.isFunctionLike(current)) {
                        return "quit";
                    }
                    if (current.kind === 238 /* LabeledStatement */ && current.label.escapedText === node.label.escapedText) {
                        grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, ts.getTextOfNode(node.label));
                        return true;
                    }
                    return false;
                });
            }
            // ensure that label is unique
            checkSourceElement(node.statement);
        }
        function checkThrowStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.expression === undefined) {
                    grammarErrorAfterFirstToken(node, ts.Diagnostics.Line_break_not_permitted_here);
                }
            }
            if (node.expression) {
                checkExpression(node.expression);
            }
        }
        function checkTryStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkBlock(node.tryBlock);
            var catchClause = node.catchClause;
            if (catchClause) {
                // Grammar checking
                if (catchClause.variableDeclaration) {
                    if (catchClause.variableDeclaration.type) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.type, ts.Diagnostics.Catch_clause_variable_cannot_have_a_type_annotation);
                    }
                    else if (catchClause.variableDeclaration.initializer) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.initializer, ts.Diagnostics.Catch_clause_variable_cannot_have_an_initializer);
                    }
                    else {
                        var blockLocals_1 = catchClause.block.locals;
                        if (blockLocals_1) {
                            ts.forEachKey(catchClause.locals, function (caughtName) {
                                var blockLocal = blockLocals_1.get(caughtName);
                                if (blockLocal && (blockLocal.flags & 2 /* BlockScopedVariable */) !== 0) {
                                    grammarErrorOnNode(blockLocal.valueDeclaration, ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName);
                                }
                            });
                        }
                    }
                }
                checkBlock(catchClause.block);
            }
            if (node.finallyBlock) {
                checkBlock(node.finallyBlock);
            }
        }
        function checkIndexConstraints(type) {
            var declaredNumberIndexer = getIndexDeclarationOfSymbol(type.symbol, 1 /* Number */);
            var declaredStringIndexer = getIndexDeclarationOfSymbol(type.symbol, 0 /* String */);
            var stringIndexType = getIndexTypeOfType(type, 0 /* String */);
            var numberIndexType = getIndexTypeOfType(type, 1 /* Number */);
            if (stringIndexType || numberIndexType) {
                ts.forEach(getPropertiesOfObjectType(type), function (prop) {
                    var propType = getTypeOfSymbol(prop);
                    checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
                    checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                });
                var classDeclaration = type.symbol.valueDeclaration;
                if (ts.getObjectFlags(type) & 1 /* Class */ && ts.isClassLike(classDeclaration)) {
                    for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) {
                        var member = _a[_i];
                        // Only process instance properties with computed names here.
                        // Static properties cannot be in conflict with indexers,
                        // and properties with literal names were already checked.
                        if (!ts.hasModifier(member, 32 /* Static */) && hasNonBindableDynamicName(member)) {
                            var symbol = getSymbolOfNode(member);
                            var propType = getTypeOfSymbol(symbol);
                            checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
                            checkIndexConstraintForProperty(symbol, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                        }
                    }
                }
            }
            var errorNode;
            if (stringIndexType && numberIndexType) {
                errorNode = declaredNumberIndexer || declaredStringIndexer;
                // condition 'errorNode === undefined' may appear if types does not declare nor string neither number indexer
                if (!errorNode && (ts.getObjectFlags(type) & 2 /* Interface */)) {
                    var someBaseTypeHasBothIndexers = ts.forEach(getBaseTypes(type), function (base) { return getIndexTypeOfType(base, 0 /* String */) && getIndexTypeOfType(base, 1 /* Number */); });
                    errorNode = someBaseTypeHasBothIndexers ? undefined : type.symbol.declarations[0];
                }
            }
            if (errorNode && !isTypeAssignableTo(numberIndexType, stringIndexType)) { // TODO: GH#18217
                error(errorNode, ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, typeToString(numberIndexType), typeToString(stringIndexType));
            }
            function checkIndexConstraintForProperty(prop, propertyType, containingType, indexDeclaration, indexType, indexKind) {
                // ESSymbol properties apply to neither string nor numeric indexers.
                if (!indexType || ts.isKnownSymbol(prop)) {
                    return;
                }
                var propDeclaration = prop.valueDeclaration;
                var name = propDeclaration && ts.getNameOfDeclaration(propDeclaration);
                if (name && ts.isPrivateIdentifier(name)) {
                    return;
                }
                // index is numeric and property name is not valid numeric literal
                if (indexKind === 1 /* Number */ && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) {
                    return;
                }
                // perform property check if property or indexer is declared in 'type'
                // this allows us to rule out cases when both property and indexer are inherited from the base class
                var errorNode;
                if (propDeclaration && name &&
                    (propDeclaration.kind === 209 /* BinaryExpression */ ||
                        name.kind === 154 /* ComputedPropertyName */ ||
                        prop.parent === containingType.symbol)) {
                    errorNode = propDeclaration;
                }
                else if (indexDeclaration) {
                    errorNode = indexDeclaration;
                }
                else if (ts.getObjectFlags(containingType) & 2 /* Interface */) {
                    // for interfaces property and indexer might be inherited from different bases
                    // check if any base class already has both property and indexer.
                    // check should be performed only if 'type' is the first type that brings property\indexer together
                    var someBaseClassHasBothPropertyAndIndexer = ts.forEach(getBaseTypes(containingType), function (base) { return getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, indexKind); });
                    errorNode = someBaseClassHasBothPropertyAndIndexer ? undefined : containingType.symbol.declarations[0];
                }
                if (errorNode && !isTypeAssignableTo(propertyType, indexType)) {
                    var errorMessage = indexKind === 0 /* String */
                        ? ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2
                        : ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2;
                    error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType));
                }
            }
        }
        function checkTypeNameIsReserved(name, message) {
            // TS 1.0 spec (April 2014): 3.6.1
            // The predefined type keywords are reserved and cannot be used as names of user defined types.
            switch (name.escapedText) {
                case "any":
                case "unknown":
                case "number":
                case "bigint":
                case "boolean":
                case "string":
                case "symbol":
                case "void":
                case "object":
                    error(name, message, name.escapedText);
            }
        }
        /**
         * The name cannot be used as 'Object' of user defined types with special target.
         */
        function checkClassNameCollisionWithObject(name) {
            if (languageVersion === 1 /* ES5 */ && name.escapedText === "Object"
                && moduleKind < ts.ModuleKind.ES2015) {
                error(name, ts.Diagnostics.Class_name_cannot_be_Object_when_targeting_ES5_with_module_0, ts.ModuleKind[moduleKind]); // https://github.com/Microsoft/TypeScript/issues/17494
            }
        }
        /**
         * Check each type parameter and check that type parameters have no duplicate type parameter declarations
         */
        function checkTypeParameters(typeParameterDeclarations) {
            if (typeParameterDeclarations) {
                var seenDefault = false;
                for (var i = 0; i < typeParameterDeclarations.length; i++) {
                    var node = typeParameterDeclarations[i];
                    checkTypeParameter(node);
                    if (produceDiagnostics) {
                        if (node.default) {
                            seenDefault = true;
                            checkTypeParametersNotReferenced(node.default, typeParameterDeclarations, i);
                        }
                        else if (seenDefault) {
                            error(node, ts.Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
                        }
                        for (var j = 0; j < i; j++) {
                            if (typeParameterDeclarations[j].symbol === node.symbol) {
                                error(node.name, ts.Diagnostics.Duplicate_identifier_0, ts.declarationNameToString(node.name));
                            }
                        }
                    }
                }
            }
        }
        /** Check that type parameter defaults only reference previously declared type parameters */
        function checkTypeParametersNotReferenced(root, typeParameters, index) {
            visit(root);
            function visit(node) {
                if (node.kind === 169 /* TypeReference */) {
                    var type = getTypeFromTypeReference(node);
                    if (type.flags & 262144 /* TypeParameter */) {
                        for (var i = index; i < typeParameters.length; i++) {
                            if (type.symbol === getSymbolOfNode(typeParameters[i])) {
                                error(node, ts.Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters);
                            }
                        }
                    }
                }
                ts.forEachChild(node, visit);
            }
        }
        /** Check that type parameter lists are identical across multiple declarations */
        function checkTypeParameterListsIdentical(symbol) {
            if (symbol.declarations.length === 1) {
                return;
            }
            var links = getSymbolLinks(symbol);
            if (!links.typeParametersChecked) {
                links.typeParametersChecked = true;
                var declarations = getClassOrInterfaceDeclarationsOfSymbol(symbol);
                if (declarations.length <= 1) {
                    return;
                }
                var type = getDeclaredTypeOfSymbol(symbol);
                if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) {
                    // Report an error on every conflicting declaration.
                    var name = symbolToString(symbol);
                    for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) {
                        var declaration = declarations_6[_i];
                        error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name);
                    }
                }
            }
        }
        function areTypeParametersIdentical(declarations, targetParameters) {
            var maxTypeArgumentCount = ts.length(targetParameters);
            var minTypeArgumentCount = getMinTypeArgumentCount(targetParameters);
            for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) {
                var declaration = declarations_7[_i];
                // If this declaration has too few or too many type parameters, we report an error
                var sourceParameters = ts.getEffectiveTypeParameterDeclarations(declaration);
                var numTypeParameters = sourceParameters.length;
                if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) {
                    return false;
                }
                for (var i = 0; i < numTypeParameters; i++) {
                    var source = sourceParameters[i];
                    var target = targetParameters[i];
                    // If the type parameter node does not have the same as the resolved type
                    // parameter at this position, we report an error.
                    if (source.name.escapedText !== target.symbol.escapedName) {
                        return false;
                    }
                    // If the type parameter node does not have an identical constraint as the resolved
                    // type parameter at this position, we report an error.
                    var constraint = ts.getEffectiveConstraintOfTypeParameter(source);
                    var sourceConstraint = constraint && getTypeFromTypeNode(constraint);
                    var targetConstraint = getConstraintOfTypeParameter(target);
                    // relax check if later interface augmentation has no constraint, it's more broad and is OK to merge with
                    // a more constrained interface (this could be generalized to a full hierarchy check, but that's maybe overkill)
                    if (sourceConstraint && targetConstraint && !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
                        return false;
                    }
                    // If the type parameter node has a default and it is not identical to the default
                    // for the type parameter at this position, we report an error.
                    var sourceDefault = source.default && getTypeFromTypeNode(source.default);
                    var targetDefault = getDefaultFromTypeParameter(target);
                    if (sourceDefault && targetDefault && !isTypeIdenticalTo(sourceDefault, targetDefault)) {
                        return false;
                    }
                }
            }
            return true;
        }
        function checkClassExpression(node) {
            checkClassLikeDeclaration(node);
            checkNodeDeferred(node);
            return getTypeOfSymbol(getSymbolOfNode(node));
        }
        function checkClassExpressionDeferred(node) {
            ts.forEach(node.members, checkSourceElement);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkClassDeclaration(node) {
            if (!node.name && !ts.hasModifier(node, 512 /* Default */)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
            }
            checkClassLikeDeclaration(node);
            ts.forEach(node.members, checkSourceElement);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkClassLikeDeclaration(node) {
            checkGrammarClassLikeDeclaration(node);
            checkDecorators(node);
            if (node.name) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Class_name_cannot_be_0);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                if (!(node.flags & 8388608 /* Ambient */)) {
                    checkClassNameCollisionWithObject(node.name);
                }
            }
            checkTypeParameters(ts.getEffectiveTypeParameterDeclarations(node));
            checkExportsOnMergedDeclarations(node);
            var symbol = getSymbolOfNode(node);
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeWithThis = getTypeWithThisArgument(type);
            var staticType = getTypeOfSymbol(symbol);
            checkTypeParameterListsIdentical(symbol);
            checkClassForDuplicateDeclarations(node);
            // Only check for reserved static identifiers on non-ambient context.
            if (!(node.flags & 8388608 /* Ambient */)) {
                checkClassForStaticPropertyNameConflicts(node);
            }
            var baseTypeNode = ts.getEffectiveBaseTypeNode(node);
            if (baseTypeNode) {
                ts.forEach(baseTypeNode.typeArguments, checkSourceElement);
                if (languageVersion < 2 /* ES2015 */) {
                    checkExternalEmitHelpers(baseTypeNode.parent, 1 /* Extends */);
                }
                // check both @extends and extends if both are specified.
                var extendsNode = ts.getClassExtendsHeritageElement(node);
                if (extendsNode && extendsNode !== baseTypeNode) {
                    checkExpression(extendsNode.expression);
                }
                var baseTypes = getBaseTypes(type);
                if (baseTypes.length && produceDiagnostics) {
                    var baseType_1 = baseTypes[0];
                    var baseConstructorType = getBaseConstructorTypeOfClass(type);
                    var staticBaseType = getApparentType(baseConstructorType);
                    checkBaseTypeAccessibility(staticBaseType, baseTypeNode);
                    checkSourceElement(baseTypeNode.expression);
                    if (ts.some(baseTypeNode.typeArguments)) {
                        ts.forEach(baseTypeNode.typeArguments, checkSourceElement);
                        for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); _i < _a.length; _i++) {
                            var constructor = _a[_i];
                            if (!checkTypeArgumentConstraints(baseTypeNode, constructor.typeParameters)) {
                                break;
                            }
                        }
                    }
                    var baseWithThis = getTypeWithThisArgument(baseType_1, type.thisType);
                    if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) {
                        issueMemberSpecificError(node, typeWithThis, baseWithThis, ts.Diagnostics.Class_0_incorrectly_extends_base_class_1);
                    }
                    else {
                        // Report static side error only when instance type is assignable
                        checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, ts.Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
                    }
                    if (baseConstructorType.flags & 8650752 /* TypeVariable */ && !isMixinConstructorType(staticType)) {
                        error(node.name || node, ts.Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any);
                    }
                    if (!(staticBaseType.symbol && staticBaseType.symbol.flags & 32 /* Class */) && !(baseConstructorType.flags & 8650752 /* TypeVariable */)) {
                        // When the static base type is a "class-like" constructor function (but not actually a class), we verify
                        // that all instantiated base constructor signatures return the same type.
                        var constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode);
                        if (ts.forEach(constructors, function (sig) { return !isJSConstructor(sig.declaration) && !isTypeIdenticalTo(getReturnTypeOfSignature(sig), baseType_1); })) {
                            error(baseTypeNode.expression, ts.Diagnostics.Base_constructors_must_all_have_the_same_return_type);
                        }
                    }
                    checkKindsOfPropertyMemberOverrides(type, baseType_1);
                }
            }
            var implementedTypeNodes = ts.getEffectiveImplementsTypeNodes(node);
            if (implementedTypeNodes) {
                for (var _b = 0, implementedTypeNodes_1 = implementedTypeNodes; _b < implementedTypeNodes_1.length; _b++) {
                    var typeRefNode = implementedTypeNodes_1[_b];
                    if (!ts.isEntityNameExpression(typeRefNode.expression)) {
                        error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments);
                    }
                    checkTypeReferenceNode(typeRefNode);
                    if (produceDiagnostics) {
                        var t = getReducedType(getTypeFromTypeNode(typeRefNode));
                        if (t !== errorType) {
                            if (isValidBaseType(t)) {
                                var genericDiag = t.symbol && t.symbol.flags & 32 /* Class */ ?
                                    ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass :
                                    ts.Diagnostics.Class_0_incorrectly_implements_interface_1;
                                var baseWithThis = getTypeWithThisArgument(t, type.thisType);
                                if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) {
                                    issueMemberSpecificError(node, typeWithThis, baseWithThis, genericDiag);
                                }
                            }
                            else {
                                error(typeRefNode, ts.Diagnostics.A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members);
                            }
                        }
                    }
                }
            }
            if (produceDiagnostics) {
                checkIndexConstraints(type);
                checkTypeForDuplicateIndexSignatures(node);
                checkPropertyInitialization(node);
            }
        }
        function issueMemberSpecificError(node, typeWithThis, baseWithThis, broadDiag) {
            // iterate over all implemented properties and issue errors on each one which isn't compatible, rather than the class as a whole, if possible
            var issuedMemberError = false;
            var _loop_19 = function (member) {
                if (ts.hasStaticModifier(member)) {
                    return "continue";
                }
                var declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member);
                if (declaredProp) {
                    var prop = getPropertyOfType(typeWithThis, declaredProp.escapedName);
                    var baseProp = getPropertyOfType(baseWithThis, declaredProp.escapedName);
                    if (prop && baseProp) {
                        var rootChain = function () { return ts.chainDiagnosticMessages(
                        /*details*/ undefined, ts.Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, symbolToString(declaredProp), typeToString(typeWithThis), typeToString(baseWithThis)); };
                        if (!checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(baseProp), member.name || member, /*message*/ undefined, rootChain)) {
                            issuedMemberError = true;
                        }
                    }
                }
            };
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                _loop_19(member);
            }
            if (!issuedMemberError) {
                // check again with diagnostics to generate a less-specific error
                checkTypeAssignableTo(typeWithThis, baseWithThis, node.name || node, broadDiag);
            }
        }
        function checkBaseTypeAccessibility(type, node) {
            var signatures = getSignaturesOfType(type, 1 /* Construct */);
            if (signatures.length) {
                var declaration = signatures[0].declaration;
                if (declaration && ts.hasModifier(declaration, 8 /* Private */)) {
                    var typeClassDeclaration = ts.getClassLikeDeclarationOfSymbol(type.symbol);
                    if (!isNodeWithinClass(node, typeClassDeclaration)) {
                        error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol));
                    }
                }
            }
        }
        function getTargetSymbol(s) {
            // if symbol is instantiated its flags are not copied from the 'target'
            // so we'll need to get back original 'target' symbol to work with correct set of flags
            return ts.getCheckFlags(s) & 1 /* Instantiated */ ? s.target : s;
        }
        function getClassOrInterfaceDeclarationsOfSymbol(symbol) {
            return ts.filter(symbol.declarations, function (d) {
                return d.kind === 245 /* ClassDeclaration */ || d.kind === 246 /* InterfaceDeclaration */;
            });
        }
        function checkKindsOfPropertyMemberOverrides(type, baseType) {
            // TypeScript 1.0 spec (April 2014): 8.2.3
            // A derived class inherits all members from its base class it doesn't override.
            // Inheritance means that a derived class implicitly contains all non - overridden members of the base class.
            // Both public and private property members are inherited, but only public property members can be overridden.
            // A property member in a derived class is said to override a property member in a base class
            // when the derived class property member has the same name and kind(instance or static)
            // as the base class property member.
            // The type of an overriding property member must be assignable(section 3.8.4)
            // to the type of the overridden property member, or otherwise a compile - time error occurs.
            // Base class instance member functions can be overridden by derived class instance member functions,
            // but not by other kinds of members.
            // Base class instance member variables and accessors can be overridden by
            // derived class instance member variables and accessors, but not by other kinds of members.
            // NOTE: assignability is checked in checkClassDeclaration
            var baseProperties = getPropertiesOfType(baseType);
            basePropertyCheck: for (var _i = 0, baseProperties_1 = baseProperties; _i < baseProperties_1.length; _i++) {
                var baseProperty = baseProperties_1[_i];
                var base = getTargetSymbol(baseProperty);
                if (base.flags & 4194304 /* Prototype */) {
                    continue;
                }
                var baseSymbol = getPropertyOfObjectType(type, base.escapedName);
                if (!baseSymbol) {
                    continue;
                }
                var derived = getTargetSymbol(baseSymbol);
                var baseDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(base);
                ts.Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration.");
                // In order to resolve whether the inherited method was overridden in the base class or not,
                // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated*
                // type declaration, derived and base resolve to the same symbol even in the case of generic classes.
                if (derived === base) {
                    // derived class inherits base without override/redeclaration
                    var derivedClassDecl = ts.getClassLikeDeclarationOfSymbol(type.symbol);
                    // It is an error to inherit an abstract member without implementing it or being declared abstract.
                    // If there is no declaration for the derived class (as in the case of class expressions),
                    // then the class cannot be declared abstract.
                    if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128 /* Abstract */))) {
                        // Searches other base types for a declaration that would satisfy the inherited abstract member.
                        // (The class may have more than one base type via declaration merging with an interface with the
                        // same name.)
                        for (var _a = 0, _b = getBaseTypes(type); _a < _b.length; _a++) {
                            var otherBaseType = _b[_a];
                            if (otherBaseType === baseType)
                                continue;
                            var baseSymbol_1 = getPropertyOfObjectType(otherBaseType, base.escapedName);
                            var derivedElsewhere = baseSymbol_1 && getTargetSymbol(baseSymbol_1);
                            if (derivedElsewhere && derivedElsewhere !== base) {
                                continue basePropertyCheck;
                            }
                        }
                        if (derivedClassDecl.kind === 214 /* ClassExpression */) {
                            error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType));
                        }
                        else {
                            error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, typeToString(type), symbolToString(baseProperty), typeToString(baseType));
                        }
                    }
                }
                else {
                    // derived overrides base.
                    var derivedDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(derived);
                    if (baseDeclarationFlags & 8 /* Private */ || derivedDeclarationFlags & 8 /* Private */) {
                        // either base or derived property is private - not override, skip it
                        continue;
                    }
                    var errorMessage = void 0;
                    var basePropertyFlags = base.flags & 98308 /* PropertyOrAccessor */;
                    var derivedPropertyFlags = derived.flags & 98308 /* PropertyOrAccessor */;
                    if (basePropertyFlags && derivedPropertyFlags) {
                        // property/accessor is overridden with property/accessor
                        if (!compilerOptions.useDefineForClassFields
                            || baseDeclarationFlags & 128 /* Abstract */ && !(base.valueDeclaration && ts.isPropertyDeclaration(base.valueDeclaration) && base.valueDeclaration.initializer)
                            || base.valueDeclaration && base.valueDeclaration.parent.kind === 246 /* InterfaceDeclaration */
                            || derived.valueDeclaration && ts.isBinaryExpression(derived.valueDeclaration)) {
                            // when the base property is abstract or from an interface, base/derived flags don't need to match
                            // same when the derived property is from an assignment
                            continue;
                        }
                        var overriddenInstanceProperty = basePropertyFlags !== 4 /* Property */ && derivedPropertyFlags === 4 /* Property */;
                        var overriddenInstanceAccessor = basePropertyFlags === 4 /* Property */ && derivedPropertyFlags !== 4 /* Property */;
                        if (overriddenInstanceProperty || overriddenInstanceAccessor) {
                            var errorMessage_1 = overriddenInstanceProperty ?
                                ts.Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property :
                                ts.Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor;
                            error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage_1, symbolToString(base), typeToString(baseType), typeToString(type));
                        }
                        else {
                            var uninitialized = ts.find(derived.declarations, function (d) { return d.kind === 159 /* PropertyDeclaration */ && !d.initializer; });
                            if (uninitialized
                                && !(derived.flags & 33554432 /* Transient */)
                                && !(baseDeclarationFlags & 128 /* Abstract */)
                                && !(derivedDeclarationFlags & 128 /* Abstract */)
                                && !derived.declarations.some(function (d) { return !!(d.flags & 8388608 /* Ambient */); })) {
                                var constructor = findConstructorDeclaration(ts.getClassLikeDeclarationOfSymbol(type.symbol));
                                var propName = uninitialized.name;
                                if (uninitialized.exclamationToken
                                    || !constructor
                                    || !ts.isIdentifier(propName)
                                    || !strictNullChecks
                                    || !isPropertyInitializedInConstructor(propName, type, constructor)) {
                                    var errorMessage_2 = ts.Diagnostics.Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration;
                                    error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage_2, symbolToString(base), typeToString(baseType));
                                }
                            }
                        }
                        // correct case
                        continue;
                    }
                    else if (isPrototypeProperty(base)) {
                        if (isPrototypeProperty(derived) || derived.flags & 4 /* Property */) {
                            // method is overridden with method or property -- correct case
                            continue;
                        }
                        else {
                            ts.Debug.assert(!!(derived.flags & 98304 /* Accessor */));
                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
                        }
                    }
                    else if (base.flags & 98304 /* Accessor */) {
                        errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
                    }
                    else {
                        errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
                    }
                    error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
                }
            }
        }
        function getNonInterhitedProperties(type, baseTypes, properties) {
            if (!ts.length(baseTypes)) {
                return properties;
            }
            var seen = ts.createUnderscoreEscapedMap();
            ts.forEach(properties, function (p) { seen.set(p.escapedName, p); });
            for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) {
                var base = baseTypes_2[_i];
                var properties_5 = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType));
                for (var _a = 0, properties_4 = properties_5; _a < properties_4.length; _a++) {
                    var prop = properties_4[_a];
                    var existing = seen.get(prop.escapedName);
                    if (existing && !isPropertyIdenticalTo(existing, prop)) {
                        seen.delete(prop.escapedName);
                    }
                }
            }
            return ts.arrayFrom(seen.values());
        }
        function checkInheritedPropertiesAreIdentical(type, typeNode) {
            var baseTypes = getBaseTypes(type);
            if (baseTypes.length < 2) {
                return true;
            }
            var seen = ts.createUnderscoreEscapedMap();
            ts.forEach(resolveDeclaredMembers(type).declaredProperties, function (p) { seen.set(p.escapedName, { prop: p, containingType: type }); });
            var ok = true;
            for (var _i = 0, baseTypes_3 = baseTypes; _i < baseTypes_3.length; _i++) {
                var base = baseTypes_3[_i];
                var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType));
                for (var _a = 0, properties_6 = properties; _a < properties_6.length; _a++) {
                    var prop = properties_6[_a];
                    var existing = seen.get(prop.escapedName);
                    if (!existing) {
                        seen.set(prop.escapedName, { prop: prop, containingType: base });
                    }
                    else {
                        var isInheritedProperty = existing.containingType !== type;
                        if (isInheritedProperty && !isPropertyIdenticalTo(existing.prop, prop)) {
                            ok = false;
                            var typeName1 = typeToString(existing.containingType);
                            var typeName2 = typeToString(base);
                            var errorInfo = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2);
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2);
                            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(typeNode, errorInfo));
                        }
                    }
                }
            }
            return ok;
        }
        function checkPropertyInitialization(node) {
            if (!strictNullChecks || !strictPropertyInitialization || node.flags & 8388608 /* Ambient */) {
                return;
            }
            var constructor = findConstructorDeclaration(node);
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (ts.getModifierFlags(member) & 2 /* Ambient */) {
                    continue;
                }
                if (isInstancePropertyWithoutInitializer(member)) {
                    var propName = member.name;
                    if (ts.isIdentifier(propName) || ts.isPrivateIdentifier(propName)) {
                        var type = getTypeOfSymbol(getSymbolOfNode(member));
                        if (!(type.flags & 3 /* AnyOrUnknown */ || getFalsyFlags(type) & 32768 /* Undefined */)) {
                            if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) {
                                error(member.name, ts.Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, ts.declarationNameToString(propName));
                            }
                        }
                    }
                }
            }
        }
        function isInstancePropertyWithoutInitializer(node) {
            return node.kind === 159 /* PropertyDeclaration */ &&
                !ts.hasModifier(node, 32 /* Static */ | 128 /* Abstract */) &&
                !node.exclamationToken &&
                !node.initializer;
        }
        function isPropertyInitializedInConstructor(propName, propType, constructor) {
            var reference = ts.createPropertyAccess(ts.createThis(), propName);
            reference.expression.parent = reference;
            reference.parent = constructor;
            reference.flowNode = constructor.returnFlowNode;
            var flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType));
            return !(getFalsyFlags(flowType) & 32768 /* Undefined */);
        }
        function checkInterfaceDeclaration(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node))
                checkGrammarInterfaceDeclaration(node);
            checkTypeParameters(node.typeParameters);
            if (produceDiagnostics) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Interface_name_cannot_be_0);
                checkExportsOnMergedDeclarations(node);
                var symbol = getSymbolOfNode(node);
                checkTypeParameterListsIdentical(symbol);
                // Only check this symbol once
                var firstInterfaceDecl = ts.getDeclarationOfKind(symbol, 246 /* InterfaceDeclaration */);
                if (node === firstInterfaceDecl) {
                    var type = getDeclaredTypeOfSymbol(symbol);
                    var typeWithThis = getTypeWithThisArgument(type);
                    // run subsequent checks only if first set succeeded
                    if (checkInheritedPropertiesAreIdentical(type, node.name)) {
                        for (var _i = 0, _a = getBaseTypes(type); _i < _a.length; _i++) {
                            var baseType = _a[_i];
                            checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, ts.Diagnostics.Interface_0_incorrectly_extends_interface_1);
                        }
                        checkIndexConstraints(type);
                    }
                }
                checkObjectTypeForDuplicateDeclarations(node);
            }
            ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) {
                if (!ts.isEntityNameExpression(heritageElement.expression)) {
                    error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments);
                }
                checkTypeReferenceNode(heritageElement);
            });
            ts.forEach(node.members, checkSourceElement);
            if (produceDiagnostics) {
                checkTypeForDuplicateIndexSignatures(node);
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkTypeAliasDeclaration(node) {
            // Grammar checking
            checkGrammarDecoratorsAndModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
            checkExportsOnMergedDeclarations(node);
            checkTypeParameters(node.typeParameters);
            checkSourceElement(node.type);
            registerForUnusedIdentifiersCheck(node);
        }
        function computeEnumMemberValues(node) {
            var nodeLinks = getNodeLinks(node);
            if (!(nodeLinks.flags & 16384 /* EnumValuesComputed */)) {
                nodeLinks.flags |= 16384 /* EnumValuesComputed */;
                var autoValue = 0;
                for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    var value = computeMemberValue(member, autoValue);
                    getNodeLinks(member).enumMemberValue = value;
                    autoValue = typeof value === "number" ? value + 1 : undefined;
                }
            }
        }
        function computeMemberValue(member, autoValue) {
            if (ts.isComputedNonLiteralName(member.name)) {
                error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
            }
            else {
                var text = ts.getTextOfPropertyName(member.name);
                if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) {
                    error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
                }
            }
            if (member.initializer) {
                return computeConstantValue(member);
            }
            // In ambient non-const numeric enum declarations, enum members without initializers are
            // considered computed members (as opposed to having auto-incremented values).
            if (member.parent.flags & 8388608 /* Ambient */ && !ts.isEnumConst(member.parent) && getEnumKind(getSymbolOfNode(member.parent)) === 0 /* Numeric */) {
                return undefined;
            }
            // If the member declaration specifies no value, the member is considered a constant enum member.
            // If the member is the first member in the enum declaration, it is assigned the value zero.
            // Otherwise, it is assigned the value of the immediately preceding member plus one, and an error
            // occurs if the immediately preceding member is not a constant enum member.
            if (autoValue !== undefined) {
                return autoValue;
            }
            error(member.name, ts.Diagnostics.Enum_member_must_have_initializer);
            return undefined;
        }
        function computeConstantValue(member) {
            var enumKind = getEnumKind(getSymbolOfNode(member.parent));
            var isConstEnum = ts.isEnumConst(member.parent);
            var initializer = member.initializer;
            var value = enumKind === 1 /* Literal */ && !isLiteralEnumMember(member) ? undefined : evaluate(initializer);
            if (value !== undefined) {
                if (isConstEnum && typeof value === "number" && !isFinite(value)) {
                    error(initializer, isNaN(value) ?
                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN :
                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
                }
            }
            else if (enumKind === 1 /* Literal */) {
                error(initializer, ts.Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members);
                return 0;
            }
            else if (isConstEnum) {
                error(initializer, ts.Diagnostics.const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values);
            }
            else if (member.parent.flags & 8388608 /* Ambient */) {
                error(initializer, ts.Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
            }
            else {
                // Only here do we need to check that the initializer is assignable to the enum type.
                var source = checkExpression(initializer);
                if (!isTypeAssignableToKind(source, 296 /* NumberLike */)) {
                    error(initializer, ts.Diagnostics.Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhaustiveness_checks_consider_using_an_object_literal_instead, typeToString(source));
                }
                else {
                    checkTypeAssignableTo(source, getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined);
                }
            }
            return value;
            function evaluate(expr) {
                switch (expr.kind) {
                    case 207 /* PrefixUnaryExpression */:
                        var value_2 = evaluate(expr.operand);
                        if (typeof value_2 === "number") {
                            switch (expr.operator) {
                                case 39 /* PlusToken */: return value_2;
                                case 40 /* MinusToken */: return -value_2;
                                case 54 /* TildeToken */: return ~value_2;
                            }
                        }
                        break;
                    case 209 /* BinaryExpression */:
                        var left = evaluate(expr.left);
                        var right = evaluate(expr.right);
                        if (typeof left === "number" && typeof right === "number") {
                            switch (expr.operatorToken.kind) {
                                case 51 /* BarToken */: return left | right;
                                case 50 /* AmpersandToken */: return left & right;
                                case 48 /* GreaterThanGreaterThanToken */: return left >> right;
                                case 49 /* GreaterThanGreaterThanGreaterThanToken */: return left >>> right;
                                case 47 /* LessThanLessThanToken */: return left << right;
                                case 52 /* CaretToken */: return left ^ right;
                                case 41 /* AsteriskToken */: return left * right;
                                case 43 /* SlashToken */: return left / right;
                                case 39 /* PlusToken */: return left + right;
                                case 40 /* MinusToken */: return left - right;
                                case 44 /* PercentToken */: return left % right;
                                case 42 /* AsteriskAsteriskToken */: return Math.pow(left, right);
                            }
                        }
                        else if (typeof left === "string" && typeof right === "string" && expr.operatorToken.kind === 39 /* PlusToken */) {
                            return left + right;
                        }
                        break;
                    case 10 /* StringLiteral */:
                    case 14 /* NoSubstitutionTemplateLiteral */:
                        return expr.text;
                    case 8 /* NumericLiteral */:
                        checkGrammarNumericLiteral(expr);
                        return +expr.text;
                    case 200 /* ParenthesizedExpression */:
                        return evaluate(expr.expression);
                    case 75 /* Identifier */:
                        var identifier = expr;
                        if (isInfinityOrNaNString(identifier.escapedText)) {
                            return +(identifier.escapedText);
                        }
                        return ts.nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText);
                    case 195 /* ElementAccessExpression */:
                    case 194 /* PropertyAccessExpression */:
                        var ex = expr;
                        if (isConstantMemberAccess(ex)) {
                            var type = getTypeOfExpression(ex.expression);
                            if (type.symbol && type.symbol.flags & 384 /* Enum */) {
                                var name = void 0;
                                if (ex.kind === 194 /* PropertyAccessExpression */) {
                                    name = ex.name.escapedText;
                                }
                                else {
                                    name = ts.escapeLeadingUnderscores(ts.cast(ex.argumentExpression, ts.isLiteralExpression).text);
                                }
                                return evaluateEnumMember(expr, type.symbol, name);
                            }
                        }
                        break;
                }
                return undefined;
            }
            function evaluateEnumMember(expr, enumSymbol, name) {
                var memberSymbol = enumSymbol.exports.get(name);
                if (memberSymbol) {
                    var declaration = memberSymbol.valueDeclaration;
                    if (declaration !== member) {
                        if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
                            return getEnumMemberValue(declaration);
                        }
                        error(expr, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
                        return 0;
                    }
                    else {
                        error(expr, ts.Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(memberSymbol));
                    }
                }
                return undefined;
            }
        }
        function isConstantMemberAccess(node) {
            return node.kind === 75 /* Identifier */ ||
                node.kind === 194 /* PropertyAccessExpression */ && isConstantMemberAccess(node.expression) ||
                node.kind === 195 /* ElementAccessExpression */ && isConstantMemberAccess(node.expression) &&
                    ts.isStringLiteralLike(node.argumentExpression);
        }
        function checkEnumDeclaration(node) {
            if (!produceDiagnostics) {
                return;
            }
            // Grammar checking
            checkGrammarDecoratorsAndModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Enum_name_cannot_be_0);
            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            checkExportsOnMergedDeclarations(node);
            node.members.forEach(checkEnumMember);
            computeEnumMemberValues(node);
            // Spec 2014 - Section 9.3:
            // It isn't possible for one enum declaration to continue the automatic numbering sequence of another,
            // and when an enum type has multiple declarations, only one declaration is permitted to omit a value
            // for the first member.
            //
            // Only perform this check once per symbol
            var enumSymbol = getSymbolOfNode(node);
            var firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind);
            if (node === firstDeclaration) {
                if (enumSymbol.declarations.length > 1) {
                    var enumIsConst_1 = ts.isEnumConst(node);
                    // check that const is placed\omitted on all enum declarations
                    ts.forEach(enumSymbol.declarations, function (decl) {
                        if (ts.isEnumDeclaration(decl) && ts.isEnumConst(decl) !== enumIsConst_1) {
                            error(ts.getNameOfDeclaration(decl), ts.Diagnostics.Enum_declarations_must_all_be_const_or_non_const);
                        }
                    });
                }
                var seenEnumMissingInitialInitializer_1 = false;
                ts.forEach(enumSymbol.declarations, function (declaration) {
                    // return true if we hit a violation of the rule, false otherwise
                    if (declaration.kind !== 248 /* EnumDeclaration */) {
                        return false;
                    }
                    var enumDeclaration = declaration;
                    if (!enumDeclaration.members.length) {
                        return false;
                    }
                    var firstEnumMember = enumDeclaration.members[0];
                    if (!firstEnumMember.initializer) {
                        if (seenEnumMissingInitialInitializer_1) {
                            error(firstEnumMember.name, ts.Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element);
                        }
                        else {
                            seenEnumMissingInitialInitializer_1 = true;
                        }
                    }
                });
            }
        }
        function checkEnumMember(node) {
            if (ts.isPrivateIdentifier(node.name)) {
                error(node, ts.Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier);
            }
        }
        function getFirstNonAmbientClassOrFunctionDeclaration(symbol) {
            var declarations = symbol.declarations;
            for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) {
                var declaration = declarations_8[_i];
                if ((declaration.kind === 245 /* ClassDeclaration */ ||
                    (declaration.kind === 244 /* FunctionDeclaration */ && ts.nodeIsPresent(declaration.body))) &&
                    !(declaration.flags & 8388608 /* Ambient */)) {
                    return declaration;
                }
            }
            return undefined;
        }
        function inSameLexicalScope(node1, node2) {
            var container1 = ts.getEnclosingBlockScopeContainer(node1);
            var container2 = ts.getEnclosingBlockScopeContainer(node2);
            if (isGlobalSourceFile(container1)) {
                return isGlobalSourceFile(container2);
            }
            else if (isGlobalSourceFile(container2)) {
                return false;
            }
            else {
                return container1 === container2;
            }
        }
        function checkModuleDeclaration(node) {
            if (produceDiagnostics) {
                // Grammar checking
                var isGlobalAugmentation = ts.isGlobalScopeAugmentation(node);
                var inAmbientContext = node.flags & 8388608 /* Ambient */;
                if (isGlobalAugmentation && !inAmbientContext) {
                    error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context);
                }
                var isAmbientExternalModule = ts.isAmbientModule(node);
                var contextErrorMessage = isAmbientExternalModule
                    ? ts.Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file
                    : ts.Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module;
                if (checkGrammarModuleElementContext(node, contextErrorMessage)) {
                    // If we hit a module declaration in an illegal context, just bail out to avoid cascading errors.
                    return;
                }
                if (!checkGrammarDecoratorsAndModifiers(node)) {
                    if (!inAmbientContext && node.name.kind === 10 /* StringLiteral */) {
                        grammarErrorOnNode(node.name, ts.Diagnostics.Only_ambient_modules_can_use_quoted_names);
                    }
                }
                if (ts.isIdentifier(node.name)) {
                    checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                    checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                }
                checkExportsOnMergedDeclarations(node);
                var symbol = getSymbolOfNode(node);
                // The following checks only apply on a non-ambient instantiated module declaration.
                if (symbol.flags & 512 /* ValueModule */
                    && !inAmbientContext
                    && symbol.declarations.length > 1
                    && isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules)) {
                    var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
                    if (firstNonAmbientClassOrFunc) {
                        if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) {
                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged);
                        }
                        else if (node.pos < firstNonAmbientClassOrFunc.pos) {
                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged);
                        }
                    }
                    // if the module merges with a class declaration in the same lexical scope,
                    // we need to track this to ensure the correct emit.
                    var mergedClass = ts.getDeclarationOfKind(symbol, 245 /* ClassDeclaration */);
                    if (mergedClass &&
                        inSameLexicalScope(node, mergedClass)) {
                        getNodeLinks(node).flags |= 32768 /* LexicalModuleMergesWithClass */;
                    }
                }
                if (isAmbientExternalModule) {
                    if (ts.isExternalModuleAugmentation(node)) {
                        // body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module)
                        // otherwise we'll be swamped in cascading errors.
                        // We can detect if augmentation was applied using following rules:
                        // - augmentation for a global scope is always applied
                        // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module).
                        var checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & 33554432 /* Transient */);
                        if (checkBody && node.body) {
                            for (var _i = 0, _a = node.body.statements; _i < _a.length; _i++) {
                                var statement = _a[_i];
                                checkModuleAugmentationElement(statement, isGlobalAugmentation);
                            }
                        }
                    }
                    else if (isGlobalSourceFile(node.parent)) {
                        if (isGlobalAugmentation) {
                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
                        }
                        else if (ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(node.name))) {
                            error(node.name, ts.Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name);
                        }
                    }
                    else {
                        if (isGlobalAugmentation) {
                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
                        }
                        else {
                            // Node is not an augmentation and is not located on the script level.
                            // This means that this is declaration of ambient module that is located in other module or namespace which is prohibited.
                            error(node.name, ts.Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces);
                        }
                    }
                }
            }
            if (node.body) {
                checkSourceElement(node.body);
                if (!ts.isGlobalScopeAugmentation(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
            }
        }
        function checkModuleAugmentationElement(node, isGlobalAugmentation) {
            switch (node.kind) {
                case 225 /* VariableStatement */:
                    // error each individual name in variable statement instead of marking the entire variable statement
                    for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        checkModuleAugmentationElement(decl, isGlobalAugmentation);
                    }
                    break;
                case 259 /* ExportAssignment */:
                case 260 /* ExportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations);
                    break;
                case 253 /* ImportEqualsDeclaration */:
                case 254 /* ImportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module);
                    break;
                case 191 /* BindingElement */:
                case 242 /* VariableDeclaration */:
                    var name = node.name;
                    if (ts.isBindingPattern(name)) {
                        for (var _b = 0, _c = name.elements; _b < _c.length; _b++) {
                            var el = _c[_b];
                            // mark individual names in binding pattern
                            checkModuleAugmentationElement(el, isGlobalAugmentation);
                        }
                        break;
                    }
                // falls through
                case 245 /* ClassDeclaration */:
                case 248 /* EnumDeclaration */:
                case 244 /* FunctionDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                    if (isGlobalAugmentation) {
                        return;
                    }
                    var symbol = getSymbolOfNode(node);
                    if (symbol) {
                        // module augmentations cannot introduce new names on the top level scope of the module
                        // this is done it two steps
                        // 1. quick check - if symbol for node is not merged - this is local symbol to this augmentation - report error
                        // 2. main check - report error if value declaration of the parent symbol is module augmentation)
                        var reportError = !(symbol.flags & 33554432 /* Transient */);
                        if (!reportError) {
                            // symbol should not originate in augmentation
                            reportError = !!symbol.parent && ts.isExternalModuleAugmentation(symbol.parent.declarations[0]);
                        }
                    }
                    break;
            }
        }
        function getFirstNonModuleExportsIdentifier(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return node;
                case 153 /* QualifiedName */:
                    do {
                        node = node.left;
                    } while (node.kind !== 75 /* Identifier */);
                    return node;
                case 194 /* PropertyAccessExpression */:
                    do {
                        if (ts.isModuleExportsAccessExpression(node.expression) && !ts.isPrivateIdentifier(node.name)) {
                            return node.name;
                        }
                        node = node.expression;
                    } while (node.kind !== 75 /* Identifier */);
                    return node;
            }
        }
        function checkExternalImportOrExportDeclaration(node) {
            var moduleName = ts.getExternalModuleName(node);
            if (!moduleName || ts.nodeIsMissing(moduleName)) {
                // Should be a parse error.
                return false;
            }
            if (!ts.isStringLiteral(moduleName)) {
                error(moduleName, ts.Diagnostics.String_literal_expected);
                return false;
            }
            var inAmbientExternalModule = node.parent.kind === 250 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
            if (node.parent.kind !== 290 /* SourceFile */ && !inAmbientExternalModule) {
                error(moduleName, node.kind === 260 /* ExportDeclaration */ ?
                    ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace :
                    ts.Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module);
                return false;
            }
            if (inAmbientExternalModule && ts.isExternalModuleNameRelative(moduleName.text)) {
                // we have already reported errors on top level imports/exports in external module augmentations in checkModuleDeclaration
                // no need to do this again.
                if (!isTopLevelInExternalModuleAugmentation(node)) {
                    // TypeScript 1.0 spec (April 2013): 12.1.6
                    // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
                    // other external modules only through top - level external module names.
                    // Relative external module names are not permitted.
                    error(node, ts.Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name);
                    return false;
                }
            }
            return true;
        }
        function checkAliasSymbol(node) {
            var symbol = getSymbolOfNode(node);
            var target = resolveAlias(symbol);
            var shouldSkipWithJSExpandoTargets = symbol.flags & 67108864 /* Assignment */;
            if (!shouldSkipWithJSExpandoTargets && target !== unknownSymbol) {
                // For external modules symbol represents local symbol for an alias.
                // This local symbol will merge any other local declarations (excluding other aliases)
                // and symbol.flags will contains combined representation for all merged declaration.
                // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have,
                // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
                // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
                symbol = getMergedSymbol(symbol.exportSymbol || symbol);
                var excludedMeanings = (symbol.flags & (111551 /* Value */ | 1048576 /* ExportValue */) ? 111551 /* Value */ : 0) |
                    (symbol.flags & 788968 /* Type */ ? 788968 /* Type */ : 0) |
                    (symbol.flags & 1920 /* Namespace */ ? 1920 /* Namespace */ : 0);
                if (target.flags & excludedMeanings) {
                    var message = node.kind === 263 /* ExportSpecifier */ ?
                        ts.Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 :
                        ts.Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0;
                    error(node, message, symbolToString(symbol));
                }
                // Don't allow to re-export something with no value side when `--isolatedModules` is set.
                if (compilerOptions.isolatedModules
                    && node.kind === 263 /* ExportSpecifier */
                    && !node.parent.parent.isTypeOnly
                    && !(target.flags & 111551 /* Value */)
                    && !(node.flags & 8388608 /* Ambient */)) {
                    error(node, ts.Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type);
                }
            }
        }
        function checkImportBinding(node) {
            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            checkAliasSymbol(node);
        }
        function checkImportDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers);
            }
            if (checkExternalImportOrExportDeclaration(node)) {
                var importClause = node.importClause;
                if (importClause && !checkGrammarImportClause(importClause)) {
                    if (importClause.name) {
                        checkImportBinding(importClause);
                    }
                    if (importClause.namedBindings) {
                        if (importClause.namedBindings.kind === 256 /* NamespaceImport */) {
                            checkImportBinding(importClause.namedBindings);
                        }
                        else {
                            var moduleExisted = resolveExternalModuleName(node, node.moduleSpecifier);
                            if (moduleExisted) {
                                ts.forEach(importClause.namedBindings.elements, checkImportBinding);
                            }
                        }
                    }
                }
            }
        }
        function checkImportEqualsDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            checkGrammarDecoratorsAndModifiers(node);
            if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
                checkImportBinding(node);
                if (ts.hasModifier(node, 1 /* Export */)) {
                    markExportAsReferenced(node);
                }
                if (node.moduleReference.kind !== 265 /* ExternalModuleReference */) {
                    var target = resolveAlias(getSymbolOfNode(node));
                    if (target !== unknownSymbol) {
                        if (target.flags & 111551 /* Value */) {
                            // Target is a value symbol, check that it is not hidden by a local declaration with the same name
                            var moduleName = ts.getFirstIdentifier(node.moduleReference);
                            if (!(resolveEntityName(moduleName, 111551 /* Value */ | 1920 /* Namespace */).flags & 1920 /* Namespace */)) {
                                error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName));
                            }
                        }
                        if (target.flags & 788968 /* Type */) {
                            checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0);
                        }
                    }
                }
                else {
                    if (moduleKind >= ts.ModuleKind.ES2015 && !(node.flags & 8388608 /* Ambient */)) {
                        // Import equals declaration is deprecated in es6 or above
                        grammarErrorOnNode(node, ts.Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
                    }
                }
            }
        }
        function checkExportDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) {
                // If we hit an export in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers);
            }
            if (node.moduleSpecifier && node.exportClause && ts.isNamedExports(node.exportClause) && ts.length(node.exportClause.elements) && languageVersion === 0 /* ES3 */) {
                checkExternalEmitHelpers(node, 1048576 /* CreateBinding */);
            }
            checkGrammarExportDeclaration(node);
            if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
                if (node.exportClause && !ts.isNamespaceExport(node.exportClause)) {
                    // export { x, y }
                    // export { x, y } from "foo"
                    ts.forEach(node.exportClause.elements, checkExportSpecifier);
                    var inAmbientExternalModule = node.parent.kind === 250 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
                    var inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === 250 /* ModuleBlock */ &&
                        !node.moduleSpecifier && node.flags & 8388608 /* Ambient */;
                    if (node.parent.kind !== 290 /* SourceFile */ && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) {
                        error(node, ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace);
                    }
                }
                else {
                    // export * from "foo"
                    var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
                    if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
                        error(node.moduleSpecifier, ts.Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
                    }
                    else if (node.exportClause) {
                        checkAliasSymbol(node.exportClause);
                    }
                    if (moduleKind !== ts.ModuleKind.System && moduleKind < ts.ModuleKind.ES2015) {
                        checkExternalEmitHelpers(node, 65536 /* ExportStar */);
                    }
                }
            }
        }
        function checkGrammarExportDeclaration(node) {
            var _a;
            var isTypeOnlyExportStar = node.isTypeOnly && ((_a = node.exportClause) === null || _a === void 0 ? void 0 : _a.kind) !== 261 /* NamedExports */;
            if (isTypeOnlyExportStar) {
                grammarErrorOnNode(node, ts.Diagnostics.Only_named_exports_may_use_export_type);
            }
            return !isTypeOnlyExportStar;
        }
        function checkGrammarModuleElementContext(node, errorMessage) {
            var isInAppropriateContext = node.parent.kind === 290 /* SourceFile */ || node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 249 /* ModuleDeclaration */;
            if (!isInAppropriateContext) {
                grammarErrorOnFirstToken(node, errorMessage);
            }
            return !isInAppropriateContext;
        }
        function importClauseContainsReferencedImport(importClause) {
            return ts.forEachImportClauseDeclaration(importClause, function (declaration) {
                return !!getSymbolOfNode(declaration).isReferenced;
            });
        }
        function importClauseContainsConstEnumUsedAsValue(importClause) {
            return ts.forEachImportClauseDeclaration(importClause, function (declaration) {
                return !!getSymbolLinks(getSymbolOfNode(declaration)).constEnumReferenced;
            });
        }
        function checkImportsForTypeOnlyConversion(sourceFile) {
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (ts.isImportDeclaration(statement) &&
                    statement.importClause &&
                    !statement.importClause.isTypeOnly &&
                    importClauseContainsReferencedImport(statement.importClause) &&
                    !isReferencedAliasDeclaration(statement.importClause, /*checkChildren*/ true) &&
                    !importClauseContainsConstEnumUsedAsValue(statement.importClause)) {
                    error(statement, ts.Diagnostics.This_import_is_never_used_as_a_value_and_must_use_import_type_because_the_importsNotUsedAsValues_is_set_to_error);
                }
            }
        }
        function checkExportSpecifier(node) {
            checkAliasSymbol(node);
            if (ts.getEmitDeclarations(compilerOptions)) {
                collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true);
            }
            if (!node.parent.parent.moduleSpecifier) {
                var exportedName = node.propertyName || node.name;
                // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases)
                var symbol = resolveName(exportedName, exportedName.escapedText, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, 
                /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
                if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {
                    error(exportedName, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, ts.idText(exportedName));
                }
                else {
                    markExportAsReferenced(node);
                    var target = symbol && (symbol.flags & 2097152 /* Alias */ ? resolveAlias(symbol) : symbol);
                    if (!target || target === unknownSymbol || target.flags & 111551 /* Value */) {
                        checkExpressionCached(node.propertyName || node.name);
                    }
                }
            }
        }
        function checkExportAssignment(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) {
                // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            var container = node.parent.kind === 290 /* SourceFile */ ? node.parent : node.parent.parent;
            if (container.kind === 249 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                if (node.isExportEquals) {
                    error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace);
                }
                else {
                    error(node, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
                }
                return;
            }
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers);
            }
            if (node.expression.kind === 75 /* Identifier */) {
                var id = node.expression;
                var sym = resolveEntityName(id, 67108863 /* All */, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node);
                if (sym) {
                    markAliasReferenced(sym, id);
                    // If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`)
                    var target = sym.flags & 2097152 /* Alias */ ? resolveAlias(sym) : sym;
                    if (target === unknownSymbol || target.flags & 111551 /* Value */) {
                        // However if it is a value, we need to check it's being used correctly
                        checkExpressionCached(node.expression);
                    }
                }
                if (ts.getEmitDeclarations(compilerOptions)) {
                    collectLinkedAliases(node.expression, /*setVisibility*/ true);
                }
            }
            else {
                checkExpressionCached(node.expression);
            }
            checkExternalModuleExports(container);
            if ((node.flags & 8388608 /* Ambient */) && !ts.isEntityNameExpression(node.expression)) {
                grammarErrorOnNode(node.expression, ts.Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context);
            }
            if (node.isExportEquals && !(node.flags & 8388608 /* Ambient */)) {
                if (moduleKind >= ts.ModuleKind.ES2015) {
                    // export assignment is not supported in es6 modules
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead);
                }
                else if (moduleKind === ts.ModuleKind.System) {
                    // system modules does not support export assignment
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system);
                }
            }
        }
        function hasExportedMembers(moduleSymbol) {
            return ts.forEachEntry(moduleSymbol.exports, function (_, id) { return id !== "export="; });
        }
        function checkExternalModuleExports(node) {
            var moduleSymbol = getSymbolOfNode(node);
            var links = getSymbolLinks(moduleSymbol);
            if (!links.exportsChecked) {
                var exportEqualsSymbol = moduleSymbol.exports.get("export=");
                if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) {
                    var declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration;
                    if (!isTopLevelInExternalModuleAugmentation(declaration) && !ts.isInJSFile(declaration)) {
                        error(declaration, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
                    }
                }
                // Checks for export * conflicts
                var exports_2 = getExportsOfModule(moduleSymbol);
                if (exports_2) {
                    exports_2.forEach(function (_a, id) {
                        var declarations = _a.declarations, flags = _a.flags;
                        if (id === "__export") {
                            return;
                        }
                        // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
                        // (TS Exceptions: namespaces, function overloads, enums, and interfaces)
                        if (flags & (1920 /* Namespace */ | 64 /* Interface */ | 384 /* Enum */)) {
                            return;
                        }
                        var exportedDeclarationsCount = ts.countWhere(declarations, isNotOverloadAndNotAccessor);
                        if (flags & 524288 /* TypeAlias */ && exportedDeclarationsCount <= 2) {
                            // it is legal to merge type alias with other values
                            // so count should be either 1 (just type alias) or 2 (type alias + merged value)
                            return;
                        }
                        if (exportedDeclarationsCount > 1) {
                            for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) {
                                var declaration = declarations_9[_i];
                                if (isNotOverload(declaration)) {
                                    diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id)));
                                }
                            }
                        }
                    });
                }
                links.exportsChecked = true;
            }
        }
        function checkSourceElement(node) {
            if (node) {
                var saveCurrentNode = currentNode;
                currentNode = node;
                instantiationCount = 0;
                checkSourceElementWorker(node);
                currentNode = saveCurrentNode;
            }
        }
        function checkSourceElementWorker(node) {
            if (ts.isInJSFile(node)) {
                ts.forEach(node.jsDoc, function (_a) {
                    var tags = _a.tags;
                    return ts.forEach(tags, checkSourceElement);
                });
            }
            var kind = node.kind;
            if (cancellationToken) {
                // Only bother checking on a few construct kinds.  We don't want to be excessively
                // hitting the cancellation token on every node we check.
                switch (kind) {
                    case 249 /* ModuleDeclaration */:
                    case 245 /* ClassDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                    case 244 /* FunctionDeclaration */:
                        cancellationToken.throwIfCancellationRequested();
                }
            }
            if (kind >= 225 /* FirstStatement */ && kind <= 241 /* LastStatement */ && node.flowNode && !isReachableFlowNode(node.flowNode)) {
                errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, ts.Diagnostics.Unreachable_code_detected);
            }
            switch (kind) {
                case 155 /* TypeParameter */:
                    return checkTypeParameter(node);
                case 156 /* Parameter */:
                    return checkParameter(node);
                case 159 /* PropertyDeclaration */:
                    return checkPropertyDeclaration(node);
                case 158 /* PropertySignature */:
                    return checkPropertySignature(node);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 167 /* IndexSignature */:
                    return checkSignatureDeclaration(node);
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    return checkMethodDeclaration(node);
                case 162 /* Constructor */:
                    return checkConstructorDeclaration(node);
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return checkAccessorDeclaration(node);
                case 169 /* TypeReference */:
                    return checkTypeReferenceNode(node);
                case 168 /* TypePredicate */:
                    return checkTypePredicate(node);
                case 172 /* TypeQuery */:
                    return checkTypeQuery(node);
                case 173 /* TypeLiteral */:
                    return checkTypeLiteral(node);
                case 174 /* ArrayType */:
                    return checkArrayType(node);
                case 175 /* TupleType */:
                    return checkTupleType(node);
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                    return checkUnionOrIntersectionType(node);
                case 182 /* ParenthesizedType */:
                case 176 /* OptionalType */:
                case 177 /* RestType */:
                    return checkSourceElement(node.type);
                case 183 /* ThisType */:
                    return checkThisType(node);
                case 184 /* TypeOperator */:
                    return checkTypeOperator(node);
                case 180 /* ConditionalType */:
                    return checkConditionalType(node);
                case 181 /* InferType */:
                    return checkInferType(node);
                case 188 /* ImportType */:
                    return checkImportType(node);
                case 307 /* JSDocAugmentsTag */:
                    return checkJSDocAugmentsTag(node);
                case 308 /* JSDocImplementsTag */:
                    return checkJSDocImplementsTag(node);
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 316 /* JSDocEnumTag */:
                    return checkJSDocTypeAliasTag(node);
                case 321 /* JSDocTemplateTag */:
                    return checkJSDocTemplateTag(node);
                case 320 /* JSDocTypeTag */:
                    return checkJSDocTypeTag(node);
                case 317 /* JSDocParameterTag */:
                    return checkJSDocParameterTag(node);
                case 323 /* JSDocPropertyTag */:
                    return checkJSDocPropertyTag(node);
                case 300 /* JSDocFunctionType */:
                    checkJSDocFunctionType(node);
                // falls through
                case 298 /* JSDocNonNullableType */:
                case 297 /* JSDocNullableType */:
                case 295 /* JSDocAllType */:
                case 296 /* JSDocUnknownType */:
                case 304 /* JSDocTypeLiteral */:
                    checkJSDocTypeIsInJsFile(node);
                    ts.forEachChild(node, checkSourceElement);
                    return;
                case 301 /* JSDocVariadicType */:
                    checkJSDocVariadicType(node);
                    return;
                case 294 /* JSDocTypeExpression */:
                    return checkSourceElement(node.type);
                case 185 /* IndexedAccessType */:
                    return checkIndexedAccessType(node);
                case 186 /* MappedType */:
                    return checkMappedType(node);
                case 244 /* FunctionDeclaration */:
                    return checkFunctionDeclaration(node);
                case 223 /* Block */:
                case 250 /* ModuleBlock */:
                    return checkBlock(node);
                case 225 /* VariableStatement */:
                    return checkVariableStatement(node);
                case 226 /* ExpressionStatement */:
                    return checkExpressionStatement(node);
                case 227 /* IfStatement */:
                    return checkIfStatement(node);
                case 228 /* DoStatement */:
                    return checkDoStatement(node);
                case 229 /* WhileStatement */:
                    return checkWhileStatement(node);
                case 230 /* ForStatement */:
                    return checkForStatement(node);
                case 231 /* ForInStatement */:
                    return checkForInStatement(node);
                case 232 /* ForOfStatement */:
                    return checkForOfStatement(node);
                case 233 /* ContinueStatement */:
                case 234 /* BreakStatement */:
                    return checkBreakOrContinueStatement(node);
                case 235 /* ReturnStatement */:
                    return checkReturnStatement(node);
                case 236 /* WithStatement */:
                    return checkWithStatement(node);
                case 237 /* SwitchStatement */:
                    return checkSwitchStatement(node);
                case 238 /* LabeledStatement */:
                    return checkLabeledStatement(node);
                case 239 /* ThrowStatement */:
                    return checkThrowStatement(node);
                case 240 /* TryStatement */:
                    return checkTryStatement(node);
                case 242 /* VariableDeclaration */:
                    return checkVariableDeclaration(node);
                case 191 /* BindingElement */:
                    return checkBindingElement(node);
                case 245 /* ClassDeclaration */:
                    return checkClassDeclaration(node);
                case 246 /* InterfaceDeclaration */:
                    return checkInterfaceDeclaration(node);
                case 247 /* TypeAliasDeclaration */:
                    return checkTypeAliasDeclaration(node);
                case 248 /* EnumDeclaration */:
                    return checkEnumDeclaration(node);
                case 249 /* ModuleDeclaration */:
                    return checkModuleDeclaration(node);
                case 254 /* ImportDeclaration */:
                    return checkImportDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    return checkImportEqualsDeclaration(node);
                case 260 /* ExportDeclaration */:
                    return checkExportDeclaration(node);
                case 259 /* ExportAssignment */:
                    return checkExportAssignment(node);
                case 224 /* EmptyStatement */:
                case 241 /* DebuggerStatement */:
                    checkGrammarStatementInAmbientContext(node);
                    return;
                case 264 /* MissingDeclaration */:
                    return checkMissingDeclaration(node);
            }
        }
        function checkJSDocTypeIsInJsFile(node) {
            if (!ts.isInJSFile(node)) {
                grammarErrorOnNode(node, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
            }
        }
        function checkJSDocVariadicType(node) {
            checkJSDocTypeIsInJsFile(node);
            checkSourceElement(node.type);
            // Only legal location is in the *last* parameter tag or last parameter of a JSDoc function.
            var parent = node.parent;
            if (ts.isParameter(parent) && ts.isJSDocFunctionType(parent.parent)) {
                if (ts.last(parent.parent.parameters) !== parent) {
                    error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
                }
                return;
            }
            if (!ts.isJSDocTypeExpression(parent)) {
                error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature);
            }
            var paramTag = node.parent.parent;
            if (!ts.isJSDocParameterTag(paramTag)) {
                error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature);
                return;
            }
            var param = ts.getParameterSymbolFromJSDoc(paramTag);
            if (!param) {
                // We will error in `checkJSDocParameterTag`.
                return;
            }
            var host = ts.getHostSignatureFromJSDoc(paramTag);
            if (!host || ts.last(host.parameters).symbol !== param) {
                error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
            }
        }
        function getTypeFromJSDocVariadicType(node) {
            var type = getTypeFromTypeNode(node.type);
            var parent = node.parent;
            var paramTag = node.parent.parent;
            if (ts.isJSDocTypeExpression(node.parent) && ts.isJSDocParameterTag(paramTag)) {
                // Else we will add a diagnostic, see `checkJSDocVariadicType`.
                var host_1 = ts.getHostSignatureFromJSDoc(paramTag);
                if (host_1) {
                    /*
                    Only return an array type if the corresponding parameter is marked as a rest parameter, or if there are no parameters.
                    So in the following situation we will not create an array type:
                        /** @param {...number} a * /
                        function f(a) {}
                    Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type.
                    */
                    var lastParamDeclaration = ts.lastOrUndefined(host_1.parameters);
                    var symbol = ts.getParameterSymbolFromJSDoc(paramTag);
                    if (!lastParamDeclaration ||
                        symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) {
                        return createArrayType(type);
                    }
                }
            }
            if (ts.isParameter(parent) && ts.isJSDocFunctionType(parent.parent)) {
                return createArrayType(type);
            }
            return addOptionality(type);
        }
        // Function and class expression bodies are checked after all statements in the enclosing body. This is
        // to ensure constructs like the following are permitted:
        //     const foo = function () {
        //        const s = foo();
        //        return "hello";
        //     }
        // Here, performing a full type check of the body of the function expression whilst in the process of
        // determining the type of foo would cause foo to be given type any because of the recursive reference.
        // Delaying the type check of the body ensures foo has been assigned a type.
        function checkNodeDeferred(node) {
            var enclosingFile = ts.getSourceFileOfNode(node);
            var links = getNodeLinks(enclosingFile);
            if (!(links.flags & 1 /* TypeChecked */)) {
                links.deferredNodes = links.deferredNodes || ts.createMap();
                var id = "" + getNodeId(node);
                links.deferredNodes.set(id, node);
            }
        }
        function checkDeferredNodes(context) {
            var links = getNodeLinks(context);
            if (links.deferredNodes) {
                links.deferredNodes.forEach(checkDeferredNode);
            }
        }
        function checkDeferredNode(node) {
            var saveCurrentNode = currentNode;
            currentNode = node;
            instantiationCount = 0;
            switch (node.kind) {
                case 196 /* CallExpression */:
                case 197 /* NewExpression */:
                case 198 /* TaggedTemplateExpression */:
                case 157 /* Decorator */:
                case 268 /* JsxOpeningElement */:
                    // These node kinds are deferred checked when overload resolution fails
                    // To save on work, we ensure the arguments are checked just once, in
                    // a deferred way
                    resolveUntypedCall(node);
                    break;
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    checkFunctionExpressionOrObjectLiteralMethodDeferred(node);
                    break;
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    checkAccessorDeclaration(node);
                    break;
                case 214 /* ClassExpression */:
                    checkClassExpressionDeferred(node);
                    break;
                case 267 /* JsxSelfClosingElement */:
                    checkJsxSelfClosingElementDeferred(node);
                    break;
                case 266 /* JsxElement */:
                    checkJsxElementDeferred(node);
                    break;
            }
            currentNode = saveCurrentNode;
        }
        function checkSourceFile(node) {
            ts.performance.mark("beforeCheck");
            checkSourceFileWorker(node);
            ts.performance.mark("afterCheck");
            ts.performance.measure("Check", "beforeCheck", "afterCheck");
        }
        function unusedIsError(kind, isAmbient) {
            if (isAmbient) {
                return false;
            }
            switch (kind) {
                case 0 /* Local */:
                    return !!compilerOptions.noUnusedLocals;
                case 1 /* Parameter */:
                    return !!compilerOptions.noUnusedParameters;
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function getPotentiallyUnusedIdentifiers(sourceFile) {
            return allPotentiallyUnusedIdentifiers.get(sourceFile.path) || ts.emptyArray;
        }
        // Fully type check a source file and collect the relevant diagnostics.
        function checkSourceFileWorker(node) {
            var links = getNodeLinks(node);
            if (!(links.flags & 1 /* TypeChecked */)) {
                if (ts.skipTypeChecking(node, compilerOptions, host)) {
                    return;
                }
                // Grammar checking
                checkGrammarSourceFile(node);
                ts.clear(potentialThisCollisions);
                ts.clear(potentialNewTargetCollisions);
                ts.clear(potentialWeakMapCollisions);
                ts.forEach(node.statements, checkSourceElement);
                checkSourceElement(node.endOfFileToken);
                checkDeferredNodes(node);
                if (ts.isExternalOrCommonJsModule(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
                if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
                    checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), function (containingNode, kind, diag) {
                        if (!ts.containsParseError(containingNode) && unusedIsError(kind, !!(containingNode.flags & 8388608 /* Ambient */))) {
                            diagnostics.add(diag);
                        }
                    });
                }
                if (compilerOptions.importsNotUsedAsValues === 2 /* Error */ &&
                    !node.isDeclarationFile &&
                    ts.isExternalModule(node)) {
                    checkImportsForTypeOnlyConversion(node);
                }
                if (ts.isExternalOrCommonJsModule(node)) {
                    checkExternalModuleExports(node);
                }
                if (potentialThisCollisions.length) {
                    ts.forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
                    ts.clear(potentialThisCollisions);
                }
                if (potentialNewTargetCollisions.length) {
                    ts.forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope);
                    ts.clear(potentialNewTargetCollisions);
                }
                if (potentialWeakMapCollisions.length) {
                    ts.forEach(potentialWeakMapCollisions, checkWeakMapCollision);
                    ts.clear(potentialWeakMapCollisions);
                }
                links.flags |= 1 /* TypeChecked */;
            }
        }
        function getDiagnostics(sourceFile, ct) {
            try {
                // Record the cancellation token so it can be checked later on during checkSourceElement.
                // Do this in a finally block so we can ensure that it gets reset back to nothing after
                // this call is done.
                cancellationToken = ct;
                return getDiagnosticsWorker(sourceFile);
            }
            finally {
                cancellationToken = undefined;
            }
        }
        function getDiagnosticsWorker(sourceFile) {
            throwIfNonDiagnosticsProducing();
            if (sourceFile) {
                // Some global diagnostics are deferred until they are needed and
                // may not be reported in the first call to getGlobalDiagnostics.
                // We should catch these changes and report them.
                var previousGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
                var previousGlobalDiagnosticsSize = previousGlobalDiagnostics.length;
                checkSourceFile(sourceFile);
                var semanticDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
                var currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
                if (currentGlobalDiagnostics !== previousGlobalDiagnostics) {
                    // If the arrays are not the same reference, new diagnostics were added.
                    var deferredGlobalDiagnostics = ts.relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, ts.compareDiagnostics);
                    return ts.concatenate(deferredGlobalDiagnostics, semanticDiagnostics);
                }
                else if (previousGlobalDiagnosticsSize === 0 && currentGlobalDiagnostics.length > 0) {
                    // If the arrays are the same reference, but the length has changed, a single
                    // new diagnostic was added as DiagnosticCollection attempts to reuse the
                    // same array.
                    return ts.concatenate(currentGlobalDiagnostics, semanticDiagnostics);
                }
                return semanticDiagnostics;
            }
            // Global diagnostics are always added when a file is not provided to
            // getDiagnostics
            ts.forEach(host.getSourceFiles(), checkSourceFile);
            return diagnostics.getDiagnostics();
        }
        function getGlobalDiagnostics() {
            throwIfNonDiagnosticsProducing();
            return diagnostics.getGlobalDiagnostics();
        }
        function throwIfNonDiagnosticsProducing() {
            if (!produceDiagnostics) {
                throw new Error("Trying to get diagnostics from a type checker that does not produce them.");
            }
        }
        // Language service support
        function getSymbolsInScope(location, meaning) {
            if (location.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return [];
            }
            var symbols = ts.createSymbolTable();
            var isStatic = false;
            populateSymbols();
            symbols.delete("this" /* This */); // Not a symbol, a keyword
            return symbolsToArray(symbols);
            function populateSymbols() {
                while (location) {
                    if (location.locals && !isGlobalSourceFile(location)) {
                        copySymbols(location.locals, meaning);
                    }
                    switch (location.kind) {
                        case 290 /* SourceFile */:
                            if (!ts.isExternalOrCommonJsModule(location))
                                break;
                        // falls through
                        case 249 /* ModuleDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 2623475 /* ModuleMember */);
                            break;
                        case 248 /* EnumDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 8 /* EnumMember */);
                            break;
                        case 214 /* ClassExpression */:
                            var className = location.name;
                            if (className) {
                                copySymbol(location.symbol, meaning);
                            }
                        // this fall-through is necessary because we would like to handle
                        // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration.
                        // falls through
                        case 245 /* ClassDeclaration */:
                        case 246 /* InterfaceDeclaration */:
                            // If we didn't come from static member of class or interface,
                            // add the type parameters into the symbol table
                            // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol.
                            // Note: that the memberFlags come from previous iteration.
                            if (!isStatic) {
                                copySymbols(getMembersOfSymbol(getSymbolOfNode(location)), meaning & 788968 /* Type */);
                            }
                            break;
                        case 201 /* FunctionExpression */:
                            var funcName = location.name;
                            if (funcName) {
                                copySymbol(location.symbol, meaning);
                            }
                            break;
                    }
                    if (ts.introducesArgumentsExoticObject(location)) {
                        copySymbol(argumentsSymbol, meaning);
                    }
                    isStatic = ts.hasModifier(location, 32 /* Static */);
                    location = location.parent;
                }
                copySymbols(globals, meaning);
            }
            /**
             * Copy the given symbol into symbol tables if the symbol has the given meaning
             * and it doesn't already existed in the symbol table
             * @param key a key for storing in symbol table; if undefined, use symbol.name
             * @param symbol the symbol to be added into symbol table
             * @param meaning meaning of symbol to filter by before adding to symbol table
             */
            function copySymbol(symbol, meaning) {
                if (ts.getCombinedLocalAndExportSymbolFlags(symbol) & meaning) {
                    var id = symbol.escapedName;
                    // We will copy all symbol regardless of its reserved name because
                    // symbolsToArray will check whether the key is a reserved name and
                    // it will not copy symbol with reserved name to the array
                    if (!symbols.has(id)) {
                        symbols.set(id, symbol);
                    }
                }
            }
            function copySymbols(source, meaning) {
                if (meaning) {
                    source.forEach(function (symbol) {
                        copySymbol(symbol, meaning);
                    });
                }
            }
        }
        function isTypeDeclarationName(name) {
            return name.kind === 75 /* Identifier */ &&
                isTypeDeclaration(name.parent) &&
                name.parent.name === name;
        }
        function isTypeDeclaration(node) {
            switch (node.kind) {
                case 155 /* TypeParameter */:
                case 245 /* ClassDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 248 /* EnumDeclaration */:
                    return true;
                case 255 /* ImportClause */:
                    return node.isTypeOnly;
                case 258 /* ImportSpecifier */:
                case 263 /* ExportSpecifier */:
                    return node.parent.parent.isTypeOnly;
                default:
                    return false;
            }
        }
        // True if the given identifier is part of a type reference
        function isTypeReferenceIdentifier(node) {
            while (node.parent.kind === 153 /* QualifiedName */) {
                node = node.parent;
            }
            return node.parent.kind === 169 /* TypeReference */;
        }
        function isHeritageClauseElementIdentifier(node) {
            while (node.parent.kind === 194 /* PropertyAccessExpression */) {
                node = node.parent;
            }
            return node.parent.kind === 216 /* ExpressionWithTypeArguments */;
        }
        function forEachEnclosingClass(node, callback) {
            var result;
            while (true) {
                node = ts.getContainingClass(node);
                if (!node)
                    break;
                if (result = callback(node))
                    break;
            }
            return result;
        }
        function isNodeUsedDuringClassInitialization(node) {
            return !!ts.findAncestor(node, function (element) {
                if (ts.isConstructorDeclaration(element) && ts.nodeIsPresent(element.body) || ts.isPropertyDeclaration(element)) {
                    return true;
                }
                else if (ts.isClassLike(element) || ts.isFunctionLikeDeclaration(element)) {
                    return "quit";
                }
                return false;
            });
        }
        function isNodeWithinClass(node, classDeclaration) {
            return !!forEachEnclosingClass(node, function (n) { return n === classDeclaration; });
        }
        function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) {
            while (nodeOnRightSide.parent.kind === 153 /* QualifiedName */) {
                nodeOnRightSide = nodeOnRightSide.parent;
            }
            if (nodeOnRightSide.parent.kind === 253 /* ImportEqualsDeclaration */) {
                return nodeOnRightSide.parent.moduleReference === nodeOnRightSide ? nodeOnRightSide.parent : undefined;
            }
            if (nodeOnRightSide.parent.kind === 259 /* ExportAssignment */) {
                return nodeOnRightSide.parent.expression === nodeOnRightSide ? nodeOnRightSide.parent : undefined;
            }
            return undefined;
        }
        function isInRightSideOfImportOrExportAssignment(node) {
            return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined;
        }
        function getSpecialPropertyAssignmentSymbolFromEntityName(entityName) {
            var specialPropertyAssignmentKind = ts.getAssignmentDeclarationKind(entityName.parent.parent);
            switch (specialPropertyAssignmentKind) {
                case 1 /* ExportsProperty */:
                case 3 /* PrototypeProperty */:
                    return getSymbolOfNode(entityName.parent);
                case 4 /* ThisProperty */:
                case 2 /* ModuleExports */:
                case 5 /* Property */:
                    return getSymbolOfNode(entityName.parent.parent);
            }
        }
        function isImportTypeQualifierPart(node) {
            var parent = node.parent;
            while (ts.isQualifiedName(parent)) {
                node = parent;
                parent = parent.parent;
            }
            if (parent && parent.kind === 188 /* ImportType */ && parent.qualifier === node) {
                return parent;
            }
            return undefined;
        }
        function getSymbolOfNameOrPropertyAccessExpression(name) {
            if (ts.isDeclarationName(name)) {
                return getSymbolOfNode(name.parent);
            }
            if (ts.isInJSFile(name) &&
                name.parent.kind === 194 /* PropertyAccessExpression */ &&
                name.parent === name.parent.parent.left) {
                // Check if this is a special property assignment
                if (!ts.isPrivateIdentifier(name)) {
                    var specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(name);
                    if (specialPropertyAssignmentSymbol) {
                        return specialPropertyAssignmentSymbol;
                    }
                }
            }
            if (name.parent.kind === 259 /* ExportAssignment */ && ts.isEntityNameExpression(name)) {
                // Even an entity name expression that doesn't resolve as an entityname may still typecheck as a property access expression
                var success = resolveEntityName(name, 
                /*all meanings*/ 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, /*ignoreErrors*/ true);
                if (success && success !== unknownSymbol) {
                    return success;
                }
            }
            else if (!ts.isPropertyAccessExpression(name) && !ts.isPrivateIdentifier(name) && isInRightSideOfImportOrExportAssignment(name)) {
                // Since we already checked for ExportAssignment, this really could only be an Import
                var importEqualsDeclaration = ts.getAncestor(name, 253 /* ImportEqualsDeclaration */);
                ts.Debug.assert(importEqualsDeclaration !== undefined);
                return getSymbolOfPartOfRightHandSideOfImportEquals(name, /*dontResolveAlias*/ true);
            }
            if (!ts.isPropertyAccessExpression(name) && !ts.isPrivateIdentifier(name)) {
                var possibleImportNode = isImportTypeQualifierPart(name);
                if (possibleImportNode) {
                    getTypeFromTypeNode(possibleImportNode);
                    var sym = getNodeLinks(name).resolvedSymbol;
                    return sym === unknownSymbol ? undefined : sym;
                }
            }
            while (ts.isRightSideOfQualifiedNameOrPropertyAccess(name)) {
                name = name.parent;
            }
            if (isHeritageClauseElementIdentifier(name)) {
                var meaning = 0 /* None */;
                // In an interface or class, we're definitely interested in a type.
                if (name.parent.kind === 216 /* ExpressionWithTypeArguments */) {
                    meaning = 788968 /* Type */;
                    // In a class 'extends' clause we are also looking for a value.
                    if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(name.parent)) {
                        meaning |= 111551 /* Value */;
                    }
                }
                else {
                    meaning = 1920 /* Namespace */;
                }
                meaning |= 2097152 /* Alias */;
                var entityNameSymbol = ts.isEntityNameExpression(name) ? resolveEntityName(name, meaning) : undefined;
                if (entityNameSymbol) {
                    return entityNameSymbol;
                }
            }
            if (name.parent.kind === 317 /* JSDocParameterTag */) {
                return ts.getParameterSymbolFromJSDoc(name.parent);
            }
            if (name.parent.kind === 155 /* TypeParameter */ && name.parent.parent.kind === 321 /* JSDocTemplateTag */) {
                ts.Debug.assert(!ts.isInJSFile(name)); // Otherwise `isDeclarationName` would have been true.
                var typeParameter = ts.getTypeParameterFromJsDoc(name.parent);
                return typeParameter && typeParameter.symbol;
            }
            if (ts.isExpressionNode(name)) {
                if (ts.nodeIsMissing(name)) {
                    // Missing entity name.
                    return undefined;
                }
                if (name.kind === 75 /* Identifier */) {
                    if (ts.isJSXTagName(name) && isJsxIntrinsicIdentifier(name)) {
                        var symbol = getIntrinsicTagSymbol(name.parent);
                        return symbol === unknownSymbol ? undefined : symbol;
                    }
                    return resolveEntityName(name, 111551 /* Value */, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
                }
                else if (name.kind === 194 /* PropertyAccessExpression */ || name.kind === 153 /* QualifiedName */) {
                    var links = getNodeLinks(name);
                    if (links.resolvedSymbol) {
                        return links.resolvedSymbol;
                    }
                    if (name.kind === 194 /* PropertyAccessExpression */) {
                        checkPropertyAccessExpression(name);
                    }
                    else {
                        checkQualifiedName(name);
                    }
                    return links.resolvedSymbol;
                }
            }
            else if (isTypeReferenceIdentifier(name)) {
                var meaning = name.parent.kind === 169 /* TypeReference */ ? 788968 /* Type */ : 1920 /* Namespace */;
                return resolveEntityName(name, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
            }
            if (name.parent.kind === 168 /* TypePredicate */) {
                return resolveEntityName(name, /*meaning*/ 1 /* FunctionScopedVariable */);
            }
            // Do we want to return undefined here?
            return undefined;
        }
        function getSymbolAtLocation(node, ignoreErrors) {
            if (node.kind === 290 /* SourceFile */) {
                return ts.isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined;
            }
            var parent = node.parent;
            var grandParent = parent.parent;
            if (node.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            if (isDeclarationNameOrImportPropertyName(node)) {
                // This is a declaration, call getSymbolOfNode
                var parentSymbol = getSymbolOfNode(parent);
                return ts.isImportOrExportSpecifier(node.parent) && node.parent.propertyName === node
                    ? getImmediateAliasedSymbol(parentSymbol)
                    : parentSymbol;
            }
            else if (ts.isLiteralComputedPropertyDeclarationName(node)) {
                return getSymbolOfNode(parent.parent);
            }
            if (node.kind === 75 /* Identifier */) {
                if (isInRightSideOfImportOrExportAssignment(node)) {
                    return getSymbolOfNameOrPropertyAccessExpression(node);
                }
                else if (parent.kind === 191 /* BindingElement */ &&
                    grandParent.kind === 189 /* ObjectBindingPattern */ &&
                    node === parent.propertyName) {
                    var typeOfPattern = getTypeOfNode(grandParent);
                    var propertyDeclaration = getPropertyOfType(typeOfPattern, node.escapedText);
                    if (propertyDeclaration) {
                        return propertyDeclaration;
                    }
                }
            }
            switch (node.kind) {
                case 75 /* Identifier */:
                case 76 /* PrivateIdentifier */:
                case 194 /* PropertyAccessExpression */:
                case 153 /* QualifiedName */:
                    return getSymbolOfNameOrPropertyAccessExpression(node);
                case 104 /* ThisKeyword */:
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    if (ts.isFunctionLike(container)) {
                        var sig = getSignatureFromDeclaration(container);
                        if (sig.thisParameter) {
                            return sig.thisParameter;
                        }
                    }
                    if (ts.isInExpressionContext(node)) {
                        return checkExpression(node).symbol;
                    }
                // falls through
                case 183 /* ThisType */:
                    return getTypeFromThisTypeNode(node).symbol;
                case 102 /* SuperKeyword */:
                    return checkExpression(node).symbol;
                case 129 /* ConstructorKeyword */:
                    // constructor keyword for an overload, should take us to the definition if it exist
                    var constructorDeclaration = node.parent;
                    if (constructorDeclaration && constructorDeclaration.kind === 162 /* Constructor */) {
                        return constructorDeclaration.parent.symbol;
                    }
                    return undefined;
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    // 1). import x = require("./mo/*gotToDefinitionHere*/d")
                    // 2). External module name in an import declaration
                    // 3). Dynamic import call or require in javascript
                    // 4). type A = import("./f/*gotToDefinitionHere*/oo")
                    if ((ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
                        ((node.parent.kind === 254 /* ImportDeclaration */ || node.parent.kind === 260 /* ExportDeclaration */) && node.parent.moduleSpecifier === node) ||
                        ((ts.isInJSFile(node) && ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || ts.isImportCall(node.parent)) ||
                        (ts.isLiteralTypeNode(node.parent) && ts.isLiteralImportTypeNode(node.parent.parent) && node.parent.parent.argument === node.parent)) {
                        return resolveExternalModuleName(node, node, ignoreErrors);
                    }
                    if (ts.isCallExpression(parent) && ts.isBindableObjectDefinePropertyCall(parent) && parent.arguments[1] === node) {
                        return getSymbolOfNode(parent);
                    }
                // falls through
                case 8 /* NumericLiteral */:
                    // index access
                    var objectType = ts.isElementAccessExpression(parent)
                        ? parent.argumentExpression === node ? getTypeOfExpression(parent.expression) : undefined
                        : ts.isLiteralTypeNode(parent) && ts.isIndexedAccessTypeNode(grandParent)
                            ? getTypeFromTypeNode(grandParent.objectType)
                            : undefined;
                    return objectType && getPropertyOfType(objectType, ts.escapeLeadingUnderscores(node.text));
                case 84 /* DefaultKeyword */:
                case 94 /* FunctionKeyword */:
                case 38 /* EqualsGreaterThanToken */:
                case 80 /* ClassKeyword */:
                    return getSymbolOfNode(node.parent);
                case 188 /* ImportType */:
                    return ts.isLiteralImportTypeNode(node) ? getSymbolAtLocation(node.argument.literal, ignoreErrors) : undefined;
                case 89 /* ExportKeyword */:
                    return ts.isExportAssignment(node.parent) ? ts.Debug.checkDefined(node.parent.symbol) : undefined;
                default:
                    return undefined;
            }
        }
        function getShorthandAssignmentValueSymbol(location) {
            if (location && location.kind === 282 /* ShorthandPropertyAssignment */) {
                return resolveEntityName(location.name, 111551 /* Value */ | 2097152 /* Alias */);
            }
            return undefined;
        }
        /** Returns the target of an export specifier without following aliases */
        function getExportSpecifierLocalTargetSymbol(node) {
            return node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node) :
                resolveEntityName(node.propertyName || node.name, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
        }
        function getTypeOfNode(node) {
            if (node.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return errorType;
            }
            var classDecl = ts.tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
            var classType = classDecl && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(classDecl.class));
            if (ts.isPartOfTypeNode(node)) {
                var typeFromTypeNode = getTypeFromTypeNode(node);
                return classType ? getTypeWithThisArgument(typeFromTypeNode, classType.thisType) : typeFromTypeNode;
            }
            if (ts.isExpressionNode(node)) {
                return getRegularTypeOfExpression(node);
            }
            if (classType && !classDecl.isImplements) {
                // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
                // extends clause of a class. We handle that case here.
                var baseType = ts.firstOrUndefined(getBaseTypes(classType));
                return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType;
            }
            if (isTypeDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                var symbol = getSymbolOfNode(node);
                return getDeclaredTypeOfSymbol(symbol);
            }
            if (isTypeDeclarationName(node)) {
                var symbol = getSymbolAtLocation(node);
                return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
            }
            if (ts.isDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                var symbol = getSymbolOfNode(node);
                return getTypeOfSymbol(symbol);
            }
            if (isDeclarationNameOrImportPropertyName(node)) {
                var symbol = getSymbolAtLocation(node);
                if (symbol) {
                    return getTypeOfSymbol(symbol);
                }
                return errorType;
            }
            if (ts.isBindingPattern(node)) {
                return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true) || errorType;
            }
            if (isInRightSideOfImportOrExportAssignment(node)) {
                var symbol = getSymbolAtLocation(node);
                if (symbol) {
                    var declaredType = getDeclaredTypeOfSymbol(symbol);
                    return declaredType !== errorType ? declaredType : getTypeOfSymbol(symbol);
                }
            }
            return errorType;
        }
        // Gets the type of object literal or array literal of destructuring assignment.
        // { a } from
        //     for ( { a } of elems) {
        //     }
        // [ a ] from
        //     [a] = [ some array ...]
        function getTypeOfAssignmentPattern(expr) {
            ts.Debug.assert(expr.kind === 193 /* ObjectLiteralExpression */ || expr.kind === 192 /* ArrayLiteralExpression */);
            // If this is from "for of"
            //     for ( { a } of elems) {
            //     }
            if (expr.parent.kind === 232 /* ForOfStatement */) {
                var iteratedType = checkRightHandSideOfForOf(expr.parent);
                return checkDestructuringAssignment(expr, iteratedType || errorType);
            }
            // If this is from "for" initializer
            //     for ({a } = elems[0];.....) { }
            if (expr.parent.kind === 209 /* BinaryExpression */) {
                var iteratedType = getTypeOfExpression(expr.parent.right);
                return checkDestructuringAssignment(expr, iteratedType || errorType);
            }
            // If this is from nested object binding pattern
            //     for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
            if (expr.parent.kind === 281 /* PropertyAssignment */) {
                var node_4 = ts.cast(expr.parent.parent, ts.isObjectLiteralExpression);
                var typeOfParentObjectLiteral = getTypeOfAssignmentPattern(node_4) || errorType;
                var propertyIndex = ts.indexOfNode(node_4.properties, expr.parent);
                return checkObjectLiteralDestructuringPropertyAssignment(node_4, typeOfParentObjectLiteral, propertyIndex);
            }
            // Array literal assignment - array destructuring pattern
            var node = ts.cast(expr.parent, ts.isArrayLiteralExpression);
            //    [{ property1: p1, property2 }] = elems;
            var typeOfArrayLiteral = getTypeOfAssignmentPattern(node) || errorType;
            var elementType = checkIteratedTypeOrElementType(65 /* Destructuring */, typeOfArrayLiteral, undefinedType, expr.parent) || errorType;
            return checkArrayLiteralDestructuringElementAssignment(node, typeOfArrayLiteral, node.elements.indexOf(expr), elementType);
        }
        // Gets the property symbol corresponding to the property in destructuring assignment
        // 'property1' from
        //     for ( { property1: a } of elems) {
        //     }
        // 'property1' at location 'a' from:
        //     [a] = [ property1, property2 ]
        function getPropertySymbolOfDestructuringAssignment(location) {
            // Get the type of the object or array literal and then look for property of given name in the type
            var typeOfObjectLiteral = getTypeOfAssignmentPattern(ts.cast(location.parent.parent, ts.isAssignmentPattern));
            return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.escapedText);
        }
        function getRegularTypeOfExpression(expr) {
            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
                expr = expr.parent;
            }
            return getRegularTypeOfLiteralType(getTypeOfExpression(expr));
        }
        /**
         * Gets either the static or instance type of a class element, based on
         * whether the element is declared as "static".
         */
        function getParentTypeOfClassElement(node) {
            var classSymbol = getSymbolOfNode(node.parent);
            return ts.hasModifier(node, 32 /* Static */)
                ? getTypeOfSymbol(classSymbol)
                : getDeclaredTypeOfSymbol(classSymbol);
        }
        function getClassElementPropertyKeyType(element) {
            var name = element.name;
            switch (name.kind) {
                case 75 /* Identifier */:
                    return getLiteralType(ts.idText(name));
                case 8 /* NumericLiteral */:
                case 10 /* StringLiteral */:
                    return getLiteralType(name.text);
                case 154 /* ComputedPropertyName */:
                    var nameType = checkComputedPropertyName(name);
                    return isTypeAssignableToKind(nameType, 12288 /* ESSymbolLike */) ? nameType : stringType;
                default:
                    return ts.Debug.fail("Unsupported property name.");
            }
        }
        // Return the list of properties of the given type, augmented with properties from Function
        // if the type has call or construct signatures
        function getAugmentedPropertiesOfType(type) {
            type = getApparentType(type);
            var propsByName = ts.createSymbolTable(getPropertiesOfType(type));
            var functionType = getSignaturesOfType(type, 0 /* Call */).length ? globalCallableFunctionType :
                getSignaturesOfType(type, 1 /* Construct */).length ? globalNewableFunctionType :
                    undefined;
            if (functionType) {
                ts.forEach(getPropertiesOfType(functionType), function (p) {
                    if (!propsByName.has(p.escapedName)) {
                        propsByName.set(p.escapedName, p);
                    }
                });
            }
            return getNamedMembers(propsByName);
        }
        function typeHasCallOrConstructSignatures(type) {
            return ts.typeHasCallOrConstructSignatures(type, checker);
        }
        function getRootSymbols(symbol) {
            var roots = getImmediateRootSymbols(symbol);
            return roots ? ts.flatMap(roots, getRootSymbols) : [symbol];
        }
        function getImmediateRootSymbols(symbol) {
            if (ts.getCheckFlags(symbol) & 6 /* Synthetic */) {
                return ts.mapDefined(getSymbolLinks(symbol).containingType.types, function (type) { return getPropertyOfType(type, symbol.escapedName); });
            }
            else if (symbol.flags & 33554432 /* Transient */) {
                var _a = symbol, leftSpread = _a.leftSpread, rightSpread = _a.rightSpread, syntheticOrigin = _a.syntheticOrigin;
                return leftSpread ? [leftSpread, rightSpread]
                    : syntheticOrigin ? [syntheticOrigin]
                        : ts.singleElementArray(tryGetAliasTarget(symbol));
            }
            return undefined;
        }
        function tryGetAliasTarget(symbol) {
            var target;
            var next = symbol;
            while (next = getSymbolLinks(next).target) {
                target = next;
            }
            return target;
        }
        // Emitter support
        function isArgumentsLocalBinding(nodeIn) {
            if (!ts.isGeneratedIdentifier(nodeIn)) {
                var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
                if (node) {
                    var isPropertyName_1 = node.parent.kind === 194 /* PropertyAccessExpression */ && node.parent.name === node;
                    return !isPropertyName_1 && getReferencedValueSymbol(node) === argumentsSymbol;
                }
            }
            return false;
        }
        function moduleExportsSomeValue(moduleReferenceExpression) {
            var moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression);
            if (!moduleSymbol || ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                // If the module is not found or is shorthand, assume that it may export a value.
                return true;
            }
            var hasExportAssignment = hasExportAssignmentSymbol(moduleSymbol);
            // if module has export assignment then 'resolveExternalModuleSymbol' will return resolved symbol for export assignment
            // otherwise it will return moduleSymbol itself
            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
            var symbolLinks = getSymbolLinks(moduleSymbol);
            if (symbolLinks.exportsSomeValue === undefined) {
                // for export assignments - check if resolved symbol for RHS is itself a value
                // otherwise - check if at least one export is value
                symbolLinks.exportsSomeValue = hasExportAssignment
                    ? !!(moduleSymbol.flags & 111551 /* Value */)
                    : ts.forEachEntry(getExportsOfModule(moduleSymbol), isValue);
            }
            return symbolLinks.exportsSomeValue;
            function isValue(s) {
                s = resolveSymbol(s);
                return s && !!(s.flags & 111551 /* Value */);
            }
        }
        function isNameOfModuleOrEnumDeclaration(node) {
            return ts.isModuleOrEnumDeclaration(node.parent) && node === node.parent.name;
        }
        // When resolved as an expression identifier, if the given node references an exported entity, return the declaration
        // node of the exported entity's container. Otherwise, return undefined.
        function getReferencedExportContainer(nodeIn, prefixLocals) {
            var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
            if (node) {
                // When resolving the export container for the name of a module or enum
                // declaration, we need to start resolution at the declaration's container.
                // Otherwise, we could incorrectly resolve the export container as the
                // declaration if it contains an exported member with the same name.
                var symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node));
                if (symbol) {
                    if (symbol.flags & 1048576 /* ExportValue */) {
                        // If we reference an exported entity within the same module declaration, then whether
                        // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
                        // kinds that we do NOT prefix.
                        var exportSymbol = getMergedSymbol(symbol.exportSymbol);
                        if (!prefixLocals && exportSymbol.flags & 944 /* ExportHasLocal */ && !(exportSymbol.flags & 3 /* Variable */)) {
                            return undefined;
                        }
                        symbol = exportSymbol;
                    }
                    var parentSymbol_1 = getParentOfSymbol(symbol);
                    if (parentSymbol_1) {
                        if (parentSymbol_1.flags & 512 /* ValueModule */ && parentSymbol_1.valueDeclaration.kind === 290 /* SourceFile */) {
                            var symbolFile = parentSymbol_1.valueDeclaration;
                            var referenceFile = ts.getSourceFileOfNode(node);
                            // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined.
                            var symbolIsUmdExport = symbolFile !== referenceFile;
                            return symbolIsUmdExport ? undefined : symbolFile;
                        }
                        return ts.findAncestor(node.parent, function (n) { return ts.isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol_1; });
                    }
                }
            }
        }
        // When resolved as an expression identifier, if the given node references an import, return the declaration of
        // that import. Otherwise, return undefined.
        function getReferencedImportDeclaration(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
            if (node) {
                var symbol = getReferencedValueSymbol(node);
                // We should only get the declaration of an alias if there isn't a local value
                // declaration for the symbol
                if (isNonLocalAlias(symbol, /*excludes*/ 111551 /* Value */) && !getTypeOnlyAliasDeclaration(symbol)) {
                    return getDeclarationOfAliasSymbol(symbol);
                }
            }
            return undefined;
        }
        function isSymbolOfDestructuredElementOfCatchBinding(symbol) {
            return ts.isBindingElement(symbol.valueDeclaration)
                && ts.walkUpBindingElementsAndPatterns(symbol.valueDeclaration).parent.kind === 280 /* CatchClause */;
        }
        function isSymbolOfDeclarationWithCollidingName(symbol) {
            if (symbol.flags & 418 /* BlockScoped */ && !ts.isSourceFile(symbol.valueDeclaration)) {
                var links = getSymbolLinks(symbol);
                if (links.isDeclarationWithCollidingName === undefined) {
                    var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
                    if (ts.isStatementWithLocals(container) || isSymbolOfDestructuredElementOfCatchBinding(symbol)) {
                        var nodeLinks_1 = getNodeLinks(symbol.valueDeclaration);
                        if (resolveName(container.parent, symbol.escapedName, 111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) {
                            // redeclaration - always should be renamed
                            links.isDeclarationWithCollidingName = true;
                        }
                        else if (nodeLinks_1.flags & 262144 /* CapturedBlockScopedBinding */) {
                            // binding is captured in the function
                            // should be renamed if:
                            // - binding is not top level - top level bindings never collide with anything
                            // AND
                            //   - binding is not declared in loop, should be renamed to avoid name reuse across siblings
                            //     let a, b
                            //     { let x = 1; a = () => x; }
                            //     { let x = 100; b = () => x; }
                            //     console.log(a()); // should print '1'
                            //     console.log(b()); // should print '100'
                            //     OR
                            //   - binding is declared inside loop but not in inside initializer of iteration statement or directly inside loop body
                            //     * variables from initializer are passed to rewritten loop body as parameters so they are not captured directly
                            //     * variables that are declared immediately in loop body will become top level variable after loop is rewritten and thus
                            //       they will not collide with anything
                            var isDeclaredInLoop = nodeLinks_1.flags & 524288 /* BlockScopedBindingInLoop */;
                            var inLoopInitializer = ts.isIterationStatement(container, /*lookInLabeledStatements*/ false);
                            var inLoopBodyBlock = container.kind === 223 /* Block */ && ts.isIterationStatement(container.parent, /*lookInLabeledStatements*/ false);
                            links.isDeclarationWithCollidingName = !ts.isBlockScopedContainerTopLevel(container) && (!isDeclaredInLoop || (!inLoopInitializer && !inLoopBodyBlock));
                        }
                        else {
                            links.isDeclarationWithCollidingName = false;
                        }
                    }
                }
                return links.isDeclarationWithCollidingName;
            }
            return false;
        }
        // When resolved as an expression identifier, if the given node references a nested block scoped entity with
        // a name that either hides an existing name or might hide it when compiled downlevel,
        // return the declaration of that entity. Otherwise, return undefined.
        function getReferencedDeclarationWithCollidingName(nodeIn) {
            if (!ts.isGeneratedIdentifier(nodeIn)) {
                var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
                if (node) {
                    var symbol = getReferencedValueSymbol(node);
                    if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) {
                        return symbol.valueDeclaration;
                    }
                }
            }
            return undefined;
        }
        // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an
        // existing name or might hide a name when compiled downlevel
        function isDeclarationWithCollidingName(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isDeclaration);
            if (node) {
                var symbol = getSymbolOfNode(node);
                if (symbol) {
                    return isSymbolOfDeclarationWithCollidingName(symbol);
                }
            }
            return false;
        }
        function isValueAliasDeclaration(node) {
            switch (node.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol);
                case 255 /* ImportClause */:
                case 256 /* NamespaceImport */:
                case 258 /* ImportSpecifier */:
                case 263 /* ExportSpecifier */:
                    var symbol = getSymbolOfNode(node) || unknownSymbol;
                    return isAliasResolvedToValue(symbol) && !getTypeOnlyAliasDeclaration(symbol);
                case 260 /* ExportDeclaration */:
                    var exportClause = node.exportClause;
                    return !!exportClause && (ts.isNamespaceExport(exportClause) ||
                        ts.some(exportClause.elements, isValueAliasDeclaration));
                case 259 /* ExportAssignment */:
                    return node.expression && node.expression.kind === 75 /* Identifier */ ?
                        isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) :
                        true;
            }
            return false;
        }
        function isTopLevelValueImportEqualsWithEntityName(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isImportEqualsDeclaration);
            if (node === undefined || node.parent.kind !== 290 /* SourceFile */ || !ts.isInternalModuleImportEqualsDeclaration(node)) {
                // parent is not source file or it is not reference to internal module
                return false;
            }
            var isValue = isAliasResolvedToValue(getSymbolOfNode(node));
            return isValue && node.moduleReference && !ts.nodeIsMissing(node.moduleReference);
        }
        function isAliasResolvedToValue(symbol) {
            var target = resolveAlias(symbol);
            if (target === unknownSymbol) {
                return true;
            }
            // const enums and modules that contain only const enums are not considered values from the emit perspective
            // unless 'preserveConstEnums' option is set to true
            return !!(target.flags & 111551 /* Value */) &&
                (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target));
        }
        function isConstEnumOrConstEnumOnlyModule(s) {
            return isConstEnumSymbol(s) || !!s.constEnumOnlyModule;
        }
        function isReferencedAliasDeclaration(node, checkChildren) {
            if (isAliasSymbolDeclaration(node)) {
                var symbol = getSymbolOfNode(node);
                if (symbol && getSymbolLinks(symbol).referenced) {
                    return true;
                }
                var target = getSymbolLinks(symbol).target; // TODO: GH#18217
                if (target && ts.getModifierFlags(node) & 1 /* Export */ &&
                    target.flags & 111551 /* Value */ &&
                    (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target))) {
                    // An `export import ... =` of a value symbol is always considered referenced
                    return true;
                }
            }
            if (checkChildren) {
                return !!ts.forEachChild(node, function (node) { return isReferencedAliasDeclaration(node, checkChildren); });
            }
            return false;
        }
        function isImplementationOfOverload(node) {
            if (ts.nodeIsPresent(node.body)) {
                if (ts.isGetAccessor(node) || ts.isSetAccessor(node))
                    return false; // Get or set accessors can never be overload implementations, but can have up to 2 signatures
                var symbol = getSymbolOfNode(node);
                var signaturesOfSymbol = getSignaturesOfSymbol(symbol);
                // If this function body corresponds to function with multiple signature, it is implementation of overload
                // e.g.: function foo(a: string): string;
                //       function foo(a: number): number;
                //       function foo(a: any) { // This is implementation of the overloads
                //           return a;
                //       }
                return signaturesOfSymbol.length > 1 ||
                    // If there is single signature for the symbol, it is overload if that signature isn't coming from the node
                    // e.g.: function foo(a: string): string;
                    //       function foo(a: any) { // This is implementation of the overloads
                    //           return a;
                    //       }
                    (signaturesOfSymbol.length === 1 && signaturesOfSymbol[0].declaration !== node);
            }
            return false;
        }
        function isRequiredInitializedParameter(parameter) {
            return !!strictNullChecks &&
                !isOptionalParameter(parameter) &&
                !ts.isJSDocParameterTag(parameter) &&
                !!parameter.initializer &&
                !ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
        }
        function isOptionalUninitializedParameterProperty(parameter) {
            return strictNullChecks &&
                isOptionalParameter(parameter) &&
                !parameter.initializer &&
                ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
        }
        function isExpandoFunctionDeclaration(node) {
            var declaration = ts.getParseTreeNode(node, ts.isFunctionDeclaration);
            if (!declaration) {
                return false;
            }
            var symbol = getSymbolOfNode(declaration);
            if (!symbol || !(symbol.flags & 16 /* Function */)) {
                return false;
            }
            return !!ts.forEachEntry(getExportsOfSymbol(symbol), function (p) { return p.flags & 111551 /* Value */ && p.valueDeclaration && ts.isPropertyAccessExpression(p.valueDeclaration); });
        }
        function getPropertiesOfContainerFunction(node) {
            var declaration = ts.getParseTreeNode(node, ts.isFunctionDeclaration);
            if (!declaration) {
                return ts.emptyArray;
            }
            var symbol = getSymbolOfNode(declaration);
            return symbol && getPropertiesOfType(getTypeOfSymbol(symbol)) || ts.emptyArray;
        }
        function getNodeCheckFlags(node) {
            return getNodeLinks(node).flags || 0;
        }
        function getEnumMemberValue(node) {
            computeEnumMemberValues(node.parent);
            return getNodeLinks(node).enumMemberValue;
        }
        function canHaveConstantValue(node) {
            switch (node.kind) {
                case 284 /* EnumMember */:
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    return true;
            }
            return false;
        }
        function getConstantValue(node) {
            if (node.kind === 284 /* EnumMember */) {
                return getEnumMemberValue(node);
            }
            var symbol = getNodeLinks(node).resolvedSymbol;
            if (symbol && (symbol.flags & 8 /* EnumMember */)) {
                // inline property\index accesses only for const enums
                var member = symbol.valueDeclaration;
                if (ts.isEnumConst(member.parent)) {
                    return getEnumMemberValue(member);
                }
            }
            return undefined;
        }
        function isFunctionType(type) {
            return !!(type.flags & 524288 /* Object */) && getSignaturesOfType(type, 0 /* Call */).length > 0;
        }
        function getTypeReferenceSerializationKind(typeNameIn, location) {
            // ensure both `typeName` and `location` are parse tree nodes.
            var typeName = ts.getParseTreeNode(typeNameIn, ts.isEntityName);
            if (!typeName)
                return ts.TypeReferenceSerializationKind.Unknown;
            if (location) {
                location = ts.getParseTreeNode(location);
                if (!location)
                    return ts.TypeReferenceSerializationKind.Unknown;
            }
            // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
            var valueSymbol = resolveEntityName(typeName, 111551 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
            // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
            var typeSymbol = resolveEntityName(typeName, 788968 /* Type */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
            if (valueSymbol && valueSymbol === typeSymbol) {
                var globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false);
                if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) {
                    return ts.TypeReferenceSerializationKind.Promise;
                }
                var constructorType = getTypeOfSymbol(valueSymbol);
                if (constructorType && isConstructorType(constructorType)) {
                    return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
                }
            }
            // We might not be able to resolve type symbol so use unknown type in that case (eg error case)
            if (!typeSymbol) {
                return ts.TypeReferenceSerializationKind.Unknown;
            }
            var type = getDeclaredTypeOfSymbol(typeSymbol);
            if (type === errorType) {
                return ts.TypeReferenceSerializationKind.Unknown;
            }
            else if (type.flags & 3 /* AnyOrUnknown */) {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
            else if (isTypeAssignableToKind(type, 16384 /* Void */ | 98304 /* Nullable */ | 131072 /* Never */)) {
                return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType;
            }
            else if (isTypeAssignableToKind(type, 528 /* BooleanLike */)) {
                return ts.TypeReferenceSerializationKind.BooleanType;
            }
            else if (isTypeAssignableToKind(type, 296 /* NumberLike */)) {
                return ts.TypeReferenceSerializationKind.NumberLikeType;
            }
            else if (isTypeAssignableToKind(type, 2112 /* BigIntLike */)) {
                return ts.TypeReferenceSerializationKind.BigIntLikeType;
            }
            else if (isTypeAssignableToKind(type, 132 /* StringLike */)) {
                return ts.TypeReferenceSerializationKind.StringLikeType;
            }
            else if (isTupleType(type)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else if (isTypeAssignableToKind(type, 12288 /* ESSymbolLike */)) {
                return ts.TypeReferenceSerializationKind.ESSymbolType;
            }
            else if (isFunctionType(type)) {
                return ts.TypeReferenceSerializationKind.TypeWithCallSignature;
            }
            else if (isArrayType(type)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
        }
        function createTypeOfDeclaration(declarationIn, enclosingDeclaration, flags, tracker, addUndefined) {
            var declaration = ts.getParseTreeNode(declarationIn, ts.isVariableLikeOrAccessor);
            if (!declaration) {
                return ts.createToken(125 /* AnyKeyword */);
            }
            // Get type of the symbol if this is the valid symbol otherwise get type at location
            var symbol = getSymbolOfNode(declaration);
            var type = symbol && !(symbol.flags & (2048 /* TypeLiteral */ | 131072 /* Signature */))
                ? getWidenedLiteralType(getTypeOfSymbol(symbol))
                : errorType;
            if (type.flags & 8192 /* UniqueESSymbol */ &&
                type.symbol === symbol) {
                flags |= 1048576 /* AllowUniqueESSymbolType */;
            }
            if (addUndefined) {
                type = getOptionalType(type);
            }
            return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function createReturnTypeOfSignatureDeclaration(signatureDeclarationIn, enclosingDeclaration, flags, tracker) {
            var signatureDeclaration = ts.getParseTreeNode(signatureDeclarationIn, ts.isFunctionLike);
            if (!signatureDeclaration) {
                return ts.createToken(125 /* AnyKeyword */);
            }
            var signature = getSignatureFromDeclaration(signatureDeclaration);
            return nodeBuilder.typeToTypeNode(getReturnTypeOfSignature(signature), enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function createTypeOfExpression(exprIn, enclosingDeclaration, flags, tracker) {
            var expr = ts.getParseTreeNode(exprIn, ts.isExpression);
            if (!expr) {
                return ts.createToken(125 /* AnyKeyword */);
            }
            var type = getWidenedType(getRegularTypeOfExpression(expr));
            return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function hasGlobalName(name) {
            return globals.has(ts.escapeLeadingUnderscores(name));
        }
        function getReferencedValueSymbol(reference, startInDeclarationContainer) {
            var resolvedSymbol = getNodeLinks(reference).resolvedSymbol;
            if (resolvedSymbol) {
                return resolvedSymbol;
            }
            var location = reference;
            if (startInDeclarationContainer) {
                // When resolving the name of a declaration as a value, we need to start resolution
                // at a point outside of the declaration.
                var parent = reference.parent;
                if (ts.isDeclaration(parent) && reference === parent.name) {
                    location = getDeclarationContainer(parent);
                }
            }
            return resolveName(location, reference.escapedText, 111551 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
        }
        function getReferencedValueDeclaration(referenceIn) {
            if (!ts.isGeneratedIdentifier(referenceIn)) {
                var reference = ts.getParseTreeNode(referenceIn, ts.isIdentifier);
                if (reference) {
                    var symbol = getReferencedValueSymbol(reference);
                    if (symbol) {
                        return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
                    }
                }
            }
            return undefined;
        }
        function isLiteralConstDeclaration(node) {
            if (ts.isDeclarationReadonly(node) || ts.isVariableDeclaration(node) && ts.isVarConst(node)) {
                return isFreshLiteralType(getTypeOfSymbol(getSymbolOfNode(node)));
            }
            return false;
        }
        function literalTypeToNode(type, enclosing, tracker) {
            var enumResult = type.flags & 1024 /* EnumLiteral */ ? nodeBuilder.symbolToExpression(type.symbol, 111551 /* Value */, enclosing, /*flags*/ undefined, tracker)
                : type === trueType ? ts.createTrue() : type === falseType && ts.createFalse();
            return enumResult || ts.createLiteral(type.value);
        }
        function createLiteralConstValue(node, tracker) {
            var type = getTypeOfSymbol(getSymbolOfNode(node));
            return literalTypeToNode(type, node, tracker);
        }
        function getJsxFactoryEntity(location) {
            return location ? (getJsxNamespace(location), (ts.getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity;
        }
        function createResolver() {
            // this variable and functions that use it are deliberately moved here from the outer scope
            // to avoid scope pollution
            var resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives();
            var fileToDirective;
            if (resolvedTypeReferenceDirectives) {
                // populate reverse mapping: file path -> type reference directive that was resolved to this file
                fileToDirective = ts.createMap();
                resolvedTypeReferenceDirectives.forEach(function (resolvedDirective, key) {
                    if (!resolvedDirective || !resolvedDirective.resolvedFileName) {
                        return;
                    }
                    var file = host.getSourceFile(resolvedDirective.resolvedFileName);
                    if (file) {
                        // Add the transitive closure of path references loaded by this file (as long as they are not)
                        // part of an existing type reference.
                        addReferencedFilesToTypeDirective(file, key);
                    }
                });
            }
            return {
                getReferencedExportContainer: getReferencedExportContainer,
                getReferencedImportDeclaration: getReferencedImportDeclaration,
                getReferencedDeclarationWithCollidingName: getReferencedDeclarationWithCollidingName,
                isDeclarationWithCollidingName: isDeclarationWithCollidingName,
                isValueAliasDeclaration: function (node) {
                    node = ts.getParseTreeNode(node);
                    // Synthesized nodes are always treated like values.
                    return node ? isValueAliasDeclaration(node) : true;
                },
                hasGlobalName: hasGlobalName,
                isReferencedAliasDeclaration: function (node, checkChildren) {
                    node = ts.getParseTreeNode(node);
                    // Synthesized nodes are always treated as referenced.
                    return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
                },
                getNodeCheckFlags: function (node) {
                    node = ts.getParseTreeNode(node);
                    return node ? getNodeCheckFlags(node) : 0;
                },
                isTopLevelValueImportEqualsWithEntityName: isTopLevelValueImportEqualsWithEntityName,
                isDeclarationVisible: isDeclarationVisible,
                isImplementationOfOverload: isImplementationOfOverload,
                isRequiredInitializedParameter: isRequiredInitializedParameter,
                isOptionalUninitializedParameterProperty: isOptionalUninitializedParameterProperty,
                isExpandoFunctionDeclaration: isExpandoFunctionDeclaration,
                getPropertiesOfContainerFunction: getPropertiesOfContainerFunction,
                createTypeOfDeclaration: createTypeOfDeclaration,
                createReturnTypeOfSignatureDeclaration: createReturnTypeOfSignatureDeclaration,
                createTypeOfExpression: createTypeOfExpression,
                createLiteralConstValue: createLiteralConstValue,
                isSymbolAccessible: isSymbolAccessible,
                isEntityNameVisible: isEntityNameVisible,
                getConstantValue: function (nodeIn) {
                    var node = ts.getParseTreeNode(nodeIn, canHaveConstantValue);
                    return node ? getConstantValue(node) : undefined;
                },
                collectLinkedAliases: collectLinkedAliases,
                getReferencedValueDeclaration: getReferencedValueDeclaration,
                getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
                isOptionalParameter: isOptionalParameter,
                moduleExportsSomeValue: moduleExportsSomeValue,
                isArgumentsLocalBinding: isArgumentsLocalBinding,
                getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration,
                getTypeReferenceDirectivesForEntityName: getTypeReferenceDirectivesForEntityName,
                getTypeReferenceDirectivesForSymbol: getTypeReferenceDirectivesForSymbol,
                isLiteralConstDeclaration: isLiteralConstDeclaration,
                isLateBound: function (nodeIn) {
                    var node = ts.getParseTreeNode(nodeIn, ts.isDeclaration);
                    var symbol = node && getSymbolOfNode(node);
                    return !!(symbol && ts.getCheckFlags(symbol) & 4096 /* Late */);
                },
                getJsxFactoryEntity: getJsxFactoryEntity,
                getAllAccessorDeclarations: function (accessor) {
                    accessor = ts.getParseTreeNode(accessor, ts.isGetOrSetAccessorDeclaration); // TODO: GH#18217
                    var otherKind = accessor.kind === 164 /* SetAccessor */ ? 163 /* GetAccessor */ : 164 /* SetAccessor */;
                    var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(accessor), otherKind);
                    var firstAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? otherAccessor : accessor;
                    var secondAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? accessor : otherAccessor;
                    var setAccessor = accessor.kind === 164 /* SetAccessor */ ? accessor : otherAccessor;
                    var getAccessor = accessor.kind === 163 /* GetAccessor */ ? accessor : otherAccessor;
                    return {
                        firstAccessor: firstAccessor,
                        secondAccessor: secondAccessor,
                        setAccessor: setAccessor,
                        getAccessor: getAccessor
                    };
                },
                getSymbolOfExternalModuleSpecifier: function (moduleName) { return resolveExternalModuleNameWorker(moduleName, moduleName, /*moduleNotFoundError*/ undefined); },
                isBindingCapturedByNode: function (node, decl) {
                    var parseNode = ts.getParseTreeNode(node);
                    var parseDecl = ts.getParseTreeNode(decl);
                    return !!parseNode && !!parseDecl && (ts.isVariableDeclaration(parseDecl) || ts.isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl);
                },
                getDeclarationStatementsForSourceFile: function (node, flags, tracker, bundled) {
                    var n = ts.getParseTreeNode(node);
                    ts.Debug.assert(n && n.kind === 290 /* SourceFile */, "Non-sourcefile node passed into getDeclarationsForSourceFile");
                    var sym = getSymbolOfNode(node);
                    if (!sym) {
                        return !node.locals ? [] : nodeBuilder.symbolTableToDeclarationStatements(node.locals, node, flags, tracker, bundled);
                    }
                    return !sym.exports ? [] : nodeBuilder.symbolTableToDeclarationStatements(sym.exports, node, flags, tracker, bundled);
                },
                isImportRequiredByAugmentation: isImportRequiredByAugmentation,
            };
            function isImportRequiredByAugmentation(node) {
                var file = ts.getSourceFileOfNode(node);
                if (!file.symbol)
                    return false;
                var importTarget = getExternalModuleFileFromDeclaration(node);
                if (!importTarget)
                    return false;
                if (importTarget === file)
                    return false;
                var exports = getExportsOfModule(file.symbol);
                for (var _i = 0, _a = ts.arrayFrom(exports.values()); _i < _a.length; _i++) {
                    var s = _a[_i];
                    if (s.mergeId) {
                        var merged = getMergedSymbol(s);
                        for (var _b = 0, _c = merged.declarations; _b < _c.length; _b++) {
                            var d = _c[_b];
                            var declFile = ts.getSourceFileOfNode(d);
                            if (declFile === importTarget) {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
            function isInHeritageClause(node) {
                return node.parent && node.parent.kind === 216 /* ExpressionWithTypeArguments */ && node.parent.parent && node.parent.parent.kind === 279 /* HeritageClause */;
            }
            // defined here to avoid outer scope pollution
            function getTypeReferenceDirectivesForEntityName(node) {
                // program does not have any files with type reference directives - bail out
                if (!fileToDirective) {
                    return undefined;
                }
                // property access can only be used as values, or types when within an expression with type arguments inside a heritage clause
                // qualified names can only be used as types\namespaces
                // identifiers are treated as values only if they appear in type queries
                var meaning = 788968 /* Type */ | 1920 /* Namespace */;
                if ((node.kind === 75 /* Identifier */ && isInTypeQuery(node)) || (node.kind === 194 /* PropertyAccessExpression */ && !isInHeritageClause(node))) {
                    meaning = 111551 /* Value */ | 1048576 /* ExportValue */;
                }
                var symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true);
                return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined;
            }
            // defined here to avoid outer scope pollution
            function getTypeReferenceDirectivesForSymbol(symbol, meaning) {
                // program does not have any files with type reference directives - bail out
                if (!fileToDirective) {
                    return undefined;
                }
                if (!isSymbolFromTypeDeclarationFile(symbol)) {
                    return undefined;
                }
                // check what declarations in the symbol can contribute to the target meaning
                var typeReferenceDirectives;
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    // check meaning of the local symbol to see if declaration needs to be analyzed further
                    if (decl.symbol && decl.symbol.flags & meaning) {
                        var file = ts.getSourceFileOfNode(decl);
                        var typeReferenceDirective = fileToDirective.get(file.path);
                        if (typeReferenceDirective) {
                            (typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective);
                        }
                        else {
                            // found at least one entry that does not originate from type reference directive
                            return undefined;
                        }
                    }
                }
                return typeReferenceDirectives;
            }
            function isSymbolFromTypeDeclarationFile(symbol) {
                // bail out if symbol does not have associated declarations (i.e. this is transient symbol created for property in binding pattern)
                if (!symbol.declarations) {
                    return false;
                }
                // walk the parent chain for symbols to make sure that top level parent symbol is in the global scope
                // external modules cannot define or contribute to type declaration files
                var current = symbol;
                while (true) {
                    var parent = getParentOfSymbol(current);
                    if (parent) {
                        current = parent;
                    }
                    else {
                        break;
                    }
                }
                if (current.valueDeclaration && current.valueDeclaration.kind === 290 /* SourceFile */ && current.flags & 512 /* ValueModule */) {
                    return false;
                }
                // check that at least one declaration of top level symbol originates from type declaration file
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var file = ts.getSourceFileOfNode(decl);
                    if (fileToDirective.has(file.path)) {
                        return true;
                    }
                }
                return false;
            }
            function addReferencedFilesToTypeDirective(file, key) {
                if (fileToDirective.has(file.path))
                    return;
                fileToDirective.set(file.path, key);
                for (var _i = 0, _a = file.referencedFiles; _i < _a.length; _i++) {
                    var fileName = _a[_i].fileName;
                    var resolvedFile = ts.resolveTripleslashReference(fileName, file.originalFileName);
                    var referencedFile = host.getSourceFile(resolvedFile);
                    if (referencedFile) {
                        addReferencedFilesToTypeDirective(referencedFile, key);
                    }
                }
            }
        }
        function getExternalModuleFileFromDeclaration(declaration) {
            var specifier = declaration.kind === 249 /* ModuleDeclaration */ ? ts.tryCast(declaration.name, ts.isStringLiteral) : ts.getExternalModuleName(declaration);
            var moduleSymbol = resolveExternalModuleNameWorker(specifier, specifier, /*moduleNotFoundError*/ undefined); // TODO: GH#18217
            if (!moduleSymbol) {
                return undefined;
            }
            return ts.getDeclarationOfKind(moduleSymbol, 290 /* SourceFile */);
        }
        function initializeTypeChecker() {
            // Bind all source files and propagate errors
            for (var _i = 0, _a = host.getSourceFiles(); _i < _a.length; _i++) {
                var file = _a[_i];
                ts.bindSourceFile(file, compilerOptions);
            }
            amalgamatedDuplicates = ts.createMap();
            // Initialize global symbol table
            var augmentations;
            for (var _b = 0, _c = host.getSourceFiles(); _b < _c.length; _b++) {
                var file = _c[_b];
                if (file.redirectInfo) {
                    continue;
                }
                if (!ts.isExternalOrCommonJsModule(file)) {
                    // It is an error for a non-external-module (i.e. script) to declare its own `globalThis`.
                    // We can't use `builtinGlobals` for this due to synthetic expando-namespace generation in JS files.
                    var fileGlobalThisSymbol = file.locals.get("globalThis");
                    if (fileGlobalThisSymbol) {
                        for (var _d = 0, _e = fileGlobalThisSymbol.declarations; _d < _e.length; _d++) {
                            var declaration = _e[_d];
                            diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis"));
                        }
                    }
                    mergeSymbolTable(globals, file.locals);
                }
                if (file.jsGlobalAugmentations) {
                    mergeSymbolTable(globals, file.jsGlobalAugmentations);
                }
                if (file.patternAmbientModules && file.patternAmbientModules.length) {
                    patternAmbientModules = ts.concatenate(patternAmbientModules, file.patternAmbientModules);
                }
                if (file.moduleAugmentations.length) {
                    (augmentations || (augmentations = [])).push(file.moduleAugmentations);
                }
                if (file.symbol && file.symbol.globalExports) {
                    // Merge in UMD exports with first-in-wins semantics (see #9771)
                    var source = file.symbol.globalExports;
                    source.forEach(function (sourceSymbol, id) {
                        if (!globals.has(id)) {
                            globals.set(id, sourceSymbol);
                        }
                    });
                }
            }
            // We do global augmentations separately from module augmentations (and before creating global types) because they
            //  1. Affect global types. We won't have the correct global types until global augmentations are merged. Also,
            //  2. Module augmentation instantiation requires creating the type of a module, which, in turn, can require
            //       checking for an export or property on the module (if export=) which, in turn, can fall back to the
            //       apparent type of the module - either globalObjectType or globalFunctionType - which wouldn't exist if we
            //       did module augmentations prior to finalizing the global types.
            if (augmentations) {
                // merge _global_ module augmentations.
                // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
                for (var _f = 0, augmentations_1 = augmentations; _f < augmentations_1.length; _f++) {
                    var list = augmentations_1[_f];
                    for (var _g = 0, list_1 = list; _g < list_1.length; _g++) {
                        var augmentation = list_1[_g];
                        if (!ts.isGlobalScopeAugmentation(augmentation.parent))
                            continue;
                        mergeModuleAugmentation(augmentation);
                    }
                }
            }
            // Setup global builtins
            addToSymbolTable(globals, builtinGlobals, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0);
            getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
            getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments", /*arity*/ 0, /*reportErrors*/ true);
            getSymbolLinks(unknownSymbol).type = errorType;
            getSymbolLinks(globalThisSymbol).type = createObjectType(16 /* Anonymous */, globalThisSymbol);
            // Initialize special types
            globalArrayType = getGlobalType("Array", /*arity*/ 1, /*reportErrors*/ true);
            globalObjectType = getGlobalType("Object", /*arity*/ 0, /*reportErrors*/ true);
            globalFunctionType = getGlobalType("Function", /*arity*/ 0, /*reportErrors*/ true);
            globalCallableFunctionType = strictBindCallApply && getGlobalType("CallableFunction", /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
            globalNewableFunctionType = strictBindCallApply && getGlobalType("NewableFunction", /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
            globalStringType = getGlobalType("String", /*arity*/ 0, /*reportErrors*/ true);
            globalNumberType = getGlobalType("Number", /*arity*/ 0, /*reportErrors*/ true);
            globalBooleanType = getGlobalType("Boolean", /*arity*/ 0, /*reportErrors*/ true);
            globalRegExpType = getGlobalType("RegExp", /*arity*/ 0, /*reportErrors*/ true);
            anyArrayType = createArrayType(anyType);
            autoArrayType = createArrayType(autoType);
            if (autoArrayType === emptyObjectType) {
                // autoArrayType is used as a marker, so even if global Array type is not defined, it needs to be a unique type
                autoArrayType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
            }
            globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1) || globalArrayType;
            anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
            globalThisType = getGlobalTypeOrUndefined("ThisType", /*arity*/ 1);
            if (augmentations) {
                // merge _nonglobal_ module augmentations.
                // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
                for (var _h = 0, augmentations_2 = augmentations; _h < augmentations_2.length; _h++) {
                    var list = augmentations_2[_h];
                    for (var _j = 0, list_2 = list; _j < list_2.length; _j++) {
                        var augmentation = list_2[_j];
                        if (ts.isGlobalScopeAugmentation(augmentation.parent))
                            continue;
                        mergeModuleAugmentation(augmentation);
                    }
                }
            }
            amalgamatedDuplicates.forEach(function (_a) {
                var firstFile = _a.firstFile, secondFile = _a.secondFile, conflictingSymbols = _a.conflictingSymbols;
                // If not many things conflict, issue individual errors
                if (conflictingSymbols.size < 8) {
                    conflictingSymbols.forEach(function (_a, symbolName) {
                        var isBlockScoped = _a.isBlockScoped, firstFileLocations = _a.firstFileLocations, secondFileLocations = _a.secondFileLocations;
                        var message = isBlockScoped ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0;
                        for (var _i = 0, firstFileLocations_1 = firstFileLocations; _i < firstFileLocations_1.length; _i++) {
                            var node = firstFileLocations_1[_i];
                            addDuplicateDeclarationError(node, message, symbolName, secondFileLocations);
                        }
                        for (var _b = 0, secondFileLocations_1 = secondFileLocations; _b < secondFileLocations_1.length; _b++) {
                            var node = secondFileLocations_1[_b];
                            addDuplicateDeclarationError(node, message, symbolName, firstFileLocations);
                        }
                    });
                }
                else {
                    // Otherwise issue top-level error since the files appear very identical in terms of what they contain
                    var list = ts.arrayFrom(conflictingSymbols.keys()).join(", ");
                    diagnostics.add(ts.addRelatedInfo(ts.createDiagnosticForNode(firstFile, ts.Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), ts.createDiagnosticForNode(secondFile, ts.Diagnostics.Conflicts_are_in_this_file)));
                    diagnostics.add(ts.addRelatedInfo(ts.createDiagnosticForNode(secondFile, ts.Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), ts.createDiagnosticForNode(firstFile, ts.Diagnostics.Conflicts_are_in_this_file)));
                }
            });
            amalgamatedDuplicates = undefined;
        }
        function checkExternalEmitHelpers(location, helpers) {
            if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
                var sourceFile = ts.getSourceFileOfNode(location);
                if (ts.isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & 8388608 /* Ambient */)) {
                    var helpersModule = resolveHelpersModule(sourceFile, location);
                    if (helpersModule !== unknownSymbol) {
                        var uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
                        for (var helper = 1 /* FirstEmitHelper */; helper <= 1048576 /* LastEmitHelper */; helper <<= 1) {
                            if (uncheckedHelpers & helper) {
                                var name = getHelperName(helper);
                                var symbol = getSymbol(helpersModule.exports, ts.escapeLeadingUnderscores(name), 111551 /* Value */);
                                if (!symbol) {
                                    error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, ts.externalHelpersModuleNameText, name);
                                }
                            }
                        }
                    }
                    requestedExternalEmitHelpers |= helpers;
                }
            }
        }
        function getHelperName(helper) {
            switch (helper) {
                case 1 /* Extends */: return "__extends";
                case 2 /* Assign */: return "__assign";
                case 4 /* Rest */: return "__rest";
                case 8 /* Decorate */: return "__decorate";
                case 16 /* Metadata */: return "__metadata";
                case 32 /* Param */: return "__param";
                case 64 /* Awaiter */: return "__awaiter";
                case 128 /* Generator */: return "__generator";
                case 256 /* Values */: return "__values";
                case 512 /* Read */: return "__read";
                case 1024 /* Spread */: return "__spread";
                case 2048 /* SpreadArrays */: return "__spreadArrays";
                case 4096 /* Await */: return "__await";
                case 8192 /* AsyncGenerator */: return "__asyncGenerator";
                case 16384 /* AsyncDelegator */: return "__asyncDelegator";
                case 32768 /* AsyncValues */: return "__asyncValues";
                case 65536 /* ExportStar */: return "__exportStar";
                case 131072 /* MakeTemplateObject */: return "__makeTemplateObject";
                case 262144 /* ClassPrivateFieldGet */: return "__classPrivateFieldGet";
                case 524288 /* ClassPrivateFieldSet */: return "__classPrivateFieldSet";
                case 1048576 /* CreateBinding */: return "__createBinding";
                default: return ts.Debug.fail("Unrecognized helper");
            }
        }
        function resolveHelpersModule(node, errorNode) {
            if (!externalHelpersModule) {
                externalHelpersModule = resolveExternalModule(node, ts.externalHelpersModuleNameText, ts.Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
            }
            return externalHelpersModule;
        }
        // GRAMMAR CHECKING
        function checkGrammarDecoratorsAndModifiers(node) {
            return checkGrammarDecorators(node) || checkGrammarModifiers(node);
        }
        function checkGrammarDecorators(node) {
            if (!node.decorators) {
                return false;
            }
            if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) {
                if (node.kind === 161 /* MethodDeclaration */ && !ts.nodeIsPresent(node.body)) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload);
                }
                else {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_are_not_valid_here);
                }
            }
            else if (node.kind === 163 /* GetAccessor */ || node.kind === 164 /* SetAccessor */) {
                var accessors = ts.getAllAccessorDeclarations(node.parent.members, node);
                if (accessors.firstAccessor.decorators && node === accessors.secondAccessor) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name);
                }
            }
            return false;
        }
        function checkGrammarModifiers(node) {
            var quickResult = reportObviousModifierErrors(node);
            if (quickResult !== undefined) {
                return quickResult;
            }
            var lastStatic, lastDeclare, lastAsync, lastReadonly;
            var flags = 0 /* None */;
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                if (modifier.kind !== 138 /* ReadonlyKeyword */) {
                    if (node.kind === 158 /* PropertySignature */ || node.kind === 160 /* MethodSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_member, ts.tokenToString(modifier.kind));
                    }
                    if (node.kind === 167 /* IndexSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_an_index_signature, ts.tokenToString(modifier.kind));
                    }
                }
                switch (modifier.kind) {
                    case 81 /* ConstKeyword */:
                        if (node.kind !== 248 /* EnumDeclaration */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.A_class_member_cannot_have_the_0_keyword, ts.tokenToString(81 /* ConstKeyword */));
                        }
                        break;
                    case 119 /* PublicKeyword */:
                    case 118 /* ProtectedKeyword */:
                    case 117 /* PrivateKeyword */:
                        var text = visibilityToString(ts.modifierToFlag(modifier.kind));
                        if (flags & 28 /* AccessibilityModifier */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.Accessibility_modifier_already_seen);
                        }
                        else if (flags & 32 /* Static */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
                        }
                        else if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
                        }
                        else if (node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 290 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text);
                        }
                        else if (flags & 128 /* Abstract */) {
                            if (modifier.kind === 117 /* PrivateKeyword */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract");
                            }
                            else {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract");
                            }
                        }
                        else if (ts.isPrivateIdentifierPropertyDeclaration(node)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier);
                        }
                        flags |= ts.modifierToFlag(modifier.kind);
                        break;
                    case 120 /* StaticKeyword */:
                        if (flags & 32 /* Static */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "static");
                        }
                        else if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
                        }
                        else if (node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 290 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static");
                        }
                        else if (node.kind === 156 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
                        }
                        else if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
                        }
                        else if (ts.isPrivateIdentifierPropertyDeclaration(node)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "static");
                        }
                        flags |= 32 /* Static */;
                        lastStatic = modifier;
                        break;
                    case 138 /* ReadonlyKeyword */:
                        if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "readonly");
                        }
                        else if (node.kind !== 159 /* PropertyDeclaration */ && node.kind !== 158 /* PropertySignature */ && node.kind !== 167 /* IndexSignature */ && node.kind !== 156 /* Parameter */) {
                            // If node.kind === SyntaxKind.Parameter, checkParameter report an error if it's not a parameter property.
                            return grammarErrorOnNode(modifier, ts.Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature);
                        }
                        flags |= 64 /* Readonly */;
                        lastReadonly = modifier;
                        break;
                    case 89 /* ExportKeyword */:
                        if (flags & 1 /* Export */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "export");
                        }
                        else if (flags & 2 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
                        }
                        else if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
                        }
                        else if (ts.isClassLike(node.parent)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
                        }
                        else if (node.kind === 156 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
                        }
                        flags |= 1 /* Export */;
                        break;
                    case 84 /* DefaultKeyword */:
                        var container = node.parent.kind === 290 /* SourceFile */ ? node.parent : node.parent.parent;
                        if (container.kind === 249 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
                        }
                        flags |= 512 /* Default */;
                        break;
                    case 130 /* DeclareKeyword */:
                        if (flags & 2 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "declare");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
                        }
                        else if (ts.isClassLike(node.parent) && !ts.isPropertyDeclaration(node)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
                        }
                        else if (node.kind === 156 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
                        }
                        else if ((node.parent.flags & 8388608 /* Ambient */) && node.parent.kind === 250 /* ModuleBlock */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
                        }
                        else if (ts.isPrivateIdentifierPropertyDeclaration(node)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "declare");
                        }
                        flags |= 2 /* Ambient */;
                        lastDeclare = modifier;
                        break;
                    case 122 /* AbstractKeyword */:
                        if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "abstract");
                        }
                        if (node.kind !== 245 /* ClassDeclaration */) {
                            if (node.kind !== 161 /* MethodDeclaration */ &&
                                node.kind !== 159 /* PropertyDeclaration */ &&
                                node.kind !== 163 /* GetAccessor */ &&
                                node.kind !== 164 /* SetAccessor */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration);
                            }
                            if (!(node.parent.kind === 245 /* ClassDeclaration */ && ts.hasModifier(node.parent, 128 /* Abstract */))) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class);
                            }
                            if (flags & 32 /* Static */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
                            }
                            if (flags & 8 /* Private */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract");
                            }
                        }
                        if (ts.isNamedDeclaration(node) && node.name.kind === 76 /* PrivateIdentifier */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "abstract");
                        }
                        flags |= 128 /* Abstract */;
                        break;
                    case 126 /* AsyncKeyword */:
                        if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "async");
                        }
                        else if (flags & 2 /* Ambient */ || node.parent.flags & 8388608 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
                        }
                        else if (node.kind === 156 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
                        }
                        flags |= 256 /* Async */;
                        lastAsync = modifier;
                        break;
                }
            }
            if (node.kind === 162 /* Constructor */) {
                if (flags & 32 /* Static */) {
                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
                }
                if (flags & 128 /* Abstract */) {
                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "abstract"); // TODO: GH#18217
                }
                else if (flags & 256 /* Async */) {
                    return grammarErrorOnNode(lastAsync, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
                }
                else if (flags & 64 /* Readonly */) {
                    return grammarErrorOnNode(lastReadonly, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "readonly");
                }
                return false;
            }
            else if ((node.kind === 254 /* ImportDeclaration */ || node.kind === 253 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) {
                return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
            }
            else if (node.kind === 156 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && ts.isBindingPattern(node.name)) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern);
            }
            else if (node.kind === 156 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && node.dotDotDotToken) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter);
            }
            if (flags & 256 /* Async */) {
                return checkGrammarAsyncModifier(node, lastAsync);
            }
            return false;
        }
        /**
         * true | false: Early return this value from checkGrammarModifiers.
         * undefined: Need to do full checking on the modifiers.
         */
        function reportObviousModifierErrors(node) {
            return !node.modifiers
                ? false
                : shouldReportBadModifier(node)
                    ? grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here)
                    : undefined;
        }
        function shouldReportBadModifier(node) {
            switch (node.kind) {
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 162 /* Constructor */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 167 /* IndexSignature */:
                case 249 /* ModuleDeclaration */:
                case 254 /* ImportDeclaration */:
                case 253 /* ImportEqualsDeclaration */:
                case 260 /* ExportDeclaration */:
                case 259 /* ExportAssignment */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 156 /* Parameter */:
                    return false;
                default:
                    if (node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 290 /* SourceFile */) {
                        return false;
                    }
                    switch (node.kind) {
                        case 244 /* FunctionDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 126 /* AsyncKeyword */);
                        case 245 /* ClassDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 122 /* AbstractKeyword */);
                        case 246 /* InterfaceDeclaration */:
                        case 225 /* VariableStatement */:
                        case 247 /* TypeAliasDeclaration */:
                            return true;
                        case 248 /* EnumDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 81 /* ConstKeyword */);
                        default:
                            ts.Debug.fail();
                            return false;
                    }
            }
        }
        function nodeHasAnyModifiersExcept(node, allowedModifier) {
            return node.modifiers.length > 1 || node.modifiers[0].kind !== allowedModifier;
        }
        function checkGrammarAsyncModifier(node, asyncModifier) {
            switch (node.kind) {
                case 161 /* MethodDeclaration */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return false;
            }
            return grammarErrorOnNode(asyncModifier, ts.Diagnostics._0_modifier_cannot_be_used_here, "async");
        }
        function checkGrammarForDisallowedTrailingComma(list, diag) {
            if (diag === void 0) { diag = ts.Diagnostics.Trailing_comma_not_allowed; }
            if (list && list.hasTrailingComma) {
                return grammarErrorAtPos(list[0], list.end - ",".length, ",".length, diag);
            }
            return false;
        }
        function checkGrammarTypeParameterList(typeParameters, file) {
            if (typeParameters && typeParameters.length === 0) {
                var start = typeParameters.pos - "<".length;
                var end = ts.skipTrivia(file.text, typeParameters.end) + ">".length;
                return grammarErrorAtPos(file, start, end - start, ts.Diagnostics.Type_parameter_list_cannot_be_empty);
            }
            return false;
        }
        function checkGrammarParameterList(parameters) {
            var seenOptionalParameter = false;
            var parameterCount = parameters.length;
            for (var i = 0; i < parameterCount; i++) {
                var parameter = parameters[i];
                if (parameter.dotDotDotToken) {
                    if (i !== (parameterCount - 1)) {
                        return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
                    }
                    if (!(parameter.flags & 8388608 /* Ambient */)) { // Allow `...foo,` in ambient declarations; see GH#23070
                        checkGrammarForDisallowedTrailingComma(parameters, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                    }
                    if (parameter.questionToken) {
                        return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_rest_parameter_cannot_be_optional);
                    }
                    if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer);
                    }
                }
                else if (parameter.questionToken) {
                    seenOptionalParameter = true;
                    if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.Parameter_cannot_have_question_mark_and_initializer);
                    }
                }
                else if (seenOptionalParameter && !parameter.initializer) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter);
                }
            }
        }
        function getNonSimpleParameters(parameters) {
            return ts.filter(parameters, function (parameter) { return !!parameter.initializer || ts.isBindingPattern(parameter.name) || ts.isRestParameter(parameter); });
        }
        function checkGrammarForUseStrictSimpleParameterList(node) {
            if (languageVersion >= 3 /* ES2016 */) {
                var useStrictDirective_1 = node.body && ts.isBlock(node.body) && ts.findUseStrictPrologue(node.body.statements);
                if (useStrictDirective_1) {
                    var nonSimpleParameters = getNonSimpleParameters(node.parameters);
                    if (ts.length(nonSimpleParameters)) {
                        ts.forEach(nonSimpleParameters, function (parameter) {
                            ts.addRelatedInfo(error(parameter, ts.Diagnostics.This_parameter_is_not_allowed_with_use_strict_directive), ts.createDiagnosticForNode(useStrictDirective_1, ts.Diagnostics.use_strict_directive_used_here));
                        });
                        var diagnostics_1 = nonSimpleParameters.map(function (parameter, index) { return (index === 0 ? ts.createDiagnosticForNode(parameter, ts.Diagnostics.Non_simple_parameter_declared_here) : ts.createDiagnosticForNode(parameter, ts.Diagnostics.and_here)); });
                        ts.addRelatedInfo.apply(void 0, __spreadArrays([error(useStrictDirective_1, ts.Diagnostics.use_strict_directive_cannot_be_used_with_non_simple_parameter_list)], diagnostics_1));
                        return true;
                    }
                }
            }
            return false;
        }
        function checkGrammarFunctionLikeDeclaration(node) {
            // Prevent cascading error by short-circuit
            var file = ts.getSourceFileOfNode(node);
            return checkGrammarDecoratorsAndModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) ||
                checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file) ||
                (ts.isFunctionLikeDeclaration(node) && checkGrammarForUseStrictSimpleParameterList(node));
        }
        function checkGrammarClassLikeDeclaration(node) {
            var file = ts.getSourceFileOfNode(node);
            return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file);
        }
        function checkGrammarArrowFunction(node, file) {
            if (!ts.isArrowFunction(node)) {
                return false;
            }
            var equalsGreaterThanToken = node.equalsGreaterThanToken;
            var startLine = ts.getLineAndCharacterOfPosition(file, equalsGreaterThanToken.pos).line;
            var endLine = ts.getLineAndCharacterOfPosition(file, equalsGreaterThanToken.end).line;
            return startLine !== endLine && grammarErrorOnNode(equalsGreaterThanToken, ts.Diagnostics.Line_terminator_not_permitted_before_arrow);
        }
        function checkGrammarIndexSignatureParameters(node) {
            var parameter = node.parameters[0];
            if (node.parameters.length !== 1) {
                if (parameter) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                }
                else {
                    return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                }
            }
            checkGrammarForDisallowedTrailingComma(node.parameters, ts.Diagnostics.An_index_signature_cannot_have_a_trailing_comma);
            if (parameter.dotDotDotToken) {
                return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
            }
            if (ts.hasModifiers(parameter)) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
            }
            if (parameter.questionToken) {
                return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark);
            }
            if (parameter.initializer) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_initializer);
            }
            if (!parameter.type) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
            }
            if (parameter.type.kind !== 143 /* StringKeyword */ && parameter.type.kind !== 140 /* NumberKeyword */) {
                var type = getTypeFromTypeNode(parameter.type);
                if (type.flags & 4 /* String */ || type.flags & 8 /* Number */) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, ts.getTextOfNode(parameter.name), typeToString(type), typeToString(node.type ? getTypeFromTypeNode(node.type) : anyType));
                }
                if (type.flags & 1048576 /* Union */ && allTypesAssignableToKind(type, 384 /* StringOrNumberLiteral */, /*strict*/ true)) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead);
                }
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_must_be_either_string_or_number);
            }
            if (!node.type) {
                return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_a_type_annotation);
            }
            return false;
        }
        function checkGrammarIndexSignature(node) {
            // Prevent cascading error by short-circuit
            return checkGrammarDecoratorsAndModifiers(node) || checkGrammarIndexSignatureParameters(node);
        }
        function checkGrammarForAtLeastOneTypeArgument(node, typeArguments) {
            if (typeArguments && typeArguments.length === 0) {
                var sourceFile = ts.getSourceFileOfNode(node);
                var start = typeArguments.pos - "<".length;
                var end = ts.skipTrivia(sourceFile.text, typeArguments.end) + ">".length;
                return grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
            }
            return false;
        }
        function checkGrammarTypeArguments(node, typeArguments) {
            return checkGrammarForDisallowedTrailingComma(typeArguments) ||
                checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
        }
        function checkGrammarTaggedTemplateChain(node) {
            if (node.questionDotToken || node.flags & 32 /* OptionalChain */) {
                return grammarErrorOnNode(node.template, ts.Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain);
            }
            return false;
        }
        function checkGrammarForOmittedArgument(args) {
            if (args) {
                for (var _i = 0, args_4 = args; _i < args_4.length; _i++) {
                    var arg = args_4[_i];
                    if (arg.kind === 215 /* OmittedExpression */) {
                        return grammarErrorAtPos(arg, arg.pos, 0, ts.Diagnostics.Argument_expression_expected);
                    }
                }
            }
            return false;
        }
        function checkGrammarArguments(args) {
            return checkGrammarForOmittedArgument(args);
        }
        function checkGrammarHeritageClause(node) {
            var types = node.types;
            if (checkGrammarForDisallowedTrailingComma(types)) {
                return true;
            }
            if (types && types.length === 0) {
                var listType = ts.tokenToString(node.token);
                return grammarErrorAtPos(node, types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType);
            }
            return ts.some(types, checkGrammarExpressionWithTypeArguments);
        }
        function checkGrammarExpressionWithTypeArguments(node) {
            return checkGrammarTypeArguments(node, node.typeArguments);
        }
        function checkGrammarClassDeclarationHeritageClauses(node) {
            var seenExtendsClause = false;
            var seenImplementsClause = false;
            if (!checkGrammarDecoratorsAndModifiers(node) && node.heritageClauses) {
                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
                    var heritageClause = _a[_i];
                    if (heritageClause.token === 90 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        if (seenImplementsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_must_precede_implements_clause);
                        }
                        if (heritageClause.types.length > 1) {
                            return grammarErrorOnFirstToken(heritageClause.types[1], ts.Diagnostics.Classes_can_only_extend_a_single_class);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 113 /* ImplementsKeyword */);
                        if (seenImplementsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.implements_clause_already_seen);
                        }
                        seenImplementsClause = true;
                    }
                    // Grammar checking heritageClause inside class declaration
                    checkGrammarHeritageClause(heritageClause);
                }
            }
        }
        function checkGrammarInterfaceDeclaration(node) {
            var seenExtendsClause = false;
            if (node.heritageClauses) {
                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
                    var heritageClause = _a[_i];
                    if (heritageClause.token === 90 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 113 /* ImplementsKeyword */);
                        return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.Interface_declaration_cannot_have_implements_clause);
                    }
                    // Grammar checking heritageClause inside class declaration
                    checkGrammarHeritageClause(heritageClause);
                }
            }
            return false;
        }
        function checkGrammarComputedPropertyName(node) {
            // If node is not a computedPropertyName, just skip the grammar checking
            if (node.kind !== 154 /* ComputedPropertyName */) {
                return false;
            }
            var computedPropertyName = node;
            if (computedPropertyName.expression.kind === 209 /* BinaryExpression */ && computedPropertyName.expression.operatorToken.kind === 27 /* CommaToken */) {
                return grammarErrorOnNode(computedPropertyName.expression, ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
            }
            return false;
        }
        function checkGrammarForGenerator(node) {
            if (node.asteriskToken) {
                ts.Debug.assert(node.kind === 244 /* FunctionDeclaration */ ||
                    node.kind === 201 /* FunctionExpression */ ||
                    node.kind === 161 /* MethodDeclaration */);
                if (node.flags & 8388608 /* Ambient */) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context);
                }
                if (!node.body) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator);
                }
            }
        }
        function checkGrammarForInvalidQuestionMark(questionToken, message) {
            return !!questionToken && grammarErrorOnNode(questionToken, message);
        }
        function checkGrammarForInvalidExclamationToken(exclamationToken, message) {
            return !!exclamationToken && grammarErrorOnNode(exclamationToken, message);
        }
        function checkGrammarObjectLiteralExpression(node, inDestructuring) {
            var seen = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var prop = _a[_i];
                if (prop.kind === 283 /* SpreadAssignment */) {
                    if (inDestructuring) {
                        // a rest property cannot be destructured any further
                        var expression = ts.skipParentheses(prop.expression);
                        if (ts.isArrayLiteralExpression(expression) || ts.isObjectLiteralExpression(expression)) {
                            return grammarErrorOnNode(prop.expression, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
                        }
                    }
                    continue;
                }
                var name = prop.name;
                if (name.kind === 154 /* ComputedPropertyName */) {
                    // If the name is not a ComputedPropertyName, the grammar checking will skip it
                    checkGrammarComputedPropertyName(name);
                }
                if (prop.kind === 282 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) {
                    // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
                    // outside of destructuring it is a syntax error
                    return grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
                }
                if (name.kind === 76 /* PrivateIdentifier */) {
                    return grammarErrorOnNode(name, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
                }
                // Modifiers are never allowed on properties except for 'async' on a method declaration
                if (prop.modifiers) {
                    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
                    for (var _b = 0, _c = prop.modifiers; _b < _c.length; _b++) { // TODO: GH#19955
                        var mod = _c[_b];
                        if (mod.kind !== 126 /* AsyncKeyword */ || prop.kind !== 161 /* MethodDeclaration */) {
                            grammarErrorOnNode(mod, ts.Diagnostics._0_modifier_cannot_be_used_here, ts.getTextOfNode(mod));
                        }
                    }
                }
                // ECMA-262 11.1.5 Object Initializer
                // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
                // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
                // IsDataDescriptor(propId.descriptor) is true.
                //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
                //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
                //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
                // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
                var currentKind = void 0;
                switch (prop.kind) {
                    case 282 /* ShorthandPropertyAssignment */:
                        checkGrammarForInvalidExclamationToken(prop.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
                    // falls through
                    case 281 /* PropertyAssignment */:
                        // Grammar checking for computedPropertyName and shorthandPropertyAssignment
                        checkGrammarForInvalidQuestionMark(prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional);
                        if (name.kind === 8 /* NumericLiteral */) {
                            checkGrammarNumericLiteral(name);
                        }
                        currentKind = 4 /* PropertyAssignment */;
                        break;
                    case 161 /* MethodDeclaration */:
                        currentKind = 8 /* Method */;
                        break;
                    case 163 /* GetAccessor */:
                        currentKind = 1 /* GetAccessor */;
                        break;
                    case 164 /* SetAccessor */:
                        currentKind = 2 /* SetAccessor */;
                        break;
                    default:
                        throw ts.Debug.assertNever(prop, "Unexpected syntax kind:" + prop.kind);
                }
                if (!inDestructuring) {
                    var effectiveName = ts.getPropertyNameForPropertyNameNode(name);
                    if (effectiveName === undefined) {
                        continue;
                    }
                    var existingKind = seen.get(effectiveName);
                    if (!existingKind) {
                        seen.set(effectiveName, currentKind);
                    }
                    else {
                        if ((currentKind & 12 /* PropertyAssignmentOrMethod */) && (existingKind & 12 /* PropertyAssignmentOrMethod */)) {
                            grammarErrorOnNode(name, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name));
                        }
                        else if ((currentKind & 3 /* GetOrSetAccessor */) && (existingKind & 3 /* GetOrSetAccessor */)) {
                            if (existingKind !== 3 /* GetOrSetAccessor */ && currentKind !== existingKind) {
                                seen.set(effectiveName, currentKind | existingKind);
                            }
                            else {
                                return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
                            }
                        }
                        else {
                            return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
                        }
                    }
                }
            }
        }
        function checkGrammarJsxElement(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            var seen = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.attributes.properties; _i < _a.length; _i++) {
                var attr = _a[_i];
                if (attr.kind === 275 /* JsxSpreadAttribute */) {
                    continue;
                }
                var name = attr.name, initializer = attr.initializer;
                if (!seen.get(name.escapedText)) {
                    seen.set(name.escapedText, true);
                }
                else {
                    return grammarErrorOnNode(name, ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name);
                }
                if (initializer && initializer.kind === 276 /* JsxExpression */ && !initializer.expression) {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression);
                }
            }
        }
        function checkGrammarJsxExpression(node) {
            if (node.expression && ts.isCommaSequence(node.expression)) {
                return grammarErrorOnNode(node.expression, ts.Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array);
            }
        }
        function checkGrammarForInOrForOfStatement(forInOrOfStatement) {
            if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
                return true;
            }
            if (forInOrOfStatement.kind === 232 /* ForOfStatement */ && forInOrOfStatement.awaitModifier) {
                if ((forInOrOfStatement.flags & 32768 /* AwaitContext */) === 0 /* None */) {
                    // use of 'for-await-of' in non-async function
                    var sourceFile = ts.getSourceFileOfNode(forInOrOfStatement);
                    if (!hasParseDiagnostics(sourceFile)) {
                        var diagnostic = ts.createDiagnosticForNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator);
                        var func = ts.getContainingFunction(forInOrOfStatement);
                        if (func && func.kind !== 162 /* Constructor */) {
                            ts.Debug.assert((ts.getFunctionFlags(func) & 2 /* Async */) === 0, "Enclosing function should never be an async function.");
                            var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async);
                            ts.addRelatedInfo(diagnostic, relatedInfo);
                        }
                        diagnostics.add(diagnostic);
                        return true;
                    }
                    return false;
                }
            }
            if (forInOrOfStatement.initializer.kind === 243 /* VariableDeclarationList */) {
                var variableList = forInOrOfStatement.initializer;
                if (!checkGrammarVariableDeclarationList(variableList)) {
                    var declarations = variableList.declarations;
                    // declarations.length can be zero if there is an error in variable declaration in for-of or for-in
                    // See http://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements for details
                    // For example:
                    //      var let = 10;
                    //      for (let of [1,2,3]) {} // this is invalid ES6 syntax
                    //      for (let in [1,2,3]) {} // this is invalid ES6 syntax
                    // We will then want to skip on grammar checking on variableList declaration
                    if (!declarations.length) {
                        return false;
                    }
                    if (declarations.length > 1) {
                        var diagnostic = forInOrOfStatement.kind === 231 /* ForInStatement */
                            ? ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
                            : ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
                        return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
                    }
                    var firstDeclaration = declarations[0];
                    if (firstDeclaration.initializer) {
                        var diagnostic = forInOrOfStatement.kind === 231 /* ForInStatement */
                            ? ts.Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
                            : ts.Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
                        return grammarErrorOnNode(firstDeclaration.name, diagnostic);
                    }
                    if (firstDeclaration.type) {
                        var diagnostic = forInOrOfStatement.kind === 231 /* ForInStatement */
                            ? ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation
                            : ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
                        return grammarErrorOnNode(firstDeclaration, diagnostic);
                    }
                }
            }
            return false;
        }
        function checkGrammarAccessor(accessor) {
            if (!(accessor.flags & 8388608 /* Ambient */)) {
                if (languageVersion < 1 /* ES5 */) {
                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
                }
                if (accessor.body === undefined && !ts.hasModifier(accessor, 128 /* Abstract */)) {
                    return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
                }
            }
            if (accessor.body && ts.hasModifier(accessor, 128 /* Abstract */)) {
                return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
            }
            if (accessor.typeParameters) {
                return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_have_type_parameters);
            }
            if (!doesAccessorHaveCorrectParameterCount(accessor)) {
                return grammarErrorOnNode(accessor.name, accessor.kind === 163 /* GetAccessor */ ?
                    ts.Diagnostics.A_get_accessor_cannot_have_parameters :
                    ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
            }
            if (accessor.kind === 164 /* SetAccessor */) {
                if (accessor.type) {
                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
                }
                var parameter = ts.Debug.checkDefined(ts.getSetAccessorValueParameter(accessor), "Return value does not match parameter count assertion.");
                if (parameter.dotDotDotToken) {
                    return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_set_accessor_cannot_have_rest_parameter);
                }
                if (parameter.questionToken) {
                    return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
                }
                if (parameter.initializer) {
                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
                }
            }
            return false;
        }
        /** Does the accessor have the right number of parameters?
         * A get accessor has no parameters or a single `this` parameter.
         * A set accessor has one parameter or a `this` parameter and one more parameter.
         */
        function doesAccessorHaveCorrectParameterCount(accessor) {
            return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === 163 /* GetAccessor */ ? 0 : 1);
        }
        function getAccessorThisParameter(accessor) {
            if (accessor.parameters.length === (accessor.kind === 163 /* GetAccessor */ ? 1 : 2)) {
                return ts.getThisParameter(accessor);
            }
        }
        function checkGrammarTypeOperatorNode(node) {
            if (node.operator === 147 /* UniqueKeyword */) {
                if (node.type.kind !== 144 /* SymbolKeyword */) {
                    return grammarErrorOnNode(node.type, ts.Diagnostics._0_expected, ts.tokenToString(144 /* SymbolKeyword */));
                }
                var parent = ts.walkUpParenthesizedTypes(node.parent);
                switch (parent.kind) {
                    case 242 /* VariableDeclaration */:
                        var decl = parent;
                        if (decl.name.kind !== 75 /* Identifier */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name);
                        }
                        if (!ts.isVariableDeclarationInVariableStatement(decl)) {
                            return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement);
                        }
                        if (!(decl.parent.flags & 2 /* Const */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const);
                        }
                        break;
                    case 159 /* PropertyDeclaration */:
                        if (!ts.hasModifier(parent, 32 /* Static */) ||
                            !ts.hasModifier(parent, 64 /* Readonly */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly);
                        }
                        break;
                    case 158 /* PropertySignature */:
                        if (!ts.hasModifier(parent, 64 /* Readonly */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly);
                        }
                        break;
                    default:
                        return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_not_allowed_here);
                }
            }
            else if (node.operator === 138 /* ReadonlyKeyword */) {
                if (node.type.kind !== 174 /* ArrayType */ && node.type.kind !== 175 /* TupleType */) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types, ts.tokenToString(144 /* SymbolKeyword */));
                }
            }
        }
        function checkGrammarForInvalidDynamicName(node, message) {
            if (isNonBindableDynamicName(node)) {
                return grammarErrorOnNode(node, message);
            }
        }
        function checkGrammarMethod(node) {
            if (checkGrammarFunctionLikeDeclaration(node)) {
                return true;
            }
            if (node.kind === 161 /* MethodDeclaration */) {
                if (node.parent.kind === 193 /* ObjectLiteralExpression */) {
                    // We only disallow modifier on a method declaration if it is a property of object-literal-expression
                    if (node.modifiers && !(node.modifiers.length === 1 && ts.first(node.modifiers).kind === 126 /* AsyncKeyword */)) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
                    }
                    else if (checkGrammarForInvalidQuestionMark(node.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional)) {
                        return true;
                    }
                    else if (checkGrammarForInvalidExclamationToken(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context)) {
                        return true;
                    }
                    else if (node.body === undefined) {
                        return grammarErrorAtPos(node, node.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
                    }
                }
                if (checkGrammarForGenerator(node)) {
                    return true;
                }
            }
            if (ts.isClassLike(node.parent)) {
                // Technically, computed properties in ambient contexts is disallowed
                // for property declarations and accessors too, not just methods.
                // However, property declarations disallow computed names in general,
                // and accessors are not allowed in ambient contexts in general,
                // so this error only really matters for methods.
                if (node.flags & 8388608 /* Ambient */) {
                    return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
                }
                else if (node.kind === 161 /* MethodDeclaration */ && !node.body) {
                    return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
                }
            }
            else if (node.parent.kind === 246 /* InterfaceDeclaration */) {
                return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
            }
            else if (node.parent.kind === 173 /* TypeLiteral */) {
                return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
            }
        }
        function checkGrammarBreakOrContinueStatement(node) {
            var current = node;
            while (current) {
                if (ts.isFunctionLike(current)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.Jump_target_cannot_cross_function_boundary);
                }
                switch (current.kind) {
                    case 238 /* LabeledStatement */:
                        if (node.label && current.label.escapedText === node.label.escapedText) {
                            // found matching label - verify that label usage is correct
                            // continue can only target labels that are on iteration statements
                            var isMisplacedContinueLabel = node.kind === 233 /* ContinueStatement */
                                && !ts.isIterationStatement(current.statement, /*lookInLabeledStatement*/ true);
                            if (isMisplacedContinueLabel) {
                                return grammarErrorOnNode(node, ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement);
                            }
                            return false;
                        }
                        break;
                    case 237 /* SwitchStatement */:
                        if (node.kind === 234 /* BreakStatement */ && !node.label) {
                            // unlabeled break within switch statement - ok
                            return false;
                        }
                        break;
                    default:
                        if (ts.isIterationStatement(current, /*lookInLabeledStatement*/ false) && !node.label) {
                            // unlabeled break or continue within iteration statement - ok
                            return false;
                        }
                        break;
                }
                current = current.parent;
            }
            if (node.label) {
                var message = node.kind === 234 /* BreakStatement */
                    ? ts.Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement
                    : ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement;
                return grammarErrorOnNode(node, message);
            }
            else {
                var message = node.kind === 234 /* BreakStatement */
                    ? ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement
                    : ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement;
                return grammarErrorOnNode(node, message);
            }
        }
        function checkGrammarBindingElement(node) {
            if (node.dotDotDotToken) {
                var elements = node.parent.elements;
                if (node !== ts.last(elements)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                checkGrammarForDisallowedTrailingComma(elements, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                if (node.propertyName) {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.A_rest_element_cannot_have_a_property_name);
                }
                if (node.initializer) {
                    // Error on equals token which immediately precedes the initializer
                    return grammarErrorAtPos(node, node.initializer.pos - 1, 1, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                }
            }
        }
        function isStringOrNumberLiteralExpression(expr) {
            return ts.isStringOrNumericLiteralLike(expr) ||
                expr.kind === 207 /* PrefixUnaryExpression */ && expr.operator === 40 /* MinusToken */ &&
                    expr.operand.kind === 8 /* NumericLiteral */;
        }
        function isBigIntLiteralExpression(expr) {
            return expr.kind === 9 /* BigIntLiteral */ ||
                expr.kind === 207 /* PrefixUnaryExpression */ && expr.operator === 40 /* MinusToken */ &&
                    expr.operand.kind === 9 /* BigIntLiteral */;
        }
        function isSimpleLiteralEnumReference(expr) {
            if ((ts.isPropertyAccessExpression(expr) || (ts.isElementAccessExpression(expr) && isStringOrNumberLiteralExpression(expr.argumentExpression))) &&
                ts.isEntityNameExpression(expr.expression)) {
                return !!(checkExpressionCached(expr).flags & 1024 /* EnumLiteral */);
            }
        }
        function checkAmbientInitializer(node) {
            var initializer = node.initializer;
            if (initializer) {
                var isInvalidInitializer = !(isStringOrNumberLiteralExpression(initializer) ||
                    isSimpleLiteralEnumReference(initializer) ||
                    initializer.kind === 106 /* TrueKeyword */ || initializer.kind === 91 /* FalseKeyword */ ||
                    isBigIntLiteralExpression(initializer));
                var isConstOrReadonly = ts.isDeclarationReadonly(node) || ts.isVariableDeclaration(node) && ts.isVarConst(node);
                if (isConstOrReadonly && !node.type) {
                    if (isInvalidInitializer) {
                        return grammarErrorOnNode(initializer, ts.Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference);
                    }
                }
                else {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                }
                if (!isConstOrReadonly || isInvalidInitializer) {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                }
            }
        }
        function checkGrammarVariableDeclaration(node) {
            if (node.parent.parent.kind !== 231 /* ForInStatement */ && node.parent.parent.kind !== 232 /* ForOfStatement */) {
                if (node.flags & 8388608 /* Ambient */) {
                    checkAmbientInitializer(node);
                }
                else if (!node.initializer) {
                    if (ts.isBindingPattern(node.name) && !ts.isBindingPattern(node.parent)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.A_destructuring_declaration_must_have_an_initializer);
                    }
                    if (ts.isVarConst(node)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_must_be_initialized);
                    }
                }
            }
            if (node.exclamationToken && (node.parent.parent.kind !== 225 /* VariableStatement */ || !node.type || node.initializer || node.flags & 8388608 /* Ambient */)) {
                return grammarErrorOnNode(node.exclamationToken, ts.Diagnostics.Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation);
            }
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            if (moduleKind < ts.ModuleKind.ES2015 && moduleKind !== ts.ModuleKind.System && !compilerOptions.noEmit &&
                !(node.parent.parent.flags & 8388608 /* Ambient */) && ts.hasModifier(node.parent.parent, 1 /* Export */)) {
                checkESModuleMarker(node.name);
            }
            var checkLetConstNames = (ts.isLet(node) || ts.isVarConst(node));
            // 1. LexicalDeclaration : LetOrConst BindingList ;
            // It is a Syntax Error if the BoundNames of BindingList contains "let".
            // 2. ForDeclaration: ForDeclaration : LetOrConst ForBinding
            // It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
            // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
            // and its Identifier is eval or arguments
            return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name);
        }
        function checkESModuleMarker(name) {
            if (name.kind === 75 /* Identifier */) {
                if (ts.idText(name) === "__esModule") {
                    return grammarErrorOnNode(name, ts.Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules);
                }
            }
            else {
                var elements = name.elements;
                for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
                    var element = elements_1[_i];
                    if (!ts.isOmittedExpression(element)) {
                        return checkESModuleMarker(element.name);
                    }
                }
            }
            return false;
        }
        function checkGrammarNameInLetOrConstDeclarations(name) {
            if (name.kind === 75 /* Identifier */) {
                if (name.originalKeywordKind === 115 /* LetKeyword */) {
                    return grammarErrorOnNode(name, ts.Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
                }
            }
            else {
                var elements = name.elements;
                for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
                    var element = elements_2[_i];
                    if (!ts.isOmittedExpression(element)) {
                        checkGrammarNameInLetOrConstDeclarations(element.name);
                    }
                }
            }
            return false;
        }
        function checkGrammarVariableDeclarationList(declarationList) {
            var declarations = declarationList.declarations;
            if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) {
                return true;
            }
            if (!declarationList.declarations.length) {
                return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty);
            }
            return false;
        }
        function allowLetAndConstDeclarations(parent) {
            switch (parent.kind) {
                case 227 /* IfStatement */:
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                case 236 /* WithStatement */:
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                    return false;
                case 238 /* LabeledStatement */:
                    return allowLetAndConstDeclarations(parent.parent);
            }
            return true;
        }
        function checkGrammarForDisallowedLetOrConstStatement(node) {
            if (!allowLetAndConstDeclarations(node.parent)) {
                if (ts.isLet(node.declarationList)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block);
                }
                else if (ts.isVarConst(node.declarationList)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block);
                }
            }
        }
        function checkGrammarMetaProperty(node) {
            var escapedText = node.name.escapedText;
            switch (node.keywordToken) {
                case 99 /* NewKeyword */:
                    if (escapedText !== "target") {
                        return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "target");
                    }
                    break;
                case 96 /* ImportKeyword */:
                    if (escapedText !== "meta") {
                        return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "meta");
                    }
                    break;
            }
        }
        function hasParseDiagnostics(sourceFile) {
            return sourceFile.parseDiagnostics.length > 0;
        }
        function grammarErrorOnFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function grammarErrorAtPos(nodeForSourceFile, start, length, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(nodeForSourceFile);
            if (!hasParseDiagnostics(sourceFile)) {
                diagnostics.add(ts.createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function grammarErrorOnNode(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                diagnostics.add(ts.createDiagnosticForNode(node, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function checkGrammarConstructorTypeParameters(node) {
            var jsdocTypeParameters = ts.isInJSFile(node) ? ts.getJSDocTypeParameterDeclarations(node) : undefined;
            var range = node.typeParameters || jsdocTypeParameters && ts.firstOrUndefined(jsdocTypeParameters);
            if (range) {
                var pos = range.pos === range.end ? range.pos : ts.skipTrivia(ts.getSourceFileOfNode(node).text, range.pos);
                return grammarErrorAtPos(node, pos, range.end - pos, ts.Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
            }
        }
        function checkGrammarConstructorTypeAnnotation(node) {
            var type = ts.getEffectiveReturnTypeNode(node);
            if (type) {
                return grammarErrorOnNode(type, ts.Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
            }
        }
        function checkGrammarProperty(node) {
            if (ts.isClassLike(node.parent)) {
                if (ts.isStringLiteral(node.name) && node.name.text === "constructor") {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.Classes_may_not_have_a_field_named_constructor);
                }
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
                if (languageVersion < 2 /* ES2015 */ && ts.isPrivateIdentifier(node.name)) {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher);
                }
            }
            else if (node.parent.kind === 246 /* InterfaceDeclaration */) {
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
                if (node.initializer) {
                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.An_interface_property_cannot_have_an_initializer);
                }
            }
            else if (node.parent.kind === 173 /* TypeLiteral */) {
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
                if (node.initializer) {
                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_type_literal_property_cannot_have_an_initializer);
                }
            }
            if (node.flags & 8388608 /* Ambient */) {
                checkAmbientInitializer(node);
            }
            if (ts.isPropertyDeclaration(node) && node.exclamationToken && (!ts.isClassLike(node.parent) || !node.type || node.initializer ||
                node.flags & 8388608 /* Ambient */ || ts.hasModifier(node, 32 /* Static */ | 128 /* Abstract */))) {
                return grammarErrorOnNode(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
            }
        }
        function checkGrammarTopLevelElementForRequiredDeclareModifier(node) {
            // A declare modifier is required for any top level .d.ts declaration except export=, export default, export as namespace
            // interfaces and imports categories:
            //
            //  DeclarationElement:
            //     ExportAssignment
            //     export_opt   InterfaceDeclaration
            //     export_opt   TypeAliasDeclaration
            //     export_opt   ImportDeclaration
            //     export_opt   ExternalImportDeclaration
            //     export_opt   AmbientDeclaration
            //
            // TODO: The spec needs to be amended to reflect this grammar.
            if (node.kind === 246 /* InterfaceDeclaration */ ||
                node.kind === 247 /* TypeAliasDeclaration */ ||
                node.kind === 254 /* ImportDeclaration */ ||
                node.kind === 253 /* ImportEqualsDeclaration */ ||
                node.kind === 260 /* ExportDeclaration */ ||
                node.kind === 259 /* ExportAssignment */ ||
                node.kind === 252 /* NamespaceExportDeclaration */ ||
                ts.hasModifier(node, 2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) {
                return false;
            }
            return grammarErrorOnFirstToken(node, ts.Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier);
        }
        function checkGrammarTopLevelElementsForRequiredDeclareModifier(file) {
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (ts.isDeclaration(decl) || decl.kind === 225 /* VariableStatement */) {
                    if (checkGrammarTopLevelElementForRequiredDeclareModifier(decl)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function checkGrammarSourceFile(node) {
            return !!(node.flags & 8388608 /* Ambient */) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
        }
        function checkGrammarStatementInAmbientContext(node) {
            if (node.flags & 8388608 /* Ambient */) {
                // Find containing block which is either Block, ModuleBlock, SourceFile
                var links = getNodeLinks(node);
                if (!links.hasReportedStatementInAmbientContext && (ts.isFunctionLike(node.parent) || ts.isAccessor(node.parent))) {
                    return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
                }
                // We are either parented by another statement, or some sort of block.
                // If we're in a block, we only want to really report an error once
                // to prevent noisiness.  So use a bit on the block to indicate if
                // this has already been reported, and don't report if it has.
                //
                if (node.parent.kind === 223 /* Block */ || node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 290 /* SourceFile */) {
                    var links_2 = getNodeLinks(node.parent);
                    // Check if the containing block ever report this error
                    if (!links_2.hasReportedStatementInAmbientContext) {
                        return links_2.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
                    }
                }
                else {
                    // We must be parented by a statement.  If so, there's no need
                    // to report the error as our parent will have already done it.
                    // Debug.assert(isStatement(node.parent));
                }
            }
            return false;
        }
        function checkGrammarNumericLiteral(node) {
            // Grammar checking
            if (node.numericLiteralFlags & 32 /* Octal */) {
                var diagnosticMessage = void 0;
                if (languageVersion >= 1 /* ES5 */) {
                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0;
                }
                else if (ts.isChildOfNodeWithKind(node, 187 /* LiteralType */)) {
                    diagnosticMessage = ts.Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0;
                }
                else if (ts.isChildOfNodeWithKind(node, 284 /* EnumMember */)) {
                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0;
                }
                if (diagnosticMessage) {
                    var withMinus = ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === 40 /* MinusToken */;
                    var literal = (withMinus ? "-" : "") + "0o" + node.text;
                    return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal);
                }
            }
            // Realism (size) checking
            checkNumericLiteralValueSize(node);
            return false;
        }
        function checkNumericLiteralValueSize(node) {
            // Scientific notation (e.g. 2e54 and 1e00000000010) can't be converted to bigint
            // Literals with 15 or fewer characters aren't long enough to reach past 2^53 - 1
            // Fractional numbers (e.g. 9000000000000000.001) are inherently imprecise anyway
            if (node.numericLiteralFlags & 16 /* Scientific */ || node.text.length <= 15 || node.text.indexOf(".") !== -1) {
                return;
            }
            // We can't rely on the runtime to accurately store and compare extremely large numeric values
            // Even for internal use, we use getTextOfNode: https://github.com/microsoft/TypeScript/issues/33298
            // Thus, if the runtime claims a too-large number is lower than Number.MAX_SAFE_INTEGER,
            // it's likely addition operations on it will fail too
            var apparentValue = +ts.getTextOfNode(node);
            if (apparentValue <= Math.pow(2, 53) - 1 && apparentValue + 1 > apparentValue) {
                return;
            }
            addErrorOrSuggestion(/*isError*/ false, ts.createDiagnosticForNode(node, ts.Diagnostics.Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers));
        }
        function checkGrammarBigIntLiteral(node) {
            var literalType = ts.isLiteralTypeNode(node.parent) ||
                ts.isPrefixUnaryExpression(node.parent) && ts.isLiteralTypeNode(node.parent.parent);
            if (!literalType) {
                if (languageVersion < 7 /* ES2020 */) {
                    if (grammarErrorOnNode(node, ts.Diagnostics.BigInt_literals_are_not_available_when_targeting_lower_than_ES2020)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function grammarErrorAfterFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, ts.textSpanEnd(span), /*length*/ 0, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function getAmbientModules() {
            if (!ambientModulesCache) {
                ambientModulesCache = [];
                globals.forEach(function (global, sym) {
                    // No need to `unescapeLeadingUnderscores`, an escaped symbol is never an ambient module.
                    if (ambientModuleSymbolRegex.test(sym)) {
                        ambientModulesCache.push(global);
                    }
                });
            }
            return ambientModulesCache;
        }
        function checkGrammarImportClause(node) {
            if (node.isTypeOnly && node.name && node.namedBindings) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both);
            }
            return false;
        }
        function checkGrammarImportCallExpression(node) {
            if (moduleKind === ts.ModuleKind.ES2015) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_esnext_commonjs_amd_system_or_umd);
            }
            if (node.typeArguments) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_have_type_arguments);
            }
            var nodeArguments = node.arguments;
            if (nodeArguments.length !== 1) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument);
            }
            checkGrammarForDisallowedTrailingComma(nodeArguments);
            // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import.
            // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import.
            if (ts.isSpreadElement(nodeArguments[0])) {
                return grammarErrorOnNode(nodeArguments[0], ts.Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element);
            }
            return false;
        }
        function findMatchingTypeReferenceOrTypeAliasReference(source, unionTarget) {
            var sourceObjectFlags = ts.getObjectFlags(source);
            if (sourceObjectFlags & (4 /* Reference */ | 16 /* Anonymous */) && unionTarget.flags & 1048576 /* Union */) {
                return ts.find(unionTarget.types, function (target) {
                    if (target.flags & 524288 /* Object */) {
                        var overlapObjFlags = sourceObjectFlags & ts.getObjectFlags(target);
                        if (overlapObjFlags & 4 /* Reference */) {
                            return source.target === target.target;
                        }
                        if (overlapObjFlags & 16 /* Anonymous */) {
                            return !!source.aliasSymbol && source.aliasSymbol === target.aliasSymbol;
                        }
                    }
                    return false;
                });
            }
        }
        function findBestTypeForObjectLiteral(source, unionTarget) {
            if (ts.getObjectFlags(source) & 128 /* ObjectLiteral */ && forEachType(unionTarget, isArrayLikeType)) {
                return ts.find(unionTarget.types, function (t) { return !isArrayLikeType(t); });
            }
        }
        function findBestTypeForInvokable(source, unionTarget) {
            var signatureKind = 0 /* Call */;
            var hasSignatures = getSignaturesOfType(source, signatureKind).length > 0 ||
                (signatureKind = 1 /* Construct */, getSignaturesOfType(source, signatureKind).length > 0);
            if (hasSignatures) {
                return ts.find(unionTarget.types, function (t) { return getSignaturesOfType(t, signatureKind).length > 0; });
            }
        }
        function findMostOverlappyType(source, unionTarget) {
            var bestMatch;
            var matchingCount = 0;
            for (var _i = 0, _a = unionTarget.types; _i < _a.length; _i++) {
                var target = _a[_i];
                var overlap = getIntersectionType([getIndexType(source), getIndexType(target)]);
                if (overlap.flags & 4194304 /* Index */) {
                    // perfect overlap of keys
                    bestMatch = target;
                    matchingCount = Infinity;
                }
                else if (overlap.flags & 1048576 /* Union */) {
                    // We only want to account for literal types otherwise.
                    // If we have a union of index types, it seems likely that we
                    // needed to elaborate between two generic mapped types anyway.
                    var len = ts.length(ts.filter(overlap.types, isUnitType));
                    if (len >= matchingCount) {
                        bestMatch = target;
                        matchingCount = len;
                    }
                }
                else if (isUnitType(overlap) && 1 >= matchingCount) {
                    bestMatch = target;
                    matchingCount = 1;
                }
            }
            return bestMatch;
        }
        function filterPrimitivesIfContainsNonPrimitive(type) {
            if (maybeTypeOfKind(type, 67108864 /* NonPrimitive */)) {
                var result = filterType(type, function (t) { return !(t.flags & 131068 /* Primitive */); });
                if (!(result.flags & 131072 /* Never */)) {
                    return result;
                }
            }
            return type;
        }
        // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly
        function findMatchingDiscriminantType(source, target, isRelatedTo, skipPartial) {
            if (target.flags & 1048576 /* Union */ && source.flags & (2097152 /* Intersection */ | 524288 /* Object */)) {
                var sourceProperties = getPropertiesOfType(source);
                if (sourceProperties) {
                    var sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
                    if (sourcePropertiesFiltered) {
                        return discriminateTypeByDiscriminableItems(target, ts.map(sourcePropertiesFiltered, function (p) { return [function () { return getTypeOfSymbol(p); }, p.escapedName]; }), isRelatedTo, /*defaultValue*/ undefined, skipPartial);
                    }
                }
            }
            return undefined;
        }
    }
    ts.createTypeChecker = createTypeChecker;
    function isNotAccessor(declaration) {
        // Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks
        return !ts.isAccessor(declaration);
    }
    function isNotOverload(declaration) {
        return (declaration.kind !== 244 /* FunctionDeclaration */ && declaration.kind !== 161 /* MethodDeclaration */) ||
            !!declaration.body;
    }
    /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */
    function isDeclarationNameOrImportPropertyName(name) {
        switch (name.parent.kind) {
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
                return ts.isIdentifier(name);
            default:
                return ts.isDeclarationName(name);
        }
    }
    function isSomeImportDeclaration(decl) {
        switch (decl.kind) {
            case 255 /* ImportClause */: // For default import
            case 253 /* ImportEqualsDeclaration */:
            case 256 /* NamespaceImport */:
            case 258 /* ImportSpecifier */: // For rename import `x as y`
                return true;
            case 75 /* Identifier */:
                // For regular import, `decl` is an Identifier under the ImportSpecifier.
                return decl.parent.kind === 258 /* ImportSpecifier */;
            default:
                return false;
        }
    }
    var JsxNames;
    (function (JsxNames) {
        JsxNames.JSX = "JSX";
        JsxNames.IntrinsicElements = "IntrinsicElements";
        JsxNames.ElementClass = "ElementClass";
        JsxNames.ElementAttributesPropertyNameContainer = "ElementAttributesProperty"; // TODO: Deprecate and remove support
        JsxNames.ElementChildrenAttributeNameContainer = "ElementChildrenAttribute";
        JsxNames.Element = "Element";
        JsxNames.IntrinsicAttributes = "IntrinsicAttributes";
        JsxNames.IntrinsicClassAttributes = "IntrinsicClassAttributes";
        JsxNames.LibraryManagedAttributes = "LibraryManagedAttributes";
    })(JsxNames || (JsxNames = {}));
    function getIterationTypesKeyFromIterationTypeKind(typeKind) {
        switch (typeKind) {
            case 0 /* Yield */: return "yieldType";
            case 1 /* Return */: return "returnType";
            case 2 /* Next */: return "nextType";
        }
    }
    function signatureHasRestParameter(s) {
        return !!(s.flags & 1 /* HasRestParameter */);
    }
    ts.signatureHasRestParameter = signatureHasRestParameter;
    function signatureHasLiteralTypes(s) {
        return !!(s.flags & 2 /* HasLiteralTypes */);
    }
    ts.signatureHasLiteralTypes = signatureHasLiteralTypes;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createSynthesizedNode(kind) {
        var node = ts.createNode(kind, -1, -1);
        node.flags |= 8 /* Synthesized */;
        return node;
    }
    /* @internal */
    function updateNode(updated, original) {
        if (updated !== original) {
            setOriginalNode(updated, original);
            setTextRange(updated, original);
            ts.aggregateTransformFlags(updated);
        }
        return updated;
    }
    ts.updateNode = updateNode;
    /**
     * Make `elements` into a `NodeArray<T>`. If `elements` is `undefined`, returns an empty `NodeArray<T>`.
     */
    function createNodeArray(elements, hasTrailingComma) {
        if (!elements || elements === ts.emptyArray) {
            elements = [];
        }
        else if (ts.isNodeArray(elements)) {
            return elements;
        }
        var array = elements;
        array.pos = -1;
        array.end = -1;
        array.hasTrailingComma = hasTrailingComma;
        return array;
    }
    ts.createNodeArray = createNodeArray;
    /**
     * Creates a shallow, memberwise clone of a node with no source map location.
     */
    /* @internal */
    function getSynthesizedClone(node) {
        // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
        // the original node. We also need to exclude specific properties and only include own-
        // properties (to skip members already defined on the shared prototype).
        if (node === undefined) {
            return node;
        }
        var clone = createSynthesizedNode(node.kind);
        clone.flags |= node.flags;
        setOriginalNode(clone, node);
        for (var key in node) {
            if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
                continue;
            }
            clone[key] = node[key];
        }
        return clone;
    }
    ts.getSynthesizedClone = getSynthesizedClone;
    function createLiteral(value, isSingleQuote) {
        if (typeof value === "number") {
            return createNumericLiteral(value + "");
        }
        // eslint-disable-next-line no-in-operator
        if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt
            return createBigIntLiteral(ts.pseudoBigIntToString(value) + "n");
        }
        if (typeof value === "boolean") {
            return value ? createTrue() : createFalse();
        }
        if (ts.isString(value)) {
            var res = createStringLiteral(value);
            if (isSingleQuote)
                res.singleQuote = true;
            return res;
        }
        return createLiteralFromNode(value);
    }
    ts.createLiteral = createLiteral;
    function createNumericLiteral(value, numericLiteralFlags) {
        if (numericLiteralFlags === void 0) { numericLiteralFlags = 0 /* None */; }
        var node = createSynthesizedNode(8 /* NumericLiteral */);
        node.text = value;
        node.numericLiteralFlags = numericLiteralFlags;
        return node;
    }
    ts.createNumericLiteral = createNumericLiteral;
    function createBigIntLiteral(value) {
        var node = createSynthesizedNode(9 /* BigIntLiteral */);
        node.text = value;
        return node;
    }
    ts.createBigIntLiteral = createBigIntLiteral;
    function createStringLiteral(text) {
        var node = createSynthesizedNode(10 /* StringLiteral */);
        node.text = text;
        return node;
    }
    ts.createStringLiteral = createStringLiteral;
    function createRegularExpressionLiteral(text) {
        var node = createSynthesizedNode(13 /* RegularExpressionLiteral */);
        node.text = text;
        return node;
    }
    ts.createRegularExpressionLiteral = createRegularExpressionLiteral;
    function createLiteralFromNode(sourceNode) {
        var node = createStringLiteral(ts.getTextOfIdentifierOrLiteral(sourceNode));
        node.textSourceNode = sourceNode;
        return node;
    }
    function createIdentifier(text, typeArguments) {
        var node = createSynthesizedNode(75 /* Identifier */);
        node.escapedText = ts.escapeLeadingUnderscores(text);
        node.originalKeywordKind = text ? ts.stringToToken(text) : 0 /* Unknown */;
        node.autoGenerateFlags = 0 /* None */;
        node.autoGenerateId = 0;
        if (typeArguments) {
            node.typeArguments = createNodeArray(typeArguments);
        }
        return node;
    }
    ts.createIdentifier = createIdentifier;
    function updateIdentifier(node, typeArguments) {
        return node.typeArguments !== typeArguments
            ? updateNode(createIdentifier(ts.idText(node), typeArguments), node)
            : node;
    }
    ts.updateIdentifier = updateIdentifier;
    var nextAutoGenerateId = 0;
    function createTempVariable(recordTempVariable, reservedInNestedScopes) {
        var name = createIdentifier("");
        name.autoGenerateFlags = 1 /* Auto */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        if (recordTempVariable) {
            recordTempVariable(name);
        }
        if (reservedInNestedScopes) {
            name.autoGenerateFlags |= 8 /* ReservedInNestedScopes */;
        }
        return name;
    }
    ts.createTempVariable = createTempVariable;
    /** Create a unique temporary variable for use in a loop. */
    function createLoopVariable() {
        var name = createIdentifier("");
        name.autoGenerateFlags = 2 /* Loop */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createLoopVariable = createLoopVariable;
    /** Create a unique name based on the supplied text. */
    function createUniqueName(text) {
        var name = createIdentifier(text);
        name.autoGenerateFlags = 3 /* Unique */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createUniqueName = createUniqueName;
    function createOptimisticUniqueName(text) {
        var name = createIdentifier(text);
        name.autoGenerateFlags = 3 /* Unique */ | 16 /* Optimistic */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createOptimisticUniqueName = createOptimisticUniqueName;
    /** Create a unique name based on the supplied text. This does not consider names injected by the transformer. */
    function createFileLevelUniqueName(text) {
        var name = createOptimisticUniqueName(text);
        name.autoGenerateFlags |= 32 /* FileLevel */;
        return name;
    }
    ts.createFileLevelUniqueName = createFileLevelUniqueName;
    function getGeneratedNameForNode(node, flags) {
        var name = createIdentifier(node && ts.isIdentifier(node) ? ts.idText(node) : "");
        name.autoGenerateFlags = 4 /* Node */ | flags;
        name.autoGenerateId = nextAutoGenerateId;
        name.original = node;
        nextAutoGenerateId++;
        return name;
    }
    ts.getGeneratedNameForNode = getGeneratedNameForNode;
    // Private Identifiers
    function createPrivateIdentifier(text) {
        if (text[0] !== "#") {
            ts.Debug.fail("First character of private identifier must be #: " + text);
        }
        var node = createSynthesizedNode(76 /* PrivateIdentifier */);
        node.escapedText = ts.escapeLeadingUnderscores(text);
        return node;
    }
    ts.createPrivateIdentifier = createPrivateIdentifier;
    // Punctuation
    function createToken(token) {
        return createSynthesizedNode(token);
    }
    ts.createToken = createToken;
    // Reserved words
    function createSuper() {
        return createSynthesizedNode(102 /* SuperKeyword */);
    }
    ts.createSuper = createSuper;
    function createThis() {
        return createSynthesizedNode(104 /* ThisKeyword */);
    }
    ts.createThis = createThis;
    function createNull() {
        return createSynthesizedNode(100 /* NullKeyword */);
    }
    ts.createNull = createNull;
    function createTrue() {
        return createSynthesizedNode(106 /* TrueKeyword */);
    }
    ts.createTrue = createTrue;
    function createFalse() {
        return createSynthesizedNode(91 /* FalseKeyword */);
    }
    ts.createFalse = createFalse;
    // Modifiers
    function createModifier(kind) {
        return createToken(kind);
    }
    ts.createModifier = createModifier;
    function createModifiersFromModifierFlags(flags) {
        var result = [];
        if (flags & 1 /* Export */) {
            result.push(createModifier(89 /* ExportKeyword */));
        }
        if (flags & 2 /* Ambient */) {
            result.push(createModifier(130 /* DeclareKeyword */));
        }
        if (flags & 512 /* Default */) {
            result.push(createModifier(84 /* DefaultKeyword */));
        }
        if (flags & 2048 /* Const */) {
            result.push(createModifier(81 /* ConstKeyword */));
        }
        if (flags & 4 /* Public */) {
            result.push(createModifier(119 /* PublicKeyword */));
        }
        if (flags & 8 /* Private */) {
            result.push(createModifier(117 /* PrivateKeyword */));
        }
        if (flags & 16 /* Protected */) {
            result.push(createModifier(118 /* ProtectedKeyword */));
        }
        if (flags & 128 /* Abstract */) {
            result.push(createModifier(122 /* AbstractKeyword */));
        }
        if (flags & 32 /* Static */) {
            result.push(createModifier(120 /* StaticKeyword */));
        }
        if (flags & 64 /* Readonly */) {
            result.push(createModifier(138 /* ReadonlyKeyword */));
        }
        if (flags & 256 /* Async */) {
            result.push(createModifier(126 /* AsyncKeyword */));
        }
        return result;
    }
    ts.createModifiersFromModifierFlags = createModifiersFromModifierFlags;
    // Names
    function createQualifiedName(left, right) {
        var node = createSynthesizedNode(153 /* QualifiedName */);
        node.left = left;
        node.right = asName(right);
        return node;
    }
    ts.createQualifiedName = createQualifiedName;
    function updateQualifiedName(node, left, right) {
        return node.left !== left
            || node.right !== right
            ? updateNode(createQualifiedName(left, right), node)
            : node;
    }
    ts.updateQualifiedName = updateQualifiedName;
    function parenthesizeForComputedName(expression) {
        return ts.isCommaSequence(expression)
            ? createParen(expression)
            : expression;
    }
    function createComputedPropertyName(expression) {
        var node = createSynthesizedNode(154 /* ComputedPropertyName */);
        node.expression = parenthesizeForComputedName(expression);
        return node;
    }
    ts.createComputedPropertyName = createComputedPropertyName;
    function updateComputedPropertyName(node, expression) {
        return node.expression !== expression
            ? updateNode(createComputedPropertyName(expression), node)
            : node;
    }
    ts.updateComputedPropertyName = updateComputedPropertyName;
    // Signature elements
    function createTypeParameterDeclaration(name, constraint, defaultType) {
        var node = createSynthesizedNode(155 /* TypeParameter */);
        node.name = asName(name);
        node.constraint = constraint;
        node.default = defaultType;
        return node;
    }
    ts.createTypeParameterDeclaration = createTypeParameterDeclaration;
    function updateTypeParameterDeclaration(node, name, constraint, defaultType) {
        return node.name !== name
            || node.constraint !== constraint
            || node.default !== defaultType
            ? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node)
            : node;
    }
    ts.updateTypeParameterDeclaration = updateTypeParameterDeclaration;
    function createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(156 /* Parameter */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.dotDotDotToken = dotDotDotToken;
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createParameter = createParameter;
    function updateParameter(node, decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.dotDotDotToken !== dotDotDotToken
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updateParameter = updateParameter;
    function createDecorator(expression) {
        var node = createSynthesizedNode(157 /* Decorator */);
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createDecorator = createDecorator;
    function updateDecorator(node, expression) {
        return node.expression !== expression
            ? updateNode(createDecorator(expression), node)
            : node;
    }
    ts.updateDecorator = updateDecorator;
    // Type Elements
    function createPropertySignature(modifiers, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(158 /* PropertySignature */);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer;
        return node;
    }
    ts.createPropertySignature = createPropertySignature;
    function updatePropertySignature(node, modifiers, name, questionToken, type, initializer) {
        return node.modifiers !== modifiers
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updatePropertySignature = updatePropertySignature;
    function createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer) {
        var node = createSynthesizedNode(159 /* PropertyDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.questionToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 57 /* QuestionToken */ ? questionOrExclamationToken : undefined;
        node.exclamationToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 53 /* ExclamationToken */ ? questionOrExclamationToken : undefined;
        node.type = type;
        node.initializer = initializer;
        return node;
    }
    ts.createProperty = createProperty;
    function updateProperty(node, decorators, modifiers, name, questionOrExclamationToken, type, initializer) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.questionToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 57 /* QuestionToken */ ? questionOrExclamationToken : undefined)
            || node.exclamationToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 53 /* ExclamationToken */ ? questionOrExclamationToken : undefined)
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer), node)
            : node;
    }
    ts.updateProperty = updateProperty;
    function createMethodSignature(typeParameters, parameters, type, name, questionToken) {
        var node = createSignatureDeclaration(160 /* MethodSignature */, typeParameters, parameters, type);
        node.name = asName(name);
        node.questionToken = questionToken;
        return node;
    }
    ts.createMethodSignature = createMethodSignature;
    function updateMethodSignature(node, typeParameters, parameters, type, name, questionToken) {
        return node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.name !== name
            || node.questionToken !== questionToken
            ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
            : node;
    }
    ts.updateMethodSignature = updateMethodSignature;
    function createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(161 /* MethodDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.questionToken = questionToken;
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createMethod = createMethod;
    function createMethodCall(object, methodName, argumentsList) {
        return createCall(createPropertyAccess(object, asName(methodName)), 
        /*typeArguments*/ undefined, argumentsList);
    }
    function createGlobalMethodCall(globalObjectName, methodName, argumentsList) {
        return createMethodCall(createIdentifier(globalObjectName), methodName, argumentsList);
    }
    /* @internal */
    function createObjectDefinePropertyCall(target, propertyName, attributes) {
        return createGlobalMethodCall("Object", "defineProperty", [target, asExpression(propertyName), attributes]);
    }
    ts.createObjectDefinePropertyCall = createObjectDefinePropertyCall;
    function tryAddPropertyAssignment(properties, propertyName, expression) {
        if (expression) {
            properties.push(createPropertyAssignment(propertyName, expression));
            return true;
        }
        return false;
    }
    /* @internal */
    function createPropertyDescriptor(attributes, singleLine) {
        var properties = [];
        tryAddPropertyAssignment(properties, "enumerable", asExpression(attributes.enumerable));
        tryAddPropertyAssignment(properties, "configurable", asExpression(attributes.configurable));
        var isData = tryAddPropertyAssignment(properties, "writable", asExpression(attributes.writable));
        isData = tryAddPropertyAssignment(properties, "value", attributes.value) || isData;
        var isAccessor = tryAddPropertyAssignment(properties, "get", attributes.get);
        isAccessor = tryAddPropertyAssignment(properties, "set", attributes.set) || isAccessor;
        ts.Debug.assert(!(isData && isAccessor), "A PropertyDescriptor may not be both an accessor descriptor and a data descriptor.");
        return createObjectLiteral(properties, !singleLine);
    }
    ts.createPropertyDescriptor = createPropertyDescriptor;
    function updateMethod(node, decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.name !== name
            || node.questionToken !== questionToken
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateMethod = updateMethod;
    function createConstructor(decorators, modifiers, parameters, body) {
        var node = createSynthesizedNode(162 /* Constructor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.type = undefined;
        node.body = body;
        return node;
    }
    ts.createConstructor = createConstructor;
    function updateConstructor(node, decorators, modifiers, parameters, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.parameters !== parameters
            || node.body !== body
            ? updateNode(createConstructor(decorators, modifiers, parameters, body), node)
            : node;
    }
    ts.updateConstructor = updateConstructor;
    function createGetAccessor(decorators, modifiers, name, parameters, type, body) {
        var node = createSynthesizedNode(163 /* GetAccessor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createGetAccessor = createGetAccessor;
    function updateGetAccessor(node, decorators, modifiers, name, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body), node)
            : node;
    }
    ts.updateGetAccessor = updateGetAccessor;
    function createSetAccessor(decorators, modifiers, name, parameters, body) {
        var node = createSynthesizedNode(164 /* SetAccessor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.body = body;
        return node;
    }
    ts.createSetAccessor = createSetAccessor;
    function updateSetAccessor(node, decorators, modifiers, name, parameters, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.parameters !== parameters
            || node.body !== body
            ? updateNode(createSetAccessor(decorators, modifiers, name, parameters, body), node)
            : node;
    }
    ts.updateSetAccessor = updateSetAccessor;
    function createCallSignature(typeParameters, parameters, type) {
        return createSignatureDeclaration(165 /* CallSignature */, typeParameters, parameters, type);
    }
    ts.createCallSignature = createCallSignature;
    function updateCallSignature(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateCallSignature = updateCallSignature;
    function createConstructSignature(typeParameters, parameters, type) {
        return createSignatureDeclaration(166 /* ConstructSignature */, typeParameters, parameters, type);
    }
    ts.createConstructSignature = createConstructSignature;
    function updateConstructSignature(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateConstructSignature = updateConstructSignature;
    function createIndexSignature(decorators, modifiers, parameters, type) {
        var node = createSynthesizedNode(167 /* IndexSignature */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        return node;
    }
    ts.createIndexSignature = createIndexSignature;
    function updateIndexSignature(node, decorators, modifiers, parameters, type) {
        return node.parameters !== parameters
            || node.type !== type
            || node.decorators !== decorators
            || node.modifiers !== modifiers
            ? updateNode(createIndexSignature(decorators, modifiers, parameters, type), node)
            : node;
    }
    ts.updateIndexSignature = updateIndexSignature;
    /* @internal */
    function createSignatureDeclaration(kind, typeParameters, parameters, type, typeArguments) {
        var node = createSynthesizedNode(kind);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = asNodeArray(parameters);
        node.type = type;
        node.typeArguments = asNodeArray(typeArguments);
        return node;
    }
    ts.createSignatureDeclaration = createSignatureDeclaration;
    function updateSignatureDeclaration(node, typeParameters, parameters, type) {
        return node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
            : node;
    }
    // Types
    function createKeywordTypeNode(kind) {
        return createSynthesizedNode(kind);
    }
    ts.createKeywordTypeNode = createKeywordTypeNode;
    function createTypePredicateNode(parameterName, type) {
        return createTypePredicateNodeWithModifier(/*assertsModifier*/ undefined, parameterName, type);
    }
    ts.createTypePredicateNode = createTypePredicateNode;
    function createTypePredicateNodeWithModifier(assertsModifier, parameterName, type) {
        var node = createSynthesizedNode(168 /* TypePredicate */);
        node.assertsModifier = assertsModifier;
        node.parameterName = asName(parameterName);
        node.type = type;
        return node;
    }
    ts.createTypePredicateNodeWithModifier = createTypePredicateNodeWithModifier;
    function updateTypePredicateNode(node, parameterName, type) {
        return updateTypePredicateNodeWithModifier(node, node.assertsModifier, parameterName, type);
    }
    ts.updateTypePredicateNode = updateTypePredicateNode;
    function updateTypePredicateNodeWithModifier(node, assertsModifier, parameterName, type) {
        return node.assertsModifier !== assertsModifier
            || node.parameterName !== parameterName
            || node.type !== type
            ? updateNode(createTypePredicateNodeWithModifier(assertsModifier, parameterName, type), node)
            : node;
    }
    ts.updateTypePredicateNodeWithModifier = updateTypePredicateNodeWithModifier;
    function createTypeReferenceNode(typeName, typeArguments) {
        var node = createSynthesizedNode(169 /* TypeReference */);
        node.typeName = asName(typeName);
        node.typeArguments = typeArguments && ts.parenthesizeTypeParameters(typeArguments);
        return node;
    }
    ts.createTypeReferenceNode = createTypeReferenceNode;
    function updateTypeReferenceNode(node, typeName, typeArguments) {
        return node.typeName !== typeName
            || node.typeArguments !== typeArguments
            ? updateNode(createTypeReferenceNode(typeName, typeArguments), node)
            : node;
    }
    ts.updateTypeReferenceNode = updateTypeReferenceNode;
    function createFunctionTypeNode(typeParameters, parameters, type) {
        return createSignatureDeclaration(170 /* FunctionType */, typeParameters, parameters, type);
    }
    ts.createFunctionTypeNode = createFunctionTypeNode;
    function updateFunctionTypeNode(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateFunctionTypeNode = updateFunctionTypeNode;
    function createConstructorTypeNode(typeParameters, parameters, type) {
        return createSignatureDeclaration(171 /* ConstructorType */, typeParameters, parameters, type);
    }
    ts.createConstructorTypeNode = createConstructorTypeNode;
    function updateConstructorTypeNode(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateConstructorTypeNode = updateConstructorTypeNode;
    function createTypeQueryNode(exprName) {
        var node = createSynthesizedNode(172 /* TypeQuery */);
        node.exprName = exprName;
        return node;
    }
    ts.createTypeQueryNode = createTypeQueryNode;
    function updateTypeQueryNode(node, exprName) {
        return node.exprName !== exprName
            ? updateNode(createTypeQueryNode(exprName), node)
            : node;
    }
    ts.updateTypeQueryNode = updateTypeQueryNode;
    function createTypeLiteralNode(members) {
        var node = createSynthesizedNode(173 /* TypeLiteral */);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createTypeLiteralNode = createTypeLiteralNode;
    function updateTypeLiteralNode(node, members) {
        return node.members !== members
            ? updateNode(createTypeLiteralNode(members), node)
            : node;
    }
    ts.updateTypeLiteralNode = updateTypeLiteralNode;
    function createArrayTypeNode(elementType) {
        var node = createSynthesizedNode(174 /* ArrayType */);
        node.elementType = ts.parenthesizeArrayTypeMember(elementType);
        return node;
    }
    ts.createArrayTypeNode = createArrayTypeNode;
    function updateArrayTypeNode(node, elementType) {
        return node.elementType !== elementType
            ? updateNode(createArrayTypeNode(elementType), node)
            : node;
    }
    ts.updateArrayTypeNode = updateArrayTypeNode;
    function createTupleTypeNode(elementTypes) {
        var node = createSynthesizedNode(175 /* TupleType */);
        node.elementTypes = createNodeArray(elementTypes);
        return node;
    }
    ts.createTupleTypeNode = createTupleTypeNode;
    function updateTupleTypeNode(node, elementTypes) {
        return node.elementTypes !== elementTypes
            ? updateNode(createTupleTypeNode(elementTypes), node)
            : node;
    }
    ts.updateTupleTypeNode = updateTupleTypeNode;
    function createOptionalTypeNode(type) {
        var node = createSynthesizedNode(176 /* OptionalType */);
        node.type = ts.parenthesizeArrayTypeMember(type);
        return node;
    }
    ts.createOptionalTypeNode = createOptionalTypeNode;
    function updateOptionalTypeNode(node, type) {
        return node.type !== type
            ? updateNode(createOptionalTypeNode(type), node)
            : node;
    }
    ts.updateOptionalTypeNode = updateOptionalTypeNode;
    function createRestTypeNode(type) {
        var node = createSynthesizedNode(177 /* RestType */);
        node.type = type;
        return node;
    }
    ts.createRestTypeNode = createRestTypeNode;
    function updateRestTypeNode(node, type) {
        return node.type !== type
            ? updateNode(createRestTypeNode(type), node)
            : node;
    }
    ts.updateRestTypeNode = updateRestTypeNode;
    function createUnionTypeNode(types) {
        return createUnionOrIntersectionTypeNode(178 /* UnionType */, types);
    }
    ts.createUnionTypeNode = createUnionTypeNode;
    function updateUnionTypeNode(node, types) {
        return updateUnionOrIntersectionTypeNode(node, types);
    }
    ts.updateUnionTypeNode = updateUnionTypeNode;
    function createIntersectionTypeNode(types) {
        return createUnionOrIntersectionTypeNode(179 /* IntersectionType */, types);
    }
    ts.createIntersectionTypeNode = createIntersectionTypeNode;
    function updateIntersectionTypeNode(node, types) {
        return updateUnionOrIntersectionTypeNode(node, types);
    }
    ts.updateIntersectionTypeNode = updateIntersectionTypeNode;
    function createUnionOrIntersectionTypeNode(kind, types) {
        var node = createSynthesizedNode(kind);
        node.types = ts.parenthesizeElementTypeMembers(types);
        return node;
    }
    ts.createUnionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode;
    function updateUnionOrIntersectionTypeNode(node, types) {
        return node.types !== types
            ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node)
            : node;
    }
    function createConditionalTypeNode(checkType, extendsType, trueType, falseType) {
        var node = createSynthesizedNode(180 /* ConditionalType */);
        node.checkType = ts.parenthesizeConditionalTypeMember(checkType);
        node.extendsType = ts.parenthesizeConditionalTypeMember(extendsType);
        node.trueType = trueType;
        node.falseType = falseType;
        return node;
    }
    ts.createConditionalTypeNode = createConditionalTypeNode;
    function updateConditionalTypeNode(node, checkType, extendsType, trueType, falseType) {
        return node.checkType !== checkType
            || node.extendsType !== extendsType
            || node.trueType !== trueType
            || node.falseType !== falseType
            ? updateNode(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node)
            : node;
    }
    ts.updateConditionalTypeNode = updateConditionalTypeNode;
    function createInferTypeNode(typeParameter) {
        var node = createSynthesizedNode(181 /* InferType */);
        node.typeParameter = typeParameter;
        return node;
    }
    ts.createInferTypeNode = createInferTypeNode;
    function updateInferTypeNode(node, typeParameter) {
        return node.typeParameter !== typeParameter
            ? updateNode(createInferTypeNode(typeParameter), node)
            : node;
    }
    ts.updateInferTypeNode = updateInferTypeNode;
    function createImportTypeNode(argument, qualifier, typeArguments, isTypeOf) {
        var node = createSynthesizedNode(188 /* ImportType */);
        node.argument = argument;
        node.qualifier = qualifier;
        node.typeArguments = ts.parenthesizeTypeParameters(typeArguments);
        node.isTypeOf = isTypeOf;
        return node;
    }
    ts.createImportTypeNode = createImportTypeNode;
    function updateImportTypeNode(node, argument, qualifier, typeArguments, isTypeOf) {
        return node.argument !== argument
            || node.qualifier !== qualifier
            || node.typeArguments !== typeArguments
            || node.isTypeOf !== isTypeOf
            ? updateNode(createImportTypeNode(argument, qualifier, typeArguments, isTypeOf), node)
            : node;
    }
    ts.updateImportTypeNode = updateImportTypeNode;
    function createParenthesizedType(type) {
        var node = createSynthesizedNode(182 /* ParenthesizedType */);
        node.type = type;
        return node;
    }
    ts.createParenthesizedType = createParenthesizedType;
    function updateParenthesizedType(node, type) {
        return node.type !== type
            ? updateNode(createParenthesizedType(type), node)
            : node;
    }
    ts.updateParenthesizedType = updateParenthesizedType;
    function createThisTypeNode() {
        return createSynthesizedNode(183 /* ThisType */);
    }
    ts.createThisTypeNode = createThisTypeNode;
    function createTypeOperatorNode(operatorOrType, type) {
        var node = createSynthesizedNode(184 /* TypeOperator */);
        node.operator = typeof operatorOrType === "number" ? operatorOrType : 134 /* KeyOfKeyword */;
        node.type = ts.parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type : operatorOrType);
        return node;
    }
    ts.createTypeOperatorNode = createTypeOperatorNode;
    function updateTypeOperatorNode(node, type) {
        return node.type !== type ? updateNode(createTypeOperatorNode(node.operator, type), node) : node;
    }
    ts.updateTypeOperatorNode = updateTypeOperatorNode;
    function createIndexedAccessTypeNode(objectType, indexType) {
        var node = createSynthesizedNode(185 /* IndexedAccessType */);
        node.objectType = ts.parenthesizeElementTypeMember(objectType);
        node.indexType = indexType;
        return node;
    }
    ts.createIndexedAccessTypeNode = createIndexedAccessTypeNode;
    function updateIndexedAccessTypeNode(node, objectType, indexType) {
        return node.objectType !== objectType
            || node.indexType !== indexType
            ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node)
            : node;
    }
    ts.updateIndexedAccessTypeNode = updateIndexedAccessTypeNode;
    function createMappedTypeNode(readonlyToken, typeParameter, questionToken, type) {
        var node = createSynthesizedNode(186 /* MappedType */);
        node.readonlyToken = readonlyToken;
        node.typeParameter = typeParameter;
        node.questionToken = questionToken;
        node.type = type;
        return node;
    }
    ts.createMappedTypeNode = createMappedTypeNode;
    function updateMappedTypeNode(node, readonlyToken, typeParameter, questionToken, type) {
        return node.readonlyToken !== readonlyToken
            || node.typeParameter !== typeParameter
            || node.questionToken !== questionToken
            || node.type !== type
            ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node)
            : node;
    }
    ts.updateMappedTypeNode = updateMappedTypeNode;
    function createLiteralTypeNode(literal) {
        var node = createSynthesizedNode(187 /* LiteralType */);
        node.literal = literal;
        return node;
    }
    ts.createLiteralTypeNode = createLiteralTypeNode;
    function updateLiteralTypeNode(node, literal) {
        return node.literal !== literal
            ? updateNode(createLiteralTypeNode(literal), node)
            : node;
    }
    ts.updateLiteralTypeNode = updateLiteralTypeNode;
    // Binding Patterns
    function createObjectBindingPattern(elements) {
        var node = createSynthesizedNode(189 /* ObjectBindingPattern */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createObjectBindingPattern = createObjectBindingPattern;
    function updateObjectBindingPattern(node, elements) {
        return node.elements !== elements
            ? updateNode(createObjectBindingPattern(elements), node)
            : node;
    }
    ts.updateObjectBindingPattern = updateObjectBindingPattern;
    function createArrayBindingPattern(elements) {
        var node = createSynthesizedNode(190 /* ArrayBindingPattern */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createArrayBindingPattern = createArrayBindingPattern;
    function updateArrayBindingPattern(node, elements) {
        return node.elements !== elements
            ? updateNode(createArrayBindingPattern(elements), node)
            : node;
    }
    ts.updateArrayBindingPattern = updateArrayBindingPattern;
    function createBindingElement(dotDotDotToken, propertyName, name, initializer) {
        var node = createSynthesizedNode(191 /* BindingElement */);
        node.dotDotDotToken = dotDotDotToken;
        node.propertyName = asName(propertyName);
        node.name = asName(name);
        node.initializer = initializer;
        return node;
    }
    ts.createBindingElement = createBindingElement;
    function updateBindingElement(node, dotDotDotToken, propertyName, name, initializer) {
        return node.propertyName !== propertyName
            || node.dotDotDotToken !== dotDotDotToken
            || node.name !== name
            || node.initializer !== initializer
            ? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node)
            : node;
    }
    ts.updateBindingElement = updateBindingElement;
    // Expression
    function createArrayLiteral(elements, multiLine) {
        var node = createSynthesizedNode(192 /* ArrayLiteralExpression */);
        node.elements = ts.parenthesizeListElements(createNodeArray(elements));
        if (multiLine)
            node.multiLine = true;
        return node;
    }
    ts.createArrayLiteral = createArrayLiteral;
    function updateArrayLiteral(node, elements) {
        return node.elements !== elements
            ? updateNode(createArrayLiteral(elements, node.multiLine), node)
            : node;
    }
    ts.updateArrayLiteral = updateArrayLiteral;
    function createObjectLiteral(properties, multiLine) {
        var node = createSynthesizedNode(193 /* ObjectLiteralExpression */);
        node.properties = createNodeArray(properties);
        if (multiLine)
            node.multiLine = true;
        return node;
    }
    ts.createObjectLiteral = createObjectLiteral;
    function updateObjectLiteral(node, properties) {
        return node.properties !== properties
            ? updateNode(createObjectLiteral(properties, node.multiLine), node)
            : node;
    }
    ts.updateObjectLiteral = updateObjectLiteral;
    function createPropertyAccess(expression, name) {
        var node = createSynthesizedNode(194 /* PropertyAccessExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.name = asName(name);
        setEmitFlags(node, 131072 /* NoIndentation */);
        return node;
    }
    ts.createPropertyAccess = createPropertyAccess;
    function updatePropertyAccess(node, expression, name) {
        if (ts.isPropertyAccessChain(node)) {
            return updatePropertyAccessChain(node, expression, node.questionDotToken, ts.cast(name, ts.isIdentifier));
        }
        // Because we are updating existed propertyAccess we want to inherit its emitFlags
        // instead of using the default from createPropertyAccess
        return node.expression !== expression
            || node.name !== name
            ? updateNode(setEmitFlags(createPropertyAccess(expression, name), ts.getEmitFlags(node)), node)
            : node;
    }
    ts.updatePropertyAccess = updatePropertyAccess;
    function createPropertyAccessChain(expression, questionDotToken, name) {
        var node = createSynthesizedNode(194 /* PropertyAccessExpression */);
        node.flags |= 32 /* OptionalChain */;
        node.expression = ts.parenthesizeForAccess(expression);
        node.questionDotToken = questionDotToken;
        node.name = asName(name);
        setEmitFlags(node, 131072 /* NoIndentation */);
        return node;
    }
    ts.createPropertyAccessChain = createPropertyAccessChain;
    function updatePropertyAccessChain(node, expression, questionDotToken, name) {
        ts.Debug.assert(!!(node.flags & 32 /* OptionalChain */), "Cannot update a PropertyAccessExpression using updatePropertyAccessChain. Use updatePropertyAccess instead.");
        // Because we are updating an existing PropertyAccessChain we want to inherit its emitFlags
        // instead of using the default from createPropertyAccess
        return node.expression !== expression
            || node.questionDotToken !== questionDotToken
            || node.name !== name
            ? updateNode(setEmitFlags(createPropertyAccessChain(expression, questionDotToken, name), ts.getEmitFlags(node)), node)
            : node;
    }
    ts.updatePropertyAccessChain = updatePropertyAccessChain;
    function createElementAccess(expression, index) {
        var node = createSynthesizedNode(195 /* ElementAccessExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.argumentExpression = asExpression(index);
        return node;
    }
    ts.createElementAccess = createElementAccess;
    function updateElementAccess(node, expression, argumentExpression) {
        if (ts.isOptionalChain(node)) {
            return updateElementAccessChain(node, expression, node.questionDotToken, argumentExpression);
        }
        return node.expression !== expression
            || node.argumentExpression !== argumentExpression
            ? updateNode(createElementAccess(expression, argumentExpression), node)
            : node;
    }
    ts.updateElementAccess = updateElementAccess;
    function createElementAccessChain(expression, questionDotToken, index) {
        var node = createSynthesizedNode(195 /* ElementAccessExpression */);
        node.flags |= 32 /* OptionalChain */;
        node.expression = ts.parenthesizeForAccess(expression);
        node.questionDotToken = questionDotToken;
        node.argumentExpression = asExpression(index);
        return node;
    }
    ts.createElementAccessChain = createElementAccessChain;
    function updateElementAccessChain(node, expression, questionDotToken, argumentExpression) {
        ts.Debug.assert(!!(node.flags & 32 /* OptionalChain */), "Cannot update an ElementAccessExpression using updateElementAccessChain. Use updateElementAccess instead.");
        return node.expression !== expression
            || node.questionDotToken !== questionDotToken
            || node.argumentExpression !== argumentExpression
            ? updateNode(createElementAccessChain(expression, questionDotToken, argumentExpression), node)
            : node;
    }
    ts.updateElementAccessChain = updateElementAccessChain;
    function createCall(expression, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(196 /* CallExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = ts.parenthesizeListElements(createNodeArray(argumentsArray));
        return node;
    }
    ts.createCall = createCall;
    function updateCall(node, expression, typeArguments, argumentsArray) {
        if (ts.isOptionalChain(node)) {
            return updateCallChain(node, expression, node.questionDotToken, typeArguments, argumentsArray);
        }
        return node.expression !== expression
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createCall(expression, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateCall = updateCall;
    function createCallChain(expression, questionDotToken, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(196 /* CallExpression */);
        node.flags |= 32 /* OptionalChain */;
        node.expression = ts.parenthesizeForAccess(expression);
        node.questionDotToken = questionDotToken;
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = ts.parenthesizeListElements(createNodeArray(argumentsArray));
        return node;
    }
    ts.createCallChain = createCallChain;
    function updateCallChain(node, expression, questionDotToken, typeArguments, argumentsArray) {
        ts.Debug.assert(!!(node.flags & 32 /* OptionalChain */), "Cannot update a CallExpression using updateCallChain. Use updateCall instead.");
        return node.expression !== expression
            || node.questionDotToken !== questionDotToken
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createCallChain(expression, questionDotToken, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateCallChain = updateCallChain;
    function createNew(expression, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(197 /* NewExpression */);
        node.expression = ts.parenthesizeForNew(expression);
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = argumentsArray ? ts.parenthesizeListElements(createNodeArray(argumentsArray)) : undefined;
        return node;
    }
    ts.createNew = createNew;
    function updateNew(node, expression, typeArguments, argumentsArray) {
        return node.expression !== expression
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createNew(expression, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateNew = updateNew;
    function createTaggedTemplate(tag, typeArgumentsOrTemplate, template) {
        var node = createSynthesizedNode(198 /* TaggedTemplateExpression */);
        node.tag = ts.parenthesizeForAccess(tag);
        if (template) {
            node.typeArguments = asNodeArray(typeArgumentsOrTemplate);
            node.template = template;
        }
        else {
            node.typeArguments = undefined;
            node.template = typeArgumentsOrTemplate;
        }
        return node;
    }
    ts.createTaggedTemplate = createTaggedTemplate;
    function updateTaggedTemplate(node, tag, typeArgumentsOrTemplate, template) {
        return node.tag !== tag
            || (template
                ? node.typeArguments !== typeArgumentsOrTemplate || node.template !== template
                : node.typeArguments !== undefined || node.template !== typeArgumentsOrTemplate)
            ? updateNode(createTaggedTemplate(tag, typeArgumentsOrTemplate, template), node)
            : node;
    }
    ts.updateTaggedTemplate = updateTaggedTemplate;
    function createTypeAssertion(type, expression) {
        var node = createSynthesizedNode(199 /* TypeAssertionExpression */);
        node.type = type;
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createTypeAssertion = createTypeAssertion;
    function updateTypeAssertion(node, type, expression) {
        return node.type !== type
            || node.expression !== expression
            ? updateNode(createTypeAssertion(type, expression), node)
            : node;
    }
    ts.updateTypeAssertion = updateTypeAssertion;
    function createParen(expression) {
        var node = createSynthesizedNode(200 /* ParenthesizedExpression */);
        node.expression = expression;
        return node;
    }
    ts.createParen = createParen;
    function updateParen(node, expression) {
        return node.expression !== expression
            ? updateNode(createParen(expression), node)
            : node;
    }
    ts.updateParen = updateParen;
    function createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(201 /* FunctionExpression */);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createFunctionExpression = createFunctionExpression;
    function updateFunctionExpression(node, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        return node.name !== name
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateFunctionExpression = updateFunctionExpression;
    function createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) {
        var node = createSynthesizedNode(202 /* ArrowFunction */);
        node.modifiers = asNodeArray(modifiers);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(38 /* EqualsGreaterThanToken */);
        node.body = ts.parenthesizeConciseBody(body);
        return node;
    }
    ts.createArrowFunction = createArrowFunction;
    function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) {
        return node.modifiers !== modifiers
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.equalsGreaterThanToken !== equalsGreaterThanToken
            || node.body !== body
            ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node)
            : node;
    }
    ts.updateArrowFunction = updateArrowFunction;
    function createDelete(expression) {
        var node = createSynthesizedNode(203 /* DeleteExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createDelete = createDelete;
    function updateDelete(node, expression) {
        return node.expression !== expression
            ? updateNode(createDelete(expression), node)
            : node;
    }
    ts.updateDelete = updateDelete;
    function createTypeOf(expression) {
        var node = createSynthesizedNode(204 /* TypeOfExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createTypeOf = createTypeOf;
    function updateTypeOf(node, expression) {
        return node.expression !== expression
            ? updateNode(createTypeOf(expression), node)
            : node;
    }
    ts.updateTypeOf = updateTypeOf;
    function createVoid(expression) {
        var node = createSynthesizedNode(205 /* VoidExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createVoid = createVoid;
    function updateVoid(node, expression) {
        return node.expression !== expression
            ? updateNode(createVoid(expression), node)
            : node;
    }
    ts.updateVoid = updateVoid;
    function createAwait(expression) {
        var node = createSynthesizedNode(206 /* AwaitExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createAwait = createAwait;
    function updateAwait(node, expression) {
        return node.expression !== expression
            ? updateNode(createAwait(expression), node)
            : node;
    }
    ts.updateAwait = updateAwait;
    function createPrefix(operator, operand) {
        var node = createSynthesizedNode(207 /* PrefixUnaryExpression */);
        node.operator = operator;
        node.operand = ts.parenthesizePrefixOperand(operand);
        return node;
    }
    ts.createPrefix = createPrefix;
    function updatePrefix(node, operand) {
        return node.operand !== operand
            ? updateNode(createPrefix(node.operator, operand), node)
            : node;
    }
    ts.updatePrefix = updatePrefix;
    function createPostfix(operand, operator) {
        var node = createSynthesizedNode(208 /* PostfixUnaryExpression */);
        node.operand = ts.parenthesizePostfixOperand(operand);
        node.operator = operator;
        return node;
    }
    ts.createPostfix = createPostfix;
    function updatePostfix(node, operand) {
        return node.operand !== operand
            ? updateNode(createPostfix(operand, node.operator), node)
            : node;
    }
    ts.updatePostfix = updatePostfix;
    function createBinary(left, operator, right) {
        var node = createSynthesizedNode(209 /* BinaryExpression */);
        var operatorToken = asToken(operator);
        var operatorKind = operatorToken.kind;
        node.left = ts.parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
        node.operatorToken = operatorToken;
        node.right = ts.parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left);
        return node;
    }
    ts.createBinary = createBinary;
    function updateBinary(node, left, right, operator) {
        return node.left !== left
            || node.right !== right
            ? updateNode(createBinary(left, operator || node.operatorToken, right), node)
            : node;
    }
    ts.updateBinary = updateBinary;
    function createConditional(condition, questionTokenOrWhenTrue, whenTrueOrWhenFalse, colonToken, whenFalse) {
        var node = createSynthesizedNode(210 /* ConditionalExpression */);
        node.condition = ts.parenthesizeForConditionalHead(condition);
        node.questionToken = whenFalse ? questionTokenOrWhenTrue : createToken(57 /* QuestionToken */);
        node.whenTrue = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : questionTokenOrWhenTrue);
        node.colonToken = whenFalse ? colonToken : createToken(58 /* ColonToken */);
        node.whenFalse = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse);
        return node;
    }
    ts.createConditional = createConditional;
    function updateConditional(node, condition, questionToken, whenTrue, colonToken, whenFalse) {
        return node.condition !== condition
            || node.questionToken !== questionToken
            || node.whenTrue !== whenTrue
            || node.colonToken !== colonToken
            || node.whenFalse !== whenFalse
            ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node)
            : node;
    }
    ts.updateConditional = updateConditional;
    function createTemplateExpression(head, templateSpans) {
        var node = createSynthesizedNode(211 /* TemplateExpression */);
        node.head = head;
        node.templateSpans = createNodeArray(templateSpans);
        return node;
    }
    ts.createTemplateExpression = createTemplateExpression;
    function updateTemplateExpression(node, head, templateSpans) {
        return node.head !== head
            || node.templateSpans !== templateSpans
            ? updateNode(createTemplateExpression(head, templateSpans), node)
            : node;
    }
    ts.updateTemplateExpression = updateTemplateExpression;
    var rawTextScanner;
    var invalidValueSentinel = {};
    function getCookedText(kind, rawText) {
        if (!rawTextScanner) {
            rawTextScanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ false, 0 /* Standard */);
        }
        switch (kind) {
            case 14 /* NoSubstitutionTemplateLiteral */:
                rawTextScanner.setText("`" + rawText + "`");
                break;
            case 15 /* TemplateHead */:
                rawTextScanner.setText("`" + rawText + "${");
                break;
            case 16 /* TemplateMiddle */:
                rawTextScanner.setText("}" + rawText + "${");
                break;
            case 17 /* TemplateTail */:
                rawTextScanner.setText("}" + rawText + "`");
                break;
        }
        var token = rawTextScanner.scan();
        if (token === 23 /* CloseBracketToken */) {
            token = rawTextScanner.reScanTemplateToken(/* isTaggedTemplate */ false);
        }
        if (rawTextScanner.isUnterminated()) {
            rawTextScanner.setText(undefined);
            return invalidValueSentinel;
        }
        var tokenValue;
        switch (token) {
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 15 /* TemplateHead */:
            case 16 /* TemplateMiddle */:
            case 17 /* TemplateTail */:
                tokenValue = rawTextScanner.getTokenValue();
                break;
        }
        if (rawTextScanner.scan() !== 1 /* EndOfFileToken */) {
            rawTextScanner.setText(undefined);
            return invalidValueSentinel;
        }
        rawTextScanner.setText(undefined);
        return tokenValue;
    }
    function createTemplateLiteralLikeNode(kind, text, rawText) {
        var node = createSynthesizedNode(kind);
        node.text = text;
        if (rawText === undefined || text === rawText) {
            node.rawText = rawText;
        }
        else {
            var cooked = getCookedText(kind, rawText);
            if (typeof cooked === "object") {
                return ts.Debug.fail("Invalid raw text");
            }
            ts.Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'.");
            node.rawText = rawText;
        }
        return node;
    }
    function createTemplateHead(text, rawText) {
        var node = createTemplateLiteralLikeNode(15 /* TemplateHead */, text, rawText);
        node.text = text;
        return node;
    }
    ts.createTemplateHead = createTemplateHead;
    function createTemplateMiddle(text, rawText) {
        var node = createTemplateLiteralLikeNode(16 /* TemplateMiddle */, text, rawText);
        node.text = text;
        return node;
    }
    ts.createTemplateMiddle = createTemplateMiddle;
    function createTemplateTail(text, rawText) {
        var node = createTemplateLiteralLikeNode(17 /* TemplateTail */, text, rawText);
        node.text = text;
        return node;
    }
    ts.createTemplateTail = createTemplateTail;
    function createNoSubstitutionTemplateLiteral(text, rawText) {
        var node = createTemplateLiteralLikeNode(14 /* NoSubstitutionTemplateLiteral */, text, rawText);
        return node;
    }
    ts.createNoSubstitutionTemplateLiteral = createNoSubstitutionTemplateLiteral;
    function createYield(asteriskTokenOrExpression, expression) {
        var asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === 41 /* AsteriskToken */ ? asteriskTokenOrExpression : undefined;
        expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== 41 /* AsteriskToken */ ? asteriskTokenOrExpression : expression;
        var node = createSynthesizedNode(212 /* YieldExpression */);
        node.asteriskToken = asteriskToken;
        node.expression = expression && ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createYield = createYield;
    function updateYield(node, asteriskToken, expression) {
        return node.expression !== expression
            || node.asteriskToken !== asteriskToken
            ? updateNode(createYield(asteriskToken, expression), node)
            : node;
    }
    ts.updateYield = updateYield;
    function createSpread(expression) {
        var node = createSynthesizedNode(213 /* SpreadElement */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createSpread = createSpread;
    function updateSpread(node, expression) {
        return node.expression !== expression
            ? updateNode(createSpread(expression), node)
            : node;
    }
    ts.updateSpread = updateSpread;
    function createClassExpression(modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(214 /* ClassExpression */);
        node.decorators = undefined;
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createClassExpression = createClassExpression;
    function updateClassExpression(node, modifiers, name, typeParameters, heritageClauses, members) {
        return node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateClassExpression = updateClassExpression;
    function createOmittedExpression() {
        return createSynthesizedNode(215 /* OmittedExpression */);
    }
    ts.createOmittedExpression = createOmittedExpression;
    function createExpressionWithTypeArguments(typeArguments, expression) {
        var node = createSynthesizedNode(216 /* ExpressionWithTypeArguments */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.typeArguments = asNodeArray(typeArguments);
        return node;
    }
    ts.createExpressionWithTypeArguments = createExpressionWithTypeArguments;
    function updateExpressionWithTypeArguments(node, typeArguments, expression) {
        return node.typeArguments !== typeArguments
            || node.expression !== expression
            ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node)
            : node;
    }
    ts.updateExpressionWithTypeArguments = updateExpressionWithTypeArguments;
    function createAsExpression(expression, type) {
        var node = createSynthesizedNode(217 /* AsExpression */);
        node.expression = expression;
        node.type = type;
        return node;
    }
    ts.createAsExpression = createAsExpression;
    function updateAsExpression(node, expression, type) {
        return node.expression !== expression
            || node.type !== type
            ? updateNode(createAsExpression(expression, type), node)
            : node;
    }
    ts.updateAsExpression = updateAsExpression;
    function createNonNullExpression(expression) {
        var node = createSynthesizedNode(218 /* NonNullExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createNonNullExpression = createNonNullExpression;
    function updateNonNullExpression(node, expression) {
        if (ts.isNonNullChain(node)) {
            return updateNonNullChain(node, expression);
        }
        return node.expression !== expression
            ? updateNode(createNonNullExpression(expression), node)
            : node;
    }
    ts.updateNonNullExpression = updateNonNullExpression;
    function createNonNullChain(expression) {
        var node = createSynthesizedNode(218 /* NonNullExpression */);
        node.flags |= 32 /* OptionalChain */;
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createNonNullChain = createNonNullChain;
    function updateNonNullChain(node, expression) {
        ts.Debug.assert(!!(node.flags & 32 /* OptionalChain */), "Cannot update a NonNullExpression using updateNonNullChain. Use updateNonNullExpression instead.");
        return node.expression !== expression
            ? updateNode(createNonNullChain(expression), node)
            : node;
    }
    ts.updateNonNullChain = updateNonNullChain;
    function createMetaProperty(keywordToken, name) {
        var node = createSynthesizedNode(219 /* MetaProperty */);
        node.keywordToken = keywordToken;
        node.name = name;
        return node;
    }
    ts.createMetaProperty = createMetaProperty;
    function updateMetaProperty(node, name) {
        return node.name !== name
            ? updateNode(createMetaProperty(node.keywordToken, name), node)
            : node;
    }
    ts.updateMetaProperty = updateMetaProperty;
    // Misc
    function createTemplateSpan(expression, literal) {
        var node = createSynthesizedNode(221 /* TemplateSpan */);
        node.expression = expression;
        node.literal = literal;
        return node;
    }
    ts.createTemplateSpan = createTemplateSpan;
    function updateTemplateSpan(node, expression, literal) {
        return node.expression !== expression
            || node.literal !== literal
            ? updateNode(createTemplateSpan(expression, literal), node)
            : node;
    }
    ts.updateTemplateSpan = updateTemplateSpan;
    function createSemicolonClassElement() {
        return createSynthesizedNode(222 /* SemicolonClassElement */);
    }
    ts.createSemicolonClassElement = createSemicolonClassElement;
    // Element
    function createBlock(statements, multiLine) {
        var block = createSynthesizedNode(223 /* Block */);
        block.statements = createNodeArray(statements);
        if (multiLine)
            block.multiLine = multiLine;
        return block;
    }
    ts.createBlock = createBlock;
    function updateBlock(node, statements) {
        return node.statements !== statements
            ? updateNode(createBlock(statements, node.multiLine), node)
            : node;
    }
    ts.updateBlock = updateBlock;
    function createVariableStatement(modifiers, declarationList) {
        var node = createSynthesizedNode(225 /* VariableStatement */);
        node.decorators = undefined;
        node.modifiers = asNodeArray(modifiers);
        node.declarationList = ts.isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList;
        return node;
    }
    ts.createVariableStatement = createVariableStatement;
    function updateVariableStatement(node, modifiers, declarationList) {
        return node.modifiers !== modifiers
            || node.declarationList !== declarationList
            ? updateNode(createVariableStatement(modifiers, declarationList), node)
            : node;
    }
    ts.updateVariableStatement = updateVariableStatement;
    function createEmptyStatement() {
        return createSynthesizedNode(224 /* EmptyStatement */);
    }
    ts.createEmptyStatement = createEmptyStatement;
    function createExpressionStatement(expression) {
        var node = createSynthesizedNode(226 /* ExpressionStatement */);
        node.expression = ts.parenthesizeExpressionForExpressionStatement(expression);
        return node;
    }
    ts.createExpressionStatement = createExpressionStatement;
    function updateExpressionStatement(node, expression) {
        return node.expression !== expression
            ? updateNode(createExpressionStatement(expression), node)
            : node;
    }
    ts.updateExpressionStatement = updateExpressionStatement;
    /** @deprecated Use `createExpressionStatement` instead.  */
    ts.createStatement = createExpressionStatement;
    /** @deprecated Use `updateExpressionStatement` instead.  */
    ts.updateStatement = updateExpressionStatement;
    function createIf(expression, thenStatement, elseStatement) {
        var node = createSynthesizedNode(227 /* IfStatement */);
        node.expression = expression;
        node.thenStatement = asEmbeddedStatement(thenStatement);
        node.elseStatement = asEmbeddedStatement(elseStatement);
        return node;
    }
    ts.createIf = createIf;
    function updateIf(node, expression, thenStatement, elseStatement) {
        return node.expression !== expression
            || node.thenStatement !== thenStatement
            || node.elseStatement !== elseStatement
            ? updateNode(createIf(expression, thenStatement, elseStatement), node)
            : node;
    }
    ts.updateIf = updateIf;
    function createDo(statement, expression) {
        var node = createSynthesizedNode(228 /* DoStatement */);
        node.statement = asEmbeddedStatement(statement);
        node.expression = expression;
        return node;
    }
    ts.createDo = createDo;
    function updateDo(node, statement, expression) {
        return node.statement !== statement
            || node.expression !== expression
            ? updateNode(createDo(statement, expression), node)
            : node;
    }
    ts.updateDo = updateDo;
    function createWhile(expression, statement) {
        var node = createSynthesizedNode(229 /* WhileStatement */);
        node.expression = expression;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createWhile = createWhile;
    function updateWhile(node, expression, statement) {
        return node.expression !== expression
            || node.statement !== statement
            ? updateNode(createWhile(expression, statement), node)
            : node;
    }
    ts.updateWhile = updateWhile;
    function createFor(initializer, condition, incrementor, statement) {
        var node = createSynthesizedNode(230 /* ForStatement */);
        node.initializer = initializer;
        node.condition = condition;
        node.incrementor = incrementor;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createFor = createFor;
    function updateFor(node, initializer, condition, incrementor, statement) {
        return node.initializer !== initializer
            || node.condition !== condition
            || node.incrementor !== incrementor
            || node.statement !== statement
            ? updateNode(createFor(initializer, condition, incrementor, statement), node)
            : node;
    }
    ts.updateFor = updateFor;
    function createForIn(initializer, expression, statement) {
        var node = createSynthesizedNode(231 /* ForInStatement */);
        node.initializer = initializer;
        node.expression = expression;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createForIn = createForIn;
    function updateForIn(node, initializer, expression, statement) {
        return node.initializer !== initializer
            || node.expression !== expression
            || node.statement !== statement
            ? updateNode(createForIn(initializer, expression, statement), node)
            : node;
    }
    ts.updateForIn = updateForIn;
    function createForOf(awaitModifier, initializer, expression, statement) {
        var node = createSynthesizedNode(232 /* ForOfStatement */);
        node.awaitModifier = awaitModifier;
        node.initializer = initializer;
        node.expression = ts.isCommaSequence(expression) ? createParen(expression) : expression;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createForOf = createForOf;
    function updateForOf(node, awaitModifier, initializer, expression, statement) {
        return node.awaitModifier !== awaitModifier
            || node.initializer !== initializer
            || node.expression !== expression
            || node.statement !== statement
            ? updateNode(createForOf(awaitModifier, initializer, expression, statement), node)
            : node;
    }
    ts.updateForOf = updateForOf;
    function createContinue(label) {
        var node = createSynthesizedNode(233 /* ContinueStatement */);
        node.label = asName(label);
        return node;
    }
    ts.createContinue = createContinue;
    function updateContinue(node, label) {
        return node.label !== label
            ? updateNode(createContinue(label), node)
            : node;
    }
    ts.updateContinue = updateContinue;
    function createBreak(label) {
        var node = createSynthesizedNode(234 /* BreakStatement */);
        node.label = asName(label);
        return node;
    }
    ts.createBreak = createBreak;
    function updateBreak(node, label) {
        return node.label !== label
            ? updateNode(createBreak(label), node)
            : node;
    }
    ts.updateBreak = updateBreak;
    function createReturn(expression) {
        var node = createSynthesizedNode(235 /* ReturnStatement */);
        node.expression = expression;
        return node;
    }
    ts.createReturn = createReturn;
    function updateReturn(node, expression) {
        return node.expression !== expression
            ? updateNode(createReturn(expression), node)
            : node;
    }
    ts.updateReturn = updateReturn;
    function createWith(expression, statement) {
        var node = createSynthesizedNode(236 /* WithStatement */);
        node.expression = expression;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createWith = createWith;
    function updateWith(node, expression, statement) {
        return node.expression !== expression
            || node.statement !== statement
            ? updateNode(createWith(expression, statement), node)
            : node;
    }
    ts.updateWith = updateWith;
    function createSwitch(expression, caseBlock) {
        var node = createSynthesizedNode(237 /* SwitchStatement */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        node.caseBlock = caseBlock;
        return node;
    }
    ts.createSwitch = createSwitch;
    function updateSwitch(node, expression, caseBlock) {
        return node.expression !== expression
            || node.caseBlock !== caseBlock
            ? updateNode(createSwitch(expression, caseBlock), node)
            : node;
    }
    ts.updateSwitch = updateSwitch;
    function createLabel(label, statement) {
        var node = createSynthesizedNode(238 /* LabeledStatement */);
        node.label = asName(label);
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createLabel = createLabel;
    function updateLabel(node, label, statement) {
        return node.label !== label
            || node.statement !== statement
            ? updateNode(createLabel(label, statement), node)
            : node;
    }
    ts.updateLabel = updateLabel;
    function createThrow(expression) {
        var node = createSynthesizedNode(239 /* ThrowStatement */);
        node.expression = expression;
        return node;
    }
    ts.createThrow = createThrow;
    function updateThrow(node, expression) {
        return node.expression !== expression
            ? updateNode(createThrow(expression), node)
            : node;
    }
    ts.updateThrow = updateThrow;
    function createTry(tryBlock, catchClause, finallyBlock) {
        var node = createSynthesizedNode(240 /* TryStatement */);
        node.tryBlock = tryBlock;
        node.catchClause = catchClause;
        node.finallyBlock = finallyBlock;
        return node;
    }
    ts.createTry = createTry;
    function updateTry(node, tryBlock, catchClause, finallyBlock) {
        return node.tryBlock !== tryBlock
            || node.catchClause !== catchClause
            || node.finallyBlock !== finallyBlock
            ? updateNode(createTry(tryBlock, catchClause, finallyBlock), node)
            : node;
    }
    ts.updateTry = updateTry;
    function createDebuggerStatement() {
        return createSynthesizedNode(241 /* DebuggerStatement */);
    }
    ts.createDebuggerStatement = createDebuggerStatement;
    function createVariableDeclaration(name, type, initializer) {
        /* Internally, one should probably use createTypeScriptVariableDeclaration instead and handle definite assignment assertions */
        var node = createSynthesizedNode(242 /* VariableDeclaration */);
        node.name = asName(name);
        node.type = type;
        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createVariableDeclaration = createVariableDeclaration;
    function updateVariableDeclaration(node, name, type, initializer) {
        /* Internally, one should probably use updateTypeScriptVariableDeclaration instead and handle definite assignment assertions */
        return node.name !== name
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createVariableDeclaration(name, type, initializer), node)
            : node;
    }
    ts.updateVariableDeclaration = updateVariableDeclaration;
    /* @internal */
    function createTypeScriptVariableDeclaration(name, exclaimationToken, type, initializer) {
        var node = createSynthesizedNode(242 /* VariableDeclaration */);
        node.name = asName(name);
        node.type = type;
        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
        node.exclamationToken = exclaimationToken;
        return node;
    }
    ts.createTypeScriptVariableDeclaration = createTypeScriptVariableDeclaration;
    /* @internal */
    function updateTypeScriptVariableDeclaration(node, name, exclaimationToken, type, initializer) {
        return node.name !== name
            || node.type !== type
            || node.initializer !== initializer
            || node.exclamationToken !== exclaimationToken
            ? updateNode(createTypeScriptVariableDeclaration(name, exclaimationToken, type, initializer), node)
            : node;
    }
    ts.updateTypeScriptVariableDeclaration = updateTypeScriptVariableDeclaration;
    function createVariableDeclarationList(declarations, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        var node = createSynthesizedNode(243 /* VariableDeclarationList */);
        node.flags |= flags & 3 /* BlockScoped */;
        node.declarations = createNodeArray(declarations);
        return node;
    }
    ts.createVariableDeclarationList = createVariableDeclarationList;
    function updateVariableDeclarationList(node, declarations) {
        return node.declarations !== declarations
            ? updateNode(createVariableDeclarationList(declarations, node.flags), node)
            : node;
    }
    ts.updateVariableDeclarationList = updateVariableDeclarationList;
    function createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(244 /* FunctionDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createFunctionDeclaration = createFunctionDeclaration;
    function updateFunctionDeclaration(node, decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateFunctionDeclaration = updateFunctionDeclaration;
    /* @internal */
    function updateFunctionLikeBody(declaration, body) {
        switch (declaration.kind) {
            case 244 /* FunctionDeclaration */:
                return createFunctionDeclaration(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body);
            case 161 /* MethodDeclaration */:
                return createMethod(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.questionToken, declaration.typeParameters, declaration.parameters, declaration.type, body);
            case 163 /* GetAccessor */:
                return createGetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, declaration.type, body);
            case 164 /* SetAccessor */:
                return createSetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, body);
            case 162 /* Constructor */:
                return createConstructor(declaration.decorators, declaration.modifiers, declaration.parameters, body);
            case 201 /* FunctionExpression */:
                return createFunctionExpression(declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body);
            case 202 /* ArrowFunction */:
                return createArrowFunction(declaration.modifiers, declaration.typeParameters, declaration.parameters, declaration.type, declaration.equalsGreaterThanToken, body);
        }
    }
    ts.updateFunctionLikeBody = updateFunctionLikeBody;
    function createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(245 /* ClassDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createClassDeclaration = createClassDeclaration;
    function updateClassDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateClassDeclaration = updateClassDeclaration;
    function createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(246 /* InterfaceDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createInterfaceDeclaration = createInterfaceDeclaration;
    function updateInterfaceDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateInterfaceDeclaration = updateInterfaceDeclaration;
    function createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type) {
        var node = createSynthesizedNode(247 /* TypeAliasDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.type = type;
        return node;
    }
    ts.createTypeAliasDeclaration = createTypeAliasDeclaration;
    function updateTypeAliasDeclaration(node, decorators, modifiers, name, typeParameters, type) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.type !== type
            ? updateNode(createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type), node)
            : node;
    }
    ts.updateTypeAliasDeclaration = updateTypeAliasDeclaration;
    function createEnumDeclaration(decorators, modifiers, name, members) {
        var node = createSynthesizedNode(248 /* EnumDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createEnumDeclaration = createEnumDeclaration;
    function updateEnumDeclaration(node, decorators, modifiers, name, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.members !== members
            ? updateNode(createEnumDeclaration(decorators, modifiers, name, members), node)
            : node;
    }
    ts.updateEnumDeclaration = updateEnumDeclaration;
    function createModuleDeclaration(decorators, modifiers, name, body, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        var node = createSynthesizedNode(249 /* ModuleDeclaration */);
        node.flags |= flags & (16 /* Namespace */ | 4 /* NestedNamespace */ | 1024 /* GlobalAugmentation */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = name;
        node.body = body;
        return node;
    }
    ts.createModuleDeclaration = createModuleDeclaration;
    function updateModuleDeclaration(node, decorators, modifiers, name, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.body !== body
            ? updateNode(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node)
            : node;
    }
    ts.updateModuleDeclaration = updateModuleDeclaration;
    function createModuleBlock(statements) {
        var node = createSynthesizedNode(250 /* ModuleBlock */);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createModuleBlock = createModuleBlock;
    function updateModuleBlock(node, statements) {
        return node.statements !== statements
            ? updateNode(createModuleBlock(statements), node)
            : node;
    }
    ts.updateModuleBlock = updateModuleBlock;
    function createCaseBlock(clauses) {
        var node = createSynthesizedNode(251 /* CaseBlock */);
        node.clauses = createNodeArray(clauses);
        return node;
    }
    ts.createCaseBlock = createCaseBlock;
    function updateCaseBlock(node, clauses) {
        return node.clauses !== clauses
            ? updateNode(createCaseBlock(clauses), node)
            : node;
    }
    ts.updateCaseBlock = updateCaseBlock;
    function createNamespaceExportDeclaration(name) {
        var node = createSynthesizedNode(252 /* NamespaceExportDeclaration */);
        node.name = asName(name);
        return node;
    }
    ts.createNamespaceExportDeclaration = createNamespaceExportDeclaration;
    function updateNamespaceExportDeclaration(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceExportDeclaration(name), node)
            : node;
    }
    ts.updateNamespaceExportDeclaration = updateNamespaceExportDeclaration;
    function createImportEqualsDeclaration(decorators, modifiers, name, moduleReference) {
        var node = createSynthesizedNode(253 /* ImportEqualsDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.moduleReference = moduleReference;
        return node;
    }
    ts.createImportEqualsDeclaration = createImportEqualsDeclaration;
    function updateImportEqualsDeclaration(node, decorators, modifiers, name, moduleReference) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.moduleReference !== moduleReference
            ? updateNode(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node)
            : node;
    }
    ts.updateImportEqualsDeclaration = updateImportEqualsDeclaration;
    function createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier) {
        var node = createSynthesizedNode(254 /* ImportDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.importClause = importClause;
        node.moduleSpecifier = moduleSpecifier;
        return node;
    }
    ts.createImportDeclaration = createImportDeclaration;
    function updateImportDeclaration(node, decorators, modifiers, importClause, moduleSpecifier) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.importClause !== importClause
            || node.moduleSpecifier !== moduleSpecifier
            ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node)
            : node;
    }
    ts.updateImportDeclaration = updateImportDeclaration;
    function createImportClause(name, namedBindings, isTypeOnly) {
        if (isTypeOnly === void 0) { isTypeOnly = false; }
        var node = createSynthesizedNode(255 /* ImportClause */);
        node.name = name;
        node.namedBindings = namedBindings;
        node.isTypeOnly = isTypeOnly;
        return node;
    }
    ts.createImportClause = createImportClause;
    function updateImportClause(node, name, namedBindings, isTypeOnly) {
        return node.name !== name
            || node.namedBindings !== namedBindings
            || node.isTypeOnly !== isTypeOnly
            ? updateNode(createImportClause(name, namedBindings, isTypeOnly), node)
            : node;
    }
    ts.updateImportClause = updateImportClause;
    function createNamespaceImport(name) {
        var node = createSynthesizedNode(256 /* NamespaceImport */);
        node.name = name;
        return node;
    }
    ts.createNamespaceImport = createNamespaceImport;
    function createNamespaceExport(name) {
        var node = createSynthesizedNode(262 /* NamespaceExport */);
        node.name = name;
        return node;
    }
    ts.createNamespaceExport = createNamespaceExport;
    function updateNamespaceImport(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceImport(name), node)
            : node;
    }
    ts.updateNamespaceImport = updateNamespaceImport;
    function updateNamespaceExport(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceExport(name), node)
            : node;
    }
    ts.updateNamespaceExport = updateNamespaceExport;
    function createNamedImports(elements) {
        var node = createSynthesizedNode(257 /* NamedImports */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createNamedImports = createNamedImports;
    function updateNamedImports(node, elements) {
        return node.elements !== elements
            ? updateNode(createNamedImports(elements), node)
            : node;
    }
    ts.updateNamedImports = updateNamedImports;
    function createImportSpecifier(propertyName, name) {
        var node = createSynthesizedNode(258 /* ImportSpecifier */);
        node.propertyName = propertyName;
        node.name = name;
        return node;
    }
    ts.createImportSpecifier = createImportSpecifier;
    function updateImportSpecifier(node, propertyName, name) {
        return node.propertyName !== propertyName
            || node.name !== name
            ? updateNode(createImportSpecifier(propertyName, name), node)
            : node;
    }
    ts.updateImportSpecifier = updateImportSpecifier;
    function createExportAssignment(decorators, modifiers, isExportEquals, expression) {
        var node = createSynthesizedNode(259 /* ExportAssignment */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.isExportEquals = isExportEquals;
        node.expression = isExportEquals ? ts.parenthesizeBinaryOperand(62 /* EqualsToken */, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : ts.parenthesizeDefaultExpression(expression);
        return node;
    }
    ts.createExportAssignment = createExportAssignment;
    function updateExportAssignment(node, decorators, modifiers, expression) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.expression !== expression
            ? updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node)
            : node;
    }
    ts.updateExportAssignment = updateExportAssignment;
    function createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, isTypeOnly) {
        if (isTypeOnly === void 0) { isTypeOnly = false; }
        var node = createSynthesizedNode(260 /* ExportDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.isTypeOnly = isTypeOnly;
        node.exportClause = exportClause;
        node.moduleSpecifier = moduleSpecifier;
        return node;
    }
    ts.createExportDeclaration = createExportDeclaration;
    function updateExportDeclaration(node, decorators, modifiers, exportClause, moduleSpecifier, isTypeOnly) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.isTypeOnly !== isTypeOnly
            || node.exportClause !== exportClause
            || node.moduleSpecifier !== moduleSpecifier
            ? updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, isTypeOnly), node)
            : node;
    }
    ts.updateExportDeclaration = updateExportDeclaration;
    /* @internal */
    function createEmptyExports() {
        return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined);
    }
    ts.createEmptyExports = createEmptyExports;
    function createNamedExports(elements) {
        var node = createSynthesizedNode(261 /* NamedExports */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createNamedExports = createNamedExports;
    function updateNamedExports(node, elements) {
        return node.elements !== elements
            ? updateNode(createNamedExports(elements), node)
            : node;
    }
    ts.updateNamedExports = updateNamedExports;
    function createExportSpecifier(propertyName, name) {
        var node = createSynthesizedNode(263 /* ExportSpecifier */);
        node.propertyName = asName(propertyName);
        node.name = asName(name);
        return node;
    }
    ts.createExportSpecifier = createExportSpecifier;
    function updateExportSpecifier(node, propertyName, name) {
        return node.propertyName !== propertyName
            || node.name !== name
            ? updateNode(createExportSpecifier(propertyName, name), node)
            : node;
    }
    ts.updateExportSpecifier = updateExportSpecifier;
    // Module references
    function createExternalModuleReference(expression) {
        var node = createSynthesizedNode(265 /* ExternalModuleReference */);
        node.expression = expression;
        return node;
    }
    ts.createExternalModuleReference = createExternalModuleReference;
    function updateExternalModuleReference(node, expression) {
        return node.expression !== expression
            ? updateNode(createExternalModuleReference(expression), node)
            : node;
    }
    ts.updateExternalModuleReference = updateExternalModuleReference;
    // JSDoc
    /* @internal */
    function createJSDocTypeExpression(type) {
        var node = createSynthesizedNode(294 /* JSDocTypeExpression */);
        node.type = type;
        return node;
    }
    ts.createJSDocTypeExpression = createJSDocTypeExpression;
    /* @internal */
    function createJSDocTypeTag(typeExpression, comment) {
        var tag = createJSDocTag(320 /* JSDocTypeTag */, "type");
        tag.typeExpression = typeExpression;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocTypeTag = createJSDocTypeTag;
    /* @internal */
    function createJSDocReturnTag(typeExpression, comment) {
        var tag = createJSDocTag(318 /* JSDocReturnTag */, "returns");
        tag.typeExpression = typeExpression;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocReturnTag = createJSDocReturnTag;
    /** @internal */
    function createJSDocThisTag(typeExpression) {
        var tag = createJSDocTag(319 /* JSDocThisTag */, "this");
        tag.typeExpression = typeExpression;
        return tag;
    }
    ts.createJSDocThisTag = createJSDocThisTag;
    /* @internal */
    function createJSDocParamTag(name, isBracketed, typeExpression, comment) {
        var tag = createJSDocTag(317 /* JSDocParameterTag */, "param");
        tag.typeExpression = typeExpression;
        tag.name = name;
        tag.isBracketed = isBracketed;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocParamTag = createJSDocParamTag;
    /* @internal */
    function createJSDocClassTag() {
        return createJSDocTag(310 /* JSDocClassTag */, "class");
    }
    ts.createJSDocClassTag = createJSDocClassTag;
    /* @internal */
    function createJSDocComment(comment, tags) {
        var node = createSynthesizedNode(303 /* JSDocComment */);
        node.comment = comment;
        node.tags = tags;
        return node;
    }
    ts.createJSDocComment = createJSDocComment;
    /* @internal */
    function createJSDocTag(kind, tagName) {
        var node = createSynthesizedNode(kind);
        node.tagName = createIdentifier(tagName);
        return node;
    }
    // JSX
    function createJsxElement(openingElement, children, closingElement) {
        var node = createSynthesizedNode(266 /* JsxElement */);
        node.openingElement = openingElement;
        node.children = createNodeArray(children);
        node.closingElement = closingElement;
        return node;
    }
    ts.createJsxElement = createJsxElement;
    function updateJsxElement(node, openingElement, children, closingElement) {
        return node.openingElement !== openingElement
            || node.children !== children
            || node.closingElement !== closingElement
            ? updateNode(createJsxElement(openingElement, children, closingElement), node)
            : node;
    }
    ts.updateJsxElement = updateJsxElement;
    function createJsxSelfClosingElement(tagName, typeArguments, attributes) {
        var node = createSynthesizedNode(267 /* JsxSelfClosingElement */);
        node.tagName = tagName;
        node.typeArguments = asNodeArray(typeArguments);
        node.attributes = attributes;
        return node;
    }
    ts.createJsxSelfClosingElement = createJsxSelfClosingElement;
    function updateJsxSelfClosingElement(node, tagName, typeArguments, attributes) {
        return node.tagName !== tagName
            || node.typeArguments !== typeArguments
            || node.attributes !== attributes
            ? updateNode(createJsxSelfClosingElement(tagName, typeArguments, attributes), node)
            : node;
    }
    ts.updateJsxSelfClosingElement = updateJsxSelfClosingElement;
    function createJsxOpeningElement(tagName, typeArguments, attributes) {
        var node = createSynthesizedNode(268 /* JsxOpeningElement */);
        node.tagName = tagName;
        node.typeArguments = asNodeArray(typeArguments);
        node.attributes = attributes;
        return node;
    }
    ts.createJsxOpeningElement = createJsxOpeningElement;
    function updateJsxOpeningElement(node, tagName, typeArguments, attributes) {
        return node.tagName !== tagName
            || node.typeArguments !== typeArguments
            || node.attributes !== attributes
            ? updateNode(createJsxOpeningElement(tagName, typeArguments, attributes), node)
            : node;
    }
    ts.updateJsxOpeningElement = updateJsxOpeningElement;
    function createJsxClosingElement(tagName) {
        var node = createSynthesizedNode(269 /* JsxClosingElement */);
        node.tagName = tagName;
        return node;
    }
    ts.createJsxClosingElement = createJsxClosingElement;
    function updateJsxClosingElement(node, tagName) {
        return node.tagName !== tagName
            ? updateNode(createJsxClosingElement(tagName), node)
            : node;
    }
    ts.updateJsxClosingElement = updateJsxClosingElement;
    function createJsxFragment(openingFragment, children, closingFragment) {
        var node = createSynthesizedNode(270 /* JsxFragment */);
        node.openingFragment = openingFragment;
        node.children = createNodeArray(children);
        node.closingFragment = closingFragment;
        return node;
    }
    ts.createJsxFragment = createJsxFragment;
    function createJsxText(text, containsOnlyTriviaWhiteSpaces) {
        var node = createSynthesizedNode(11 /* JsxText */);
        node.text = text;
        node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces;
        return node;
    }
    ts.createJsxText = createJsxText;
    function updateJsxText(node, text, containsOnlyTriviaWhiteSpaces) {
        return node.text !== text
            || node.containsOnlyTriviaWhiteSpaces !== containsOnlyTriviaWhiteSpaces
            ? updateNode(createJsxText(text, containsOnlyTriviaWhiteSpaces), node)
            : node;
    }
    ts.updateJsxText = updateJsxText;
    function createJsxOpeningFragment() {
        return createSynthesizedNode(271 /* JsxOpeningFragment */);
    }
    ts.createJsxOpeningFragment = createJsxOpeningFragment;
    function createJsxJsxClosingFragment() {
        return createSynthesizedNode(272 /* JsxClosingFragment */);
    }
    ts.createJsxJsxClosingFragment = createJsxJsxClosingFragment;
    function updateJsxFragment(node, openingFragment, children, closingFragment) {
        return node.openingFragment !== openingFragment
            || node.children !== children
            || node.closingFragment !== closingFragment
            ? updateNode(createJsxFragment(openingFragment, children, closingFragment), node)
            : node;
    }
    ts.updateJsxFragment = updateJsxFragment;
    function createJsxAttribute(name, initializer) {
        var node = createSynthesizedNode(273 /* JsxAttribute */);
        node.name = name;
        node.initializer = initializer;
        return node;
    }
    ts.createJsxAttribute = createJsxAttribute;
    function updateJsxAttribute(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createJsxAttribute(name, initializer), node)
            : node;
    }
    ts.updateJsxAttribute = updateJsxAttribute;
    function createJsxAttributes(properties) {
        var node = createSynthesizedNode(274 /* JsxAttributes */);
        node.properties = createNodeArray(properties);
        return node;
    }
    ts.createJsxAttributes = createJsxAttributes;
    function updateJsxAttributes(node, properties) {
        return node.properties !== properties
            ? updateNode(createJsxAttributes(properties), node)
            : node;
    }
    ts.updateJsxAttributes = updateJsxAttributes;
    function createJsxSpreadAttribute(expression) {
        var node = createSynthesizedNode(275 /* JsxSpreadAttribute */);
        node.expression = expression;
        return node;
    }
    ts.createJsxSpreadAttribute = createJsxSpreadAttribute;
    function updateJsxSpreadAttribute(node, expression) {
        return node.expression !== expression
            ? updateNode(createJsxSpreadAttribute(expression), node)
            : node;
    }
    ts.updateJsxSpreadAttribute = updateJsxSpreadAttribute;
    function createJsxExpression(dotDotDotToken, expression) {
        var node = createSynthesizedNode(276 /* JsxExpression */);
        node.dotDotDotToken = dotDotDotToken;
        node.expression = expression;
        return node;
    }
    ts.createJsxExpression = createJsxExpression;
    function updateJsxExpression(node, expression) {
        return node.expression !== expression
            ? updateNode(createJsxExpression(node.dotDotDotToken, expression), node)
            : node;
    }
    ts.updateJsxExpression = updateJsxExpression;
    // Clauses
    function createCaseClause(expression, statements) {
        var node = createSynthesizedNode(277 /* CaseClause */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createCaseClause = createCaseClause;
    function updateCaseClause(node, expression, statements) {
        return node.expression !== expression
            || node.statements !== statements
            ? updateNode(createCaseClause(expression, statements), node)
            : node;
    }
    ts.updateCaseClause = updateCaseClause;
    function createDefaultClause(statements) {
        var node = createSynthesizedNode(278 /* DefaultClause */);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createDefaultClause = createDefaultClause;
    function updateDefaultClause(node, statements) {
        return node.statements !== statements
            ? updateNode(createDefaultClause(statements), node)
            : node;
    }
    ts.updateDefaultClause = updateDefaultClause;
    function createHeritageClause(token, types) {
        var node = createSynthesizedNode(279 /* HeritageClause */);
        node.token = token;
        node.types = createNodeArray(types);
        return node;
    }
    ts.createHeritageClause = createHeritageClause;
    function updateHeritageClause(node, types) {
        return node.types !== types
            ? updateNode(createHeritageClause(node.token, types), node)
            : node;
    }
    ts.updateHeritageClause = updateHeritageClause;
    function createCatchClause(variableDeclaration, block) {
        var node = createSynthesizedNode(280 /* CatchClause */);
        node.variableDeclaration = ts.isString(variableDeclaration) ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
        node.block = block;
        return node;
    }
    ts.createCatchClause = createCatchClause;
    function updateCatchClause(node, variableDeclaration, block) {
        return node.variableDeclaration !== variableDeclaration
            || node.block !== block
            ? updateNode(createCatchClause(variableDeclaration, block), node)
            : node;
    }
    ts.updateCatchClause = updateCatchClause;
    // Property assignments
    function createPropertyAssignment(name, initializer) {
        var node = createSynthesizedNode(281 /* PropertyAssignment */);
        node.name = asName(name);
        node.questionToken = undefined;
        node.initializer = ts.parenthesizeExpressionForList(initializer);
        return node;
    }
    ts.createPropertyAssignment = createPropertyAssignment;
    function updatePropertyAssignment(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createPropertyAssignment(name, initializer), node)
            : node;
    }
    ts.updatePropertyAssignment = updatePropertyAssignment;
    function createShorthandPropertyAssignment(name, objectAssignmentInitializer) {
        var node = createSynthesizedNode(282 /* ShorthandPropertyAssignment */);
        node.name = asName(name);
        node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? ts.parenthesizeExpressionForList(objectAssignmentInitializer) : undefined;
        return node;
    }
    ts.createShorthandPropertyAssignment = createShorthandPropertyAssignment;
    function updateShorthandPropertyAssignment(node, name, objectAssignmentInitializer) {
        return node.name !== name
            || node.objectAssignmentInitializer !== objectAssignmentInitializer
            ? updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node)
            : node;
    }
    ts.updateShorthandPropertyAssignment = updateShorthandPropertyAssignment;
    function createSpreadAssignment(expression) {
        var node = createSynthesizedNode(283 /* SpreadAssignment */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createSpreadAssignment = createSpreadAssignment;
    function updateSpreadAssignment(node, expression) {
        return node.expression !== expression
            ? updateNode(createSpreadAssignment(expression), node)
            : node;
    }
    ts.updateSpreadAssignment = updateSpreadAssignment;
    // Enum
    function createEnumMember(name, initializer) {
        var node = createSynthesizedNode(284 /* EnumMember */);
        node.name = asName(name);
        node.initializer = initializer && ts.parenthesizeExpressionForList(initializer);
        return node;
    }
    ts.createEnumMember = createEnumMember;
    function updateEnumMember(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createEnumMember(name, initializer), node)
            : node;
    }
    ts.updateEnumMember = updateEnumMember;
    // Top-level nodes
    function updateSourceFileNode(node, statements, isDeclarationFile, referencedFiles, typeReferences, hasNoDefaultLib, libReferences) {
        if (node.statements !== statements ||
            (isDeclarationFile !== undefined && node.isDeclarationFile !== isDeclarationFile) ||
            (referencedFiles !== undefined && node.referencedFiles !== referencedFiles) ||
            (typeReferences !== undefined && node.typeReferenceDirectives !== typeReferences) ||
            (libReferences !== undefined && node.libReferenceDirectives !== libReferences) ||
            (hasNoDefaultLib !== undefined && node.hasNoDefaultLib !== hasNoDefaultLib)) {
            var updated = createSynthesizedNode(290 /* SourceFile */);
            updated.flags |= node.flags;
            updated.statements = createNodeArray(statements);
            updated.endOfFileToken = node.endOfFileToken;
            updated.fileName = node.fileName;
            updated.path = node.path;
            updated.text = node.text;
            updated.isDeclarationFile = isDeclarationFile === undefined ? node.isDeclarationFile : isDeclarationFile;
            updated.referencedFiles = referencedFiles === undefined ? node.referencedFiles : referencedFiles;
            updated.typeReferenceDirectives = typeReferences === undefined ? node.typeReferenceDirectives : typeReferences;
            updated.hasNoDefaultLib = hasNoDefaultLib === undefined ? node.hasNoDefaultLib : hasNoDefaultLib;
            updated.libReferenceDirectives = libReferences === undefined ? node.libReferenceDirectives : libReferences;
            if (node.amdDependencies !== undefined)
                updated.amdDependencies = node.amdDependencies;
            if (node.moduleName !== undefined)
                updated.moduleName = node.moduleName;
            if (node.languageVariant !== undefined)
                updated.languageVariant = node.languageVariant;
            if (node.renamedDependencies !== undefined)
                updated.renamedDependencies = node.renamedDependencies;
            if (node.languageVersion !== undefined)
                updated.languageVersion = node.languageVersion;
            if (node.scriptKind !== undefined)
                updated.scriptKind = node.scriptKind;
            if (node.externalModuleIndicator !== undefined)
                updated.externalModuleIndicator = node.externalModuleIndicator;
            if (node.commonJsModuleIndicator !== undefined)
                updated.commonJsModuleIndicator = node.commonJsModuleIndicator;
            if (node.identifiers !== undefined)
                updated.identifiers = node.identifiers;
            if (node.nodeCount !== undefined)
                updated.nodeCount = node.nodeCount;
            if (node.identifierCount !== undefined)
                updated.identifierCount = node.identifierCount;
            if (node.symbolCount !== undefined)
                updated.symbolCount = node.symbolCount;
            if (node.parseDiagnostics !== undefined)
                updated.parseDiagnostics = node.parseDiagnostics;
            if (node.bindDiagnostics !== undefined)
                updated.bindDiagnostics = node.bindDiagnostics;
            if (node.bindSuggestionDiagnostics !== undefined)
                updated.bindSuggestionDiagnostics = node.bindSuggestionDiagnostics;
            if (node.lineMap !== undefined)
                updated.lineMap = node.lineMap;
            if (node.classifiableNames !== undefined)
                updated.classifiableNames = node.classifiableNames;
            if (node.resolvedModules !== undefined)
                updated.resolvedModules = node.resolvedModules;
            if (node.resolvedTypeReferenceDirectiveNames !== undefined)
                updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames;
            if (node.imports !== undefined)
                updated.imports = node.imports;
            if (node.moduleAugmentations !== undefined)
                updated.moduleAugmentations = node.moduleAugmentations;
            if (node.pragmas !== undefined)
                updated.pragmas = node.pragmas;
            if (node.localJsxFactory !== undefined)
                updated.localJsxFactory = node.localJsxFactory;
            if (node.localJsxNamespace !== undefined)
                updated.localJsxNamespace = node.localJsxNamespace;
            return updateNode(updated, node);
        }
        return node;
    }
    ts.updateSourceFileNode = updateSourceFileNode;
    /**
     * Creates a shallow, memberwise clone of a node for mutation.
     */
    function getMutableClone(node) {
        var clone = getSynthesizedClone(node);
        clone.pos = node.pos;
        clone.end = node.end;
        clone.parent = node.parent;
        return clone;
    }
    ts.getMutableClone = getMutableClone;
    // Transformation nodes
    /**
     * Creates a synthetic statement to act as a placeholder for a not-emitted statement in
     * order to preserve comments.
     *
     * @param original The original statement.
     */
    function createNotEmittedStatement(original) {
        var node = createSynthesizedNode(325 /* NotEmittedStatement */);
        node.original = original;
        setTextRange(node, original);
        return node;
    }
    ts.createNotEmittedStatement = createNotEmittedStatement;
    /**
     * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in
     * order to properly emit exports.
     */
    /* @internal */
    function createEndOfDeclarationMarker(original) {
        var node = createSynthesizedNode(329 /* EndOfDeclarationMarker */);
        node.emitNode = {};
        node.original = original;
        return node;
    }
    ts.createEndOfDeclarationMarker = createEndOfDeclarationMarker;
    /**
     * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in
     * order to properly emit exports.
     */
    /* @internal */
    function createMergeDeclarationMarker(original) {
        var node = createSynthesizedNode(328 /* MergeDeclarationMarker */);
        node.emitNode = {};
        node.original = original;
        return node;
    }
    ts.createMergeDeclarationMarker = createMergeDeclarationMarker;
    /**
     * Creates a synthetic expression to act as a placeholder for a not-emitted expression in
     * order to preserve comments or sourcemap positions.
     *
     * @param expression The inner expression to emit.
     * @param original The original outer expression.
     * @param location The location for the expression. Defaults to the positions from "original" if provided.
     */
    function createPartiallyEmittedExpression(expression, original) {
        var node = createSynthesizedNode(326 /* PartiallyEmittedExpression */);
        node.expression = expression;
        node.original = original;
        setTextRange(node, original);
        return node;
    }
    ts.createPartiallyEmittedExpression = createPartiallyEmittedExpression;
    function updatePartiallyEmittedExpression(node, expression) {
        if (node.expression !== expression) {
            return updateNode(createPartiallyEmittedExpression(expression, node.original), node);
        }
        return node;
    }
    ts.updatePartiallyEmittedExpression = updatePartiallyEmittedExpression;
    function flattenCommaElements(node) {
        if (ts.nodeIsSynthesized(node) && !ts.isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) {
            if (node.kind === 327 /* CommaListExpression */) {
                return node.elements;
            }
            if (ts.isBinaryExpression(node) && node.operatorToken.kind === 27 /* CommaToken */) {
                return [node.left, node.right];
            }
        }
        return node;
    }
    function createCommaList(elements) {
        var node = createSynthesizedNode(327 /* CommaListExpression */);
        node.elements = createNodeArray(ts.sameFlatMap(elements, flattenCommaElements));
        return node;
    }
    ts.createCommaList = createCommaList;
    function updateCommaList(node, elements) {
        return node.elements !== elements
            ? updateNode(createCommaList(elements), node)
            : node;
    }
    ts.updateCommaList = updateCommaList;
    /* @internal */
    function createSyntheticReferenceExpression(expression, thisArg) {
        var node = createSynthesizedNode(330 /* SyntheticReferenceExpression */);
        node.expression = expression;
        node.thisArg = thisArg;
        return node;
    }
    ts.createSyntheticReferenceExpression = createSyntheticReferenceExpression;
    /* @internal */
    function updateSyntheticReferenceExpression(node, expression, thisArg) {
        return node.expression !== expression
            || node.thisArg !== thisArg
            ? updateNode(createSyntheticReferenceExpression(expression, thisArg), node)
            : node;
    }
    ts.updateSyntheticReferenceExpression = updateSyntheticReferenceExpression;
    function createBundle(sourceFiles, prepends) {
        if (prepends === void 0) { prepends = ts.emptyArray; }
        var node = ts.createNode(291 /* Bundle */);
        node.prepends = prepends;
        node.sourceFiles = sourceFiles;
        return node;
    }
    ts.createBundle = createBundle;
    var allUnscopedEmitHelpers;
    function getAllUnscopedEmitHelpers() {
        return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = ts.arrayToMap([
            ts.valuesHelper,
            ts.readHelper,
            ts.spreadHelper,
            ts.spreadArraysHelper,
            ts.restHelper,
            ts.decorateHelper,
            ts.metadataHelper,
            ts.paramHelper,
            ts.awaiterHelper,
            ts.assignHelper,
            ts.awaitHelper,
            ts.asyncGeneratorHelper,
            ts.asyncDelegator,
            ts.asyncValues,
            ts.extendsHelper,
            ts.templateObjectHelper,
            ts.generatorHelper,
            ts.importStarHelper,
            ts.importDefaultHelper,
            ts.classPrivateFieldGetHelper,
            ts.classPrivateFieldSetHelper,
            ts.createBindingHelper,
            ts.setModuleDefaultHelper
        ], function (helper) { return helper.name; }));
    }
    function createUnparsedSource() {
        var node = ts.createNode(292 /* UnparsedSource */);
        node.prologues = ts.emptyArray;
        node.referencedFiles = ts.emptyArray;
        node.libReferenceDirectives = ts.emptyArray;
        node.getLineAndCharacterOfPosition = function (pos) { return ts.getLineAndCharacterOfPosition(node, pos); };
        return node;
    }
    function createUnparsedSourceFile(textOrInputFiles, mapPathOrType, mapTextOrStripInternal) {
        var node = createUnparsedSource();
        var stripInternal;
        var bundleFileInfo;
        if (!ts.isString(textOrInputFiles)) {
            ts.Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts");
            node.fileName = (mapPathOrType === "js" ? textOrInputFiles.javascriptPath : textOrInputFiles.declarationPath) || "";
            node.sourceMapPath = mapPathOrType === "js" ? textOrInputFiles.javascriptMapPath : textOrInputFiles.declarationMapPath;
            Object.defineProperties(node, {
                text: { get: function () { return mapPathOrType === "js" ? textOrInputFiles.javascriptText : textOrInputFiles.declarationText; } },
                sourceMapText: { get: function () { return mapPathOrType === "js" ? textOrInputFiles.javascriptMapText : textOrInputFiles.declarationMapText; } },
            });
            if (textOrInputFiles.buildInfo && textOrInputFiles.buildInfo.bundle) {
                node.oldFileOfCurrentEmit = textOrInputFiles.oldFileOfCurrentEmit;
                ts.Debug.assert(mapTextOrStripInternal === undefined || typeof mapTextOrStripInternal === "boolean");
                stripInternal = mapTextOrStripInternal;
                bundleFileInfo = mapPathOrType === "js" ? textOrInputFiles.buildInfo.bundle.js : textOrInputFiles.buildInfo.bundle.dts;
                if (node.oldFileOfCurrentEmit) {
                    parseOldFileOfCurrentEmit(node, ts.Debug.checkDefined(bundleFileInfo));
                    return node;
                }
            }
        }
        else {
            node.fileName = "";
            node.text = textOrInputFiles;
            node.sourceMapPath = mapPathOrType;
            node.sourceMapText = mapTextOrStripInternal;
        }
        ts.Debug.assert(!node.oldFileOfCurrentEmit);
        parseUnparsedSourceFile(node, bundleFileInfo, stripInternal);
        return node;
    }
    ts.createUnparsedSourceFile = createUnparsedSourceFile;
    function parseUnparsedSourceFile(node, bundleFileInfo, stripInternal) {
        var prologues;
        var helpers;
        var referencedFiles;
        var typeReferenceDirectives;
        var libReferenceDirectives;
        var texts;
        for (var _i = 0, _a = bundleFileInfo ? bundleFileInfo.sections : ts.emptyArray; _i < _a.length; _i++) {
            var section = _a[_i];
            switch (section.kind) {
                case "prologue" /* Prologue */:
                    (prologues || (prologues = [])).push(createUnparsedNode(section, node));
                    break;
                case "emitHelpers" /* EmitHelpers */:
                    (helpers || (helpers = [])).push(getAllUnscopedEmitHelpers().get(section.data));
                    break;
                case "no-default-lib" /* NoDefaultLib */:
                    node.hasNoDefaultLib = true;
                    break;
                case "reference" /* Reference */:
                    (referencedFiles || (referencedFiles = [])).push({ pos: -1, end: -1, fileName: section.data });
                    break;
                case "type" /* Type */:
                    (typeReferenceDirectives || (typeReferenceDirectives = [])).push(section.data);
                    break;
                case "lib" /* Lib */:
                    (libReferenceDirectives || (libReferenceDirectives = [])).push({ pos: -1, end: -1, fileName: section.data });
                    break;
                case "prepend" /* Prepend */:
                    var prependNode = createUnparsedNode(section, node);
                    var prependTexts = void 0;
                    for (var _b = 0, _c = section.texts; _b < _c.length; _b++) {
                        var text = _c[_b];
                        if (!stripInternal || text.kind !== "internal" /* Internal */) {
                            (prependTexts || (prependTexts = [])).push(createUnparsedNode(text, node));
                        }
                    }
                    prependNode.texts = prependTexts || ts.emptyArray;
                    (texts || (texts = [])).push(prependNode);
                    break;
                case "internal" /* Internal */:
                    if (stripInternal) {
                        if (!texts)
                            texts = [];
                        break;
                    }
                // falls through
                case "text" /* Text */:
                    (texts || (texts = [])).push(createUnparsedNode(section, node));
                    break;
                default:
                    ts.Debug.assertNever(section);
            }
        }
        node.prologues = prologues || ts.emptyArray;
        node.helpers = helpers;
        node.referencedFiles = referencedFiles || ts.emptyArray;
        node.typeReferenceDirectives = typeReferenceDirectives;
        node.libReferenceDirectives = libReferenceDirectives || ts.emptyArray;
        node.texts = texts || [createUnparsedNode({ kind: "text" /* Text */, pos: 0, end: node.text.length }, node)];
    }
    function parseOldFileOfCurrentEmit(node, bundleFileInfo) {
        ts.Debug.assert(!!node.oldFileOfCurrentEmit);
        var texts;
        var syntheticReferences;
        for (var _i = 0, _a = bundleFileInfo.sections; _i < _a.length; _i++) {
            var section = _a[_i];
            switch (section.kind) {
                case "internal" /* Internal */:
                case "text" /* Text */:
                    (texts || (texts = [])).push(createUnparsedNode(section, node));
                    break;
                case "no-default-lib" /* NoDefaultLib */:
                case "reference" /* Reference */:
                case "type" /* Type */:
                case "lib" /* Lib */:
                    (syntheticReferences || (syntheticReferences = [])).push(createUnparsedSyntheticReference(section, node));
                    break;
                // Ignore
                case "prologue" /* Prologue */:
                case "emitHelpers" /* EmitHelpers */:
                case "prepend" /* Prepend */:
                    break;
                default:
                    ts.Debug.assertNever(section);
            }
        }
        node.texts = texts || ts.emptyArray;
        node.helpers = ts.map(bundleFileInfo.sources && bundleFileInfo.sources.helpers, function (name) { return getAllUnscopedEmitHelpers().get(name); });
        node.syntheticReferences = syntheticReferences;
        return node;
    }
    function mapBundleFileSectionKindToSyntaxKind(kind) {
        switch (kind) {
            case "prologue" /* Prologue */: return 285 /* UnparsedPrologue */;
            case "prepend" /* Prepend */: return 286 /* UnparsedPrepend */;
            case "internal" /* Internal */: return 288 /* UnparsedInternalText */;
            case "text" /* Text */: return 287 /* UnparsedText */;
            case "emitHelpers" /* EmitHelpers */:
            case "no-default-lib" /* NoDefaultLib */:
            case "reference" /* Reference */:
            case "type" /* Type */:
            case "lib" /* Lib */:
                return ts.Debug.fail("BundleFileSectionKind: " + kind + " not yet mapped to SyntaxKind");
            default:
                return ts.Debug.assertNever(kind);
        }
    }
    function createUnparsedNode(section, parent) {
        var node = ts.createNode(mapBundleFileSectionKindToSyntaxKind(section.kind), section.pos, section.end);
        node.parent = parent;
        node.data = section.data;
        return node;
    }
    function createUnparsedSyntheticReference(section, parent) {
        var node = ts.createNode(289 /* UnparsedSyntheticReference */, section.pos, section.end);
        node.parent = parent;
        node.data = section.data;
        node.section = section;
        return node;
    }
    function createInputFiles(javascriptTextOrReadFileText, declarationTextOrJavascriptPath, javascriptMapPath, javascriptMapTextOrDeclarationPath, declarationMapPath, declarationMapTextOrBuildInfoPath, javascriptPath, declarationPath, buildInfoPath, buildInfo, oldFileOfCurrentEmit) {
        var node = ts.createNode(293 /* InputFiles */);
        if (!ts.isString(javascriptTextOrReadFileText)) {
            var cache_1 = ts.createMap();
            var textGetter_1 = function (path) {
                if (path === undefined)
                    return undefined;
                var value = cache_1.get(path);
                if (value === undefined) {
                    value = javascriptTextOrReadFileText(path);
                    cache_1.set(path, value !== undefined ? value : false);
                }
                return value !== false ? value : undefined;
            };
            var definedTextGetter_1 = function (path) {
                var result = textGetter_1(path);
                return result !== undefined ? result : "/* Input file " + path + " was missing */\r\n";
            };
            var buildInfo_1;
            var getAndCacheBuildInfo_1 = function (getText) {
                if (buildInfo_1 === undefined) {
                    var result = getText();
                    buildInfo_1 = result !== undefined ? ts.getBuildInfo(result) : false;
                }
                return buildInfo_1 || undefined;
            };
            node.javascriptPath = declarationTextOrJavascriptPath;
            node.javascriptMapPath = javascriptMapPath;
            node.declarationPath = ts.Debug.checkDefined(javascriptMapTextOrDeclarationPath);
            node.declarationMapPath = declarationMapPath;
            node.buildInfoPath = declarationMapTextOrBuildInfoPath;
            Object.defineProperties(node, {
                javascriptText: { get: function () { return definedTextGetter_1(declarationTextOrJavascriptPath); } },
                javascriptMapText: { get: function () { return textGetter_1(javascriptMapPath); } },
                declarationText: { get: function () { return definedTextGetter_1(ts.Debug.checkDefined(javascriptMapTextOrDeclarationPath)); } },
                declarationMapText: { get: function () { return textGetter_1(declarationMapPath); } },
                buildInfo: { get: function () { return getAndCacheBuildInfo_1(function () { return textGetter_1(declarationMapTextOrBuildInfoPath); }); } }
            });
        }
        else {
            node.javascriptText = javascriptTextOrReadFileText;
            node.javascriptMapPath = javascriptMapPath;
            node.javascriptMapText = javascriptMapTextOrDeclarationPath;
            node.declarationText = declarationTextOrJavascriptPath;
            node.declarationMapPath = declarationMapPath;
            node.declarationMapText = declarationMapTextOrBuildInfoPath;
            node.javascriptPath = javascriptPath;
            node.declarationPath = declarationPath;
            node.buildInfoPath = buildInfoPath;
            node.buildInfo = buildInfo;
            node.oldFileOfCurrentEmit = oldFileOfCurrentEmit;
        }
        return node;
    }
    ts.createInputFiles = createInputFiles;
    function updateBundle(node, sourceFiles, prepends) {
        if (prepends === void 0) { prepends = ts.emptyArray; }
        if (node.sourceFiles !== sourceFiles || node.prepends !== prepends) {
            return createBundle(sourceFiles, prepends);
        }
        return node;
    }
    ts.updateBundle = updateBundle;
    function createImmediatelyInvokedFunctionExpression(statements, param, paramValue) {
        return createCall(createFunctionExpression(
        /*modifiers*/ undefined, 
        /*asteriskToken*/ undefined, 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ param ? [param] : [], 
        /*type*/ undefined, createBlock(statements, /*multiLine*/ true)), 
        /*typeArguments*/ undefined, 
        /*argumentsArray*/ paramValue ? [paramValue] : []);
    }
    ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression;
    function createImmediatelyInvokedArrowFunction(statements, param, paramValue) {
        return createCall(createArrowFunction(
        /*modifiers*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ param ? [param] : [], 
        /*type*/ undefined, 
        /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), 
        /*typeArguments*/ undefined, 
        /*argumentsArray*/ paramValue ? [paramValue] : []);
    }
    ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction;
    function createComma(left, right) {
        return createBinary(left, 27 /* CommaToken */, right);
    }
    ts.createComma = createComma;
    function createLessThan(left, right) {
        return createBinary(left, 29 /* LessThanToken */, right);
    }
    ts.createLessThan = createLessThan;
    function createAssignment(left, right) {
        return createBinary(left, 62 /* EqualsToken */, right);
    }
    ts.createAssignment = createAssignment;
    function createStrictEquality(left, right) {
        return createBinary(left, 36 /* EqualsEqualsEqualsToken */, right);
    }
    ts.createStrictEquality = createStrictEquality;
    function createStrictInequality(left, right) {
        return createBinary(left, 37 /* ExclamationEqualsEqualsToken */, right);
    }
    ts.createStrictInequality = createStrictInequality;
    function createAdd(left, right) {
        return createBinary(left, 39 /* PlusToken */, right);
    }
    ts.createAdd = createAdd;
    function createSubtract(left, right) {
        return createBinary(left, 40 /* MinusToken */, right);
    }
    ts.createSubtract = createSubtract;
    function createPostfixIncrement(operand) {
        return createPostfix(operand, 45 /* PlusPlusToken */);
    }
    ts.createPostfixIncrement = createPostfixIncrement;
    function createLogicalAnd(left, right) {
        return createBinary(left, 55 /* AmpersandAmpersandToken */, right);
    }
    ts.createLogicalAnd = createLogicalAnd;
    function createLogicalOr(left, right) {
        return createBinary(left, 56 /* BarBarToken */, right);
    }
    ts.createLogicalOr = createLogicalOr;
    function createNullishCoalesce(left, right) {
        return createBinary(left, 60 /* QuestionQuestionToken */, right);
    }
    ts.createNullishCoalesce = createNullishCoalesce;
    function createLogicalNot(operand) {
        return createPrefix(53 /* ExclamationToken */, operand);
    }
    ts.createLogicalNot = createLogicalNot;
    function createVoidZero() {
        return createVoid(createLiteral(0));
    }
    ts.createVoidZero = createVoidZero;
    function createExportDefault(expression) {
        return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression);
    }
    ts.createExportDefault = createExportDefault;
    function createExternalModuleExport(exportName) {
        return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)]));
    }
    ts.createExternalModuleExport = createExternalModuleExport;
    // Utilities
    function asName(name) {
        return ts.isString(name) ? createIdentifier(name) : name;
    }
    function asExpression(value) {
        return typeof value === "string" ? createStringLiteral(value) :
            typeof value === "number" ? createNumericLiteral("" + value) :
                typeof value === "boolean" ? value ? createTrue() : createFalse() :
                    value;
    }
    function asNodeArray(array) {
        return array ? createNodeArray(array) : undefined;
    }
    function asToken(value) {
        return typeof value === "number" ? createToken(value) : value;
    }
    function asEmbeddedStatement(statement) {
        return statement && ts.isNotEmittedStatement(statement) ? setTextRange(setOriginalNode(createEmptyStatement(), statement), statement) : statement;
    }
    /**
     * Clears any EmitNode entries from parse-tree nodes.
     * @param sourceFile A source file.
     */
    function disposeEmitNodes(sourceFile) {
        // During transformation we may need to annotate a parse tree node with transient
        // transformation properties. As parse tree nodes live longer than transformation
        // nodes, we need to make sure we reclaim any memory allocated for custom ranges
        // from these nodes to ensure we do not hold onto entire subtrees just for position
        // information. We also need to reset these nodes to a pre-transformation state
        // for incremental parsing scenarios so that we do not impact later emit.
        sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(sourceFile));
        var emitNode = sourceFile && sourceFile.emitNode;
        var annotatedNodes = emitNode && emitNode.annotatedNodes;
        if (annotatedNodes) {
            for (var _i = 0, annotatedNodes_1 = annotatedNodes; _i < annotatedNodes_1.length; _i++) {
                var node = annotatedNodes_1[_i];
                node.emitNode = undefined;
            }
        }
    }
    ts.disposeEmitNodes = disposeEmitNodes;
    /**
     * Associates a node with the current transformation, initializing
     * various transient transformation properties.
     */
    /* @internal */
    function getOrCreateEmitNode(node) {
        if (!node.emitNode) {
            if (ts.isParseTreeNode(node)) {
                // To avoid holding onto transformation artifacts, we keep track of any
                // parse tree node we are annotating. This allows us to clean them up after
                // all transformations have completed.
                if (node.kind === 290 /* SourceFile */) {
                    return node.emitNode = { annotatedNodes: [node] };
                }
                var sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(ts.getSourceFileOfNode(node)));
                getOrCreateEmitNode(sourceFile).annotatedNodes.push(node);
            }
            node.emitNode = {};
        }
        return node.emitNode;
    }
    ts.getOrCreateEmitNode = getOrCreateEmitNode;
    /**
     * Sets `EmitFlags.NoComments` on a node and removes any leading and trailing synthetic comments.
     * @internal
     */
    function removeAllComments(node) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.flags |= 1536 /* NoComments */;
        emitNode.leadingComments = undefined;
        emitNode.trailingComments = undefined;
        return node;
    }
    ts.removeAllComments = removeAllComments;
    function setTextRange(range, location) {
        if (location) {
            range.pos = location.pos;
            range.end = location.end;
        }
        return range;
    }
    ts.setTextRange = setTextRange;
    /**
     * Sets flags that control emit behavior of a node.
     */
    function setEmitFlags(node, emitFlags) {
        getOrCreateEmitNode(node).flags = emitFlags;
        return node;
    }
    ts.setEmitFlags = setEmitFlags;
    /**
     * Sets flags that control emit behavior of a node.
     */
    /* @internal */
    function addEmitFlags(node, emitFlags) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.flags = emitNode.flags | emitFlags;
        return node;
    }
    ts.addEmitFlags = addEmitFlags;
    /**
     * Gets a custom text range to use when emitting source maps.
     */
    function getSourceMapRange(node) {
        var emitNode = node.emitNode;
        return (emitNode && emitNode.sourceMapRange) || node;
    }
    ts.getSourceMapRange = getSourceMapRange;
    /**
     * Sets a custom text range to use when emitting source maps.
     */
    function setSourceMapRange(node, range) {
        getOrCreateEmitNode(node).sourceMapRange = range;
        return node;
    }
    ts.setSourceMapRange = setSourceMapRange;
    var SourceMapSource;
    /**
     * Create an external source map source file reference
     */
    function createSourceMapSource(fileName, text, skipTrivia) {
        return new (SourceMapSource || (SourceMapSource = ts.objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia);
    }
    ts.createSourceMapSource = createSourceMapSource;
    /**
     * Gets the TextRange to use for source maps for a token of a node.
     */
    function getTokenSourceMapRange(node, token) {
        var emitNode = node.emitNode;
        var tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
        return tokenSourceMapRanges && tokenSourceMapRanges[token];
    }
    ts.getTokenSourceMapRange = getTokenSourceMapRange;
    /**
     * Sets the TextRange to use for source maps for a token of a node.
     */
    function setTokenSourceMapRange(node, token, range) {
        var emitNode = getOrCreateEmitNode(node);
        var tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
        tokenSourceMapRanges[token] = range;
        return node;
    }
    ts.setTokenSourceMapRange = setTokenSourceMapRange;
    /**
     * Gets a custom text range to use when emitting comments.
     */
    /*@internal*/
    function getStartsOnNewLine(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.startsOnNewLine;
    }
    ts.getStartsOnNewLine = getStartsOnNewLine;
    /**
     * Sets a custom text range to use when emitting comments.
     */
    /*@internal*/
    function setStartsOnNewLine(node, newLine) {
        getOrCreateEmitNode(node).startsOnNewLine = newLine;
        return node;
    }
    ts.setStartsOnNewLine = setStartsOnNewLine;
    /**
     * Gets a custom text range to use when emitting comments.
     */
    function getCommentRange(node) {
        var emitNode = node.emitNode;
        return (emitNode && emitNode.commentRange) || node;
    }
    ts.getCommentRange = getCommentRange;
    /**
     * Sets a custom text range to use when emitting comments.
     */
    function setCommentRange(node, range) {
        getOrCreateEmitNode(node).commentRange = range;
        return node;
    }
    ts.setCommentRange = setCommentRange;
    function getSyntheticLeadingComments(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.leadingComments;
    }
    ts.getSyntheticLeadingComments = getSyntheticLeadingComments;
    function setSyntheticLeadingComments(node, comments) {
        getOrCreateEmitNode(node).leadingComments = comments;
        return node;
    }
    ts.setSyntheticLeadingComments = setSyntheticLeadingComments;
    function addSyntheticLeadingComment(node, kind, text, hasTrailingNewLine) {
        return setSyntheticLeadingComments(node, ts.append(getSyntheticLeadingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
    }
    ts.addSyntheticLeadingComment = addSyntheticLeadingComment;
    function getSyntheticTrailingComments(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.trailingComments;
    }
    ts.getSyntheticTrailingComments = getSyntheticTrailingComments;
    function setSyntheticTrailingComments(node, comments) {
        getOrCreateEmitNode(node).trailingComments = comments;
        return node;
    }
    ts.setSyntheticTrailingComments = setSyntheticTrailingComments;
    function addSyntheticTrailingComment(node, kind, text, hasTrailingNewLine) {
        return setSyntheticTrailingComments(node, ts.append(getSyntheticTrailingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
    }
    ts.addSyntheticTrailingComment = addSyntheticTrailingComment;
    function moveSyntheticComments(node, original) {
        setSyntheticLeadingComments(node, getSyntheticLeadingComments(original));
        setSyntheticTrailingComments(node, getSyntheticTrailingComments(original));
        var emit = getOrCreateEmitNode(original);
        emit.leadingComments = undefined;
        emit.trailingComments = undefined;
        return node;
    }
    ts.moveSyntheticComments = moveSyntheticComments;
    /** @internal */
    function ignoreSourceNewlines(node) {
        getOrCreateEmitNode(node).flags |= 134217728 /* IgnoreSourceNewlines */;
        return node;
    }
    ts.ignoreSourceNewlines = ignoreSourceNewlines;
    /**
     * Gets the constant value to emit for an expression.
     */
    function getConstantValue(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.constantValue;
    }
    ts.getConstantValue = getConstantValue;
    /**
     * Sets the constant value to emit for an expression.
     */
    function setConstantValue(node, value) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.constantValue = value;
        return node;
    }
    ts.setConstantValue = setConstantValue;
    /**
     * Adds an EmitHelper to a node.
     */
    function addEmitHelper(node, helper) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.helpers = ts.append(emitNode.helpers, helper);
        return node;
    }
    ts.addEmitHelper = addEmitHelper;
    /**
     * Add EmitHelpers to a node.
     */
    function addEmitHelpers(node, helpers) {
        if (ts.some(helpers)) {
            var emitNode = getOrCreateEmitNode(node);
            for (var _i = 0, helpers_1 = helpers; _i < helpers_1.length; _i++) {
                var helper = helpers_1[_i];
                emitNode.helpers = ts.appendIfUnique(emitNode.helpers, helper);
            }
        }
        return node;
    }
    ts.addEmitHelpers = addEmitHelpers;
    /**
     * Removes an EmitHelper from a node.
     */
    function removeEmitHelper(node, helper) {
        var emitNode = node.emitNode;
        if (emitNode) {
            var helpers = emitNode.helpers;
            if (helpers) {
                return ts.orderedRemoveItem(helpers, helper);
            }
        }
        return false;
    }
    ts.removeEmitHelper = removeEmitHelper;
    /**
     * Gets the EmitHelpers of a node.
     */
    function getEmitHelpers(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.helpers;
    }
    ts.getEmitHelpers = getEmitHelpers;
    /**
     * Moves matching emit helpers from a source node to a target node.
     */
    function moveEmitHelpers(source, target, predicate) {
        var sourceEmitNode = source.emitNode;
        var sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers;
        if (!ts.some(sourceEmitHelpers))
            return;
        var targetEmitNode = getOrCreateEmitNode(target);
        var helpersRemoved = 0;
        for (var i = 0; i < sourceEmitHelpers.length; i++) {
            var helper = sourceEmitHelpers[i];
            if (predicate(helper)) {
                helpersRemoved++;
                targetEmitNode.helpers = ts.appendIfUnique(targetEmitNode.helpers, helper);
            }
            else if (helpersRemoved > 0) {
                sourceEmitHelpers[i - helpersRemoved] = helper;
            }
        }
        if (helpersRemoved > 0) {
            sourceEmitHelpers.length -= helpersRemoved;
        }
    }
    ts.moveEmitHelpers = moveEmitHelpers;
    /* @internal */
    function compareEmitHelpers(x, y) {
        if (x === y)
            return 0 /* EqualTo */;
        if (x.priority === y.priority)
            return 0 /* EqualTo */;
        if (x.priority === undefined)
            return 1 /* GreaterThan */;
        if (y.priority === undefined)
            return -1 /* LessThan */;
        return ts.compareValues(x.priority, y.priority);
    }
    ts.compareEmitHelpers = compareEmitHelpers;
    function setOriginalNode(node, original) {
        node.original = original;
        if (original) {
            var emitNode = original.emitNode;
            if (emitNode)
                node.emitNode = mergeEmitNode(emitNode, node.emitNode);
        }
        return node;
    }
    ts.setOriginalNode = setOriginalNode;
    function mergeEmitNode(sourceEmitNode, destEmitNode) {
        var flags = sourceEmitNode.flags, leadingComments = sourceEmitNode.leadingComments, trailingComments = sourceEmitNode.trailingComments, commentRange = sourceEmitNode.commentRange, sourceMapRange = sourceEmitNode.sourceMapRange, tokenSourceMapRanges = sourceEmitNode.tokenSourceMapRanges, constantValue = sourceEmitNode.constantValue, helpers = sourceEmitNode.helpers, startsOnNewLine = sourceEmitNode.startsOnNewLine;
        if (!destEmitNode)
            destEmitNode = {};
        // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
        if (leadingComments)
            destEmitNode.leadingComments = ts.addRange(leadingComments.slice(), destEmitNode.leadingComments);
        if (trailingComments)
            destEmitNode.trailingComments = ts.addRange(trailingComments.slice(), destEmitNode.trailingComments);
        if (flags)
            destEmitNode.flags = flags;
        if (commentRange)
            destEmitNode.commentRange = commentRange;
        if (sourceMapRange)
            destEmitNode.sourceMapRange = sourceMapRange;
        if (tokenSourceMapRanges)
            destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges);
        if (constantValue !== undefined)
            destEmitNode.constantValue = constantValue;
        if (helpers)
            destEmitNode.helpers = ts.addRange(destEmitNode.helpers, helpers);
        if (startsOnNewLine !== undefined)
            destEmitNode.startsOnNewLine = startsOnNewLine;
        return destEmitNode;
    }
    function mergeTokenSourceMapRanges(sourceRanges, destRanges) {
        if (!destRanges)
            destRanges = [];
        for (var key in sourceRanges) {
            destRanges[key] = sourceRanges[key];
        }
        return destRanges;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    ts.nullTransformationContext = {
        enableEmitNotification: ts.noop,
        enableSubstitution: ts.noop,
        endLexicalEnvironment: ts.returnUndefined,
        getCompilerOptions: function () { return ({}); },
        getEmitHost: ts.notImplemented,
        getEmitResolver: ts.notImplemented,
        setLexicalEnvironmentFlags: ts.noop,
        getLexicalEnvironmentFlags: function () { return 0; },
        hoistFunctionDeclaration: ts.noop,
        hoistVariableDeclaration: ts.noop,
        addInitializationStatement: ts.noop,
        isEmitNotificationEnabled: ts.notImplemented,
        isSubstitutionEnabled: ts.notImplemented,
        onEmitNode: ts.noop,
        onSubstituteNode: ts.notImplemented,
        readEmitHelpers: ts.notImplemented,
        requestEmitHelper: ts.noop,
        resumeLexicalEnvironment: ts.noop,
        startLexicalEnvironment: ts.noop,
        suspendLexicalEnvironment: ts.noop,
        addDiagnostic: ts.noop,
    };
    function createTypeCheck(value, tag) {
        return tag === "undefined"
            ? ts.createStrictEquality(value, ts.createVoidZero())
            : ts.createStrictEquality(ts.createTypeOf(value), ts.createLiteral(tag));
    }
    ts.createTypeCheck = createTypeCheck;
    function createMemberAccessForPropertyName(target, memberName, location) {
        if (ts.isComputedPropertyName(memberName)) {
            return ts.setTextRange(ts.createElementAccess(target, memberName.expression), location);
        }
        else {
            var expression = ts.setTextRange((ts.isIdentifier(memberName) || ts.isPrivateIdentifier(memberName))
                ? ts.createPropertyAccess(target, memberName)
                : ts.createElementAccess(target, memberName), memberName);
            ts.getOrCreateEmitNode(expression).flags |= 64 /* NoNestedSourceMaps */;
            return expression;
        }
    }
    ts.createMemberAccessForPropertyName = createMemberAccessForPropertyName;
    function createFunctionCall(func, thisArg, argumentsList, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "call"), 
        /*typeArguments*/ undefined, __spreadArrays([
            thisArg
        ], argumentsList)), location);
    }
    ts.createFunctionCall = createFunctionCall;
    function createFunctionApply(func, thisArg, argumentsExpression, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "apply"), 
        /*typeArguments*/ undefined, [
            thisArg,
            argumentsExpression
        ]), location);
    }
    ts.createFunctionApply = createFunctionApply;
    function createArraySlice(array, start) {
        var argumentsList = [];
        if (start !== undefined) {
            argumentsList.push(typeof start === "number" ? ts.createLiteral(start) : start);
        }
        return ts.createCall(ts.createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList);
    }
    ts.createArraySlice = createArraySlice;
    function createArrayConcat(array, values) {
        return ts.createCall(ts.createPropertyAccess(array, "concat"), 
        /*typeArguments*/ undefined, values);
    }
    ts.createArrayConcat = createArrayConcat;
    function createMathPow(left, right, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Math"), "pow"), 
        /*typeArguments*/ undefined, [left, right]), location);
    }
    ts.createMathPow = createMathPow;
    function createReactNamespace(reactNamespace, parent) {
        // To ensure the emit resolver can properly resolve the namespace, we need to
        // treat this identifier as if it were a source tree node by clearing the `Synthesized`
        // flag and setting a parent node.
        var react = ts.createIdentifier(reactNamespace || "React");
        react.flags &= ~8 /* Synthesized */;
        // Set the parent that is in parse tree
        // this makes sure that parent chain is intact for checker to traverse complete scope tree
        react.parent = ts.getParseTreeNode(parent);
        return react;
    }
    function createJsxFactoryExpressionFromEntityName(jsxFactory, parent) {
        if (ts.isQualifiedName(jsxFactory)) {
            var left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
            var right = ts.createIdentifier(ts.idText(jsxFactory.right));
            right.escapedText = jsxFactory.right.escapedText;
            return ts.createPropertyAccess(left, right);
        }
        else {
            return createReactNamespace(ts.idText(jsxFactory), parent);
        }
    }
    function createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parent) {
        return jsxFactoryEntity ?
            createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
            ts.createPropertyAccess(createReactNamespace(reactNamespace, parent), "createElement");
    }
    function createExpressionForJsxElement(jsxFactoryEntity, reactNamespace, tagName, props, children, parentElement, location) {
        var argumentsList = [tagName];
        if (props) {
            argumentsList.push(props);
        }
        if (children && children.length > 0) {
            if (!props) {
                argumentsList.push(ts.createNull());
            }
            if (children.length > 1) {
                for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
                    var child = children_2[_i];
                    startOnNewLine(child);
                    argumentsList.push(child);
                }
            }
            else {
                argumentsList.push(children[0]);
            }
        }
        return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), 
        /*typeArguments*/ undefined, argumentsList), location);
    }
    ts.createExpressionForJsxElement = createExpressionForJsxElement;
    function createExpressionForJsxFragment(jsxFactoryEntity, reactNamespace, children, parentElement, location) {
        var tagName = ts.createPropertyAccess(createReactNamespace(reactNamespace, parentElement), "Fragment");
        var argumentsList = [tagName];
        argumentsList.push(ts.createNull());
        if (children && children.length > 0) {
            if (children.length > 1) {
                for (var _i = 0, children_3 = children; _i < children_3.length; _i++) {
                    var child = children_3[_i];
                    startOnNewLine(child);
                    argumentsList.push(child);
                }
            }
            else {
                argumentsList.push(children[0]);
            }
        }
        return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), 
        /*typeArguments*/ undefined, argumentsList), location);
    }
    ts.createExpressionForJsxFragment = createExpressionForJsxFragment;
    // Helpers
    /**
     * Gets an identifier for the name of an *unscoped* emit helper.
     */
    function getUnscopedHelperName(name) {
        return ts.setEmitFlags(ts.createIdentifier(name), 4096 /* HelperName */ | 2 /* AdviseOnEmitNode */);
    }
    ts.getUnscopedHelperName = getUnscopedHelperName;
    ts.valuesHelper = {
        name: "typescript:values",
        importName: "__values",
        scoped: false,
        text: "\n            var __values = (this && this.__values) || function(o) {\n                var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n                if (m) return m.call(o);\n                if (o && typeof o.length === \"number\") return {\n                    next: function () {\n                        if (o && i >= o.length) o = void 0;\n                        return { value: o && o[i++], done: !o };\n                    }\n                };\n                throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n            };"
    };
    function createValuesHelper(context, expression, location) {
        context.requestEmitHelper(ts.valuesHelper);
        return ts.setTextRange(ts.createCall(getUnscopedHelperName("__values"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
    ts.createValuesHelper = createValuesHelper;
    ts.readHelper = {
        name: "typescript:read",
        importName: "__read",
        scoped: false,
        text: "\n            var __read = (this && this.__read) || function (o, n) {\n                var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n                if (!m) return o;\n                var i = m.call(o), r, ar = [], e;\n                try {\n                    while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n                }\n                catch (error) { e = { error: error }; }\n                finally {\n                    try {\n                        if (r && !r.done && (m = i[\"return\"])) m.call(i);\n                    }\n                    finally { if (e) throw e.error; }\n                }\n                return ar;\n            };"
    };
    function createReadHelper(context, iteratorRecord, count, location) {
        context.requestEmitHelper(ts.readHelper);
        return ts.setTextRange(ts.createCall(getUnscopedHelperName("__read"), 
        /*typeArguments*/ undefined, count !== undefined
            ? [iteratorRecord, ts.createLiteral(count)]
            : [iteratorRecord]), location);
    }
    ts.createReadHelper = createReadHelper;
    ts.spreadHelper = {
        name: "typescript:spread",
        importName: "__spread",
        scoped: false,
        dependencies: [ts.readHelper],
        text: "\n            var __spread = (this && this.__spread) || function () {\n                for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));\n                return ar;\n            };"
    };
    function createSpreadHelper(context, argumentList, location) {
        context.requestEmitHelper(ts.spreadHelper);
        return ts.setTextRange(ts.createCall(getUnscopedHelperName("__spread"), 
        /*typeArguments*/ undefined, argumentList), location);
    }
    ts.createSpreadHelper = createSpreadHelper;
    ts.spreadArraysHelper = {
        name: "typescript:spreadArrays",
        importName: "__spreadArrays",
        scoped: false,
        text: "\n            var __spreadArrays = (this && this.__spreadArrays) || function () {\n                for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n                for (var r = Array(s), k = 0, i = 0; i < il; i++)\n                    for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n                        r[k] = a[j];\n                return r;\n            };"
    };
    function createSpreadArraysHelper(context, argumentList, location) {
        context.requestEmitHelper(ts.spreadArraysHelper);
        return ts.setTextRange(ts.createCall(getUnscopedHelperName("__spreadArrays"), 
        /*typeArguments*/ undefined, argumentList), location);
    }
    ts.createSpreadArraysHelper = createSpreadArraysHelper;
    // Utilities
    function createForOfBindingStatement(node, boundValue) {
        if (ts.isVariableDeclarationList(node)) {
            var firstDeclaration = ts.first(node.declarations);
            var updatedDeclaration = ts.updateVariableDeclaration(firstDeclaration, firstDeclaration.name, 
            /*typeNode*/ undefined, boundValue);
            return ts.setTextRange(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.updateVariableDeclarationList(node, [updatedDeclaration])), 
            /*location*/ node);
        }
        else {
            var updatedExpression = ts.setTextRange(ts.createAssignment(node, boundValue), /*location*/ node);
            return ts.setTextRange(ts.createStatement(updatedExpression), /*location*/ node);
        }
    }
    ts.createForOfBindingStatement = createForOfBindingStatement;
    function insertLeadingStatement(dest, source) {
        if (ts.isBlock(dest)) {
            return ts.updateBlock(dest, ts.setTextRange(ts.createNodeArray(__spreadArrays([source], dest.statements)), dest.statements));
        }
        else {
            return ts.createBlock(ts.createNodeArray([dest, source]), /*multiLine*/ true);
        }
    }
    ts.insertLeadingStatement = insertLeadingStatement;
    function restoreEnclosingLabel(node, outermostLabeledStatement, afterRestoreLabelCallback) {
        if (!outermostLabeledStatement) {
            return node;
        }
        var updated = ts.updateLabel(outermostLabeledStatement, outermostLabeledStatement.label, outermostLabeledStatement.statement.kind === 238 /* LabeledStatement */
            ? restoreEnclosingLabel(node, outermostLabeledStatement.statement)
            : node);
        if (afterRestoreLabelCallback) {
            afterRestoreLabelCallback(outermostLabeledStatement);
        }
        return updated;
    }
    ts.restoreEnclosingLabel = restoreEnclosingLabel;
    function shouldBeCapturedInTempVariable(node, cacheIdentifiers) {
        var target = ts.skipParentheses(node);
        switch (target.kind) {
            case 75 /* Identifier */:
                return cacheIdentifiers;
            case 104 /* ThisKeyword */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
                return false;
            case 192 /* ArrayLiteralExpression */:
                var elements = target.elements;
                if (elements.length === 0) {
                    return false;
                }
                return true;
            case 193 /* ObjectLiteralExpression */:
                return target.properties.length > 0;
            default:
                return true;
        }
    }
    function createCallBinding(expression, recordTempVariable, languageVersion, cacheIdentifiers) {
        if (cacheIdentifiers === void 0) { cacheIdentifiers = false; }
        var callee = skipOuterExpressions(expression, 15 /* All */);
        var thisArg;
        var target;
        if (ts.isSuperProperty(callee)) {
            thisArg = ts.createThis();
            target = callee;
        }
        else if (callee.kind === 102 /* SuperKeyword */) {
            thisArg = ts.createThis();
            target = languageVersion < 2 /* ES2015 */
                ? ts.setTextRange(ts.createIdentifier("_super"), callee)
                : callee;
        }
        else if (ts.getEmitFlags(callee) & 4096 /* HelperName */) {
            thisArg = ts.createVoidZero();
            target = parenthesizeForAccess(callee);
        }
        else {
            switch (callee.kind) {
                case 194 /* PropertyAccessExpression */: {
                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
                        // for `a.b()` target is `(_a = a).b` and thisArg is `_a`
                        thisArg = ts.createTempVariable(recordTempVariable);
                        target = ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.name);
                        ts.setTextRange(target, callee);
                    }
                    else {
                        thisArg = callee.expression;
                        target = callee;
                    }
                    break;
                }
                case 195 /* ElementAccessExpression */: {
                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
                        // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a`
                        thisArg = ts.createTempVariable(recordTempVariable);
                        target = ts.createElementAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.argumentExpression);
                        ts.setTextRange(target, callee);
                    }
                    else {
                        thisArg = callee.expression;
                        target = callee;
                    }
                    break;
                }
                default: {
                    // for `a()` target is `a` and thisArg is `void 0`
                    thisArg = ts.createVoidZero();
                    target = parenthesizeForAccess(expression);
                    break;
                }
            }
        }
        return { target: target, thisArg: thisArg };
    }
    ts.createCallBinding = createCallBinding;
    function inlineExpressions(expressions) {
        // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call
        // stack size exceeded" errors.
        return expressions.length > 10
            ? ts.createCommaList(expressions)
            : ts.reduceLeft(expressions, ts.createComma);
    }
    ts.inlineExpressions = inlineExpressions;
    function createExpressionFromEntityName(node) {
        if (ts.isQualifiedName(node)) {
            var left = createExpressionFromEntityName(node.left);
            var right = ts.getMutableClone(node.right);
            return ts.setTextRange(ts.createPropertyAccess(left, right), node);
        }
        else {
            return ts.getMutableClone(node);
        }
    }
    ts.createExpressionFromEntityName = createExpressionFromEntityName;
    function createExpressionForPropertyName(memberName) {
        if (ts.isIdentifier(memberName)) {
            return ts.createLiteral(memberName);
        }
        else if (ts.isComputedPropertyName(memberName)) {
            return ts.getMutableClone(memberName.expression);
        }
        else {
            return ts.getMutableClone(memberName);
        }
    }
    ts.createExpressionForPropertyName = createExpressionForPropertyName;
    function createExpressionForObjectLiteralElementLike(node, property, receiver) {
        if (property.name && ts.isPrivateIdentifier(property.name)) {
            ts.Debug.failBadSyntaxKind(property.name, "Private identifiers are not allowed in object literals.");
        }
        switch (property.kind) {
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
                return createExpressionForAccessorDeclaration(node.properties, property, receiver, !!node.multiLine);
            case 281 /* PropertyAssignment */:
                return createExpressionForPropertyAssignment(property, receiver);
            case 282 /* ShorthandPropertyAssignment */:
                return createExpressionForShorthandPropertyAssignment(property, receiver);
            case 161 /* MethodDeclaration */:
                return createExpressionForMethodDeclaration(property, receiver);
        }
    }
    ts.createExpressionForObjectLiteralElementLike = createExpressionForObjectLiteralElementLike;
    function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) {
        var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
        if (property === firstAccessor) {
            var properties_7 = [];
            if (getAccessor) {
                var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, getAccessor.parameters, 
                /*type*/ undefined, getAccessor.body // TODO: GH#18217
                );
                ts.setTextRange(getterFunction, getAccessor);
                ts.setOriginalNode(getterFunction, getAccessor);
                var getter = ts.createPropertyAssignment("get", getterFunction);
                properties_7.push(getter);
            }
            if (setAccessor) {
                var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, setAccessor.parameters, 
                /*type*/ undefined, setAccessor.body // TODO: GH#18217
                );
                ts.setTextRange(setterFunction, setAccessor);
                ts.setOriginalNode(setterFunction, setAccessor);
                var setter = ts.createPropertyAssignment("set", setterFunction);
                properties_7.push(setter);
            }
            properties_7.push(ts.createPropertyAssignment("enumerable", getAccessor || setAccessor ? ts.createFalse() : ts.createTrue()));
            properties_7.push(ts.createPropertyAssignment("configurable", ts.createTrue()));
            var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                receiver,
                createExpressionForPropertyName(property.name),
                ts.createObjectLiteral(properties_7, multiLine)
            ]), 
            /*location*/ firstAccessor);
            return ts.aggregateTransformFlags(expression);
        }
        return undefined;
    }
    function createExpressionForPropertyAssignment(property, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), property.initializer), property), property));
    }
    function createExpressionForShorthandPropertyAssignment(property, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), ts.getSynthesizedClone(property.name)), 
        /*location*/ property), 
        /*original*/ property));
    }
    function createExpressionForMethodDeclaration(method, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(method.modifiers, method.asteriskToken, 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, method.parameters, 
        /*type*/ undefined, method.body // TODO: GH#18217
        ), 
        /*location*/ method), 
        /*original*/ method)), 
        /*location*/ method), 
        /*original*/ method));
    }
    /**
     * Gets the internal name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the body of an ES5 class function body. An internal name will *never*
     * be prefixed with an module or namespace export modifier like "exports." when emitted as an
     * expression. An internal name will also *never* be renamed due to a collision with a block
     * scoped variable.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getInternalName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */ | 32768 /* InternalName */);
    }
    ts.getInternalName = getInternalName;
    /**
     * Gets whether an identifier should only be referred to by its internal name.
     */
    function isInternalName(node) {
        return (ts.getEmitFlags(node) & 32768 /* InternalName */) !== 0;
    }
    ts.isInternalName = isInternalName;
    /**
     * Gets the local name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A
     * local name will *never* be prefixed with an module or namespace export modifier like
     * "exports." when emitted as an expression.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getLocalName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */);
    }
    ts.getLocalName = getLocalName;
    /**
     * Gets whether an identifier should only be referred to by its local name.
     */
    function isLocalName(node) {
        return (ts.getEmitFlags(node) & 16384 /* LocalName */) !== 0;
    }
    ts.isLocalName = isLocalName;
    /**
     * Gets the export name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An
     * export name will *always* be prefixed with an module or namespace export modifier like
     * `"exports."` when emitted as an expression if the name points to an exported symbol.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getExportName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 8192 /* ExportName */);
    }
    ts.getExportName = getExportName;
    /**
     * Gets whether an identifier should only be referred to by its export representation if the
     * name points to an exported symbol.
     */
    function isExportName(node) {
        return (ts.getEmitFlags(node) & 8192 /* ExportName */) !== 0;
    }
    ts.isExportName = isExportName;
    /**
     * Gets the name of a declaration for use in declarations.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getDeclarationName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps);
    }
    ts.getDeclarationName = getDeclarationName;
    function getName(node, allowComments, allowSourceMaps, emitFlags) {
        if (emitFlags === void 0) { emitFlags = 0; }
        var nodeName = ts.getNameOfDeclaration(node);
        if (nodeName && ts.isIdentifier(nodeName) && !ts.isGeneratedIdentifier(nodeName)) {
            var name = ts.getMutableClone(nodeName);
            emitFlags |= ts.getEmitFlags(nodeName);
            if (!allowSourceMaps)
                emitFlags |= 48 /* NoSourceMap */;
            if (!allowComments)
                emitFlags |= 1536 /* NoComments */;
            if (emitFlags)
                ts.setEmitFlags(name, emitFlags);
            return name;
        }
        return ts.getGeneratedNameForNode(node);
    }
    /**
     * Gets the exported name of a declaration for use in expressions.
     *
     * An exported name will *always* be prefixed with an module or namespace export modifier like
     * "exports." if the name points to an exported symbol.
     *
     * @param ns The namespace identifier.
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getExternalModuleOrNamespaceExportName(ns, node, allowComments, allowSourceMaps) {
        if (ns && ts.hasModifier(node, 1 /* Export */)) {
            return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps);
        }
        return getExportName(node, allowComments, allowSourceMaps);
    }
    ts.getExternalModuleOrNamespaceExportName = getExternalModuleOrNamespaceExportName;
    /**
     * Gets a namespace-qualified name for use in expressions.
     *
     * @param ns The namespace identifier.
     * @param name The name.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getNamespaceMemberName(ns, name, allowComments, allowSourceMaps) {
        var qualifiedName = ts.createPropertyAccess(ns, ts.nodeIsSynthesized(name) ? name : ts.getSynthesizedClone(name));
        ts.setTextRange(qualifiedName, name);
        var emitFlags = 0;
        if (!allowSourceMaps)
            emitFlags |= 48 /* NoSourceMap */;
        if (!allowComments)
            emitFlags |= 1536 /* NoComments */;
        if (emitFlags)
            ts.setEmitFlags(qualifiedName, emitFlags);
        return qualifiedName;
    }
    ts.getNamespaceMemberName = getNamespaceMemberName;
    function convertToFunctionBody(node, multiLine) {
        return ts.isBlock(node) ? node : ts.setTextRange(ts.createBlock([ts.setTextRange(ts.createReturn(node), node)], multiLine), node);
    }
    ts.convertToFunctionBody = convertToFunctionBody;
    function convertFunctionDeclarationToExpression(node) {
        if (!node.body)
            return ts.Debug.fail();
        var updated = ts.createFunctionExpression(node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body);
        ts.setOriginalNode(updated, node);
        ts.setTextRange(updated, node);
        if (ts.getStartsOnNewLine(node)) {
            ts.setStartsOnNewLine(updated, /*newLine*/ true);
        }
        ts.aggregateTransformFlags(updated);
        return updated;
    }
    ts.convertFunctionDeclarationToExpression = convertFunctionDeclarationToExpression;
    function isUseStrictPrologue(node) {
        return ts.isStringLiteral(node.expression) && node.expression.text === "use strict";
    }
    /**
     * Add any necessary prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     *
     * @param target: result statements array
     * @param source: origin statements array
     * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
     * @param visitor: Optional callback used to visit any custom prologue directives.
     */
    function addPrologue(target, source, ensureUseStrict, visitor) {
        var offset = addStandardPrologue(target, source, ensureUseStrict);
        return addCustomPrologue(target, source, offset, visitor);
    }
    ts.addPrologue = addPrologue;
    /**
     * Add just the standard (string-expression) prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     */
    function addStandardPrologue(target, source, ensureUseStrict) {
        ts.Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
        var foundUseStrict = false;
        var statementOffset = 0;
        var numStatements = source.length;
        while (statementOffset < numStatements) {
            var statement = source[statementOffset];
            if (ts.isPrologueDirective(statement)) {
                if (isUseStrictPrologue(statement)) {
                    foundUseStrict = true;
                }
                target.push(statement);
            }
            else {
                break;
            }
            statementOffset++;
        }
        if (ensureUseStrict && !foundUseStrict) {
            target.push(startOnNewLine(ts.createStatement(ts.createLiteral("use strict"))));
        }
        return statementOffset;
    }
    ts.addStandardPrologue = addStandardPrologue;
    function addCustomPrologue(target, source, statementOffset, visitor, filter) {
        if (filter === void 0) { filter = ts.returnTrue; }
        var numStatements = source.length;
        while (statementOffset !== undefined && statementOffset < numStatements) {
            var statement = source[statementOffset];
            if (ts.getEmitFlags(statement) & 1048576 /* CustomPrologue */ && filter(statement)) {
                ts.append(target, visitor ? ts.visitNode(statement, visitor, ts.isStatement) : statement);
            }
            else {
                break;
            }
            statementOffset++;
        }
        return statementOffset;
    }
    ts.addCustomPrologue = addCustomPrologue;
    function findUseStrictPrologue(statements) {
        for (var _i = 0, statements_4 = statements; _i < statements_4.length; _i++) {
            var statement = statements_4[_i];
            if (ts.isPrologueDirective(statement)) {
                if (isUseStrictPrologue(statement)) {
                    return statement;
                }
            }
            else {
                break;
            }
        }
        return undefined;
    }
    ts.findUseStrictPrologue = findUseStrictPrologue;
    function startsWithUseStrict(statements) {
        var firstStatement = ts.firstOrUndefined(statements);
        return firstStatement !== undefined
            && ts.isPrologueDirective(firstStatement)
            && isUseStrictPrologue(firstStatement);
    }
    ts.startsWithUseStrict = startsWithUseStrict;
    /**
     * Ensures "use strict" directive is added
     *
     * @param statements An array of statements
     */
    function ensureUseStrict(statements) {
        var foundUseStrict = findUseStrictPrologue(statements);
        if (!foundUseStrict) {
            return ts.setTextRange(ts.createNodeArray(__spreadArrays([
                startOnNewLine(ts.createStatement(ts.createLiteral("use strict")))
            ], statements)), statements);
        }
        return statements;
    }
    ts.ensureUseStrict = ensureUseStrict;
    /**
     * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
     * order of operations.
     *
     * @param binaryOperator The operator for the BinaryExpression.
     * @param operand The operand for the BinaryExpression.
     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
     *                           BinaryExpression.
     */
    function parenthesizeBinaryOperand(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
        var skipped = ts.skipPartiallyEmittedExpressions(operand);
        // If the resulting expression is already parenthesized, we do not need to do any further processing.
        if (skipped.kind === 200 /* ParenthesizedExpression */) {
            return operand;
        }
        return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand)
            ? ts.createParen(operand)
            : operand;
    }
    ts.parenthesizeBinaryOperand = parenthesizeBinaryOperand;
    /**
     * Determines whether the operand to a BinaryExpression needs to be parenthesized.
     *
     * @param binaryOperator The operator for the BinaryExpression.
     * @param operand The operand for the BinaryExpression.
     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
     *                           BinaryExpression.
     */
    function binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
        // If the operand has lower precedence, then it needs to be parenthesized to preserve the
        // intent of the expression. For example, if the operand is `a + b` and the operator is
        // `*`, then we need to parenthesize the operand to preserve the intended order of
        // operations: `(a + b) * x`.
        //
        // If the operand has higher precedence, then it does not need to be parenthesized. For
        // example, if the operand is `a * b` and the operator is `+`, then we do not need to
        // parenthesize to preserve the intended order of operations: `a * b + x`.
        //
        // If the operand has the same precedence, then we need to check the associativity of
        // the operator based on whether this is the left or right operand of the expression.
        //
        // For example, if `a / d` is on the right of operator `*`, we need to parenthesize
        // to preserve the intended order of operations: `x * (a / d)`
        //
        // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve
        // the intended order of operations: `(a ** b) ** c`
        var binaryOperatorPrecedence = ts.getOperatorPrecedence(209 /* BinaryExpression */, binaryOperator);
        var binaryOperatorAssociativity = ts.getOperatorAssociativity(209 /* BinaryExpression */, binaryOperator);
        var emittedOperand = ts.skipPartiallyEmittedExpressions(operand);
        if (!isLeftSideOfBinary && operand.kind === 202 /* ArrowFunction */ && binaryOperatorPrecedence > 3) {
            // We need to parenthesize arrow functions on the right side to avoid it being
            // parsed as parenthesized expression: `a && (() => {})`
            return true;
        }
        var operandPrecedence = ts.getExpressionPrecedence(emittedOperand);
        switch (ts.compareValues(operandPrecedence, binaryOperatorPrecedence)) {
            case -1 /* LessThan */:
                // If the operand is the right side of a right-associative binary operation
                // and is a yield expression, then we do not need parentheses.
                if (!isLeftSideOfBinary
                    && binaryOperatorAssociativity === 1 /* Right */
                    && operand.kind === 212 /* YieldExpression */) {
                    return false;
                }
                return true;
            case 1 /* GreaterThan */:
                return false;
            case 0 /* EqualTo */:
                if (isLeftSideOfBinary) {
                    // No need to parenthesize the left operand when the binary operator is
                    // left associative:
                    //  (a*b)/x    -> a*b/x
                    //  (a**b)/x   -> a**b/x
                    //
                    // Parentheses are needed for the left operand when the binary operator is
                    // right associative:
                    //  (a/b)**x   -> (a/b)**x
                    //  (a**b)**x  -> (a**b)**x
                    return binaryOperatorAssociativity === 1 /* Right */;
                }
                else {
                    if (ts.isBinaryExpression(emittedOperand)
                        && emittedOperand.operatorToken.kind === binaryOperator) {
                        // No need to parenthesize the right operand when the binary operator and
                        // operand are the same and one of the following:
                        //  x*(a*b)     => x*a*b
                        //  x|(a|b)     => x|a|b
                        //  x&(a&b)     => x&a&b
                        //  x^(a^b)     => x^a^b
                        if (operatorHasAssociativeProperty(binaryOperator)) {
                            return false;
                        }
                        // No need to parenthesize the right operand when the binary operator
                        // is plus (+) if both the left and right operands consist solely of either
                        // literals of the same kind or binary plus (+) expressions for literals of
                        // the same kind (recursively).
                        //  "a"+(1+2)       => "a"+(1+2)
                        //  "a"+("b"+"c")   => "a"+"b"+"c"
                        if (binaryOperator === 39 /* PlusToken */) {
                            var leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : 0 /* Unknown */;
                            if (ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) {
                                return false;
                            }
                        }
                    }
                    // No need to parenthesize the right operand when the operand is right
                    // associative:
                    //  x/(a**b)    -> x/a**b
                    //  x**(a**b)   -> x**a**b
                    //
                    // Parentheses are needed for the right operand when the operand is left
                    // associative:
                    //  x/(a*b)     -> x/(a*b)
                    //  x**(a/b)    -> x**(a/b)
                    var operandAssociativity = ts.getExpressionAssociativity(emittedOperand);
                    return operandAssociativity === 0 /* Left */;
                }
        }
    }
    /**
     * Determines whether a binary operator is mathematically associative.
     *
     * @param binaryOperator The binary operator.
     */
    function operatorHasAssociativeProperty(binaryOperator) {
        // The following operators are associative in JavaScript:
        //  (a*b)*c     -> a*(b*c)  -> a*b*c
        //  (a|b)|c     -> a|(b|c)  -> a|b|c
        //  (a&b)&c     -> a&(b&c)  -> a&b&c
        //  (a^b)^c     -> a^(b^c)  -> a^b^c
        //
        // While addition is associative in mathematics, JavaScript's `+` is not
        // guaranteed to be associative as it is overloaded with string concatenation.
        return binaryOperator === 41 /* AsteriskToken */
            || binaryOperator === 51 /* BarToken */
            || binaryOperator === 50 /* AmpersandToken */
            || binaryOperator === 52 /* CaretToken */;
    }
    /**
     * This function determines whether an expression consists of a homogeneous set of
     * literal expressions or binary plus expressions that all share the same literal kind.
     * It is used to determine whether the right-hand operand of a binary plus expression can be
     * emitted without parentheses.
     */
    function getLiteralKindOfBinaryPlusOperand(node) {
        node = ts.skipPartiallyEmittedExpressions(node);
        if (ts.isLiteralKind(node.kind)) {
            return node.kind;
        }
        if (node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 39 /* PlusToken */) {
            if (node.cachedLiteralKind !== undefined) {
                return node.cachedLiteralKind;
            }
            var leftKind = getLiteralKindOfBinaryPlusOperand(node.left);
            var literalKind = ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(node.right) ? leftKind :
                0 /* Unknown */;
            node.cachedLiteralKind = literalKind;
            return literalKind;
        }
        return 0 /* Unknown */;
    }
    function parenthesizeForConditionalHead(condition) {
        var conditionalPrecedence = ts.getOperatorPrecedence(210 /* ConditionalExpression */, 57 /* QuestionToken */);
        var emittedCondition = ts.skipPartiallyEmittedExpressions(condition);
        var conditionPrecedence = ts.getExpressionPrecedence(emittedCondition);
        if (ts.compareValues(conditionPrecedence, conditionalPrecedence) !== 1 /* GreaterThan */) {
            return ts.createParen(condition);
        }
        return condition;
    }
    ts.parenthesizeForConditionalHead = parenthesizeForConditionalHead;
    function parenthesizeSubexpressionOfConditionalExpression(e) {
        // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions
        // so in case when comma expression is introduced as a part of previous transformations
        // if should be wrapped in parens since comma operator has the lowest precedence
        var emittedExpression = ts.skipPartiallyEmittedExpressions(e);
        return isCommaSequence(emittedExpression)
            ? ts.createParen(e)
            : e;
    }
    ts.parenthesizeSubexpressionOfConditionalExpression = parenthesizeSubexpressionOfConditionalExpression;
    /**
     *  [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but
     *  has a lookahead restriction for `function`, `async function`, and `class`.
     *
     * Basically, that means we need to parenthesize in the following cases:
     *
     * - BinaryExpression of CommaToken
     * - CommaList (synthetic list of multiple comma expressions)
     * - FunctionExpression
     * - ClassExpression
     */
    function parenthesizeDefaultExpression(e) {
        var check = ts.skipPartiallyEmittedExpressions(e);
        var needsParens = isCommaSequence(check);
        if (!needsParens) {
            switch (getLeftmostExpression(check, /*stopAtCallExpression*/ false).kind) {
                case 214 /* ClassExpression */:
                case 201 /* FunctionExpression */:
                    needsParens = true;
            }
        }
        return needsParens ? ts.createParen(e) : e;
    }
    ts.parenthesizeDefaultExpression = parenthesizeDefaultExpression;
    /**
     * Wraps an expression in parentheses if it is needed in order to use the expression
     * as the expression of a NewExpression node.
     *
     * @param expression The Expression node.
     */
    function parenthesizeForNew(expression) {
        var leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true);
        switch (leftmostExpr.kind) {
            case 196 /* CallExpression */:
                return ts.createParen(expression);
            case 197 /* NewExpression */:
                return !leftmostExpr.arguments
                    ? ts.createParen(expression)
                    : expression;
        }
        return parenthesizeForAccess(expression);
    }
    ts.parenthesizeForNew = parenthesizeForNew;
    /**
     * Wraps an expression in parentheses if it is needed in order to use the expression for
     * property or element access.
     *
     * @param expr The expression node.
     */
    function parenthesizeForAccess(expression) {
        // isLeftHandSideExpression is almost the correct criterion for when it is not necessary
        // to parenthesize the expression before a dot. The known exception is:
        //
        //    NewExpression:
        //       new C.x        -> not the same as (new C).x
        //
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        if (ts.isLeftHandSideExpression(emittedExpression)
            && (emittedExpression.kind !== 197 /* NewExpression */ || emittedExpression.arguments)) {
            return expression;
        }
        return ts.setTextRange(ts.createParen(expression), expression);
    }
    ts.parenthesizeForAccess = parenthesizeForAccess;
    function parenthesizePostfixOperand(operand) {
        return ts.isLeftHandSideExpression(operand)
            ? operand
            : ts.setTextRange(ts.createParen(operand), operand);
    }
    ts.parenthesizePostfixOperand = parenthesizePostfixOperand;
    function parenthesizePrefixOperand(operand) {
        return ts.isUnaryExpression(operand)
            ? operand
            : ts.setTextRange(ts.createParen(operand), operand);
    }
    ts.parenthesizePrefixOperand = parenthesizePrefixOperand;
    function parenthesizeListElements(elements) {
        var result;
        for (var i = 0; i < elements.length; i++) {
            var element = parenthesizeExpressionForList(elements[i]);
            if (result !== undefined || element !== elements[i]) {
                if (result === undefined) {
                    result = elements.slice(0, i);
                }
                result.push(element);
            }
        }
        if (result !== undefined) {
            return ts.setTextRange(ts.createNodeArray(result, elements.hasTrailingComma), elements);
        }
        return elements;
    }
    ts.parenthesizeListElements = parenthesizeListElements;
    function parenthesizeExpressionForList(expression) {
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        var expressionPrecedence = ts.getExpressionPrecedence(emittedExpression);
        var commaPrecedence = ts.getOperatorPrecedence(209 /* BinaryExpression */, 27 /* CommaToken */);
        return expressionPrecedence > commaPrecedence
            ? expression
            : ts.setTextRange(ts.createParen(expression), expression);
    }
    ts.parenthesizeExpressionForList = parenthesizeExpressionForList;
    function parenthesizeExpressionForExpressionStatement(expression) {
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        if (ts.isCallExpression(emittedExpression)) {
            var callee = emittedExpression.expression;
            var kind = ts.skipPartiallyEmittedExpressions(callee).kind;
            if (kind === 201 /* FunctionExpression */ || kind === 202 /* ArrowFunction */) {
                var mutableCall = ts.getMutableClone(emittedExpression);
                mutableCall.expression = ts.setTextRange(ts.createParen(callee), callee);
                return recreateOuterExpressions(expression, mutableCall, 8 /* PartiallyEmittedExpressions */);
            }
        }
        var leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind;
        if (leftmostExpressionKind === 193 /* ObjectLiteralExpression */ || leftmostExpressionKind === 201 /* FunctionExpression */) {
            return ts.setTextRange(ts.createParen(expression), expression);
        }
        return expression;
    }
    ts.parenthesizeExpressionForExpressionStatement = parenthesizeExpressionForExpressionStatement;
    function parenthesizeConditionalTypeMember(member) {
        return member.kind === 180 /* ConditionalType */ ? ts.createParenthesizedType(member) : member;
    }
    ts.parenthesizeConditionalTypeMember = parenthesizeConditionalTypeMember;
    function parenthesizeElementTypeMember(member) {
        switch (member.kind) {
            case 178 /* UnionType */:
            case 179 /* IntersectionType */:
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
                return ts.createParenthesizedType(member);
        }
        return parenthesizeConditionalTypeMember(member);
    }
    ts.parenthesizeElementTypeMember = parenthesizeElementTypeMember;
    function parenthesizeArrayTypeMember(member) {
        switch (member.kind) {
            case 172 /* TypeQuery */:
            case 184 /* TypeOperator */:
            case 181 /* InferType */:
                return ts.createParenthesizedType(member);
        }
        return parenthesizeElementTypeMember(member);
    }
    ts.parenthesizeArrayTypeMember = parenthesizeArrayTypeMember;
    function parenthesizeElementTypeMembers(members) {
        return ts.createNodeArray(ts.sameMap(members, parenthesizeElementTypeMember));
    }
    ts.parenthesizeElementTypeMembers = parenthesizeElementTypeMembers;
    function parenthesizeTypeParameters(typeParameters) {
        if (ts.some(typeParameters)) {
            var params = [];
            for (var i = 0; i < typeParameters.length; ++i) {
                var entry = typeParameters[i];
                params.push(i === 0 && ts.isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ?
                    ts.createParenthesizedType(entry) :
                    entry);
            }
            return ts.createNodeArray(params);
        }
    }
    ts.parenthesizeTypeParameters = parenthesizeTypeParameters;
    function getLeftmostExpression(node, stopAtCallExpressions) {
        while (true) {
            switch (node.kind) {
                case 208 /* PostfixUnaryExpression */:
                    node = node.operand;
                    continue;
                case 209 /* BinaryExpression */:
                    node = node.left;
                    continue;
                case 210 /* ConditionalExpression */:
                    node = node.condition;
                    continue;
                case 198 /* TaggedTemplateExpression */:
                    node = node.tag;
                    continue;
                case 196 /* CallExpression */:
                    if (stopAtCallExpressions) {
                        return node;
                    }
                // falls through
                case 217 /* AsExpression */:
                case 195 /* ElementAccessExpression */:
                case 194 /* PropertyAccessExpression */:
                case 218 /* NonNullExpression */:
                case 326 /* PartiallyEmittedExpression */:
                    node = node.expression;
                    continue;
            }
            return node;
        }
    }
    ts.getLeftmostExpression = getLeftmostExpression;
    function parenthesizeConciseBody(body) {
        if (!ts.isBlock(body) && (isCommaSequence(body) || getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === 193 /* ObjectLiteralExpression */)) {
            return ts.setTextRange(ts.createParen(body), body);
        }
        return body;
    }
    ts.parenthesizeConciseBody = parenthesizeConciseBody;
    function isCommaSequence(node) {
        return node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 27 /* CommaToken */ ||
            node.kind === 327 /* CommaListExpression */;
    }
    ts.isCommaSequence = isCommaSequence;
    var OuterExpressionKinds;
    (function (OuterExpressionKinds) {
        OuterExpressionKinds[OuterExpressionKinds["Parentheses"] = 1] = "Parentheses";
        OuterExpressionKinds[OuterExpressionKinds["TypeAssertions"] = 2] = "TypeAssertions";
        OuterExpressionKinds[OuterExpressionKinds["NonNullAssertions"] = 4] = "NonNullAssertions";
        OuterExpressionKinds[OuterExpressionKinds["PartiallyEmittedExpressions"] = 8] = "PartiallyEmittedExpressions";
        OuterExpressionKinds[OuterExpressionKinds["Assertions"] = 6] = "Assertions";
        OuterExpressionKinds[OuterExpressionKinds["All"] = 15] = "All";
    })(OuterExpressionKinds = ts.OuterExpressionKinds || (ts.OuterExpressionKinds = {}));
    function isOuterExpression(node, kinds) {
        if (kinds === void 0) { kinds = 15 /* All */; }
        switch (node.kind) {
            case 200 /* ParenthesizedExpression */:
                return (kinds & 1 /* Parentheses */) !== 0;
            case 199 /* TypeAssertionExpression */:
            case 217 /* AsExpression */:
                return (kinds & 2 /* TypeAssertions */) !== 0;
            case 218 /* NonNullExpression */:
                return (kinds & 4 /* NonNullAssertions */) !== 0;
            case 326 /* PartiallyEmittedExpression */:
                return (kinds & 8 /* PartiallyEmittedExpressions */) !== 0;
        }
        return false;
    }
    ts.isOuterExpression = isOuterExpression;
    function skipOuterExpressions(node, kinds) {
        if (kinds === void 0) { kinds = 15 /* All */; }
        while (isOuterExpression(node, kinds)) {
            node = node.expression;
        }
        return node;
    }
    ts.skipOuterExpressions = skipOuterExpressions;
    function skipAssertions(node) {
        return skipOuterExpressions(node, 6 /* Assertions */);
    }
    ts.skipAssertions = skipAssertions;
    function updateOuterExpression(outerExpression, expression) {
        switch (outerExpression.kind) {
            case 200 /* ParenthesizedExpression */: return ts.updateParen(outerExpression, expression);
            case 199 /* TypeAssertionExpression */: return ts.updateTypeAssertion(outerExpression, outerExpression.type, expression);
            case 217 /* AsExpression */: return ts.updateAsExpression(outerExpression, expression, outerExpression.type);
            case 218 /* NonNullExpression */: return ts.updateNonNullExpression(outerExpression, expression);
            case 326 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(outerExpression, expression);
        }
    }
    /**
     * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions.
     *
     * A parenthesized expression can be ignored when all of the following are true:
     *
     * - It's `pos` and `end` are not -1
     * - It does not have a custom source map range
     * - It does not have a custom comment range
     * - It does not have synthetic leading or trailing comments
     *
     * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around
     * the expression to maintain precedence, a new parenthesized expression should be created automatically when
     * the containing expression is created/updated.
     */
    function isIgnorableParen(node) {
        return node.kind === 200 /* ParenthesizedExpression */
            && ts.nodeIsSynthesized(node)
            && ts.nodeIsSynthesized(ts.getSourceMapRange(node))
            && ts.nodeIsSynthesized(ts.getCommentRange(node))
            && !ts.some(ts.getSyntheticLeadingComments(node))
            && !ts.some(ts.getSyntheticTrailingComments(node));
    }
    function recreateOuterExpressions(outerExpression, innerExpression, kinds) {
        if (kinds === void 0) { kinds = 15 /* All */; }
        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
            return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
        }
        return innerExpression;
    }
    ts.recreateOuterExpressions = recreateOuterExpressions;
    function startOnNewLine(node) {
        return ts.setStartsOnNewLine(node, /*newLine*/ true);
    }
    ts.startOnNewLine = startOnNewLine;
    function getExternalHelpersModuleName(node) {
        var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
        var emitNode = parseNode && parseNode.emitNode;
        return emitNode && emitNode.externalHelpersModuleName;
    }
    ts.getExternalHelpersModuleName = getExternalHelpersModuleName;
    function hasRecordedExternalHelpers(sourceFile) {
        var parseNode = ts.getOriginalNode(sourceFile, ts.isSourceFile);
        var emitNode = parseNode && parseNode.emitNode;
        return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers);
    }
    ts.hasRecordedExternalHelpers = hasRecordedExternalHelpers;
    function createExternalHelpersImportDeclarationIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar, hasImportDefault) {
        if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(sourceFile, compilerOptions)) {
            var namedBindings = void 0;
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            if (moduleKind >= ts.ModuleKind.ES2015 && moduleKind <= ts.ModuleKind.ESNext) {
                // use named imports
                var helpers = ts.getEmitHelpers(sourceFile);
                if (helpers) {
                    var helperNames = [];
                    for (var _i = 0, helpers_2 = helpers; _i < helpers_2.length; _i++) {
                        var helper = helpers_2[_i];
                        if (!helper.scoped) {
                            var importName = helper.importName;
                            if (importName) {
                                ts.pushIfUnique(helperNames, importName);
                            }
                        }
                    }
                    if (ts.some(helperNames)) {
                        helperNames.sort(ts.compareStringsCaseSensitive);
                        // Alias the imports if the names are used somewhere in the file.
                        // NOTE: We don't need to care about global import collisions as this is a module.
                        namedBindings = ts.createNamedImports(ts.map(helperNames, function (name) { return ts.isFileLevelUniqueName(sourceFile, name)
                            ? ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(name))
                            : ts.createImportSpecifier(ts.createIdentifier(name), getUnscopedHelperName(name)); }));
                        var parseNode = ts.getOriginalNode(sourceFile, ts.isSourceFile);
                        var emitNode = ts.getOrCreateEmitNode(parseNode);
                        emitNode.externalHelpers = true;
                    }
                }
            }
            else {
                // use a namespace import
                var externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar || hasImportDefault);
                if (externalHelpersModuleName) {
                    namedBindings = ts.createNamespaceImport(externalHelpersModuleName);
                }
            }
            if (namedBindings) {
                var externalHelpersImportDeclaration = ts.createImportDeclaration(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, namedBindings), ts.createLiteral(ts.externalHelpersModuleNameText));
                ts.addEmitFlags(externalHelpersImportDeclaration, 67108864 /* NeverApplyImportHelper */);
                return externalHelpersImportDeclaration;
            }
        }
    }
    ts.createExternalHelpersImportDeclarationIfNeeded = createExternalHelpersImportDeclarationIfNeeded;
    function getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions, hasExportStarsToExportValues, hasImportStarOrImportDefault) {
        if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(node, compilerOptions)) {
            var externalHelpersModuleName = getExternalHelpersModuleName(node);
            if (externalHelpersModuleName) {
                return externalHelpersModuleName;
            }
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            var create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault))
                && moduleKind !== ts.ModuleKind.System
                && moduleKind < ts.ModuleKind.ES2015;
            if (!create) {
                var helpers = ts.getEmitHelpers(node);
                if (helpers) {
                    for (var _i = 0, helpers_3 = helpers; _i < helpers_3.length; _i++) {
                        var helper = helpers_3[_i];
                        if (!helper.scoped) {
                            create = true;
                            break;
                        }
                    }
                }
            }
            if (create) {
                var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
                var emitNode = ts.getOrCreateEmitNode(parseNode);
                return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = ts.createUniqueName(ts.externalHelpersModuleNameText));
            }
        }
    }
    ts.getOrCreateExternalHelpersModuleNameIfNeeded = getOrCreateExternalHelpersModuleNameIfNeeded;
    /**
     * Get the name of that target module from an import or export declaration
     */
    function getLocalNameForExternalImport(node, sourceFile) {
        var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
        if (namespaceDeclaration && !ts.isDefaultImport(node)) {
            var name = namespaceDeclaration.name;
            return ts.isGeneratedIdentifier(name) ? name : ts.createIdentifier(ts.getSourceTextOfNodeFromSourceFile(sourceFile, name) || ts.idText(name));
        }
        if (node.kind === 254 /* ImportDeclaration */ && node.importClause) {
            return ts.getGeneratedNameForNode(node);
        }
        if (node.kind === 260 /* ExportDeclaration */ && node.moduleSpecifier) {
            return ts.getGeneratedNameForNode(node);
        }
        return undefined;
    }
    ts.getLocalNameForExternalImport = getLocalNameForExternalImport;
    /**
     * Get the name of a target module from an import/export declaration as should be written in the emitted output.
     * The emitted output name can be different from the input if:
     *  1. The module has a /// <amd-module name="<new name>" />
     *  2. --out or --outFile is used, making the name relative to the rootDir
     *  3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System).
     * Otherwise, a new StringLiteral node representing the module name will be returned.
     */
    function getExternalModuleNameLiteral(importNode, sourceFile, host, resolver, compilerOptions) {
        var moduleName = ts.getExternalModuleName(importNode); // TODO: GH#18217
        if (moduleName.kind === 10 /* StringLiteral */) {
            return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions)
                || tryRenameExternalModule(moduleName, sourceFile)
                || ts.getSynthesizedClone(moduleName);
        }
        return undefined;
    }
    ts.getExternalModuleNameLiteral = getExternalModuleNameLiteral;
    /**
     * Some bundlers (SystemJS builder) sometimes want to rename dependencies.
     * Here we check if alternative name was provided for a given moduleName and return it if possible.
     */
    function tryRenameExternalModule(moduleName, sourceFile) {
        var rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text);
        return rename && ts.createLiteral(rename);
    }
    /**
     * Get the name of a module as should be written in the emitted output.
     * The emitted output name can be different from the input if:
     *  1. The module has a /// <amd-module name="<new name>" />
     *  2. --out or --outFile is used, making the name relative to the rootDir
     * Otherwise, a new StringLiteral node representing the module name will be returned.
     */
    function tryGetModuleNameFromFile(file, host, options) {
        if (!file) {
            return undefined;
        }
        if (file.moduleName) {
            return ts.createLiteral(file.moduleName);
        }
        if (!file.isDeclarationFile && (options.out || options.outFile)) {
            return ts.createLiteral(ts.getExternalModuleNameFromPath(host, file.fileName));
        }
        return undefined;
    }
    ts.tryGetModuleNameFromFile = tryGetModuleNameFromFile;
    function tryGetModuleNameFromDeclaration(declaration, host, resolver, compilerOptions) {
        return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions);
    }
    /**
     * Gets the initializer of an BindingOrAssignmentElement.
     */
    function getInitializerOfBindingOrAssignmentElement(bindingElement) {
        if (ts.isDeclarationBindingElement(bindingElement)) {
            // `1` in `let { a = 1 } = ...`
            // `1` in `let { a: b = 1 } = ...`
            // `1` in `let { a: {b} = 1 } = ...`
            // `1` in `let { a: [b] = 1 } = ...`
            // `1` in `let [a = 1] = ...`
            // `1` in `let [{a} = 1] = ...`
            // `1` in `let [[a] = 1] = ...`
            return bindingElement.initializer;
        }
        if (ts.isPropertyAssignment(bindingElement)) {
            // `1` in `({ a: b = 1 } = ...)`
            // `1` in `({ a: {b} = 1 } = ...)`
            // `1` in `({ a: [b] = 1 } = ...)`
            var initializer = bindingElement.initializer;
            return ts.isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true)
                ? initializer.right
                : undefined;
        }
        if (ts.isShorthandPropertyAssignment(bindingElement)) {
            // `1` in `({ a = 1 } = ...)`
            return bindingElement.objectAssignmentInitializer;
        }
        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
            // `1` in `[a = 1] = ...`
            // `1` in `[{a} = 1] = ...`
            // `1` in `[[a] = 1] = ...`
            return bindingElement.right;
        }
        if (ts.isSpreadElement(bindingElement)) {
            // Recovery consistent with existing emit.
            return getInitializerOfBindingOrAssignmentElement(bindingElement.expression);
        }
    }
    ts.getInitializerOfBindingOrAssignmentElement = getInitializerOfBindingOrAssignmentElement;
    /**
     * Gets the name of an BindingOrAssignmentElement.
     */
    function getTargetOfBindingOrAssignmentElement(bindingElement) {
        if (ts.isDeclarationBindingElement(bindingElement)) {
            // `a` in `let { a } = ...`
            // `a` in `let { a = 1 } = ...`
            // `b` in `let { a: b } = ...`
            // `b` in `let { a: b = 1 } = ...`
            // `a` in `let { ...a } = ...`
            // `{b}` in `let { a: {b} } = ...`
            // `{b}` in `let { a: {b} = 1 } = ...`
            // `[b]` in `let { a: [b] } = ...`
            // `[b]` in `let { a: [b] = 1 } = ...`
            // `a` in `let [a] = ...`
            // `a` in `let [a = 1] = ...`
            // `a` in `let [...a] = ...`
            // `{a}` in `let [{a}] = ...`
            // `{a}` in `let [{a} = 1] = ...`
            // `[a]` in `let [[a]] = ...`
            // `[a]` in `let [[a] = 1] = ...`
            return bindingElement.name;
        }
        if (ts.isObjectLiteralElementLike(bindingElement)) {
            switch (bindingElement.kind) {
                case 281 /* PropertyAssignment */:
                    // `b` in `({ a: b } = ...)`
                    // `b` in `({ a: b = 1 } = ...)`
                    // `{b}` in `({ a: {b} } = ...)`
                    // `{b}` in `({ a: {b} = 1 } = ...)`
                    // `[b]` in `({ a: [b] } = ...)`
                    // `[b]` in `({ a: [b] = 1 } = ...)`
                    // `b.c` in `({ a: b.c } = ...)`
                    // `b.c` in `({ a: b.c = 1 } = ...)`
                    // `b[0]` in `({ a: b[0] } = ...)`
                    // `b[0]` in `({ a: b[0] = 1 } = ...)`
                    return getTargetOfBindingOrAssignmentElement(bindingElement.initializer);
                case 282 /* ShorthandPropertyAssignment */:
                    // `a` in `({ a } = ...)`
                    // `a` in `({ a = 1 } = ...)`
                    return bindingElement.name;
                case 283 /* SpreadAssignment */:
                    // `a` in `({ ...a } = ...)`
                    return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
            }
            // no target
            return undefined;
        }
        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
            // `a` in `[a = 1] = ...`
            // `{a}` in `[{a} = 1] = ...`
            // `[a]` in `[[a] = 1] = ...`
            // `a.b` in `[a.b = 1] = ...`
            // `a[0]` in `[a[0] = 1] = ...`
            return getTargetOfBindingOrAssignmentElement(bindingElement.left);
        }
        if (ts.isSpreadElement(bindingElement)) {
            // `a` in `[...a] = ...`
            return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
        }
        // `a` in `[a] = ...`
        // `{a}` in `[{a}] = ...`
        // `[a]` in `[[a]] = ...`
        // `a.b` in `[a.b] = ...`
        // `a[0]` in `[a[0]] = ...`
        return bindingElement;
    }
    ts.getTargetOfBindingOrAssignmentElement = getTargetOfBindingOrAssignmentElement;
    /**
     * Determines whether an BindingOrAssignmentElement is a rest element.
     */
    function getRestIndicatorOfBindingOrAssignmentElement(bindingElement) {
        switch (bindingElement.kind) {
            case 156 /* Parameter */:
            case 191 /* BindingElement */:
                // `...` in `let [...a] = ...`
                return bindingElement.dotDotDotToken;
            case 213 /* SpreadElement */:
            case 283 /* SpreadAssignment */:
                // `...` in `[...a] = ...`
                return bindingElement;
        }
        return undefined;
    }
    ts.getRestIndicatorOfBindingOrAssignmentElement = getRestIndicatorOfBindingOrAssignmentElement;
    /**
     * Gets the property name of a BindingOrAssignmentElement
     */
    function getPropertyNameOfBindingOrAssignmentElement(bindingElement) {
        var propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement);
        ts.Debug.assert(!!propertyName || ts.isSpreadAssignment(bindingElement), "Invalid property name for binding element.");
        return propertyName;
    }
    ts.getPropertyNameOfBindingOrAssignmentElement = getPropertyNameOfBindingOrAssignmentElement;
    function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement) {
        switch (bindingElement.kind) {
            case 191 /* BindingElement */:
                // `a` in `let { a: b } = ...`
                // `[a]` in `let { [a]: b } = ...`
                // `"a"` in `let { "a": b } = ...`
                // `1` in `let { 1: b } = ...`
                if (bindingElement.propertyName) {
                    var propertyName = bindingElement.propertyName;
                    if (ts.isPrivateIdentifier(propertyName)) {
                        return ts.Debug.failBadSyntaxKind(propertyName);
                    }
                    return ts.isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
                        ? propertyName.expression
                        : propertyName;
                }
                break;
            case 281 /* PropertyAssignment */:
                // `a` in `({ a: b } = ...)`
                // `[a]` in `({ [a]: b } = ...)`
                // `"a"` in `({ "a": b } = ...)`
                // `1` in `({ 1: b } = ...)`
                if (bindingElement.name) {
                    var propertyName = bindingElement.name;
                    if (ts.isPrivateIdentifier(propertyName)) {
                        return ts.Debug.failBadSyntaxKind(propertyName);
                    }
                    return ts.isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
                        ? propertyName.expression
                        : propertyName;
                }
                break;
            case 283 /* SpreadAssignment */:
                // `a` in `({ ...a } = ...)`
                if (bindingElement.name && ts.isPrivateIdentifier(bindingElement.name)) {
                    return ts.Debug.failBadSyntaxKind(bindingElement.name);
                }
                return bindingElement.name;
        }
        var target = getTargetOfBindingOrAssignmentElement(bindingElement);
        if (target && ts.isPropertyName(target)) {
            return target;
        }
    }
    ts.tryGetPropertyNameOfBindingOrAssignmentElement = tryGetPropertyNameOfBindingOrAssignmentElement;
    function isStringOrNumericLiteral(node) {
        var kind = node.kind;
        return kind === 10 /* StringLiteral */
            || kind === 8 /* NumericLiteral */;
    }
    /**
     * Gets the elements of a BindingOrAssignmentPattern
     */
    function getElementsOfBindingOrAssignmentPattern(name) {
        switch (name.kind) {
            case 189 /* ObjectBindingPattern */:
            case 190 /* ArrayBindingPattern */:
            case 192 /* ArrayLiteralExpression */:
                // `a` in `{a}`
                // `a` in `[a]`
                return name.elements;
            case 193 /* ObjectLiteralExpression */:
                // `a` in `{a}`
                return name.properties;
        }
    }
    ts.getElementsOfBindingOrAssignmentPattern = getElementsOfBindingOrAssignmentPattern;
    function convertToArrayAssignmentElement(element) {
        if (ts.isBindingElement(element)) {
            if (element.dotDotDotToken) {
                ts.Debug.assertNode(element.name, ts.isIdentifier);
                return ts.setOriginalNode(ts.setTextRange(ts.createSpread(element.name), element), element);
            }
            var expression = convertToAssignmentElementTarget(element.name);
            return element.initializer
                ? ts.setOriginalNode(ts.setTextRange(ts.createAssignment(expression, element.initializer), element), element)
                : expression;
        }
        ts.Debug.assertNode(element, ts.isExpression);
        return element;
    }
    ts.convertToArrayAssignmentElement = convertToArrayAssignmentElement;
    function convertToObjectAssignmentElement(element) {
        if (ts.isBindingElement(element)) {
            if (element.dotDotDotToken) {
                ts.Debug.assertNode(element.name, ts.isIdentifier);
                return ts.setOriginalNode(ts.setTextRange(ts.createSpreadAssignment(element.name), element), element);
            }
            if (element.propertyName) {
                var expression = convertToAssignmentElementTarget(element.name);
                return ts.setOriginalNode(ts.setTextRange(ts.createPropertyAssignment(element.propertyName, element.initializer ? ts.createAssignment(expression, element.initializer) : expression), element), element);
            }
            ts.Debug.assertNode(element.name, ts.isIdentifier);
            return ts.setOriginalNode(ts.setTextRange(ts.createShorthandPropertyAssignment(element.name, element.initializer), element), element);
        }
        ts.Debug.assertNode(element, ts.isObjectLiteralElementLike);
        return element;
    }
    ts.convertToObjectAssignmentElement = convertToObjectAssignmentElement;
    function convertToAssignmentPattern(node) {
        switch (node.kind) {
            case 190 /* ArrayBindingPattern */:
            case 192 /* ArrayLiteralExpression */:
                return convertToArrayAssignmentPattern(node);
            case 189 /* ObjectBindingPattern */:
            case 193 /* ObjectLiteralExpression */:
                return convertToObjectAssignmentPattern(node);
        }
    }
    ts.convertToAssignmentPattern = convertToAssignmentPattern;
    function convertToObjectAssignmentPattern(node) {
        if (ts.isObjectBindingPattern(node)) {
            return ts.setOriginalNode(ts.setTextRange(ts.createObjectLiteral(ts.map(node.elements, convertToObjectAssignmentElement)), node), node);
        }
        ts.Debug.assertNode(node, ts.isObjectLiteralExpression);
        return node;
    }
    ts.convertToObjectAssignmentPattern = convertToObjectAssignmentPattern;
    function convertToArrayAssignmentPattern(node) {
        if (ts.isArrayBindingPattern(node)) {
            return ts.setOriginalNode(ts.setTextRange(ts.createArrayLiteral(ts.map(node.elements, convertToArrayAssignmentElement)), node), node);
        }
        ts.Debug.assertNode(node, ts.isArrayLiteralExpression);
        return node;
    }
    ts.convertToArrayAssignmentPattern = convertToArrayAssignmentPattern;
    function convertToAssignmentElementTarget(node) {
        if (ts.isBindingPattern(node)) {
            return convertToAssignmentPattern(node);
        }
        ts.Debug.assertNode(node, ts.isExpression);
        return node;
    }
    ts.convertToAssignmentElementTarget = convertToAssignmentElementTarget;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var isTypeNodeOrTypeParameterDeclaration = ts.or(ts.isTypeNode, ts.isTypeParameterDeclaration);
    function visitNode(node, visitor, test, lift) {
        if (node === undefined || visitor === undefined) {
            return node;
        }
        ts.aggregateTransformFlags(node);
        var visited = visitor(node);
        if (visited === node) {
            return node;
        }
        var visitedNode;
        if (visited === undefined) {
            return undefined;
        }
        else if (ts.isArray(visited)) {
            visitedNode = (lift || extractSingleNode)(visited);
        }
        else {
            visitedNode = visited;
        }
        ts.Debug.assertNode(visitedNode, test);
        ts.aggregateTransformFlags(visitedNode);
        return visitedNode;
    }
    ts.visitNode = visitNode;
    /**
     * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
     *
     * @param nodes The NodeArray to visit.
     * @param visitor The callback used to visit a Node.
     * @param test A node test to execute for each node.
     * @param start An optional value indicating the starting offset at which to start visiting.
     * @param count An optional value indicating the maximum number of nodes to visit.
     */
    function visitNodes(nodes, visitor, test, start, count) {
        if (nodes === undefined || visitor === undefined) {
            return nodes;
        }
        var updated;
        // Ensure start and count have valid values
        var length = nodes.length;
        if (start === undefined || start < 0) {
            start = 0;
        }
        if (count === undefined || count > length - start) {
            count = length - start;
        }
        if (start > 0 || count < length) {
            // If we are not visiting all of the original nodes, we must always create a new array.
            // Since this is a fragment of a node array, we do not copy over the previous location
            // and will only copy over `hasTrailingComma` if we are including the last element.
            updated = ts.createNodeArray([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
        }
        // Visit each original node.
        for (var i = 0; i < count; i++) {
            var node = nodes[i + start];
            ts.aggregateTransformFlags(node);
            var visited = node !== undefined ? visitor(node) : undefined;
            if (updated !== undefined || visited === undefined || visited !== node) {
                if (updated === undefined) {
                    // Ensure we have a copy of `nodes`, up to the current index.
                    updated = ts.createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma);
                    ts.setTextRange(updated, nodes);
                }
                if (visited) {
                    if (ts.isArray(visited)) {
                        for (var _i = 0, visited_1 = visited; _i < visited_1.length; _i++) {
                            var visitedNode = visited_1[_i];
                            ts.Debug.assertNode(visitedNode, test);
                            ts.aggregateTransformFlags(visitedNode);
                            updated.push(visitedNode);
                        }
                    }
                    else {
                        ts.Debug.assertNode(visited, test);
                        ts.aggregateTransformFlags(visited);
                        updated.push(visited);
                    }
                }
            }
        }
        return updated || nodes;
    }
    ts.visitNodes = visitNodes;
    /**
     * Starts a new lexical environment and visits a statement list, ending the lexical environment
     * and merging hoisted declarations upon completion.
     */
    function visitLexicalEnvironment(statements, visitor, context, start, ensureUseStrict) {
        context.startLexicalEnvironment();
        statements = visitNodes(statements, visitor, ts.isStatement, start);
        if (ensureUseStrict)
            statements = ts.ensureUseStrict(statements); // eslint-disable-line @typescript-eslint/no-unnecessary-qualifier
        return ts.mergeLexicalEnvironment(statements, context.endLexicalEnvironment());
    }
    ts.visitLexicalEnvironment = visitLexicalEnvironment;
    function visitParameterList(nodes, visitor, context, nodesVisitor) {
        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
        var updated;
        context.startLexicalEnvironment();
        if (nodes) {
            context.setLexicalEnvironmentFlags(1 /* InParameters */, true);
            updated = nodesVisitor(nodes, visitor, ts.isParameterDeclaration);
            // As of ES2015, any runtime execution of that occurs in for a parameter (such as evaluating an
            // initializer or a binding pattern), occurs in its own lexical scope. As a result, any expression
            // that we might transform that introduces a temporary variable would fail as the temporary variable
            // exists in a different lexical scope. To address this, we move any binding patterns and initializers
            // in a parameter list to the body if we detect a variable being hoisted while visiting a parameter list
            // when the emit target is greater than ES2015.
            if (context.getLexicalEnvironmentFlags() & 2 /* VariablesHoistedInParameters */ &&
                ts.getEmitScriptTarget(context.getCompilerOptions()) >= 2 /* ES2015 */) {
                updated = addDefaultValueAssignmentsIfNeeded(updated, context);
            }
            context.setLexicalEnvironmentFlags(1 /* InParameters */, false);
        }
        context.suspendLexicalEnvironment();
        return updated;
    }
    ts.visitParameterList = visitParameterList;
    function addDefaultValueAssignmentsIfNeeded(parameters, context) {
        var result;
        for (var i = 0; i < parameters.length; i++) {
            var parameter = parameters[i];
            var updated = addDefaultValueAssignmentIfNeeded(parameter, context);
            if (result || updated !== parameter) {
                if (!result)
                    result = parameters.slice(0, i);
                result[i] = updated;
            }
        }
        if (result) {
            return ts.setTextRange(ts.createNodeArray(result, parameters.hasTrailingComma), parameters);
        }
        return parameters;
    }
    function addDefaultValueAssignmentIfNeeded(parameter, context) {
        // A rest parameter cannot have a binding pattern or an initializer,
        // so let's just ignore it.
        return parameter.dotDotDotToken ? parameter :
            ts.isBindingPattern(parameter.name) ? addDefaultValueAssignmentForBindingPattern(parameter, context) :
                parameter.initializer ? addDefaultValueAssignmentForInitializer(parameter, parameter.name, parameter.initializer, context) :
                    parameter;
    }
    function addDefaultValueAssignmentForBindingPattern(parameter, context) {
        context.addInitializationStatement(ts.createVariableStatement(
        /*modifiers*/ undefined, ts.createVariableDeclarationList([
            ts.createVariableDeclaration(parameter.name, parameter.type, parameter.initializer ?
                ts.createConditional(ts.createStrictEquality(ts.getGeneratedNameForNode(parameter), ts.createVoidZero()), parameter.initializer, ts.getGeneratedNameForNode(parameter)) :
                ts.getGeneratedNameForNode(parameter)),
        ])));
        return ts.updateParameter(parameter, parameter.decorators, parameter.modifiers, parameter.dotDotDotToken, ts.getGeneratedNameForNode(parameter), parameter.questionToken, parameter.type, 
        /*initializer*/ undefined);
    }
    function addDefaultValueAssignmentForInitializer(parameter, name, initializer, context) {
        context.addInitializationStatement(ts.createIf(ts.createTypeCheck(ts.getSynthesizedClone(name), "undefined"), ts.setEmitFlags(ts.setTextRange(ts.createBlock([
            ts.createExpressionStatement(ts.setEmitFlags(ts.setTextRange(ts.createAssignment(ts.setEmitFlags(ts.getMutableClone(name), 48 /* NoSourceMap */), ts.setEmitFlags(initializer, 48 /* NoSourceMap */ | ts.getEmitFlags(initializer) | 1536 /* NoComments */)), parameter), 1536 /* NoComments */))
        ]), parameter), 1 /* SingleLine */ | 32 /* NoTrailingSourceMap */ | 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */)));
        return ts.updateParameter(parameter, parameter.decorators, parameter.modifiers, parameter.dotDotDotToken, parameter.name, parameter.questionToken, parameter.type, 
        /*initializer*/ undefined);
    }
    function visitFunctionBody(node, visitor, context) {
        context.resumeLexicalEnvironment();
        var updated = visitNode(node, visitor, ts.isConciseBody);
        var declarations = context.endLexicalEnvironment();
        if (ts.some(declarations)) {
            var block = ts.convertToFunctionBody(updated);
            var statements = ts.mergeLexicalEnvironment(block.statements, declarations);
            return ts.updateBlock(block, statements);
        }
        return updated;
    }
    ts.visitFunctionBody = visitFunctionBody;
    function visitEachChild(node, visitor, context, nodesVisitor, tokenVisitor) {
        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
        if (node === undefined) {
            return undefined;
        }
        var kind = node.kind;
        // No need to visit nodes with no children.
        if ((kind > 0 /* FirstToken */ && kind <= 152 /* LastToken */) || kind === 183 /* ThisType */) {
            return node;
        }
        switch (kind) {
            // Names
            case 75 /* Identifier */:
                return ts.updateIdentifier(node, nodesVisitor(node.typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration));
            case 153 /* QualifiedName */:
                return ts.updateQualifiedName(node, visitNode(node.left, visitor, ts.isEntityName), visitNode(node.right, visitor, ts.isIdentifier));
            case 154 /* ComputedPropertyName */:
                return ts.updateComputedPropertyName(node, visitNode(node.expression, visitor, ts.isExpression));
            // Signature elements
            case 155 /* TypeParameter */:
                return ts.updateTypeParameterDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.constraint, visitor, ts.isTypeNode), visitNode(node.default, visitor, ts.isTypeNode));
            case 156 /* Parameter */:
                return ts.updateParameter(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 157 /* Decorator */:
                return ts.updateDecorator(node, visitNode(node.expression, visitor, ts.isExpression));
            // Type elements
            case 158 /* PropertySignature */:
                return ts.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 159 /* PropertyDeclaration */:
                return ts.updateProperty(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), 
                // QuestionToken and ExclamationToken is uniqued in Property Declaration and the signature of 'updateProperty' is that too
                visitNode(node.questionToken || node.exclamationToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 160 /* MethodSignature */:
                return ts.updateMethodSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken));
            case 161 /* MethodDeclaration */:
                return ts.updateMethod(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 162 /* Constructor */:
                return ts.updateConstructor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
            case 163 /* GetAccessor */:
                return ts.updateGetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 164 /* SetAccessor */:
                return ts.updateSetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
            case 165 /* CallSignature */:
                return ts.updateCallSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 166 /* ConstructSignature */:
                return ts.updateConstructSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 167 /* IndexSignature */:
                return ts.updateIndexSignature(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            // Types
            case 168 /* TypePredicate */:
                return ts.updateTypePredicateNodeWithModifier(node, visitNode(node.assertsModifier, visitor), visitNode(node.parameterName, visitor), visitNode(node.type, visitor, ts.isTypeNode));
            case 169 /* TypeReference */:
                return ts.updateTypeReferenceNode(node, visitNode(node.typeName, visitor, ts.isEntityName), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode));
            case 170 /* FunctionType */:
                return ts.updateFunctionTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 171 /* ConstructorType */:
                return ts.updateConstructorTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 172 /* TypeQuery */:
                return ts.updateTypeQueryNode(node, visitNode(node.exprName, visitor, ts.isEntityName));
            case 173 /* TypeLiteral */:
                return ts.updateTypeLiteralNode(node, nodesVisitor(node.members, visitor, ts.isTypeElement));
            case 174 /* ArrayType */:
                return ts.updateArrayTypeNode(node, visitNode(node.elementType, visitor, ts.isTypeNode));
            case 175 /* TupleType */:
                return ts.updateTupleTypeNode(node, nodesVisitor(node.elementTypes, visitor, ts.isTypeNode));
            case 176 /* OptionalType */:
                return ts.updateOptionalTypeNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 177 /* RestType */:
                return ts.updateRestTypeNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 178 /* UnionType */:
                return ts.updateUnionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
            case 179 /* IntersectionType */:
                return ts.updateIntersectionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
            case 180 /* ConditionalType */:
                return ts.updateConditionalTypeNode(node, visitNode(node.checkType, visitor, ts.isTypeNode), visitNode(node.extendsType, visitor, ts.isTypeNode), visitNode(node.trueType, visitor, ts.isTypeNode), visitNode(node.falseType, visitor, ts.isTypeNode));
            case 181 /* InferType */:
                return ts.updateInferTypeNode(node, visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration));
            case 188 /* ImportType */:
                return ts.updateImportTypeNode(node, visitNode(node.argument, visitor, ts.isTypeNode), visitNode(node.qualifier, visitor, ts.isEntityName), visitNodes(node.typeArguments, visitor, ts.isTypeNode), node.isTypeOf);
            case 182 /* ParenthesizedType */:
                return ts.updateParenthesizedType(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 184 /* TypeOperator */:
                return ts.updateTypeOperatorNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 185 /* IndexedAccessType */:
                return ts.updateIndexedAccessTypeNode(node, visitNode(node.objectType, visitor, ts.isTypeNode), visitNode(node.indexType, visitor, ts.isTypeNode));
            case 186 /* MappedType */:
                return ts.updateMappedTypeNode(node, visitNode(node.readonlyToken, tokenVisitor, ts.isToken), visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode));
            case 187 /* LiteralType */:
                return ts.updateLiteralTypeNode(node, visitNode(node.literal, visitor, ts.isExpression));
            // Binding patterns
            case 189 /* ObjectBindingPattern */:
                return ts.updateObjectBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isBindingElement));
            case 190 /* ArrayBindingPattern */:
                return ts.updateArrayBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isArrayBindingElement));
            case 191 /* BindingElement */:
                return ts.updateBindingElement(node, visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.propertyName, visitor, ts.isPropertyName), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.initializer, visitor, ts.isExpression));
            // Expression
            case 192 /* ArrayLiteralExpression */:
                return ts.updateArrayLiteral(node, nodesVisitor(node.elements, visitor, ts.isExpression));
            case 193 /* ObjectLiteralExpression */:
                return ts.updateObjectLiteral(node, nodesVisitor(node.properties, visitor, ts.isObjectLiteralElementLike));
            case 194 /* PropertyAccessExpression */:
                if (node.flags & 32 /* OptionalChain */) {
                    return ts.updatePropertyAccessChain(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.questionDotToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier));
                }
                return ts.updatePropertyAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.name, visitor, ts.isIdentifierOrPrivateIdentifier));
            case 195 /* ElementAccessExpression */:
                if (node.flags & 32 /* OptionalChain */) {
                    return ts.updateElementAccessChain(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.questionDotToken, tokenVisitor, ts.isToken), visitNode(node.argumentExpression, visitor, ts.isExpression));
                }
                return ts.updateElementAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.argumentExpression, visitor, ts.isExpression));
            case 196 /* CallExpression */:
                if (node.flags & 32 /* OptionalChain */) {
                    return ts.updateCallChain(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.questionDotToken, tokenVisitor, ts.isToken), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
                }
                return ts.updateCall(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
            case 197 /* NewExpression */:
                return ts.updateNew(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
            case 198 /* TaggedTemplateExpression */:
                return ts.updateTaggedTemplate(node, visitNode(node.tag, visitor, ts.isExpression), visitNodes(node.typeArguments, visitor, ts.isExpression), visitNode(node.template, visitor, ts.isTemplateLiteral));
            case 199 /* TypeAssertionExpression */:
                return ts.updateTypeAssertion(node, visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
            case 200 /* ParenthesizedExpression */:
                return ts.updateParen(node, visitNode(node.expression, visitor, ts.isExpression));
            case 201 /* FunctionExpression */:
                return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 202 /* ArrowFunction */:
                return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, tokenVisitor, ts.isToken), visitFunctionBody(node.body, visitor, context));
            case 203 /* DeleteExpression */:
                return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression));
            case 204 /* TypeOfExpression */:
                return ts.updateTypeOf(node, visitNode(node.expression, visitor, ts.isExpression));
            case 205 /* VoidExpression */:
                return ts.updateVoid(node, visitNode(node.expression, visitor, ts.isExpression));
            case 206 /* AwaitExpression */:
                return ts.updateAwait(node, visitNode(node.expression, visitor, ts.isExpression));
            case 207 /* PrefixUnaryExpression */:
                return ts.updatePrefix(node, visitNode(node.operand, visitor, ts.isExpression));
            case 208 /* PostfixUnaryExpression */:
                return ts.updatePostfix(node, visitNode(node.operand, visitor, ts.isExpression));
            case 209 /* BinaryExpression */:
                return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, tokenVisitor, ts.isToken));
            case 210 /* ConditionalExpression */:
                return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, tokenVisitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression));
            case 211 /* TemplateExpression */:
                return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan));
            case 212 /* YieldExpression */:
                return ts.updateYield(node, visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.expression, visitor, ts.isExpression));
            case 213 /* SpreadElement */:
                return ts.updateSpread(node, visitNode(node.expression, visitor, ts.isExpression));
            case 214 /* ClassExpression */:
                return ts.updateClassExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
            case 216 /* ExpressionWithTypeArguments */:
                return ts.updateExpressionWithTypeArguments(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
            case 217 /* AsExpression */:
                return ts.updateAsExpression(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.type, visitor, ts.isTypeNode));
            case 218 /* NonNullExpression */:
                return ts.updateNonNullExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            case 219 /* MetaProperty */:
                return ts.updateMetaProperty(node, visitNode(node.name, visitor, ts.isIdentifier));
            // Misc
            case 221 /* TemplateSpan */:
                return ts.updateTemplateSpan(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.literal, visitor, ts.isTemplateMiddleOrTemplateTail));
            // Element
            case 223 /* Block */:
                return ts.updateBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 225 /* VariableStatement */:
                return ts.updateVariableStatement(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.declarationList, visitor, ts.isVariableDeclarationList));
            case 226 /* ExpressionStatement */:
                return ts.updateExpressionStatement(node, visitNode(node.expression, visitor, ts.isExpression));
            case 227 /* IfStatement */:
                return ts.updateIf(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.thenStatement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.elseStatement, visitor, ts.isStatement, ts.liftToBlock));
            case 228 /* DoStatement */:
                return ts.updateDo(node, visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.expression, visitor, ts.isExpression));
            case 229 /* WhileStatement */:
                return ts.updateWhile(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 230 /* ForStatement */:
                return ts.updateFor(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.condition, visitor, ts.isExpression), visitNode(node.incrementor, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 231 /* ForInStatement */:
                return ts.updateForIn(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 232 /* ForOfStatement */:
                return ts.updateForOf(node, visitNode(node.awaitModifier, tokenVisitor, ts.isToken), visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 233 /* ContinueStatement */:
                return ts.updateContinue(node, visitNode(node.label, visitor, ts.isIdentifier));
            case 234 /* BreakStatement */:
                return ts.updateBreak(node, visitNode(node.label, visitor, ts.isIdentifier));
            case 235 /* ReturnStatement */:
                return ts.updateReturn(node, visitNode(node.expression, visitor, ts.isExpression));
            case 236 /* WithStatement */:
                return ts.updateWith(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 237 /* SwitchStatement */:
                return ts.updateSwitch(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.caseBlock, visitor, ts.isCaseBlock));
            case 238 /* LabeledStatement */:
                return ts.updateLabel(node, visitNode(node.label, visitor, ts.isIdentifier), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 239 /* ThrowStatement */:
                return ts.updateThrow(node, visitNode(node.expression, visitor, ts.isExpression));
            case 240 /* TryStatement */:
                return ts.updateTry(node, visitNode(node.tryBlock, visitor, ts.isBlock), visitNode(node.catchClause, visitor, ts.isCatchClause), visitNode(node.finallyBlock, visitor, ts.isBlock));
            case 242 /* VariableDeclaration */:
                return ts.updateTypeScriptVariableDeclaration(node, visitNode(node.name, visitor, ts.isBindingName), visitNode(node.exclamationToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 243 /* VariableDeclarationList */:
                return ts.updateVariableDeclarationList(node, nodesVisitor(node.declarations, visitor, ts.isVariableDeclaration));
            case 244 /* FunctionDeclaration */:
                return ts.updateFunctionDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 245 /* ClassDeclaration */:
                return ts.updateClassDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
            case 246 /* InterfaceDeclaration */:
                return ts.updateInterfaceDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isTypeElement));
            case 247 /* TypeAliasDeclaration */:
                return ts.updateTypeAliasDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 248 /* EnumDeclaration */:
                return ts.updateEnumDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.members, visitor, ts.isEnumMember));
            case 249 /* ModuleDeclaration */:
                return ts.updateModuleDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.body, visitor, ts.isModuleBody));
            case 250 /* ModuleBlock */:
                return ts.updateModuleBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 251 /* CaseBlock */:
                return ts.updateCaseBlock(node, nodesVisitor(node.clauses, visitor, ts.isCaseOrDefaultClause));
            case 252 /* NamespaceExportDeclaration */:
                return ts.updateNamespaceExportDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 253 /* ImportEqualsDeclaration */:
                return ts.updateImportEqualsDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.moduleReference, visitor, ts.isModuleReference));
            case 254 /* ImportDeclaration */:
                return ts.updateImportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.importClause, visitor, ts.isImportClause), visitNode(node.moduleSpecifier, visitor, ts.isExpression));
            case 255 /* ImportClause */:
                return ts.updateImportClause(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.namedBindings, visitor, ts.isNamedImportBindings), node.isTypeOnly);
            case 256 /* NamespaceImport */:
                return ts.updateNamespaceImport(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 262 /* NamespaceExport */:
                return ts.updateNamespaceExport(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 257 /* NamedImports */:
                return ts.updateNamedImports(node, nodesVisitor(node.elements, visitor, ts.isImportSpecifier));
            case 258 /* ImportSpecifier */:
                return ts.updateImportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
            case 259 /* ExportAssignment */:
                return ts.updateExportAssignment(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.expression, visitor, ts.isExpression));
            case 260 /* ExportDeclaration */:
                return ts.updateExportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.exportClause, visitor, ts.isNamedExportBindings), visitNode(node.moduleSpecifier, visitor, ts.isExpression), node.isTypeOnly);
            case 261 /* NamedExports */:
                return ts.updateNamedExports(node, nodesVisitor(node.elements, visitor, ts.isExportSpecifier));
            case 263 /* ExportSpecifier */:
                return ts.updateExportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
            // Module references
            case 265 /* ExternalModuleReference */:
                return ts.updateExternalModuleReference(node, visitNode(node.expression, visitor, ts.isExpression));
            // JSX
            case 266 /* JsxElement */:
                return ts.updateJsxElement(node, visitNode(node.openingElement, visitor, ts.isJsxOpeningElement), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingElement, visitor, ts.isJsxClosingElement));
            case 267 /* JsxSelfClosingElement */:
                return ts.updateJsxSelfClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.attributes, visitor, ts.isJsxAttributes));
            case 268 /* JsxOpeningElement */:
                return ts.updateJsxOpeningElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.attributes, visitor, ts.isJsxAttributes));
            case 269 /* JsxClosingElement */:
                return ts.updateJsxClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression));
            case 270 /* JsxFragment */:
                return ts.updateJsxFragment(node, visitNode(node.openingFragment, visitor, ts.isJsxOpeningFragment), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingFragment, visitor, ts.isJsxClosingFragment));
            case 273 /* JsxAttribute */:
                return ts.updateJsxAttribute(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.initializer, visitor, ts.isStringLiteralOrJsxExpression));
            case 274 /* JsxAttributes */:
                return ts.updateJsxAttributes(node, nodesVisitor(node.properties, visitor, ts.isJsxAttributeLike));
            case 275 /* JsxSpreadAttribute */:
                return ts.updateJsxSpreadAttribute(node, visitNode(node.expression, visitor, ts.isExpression));
            case 276 /* JsxExpression */:
                return ts.updateJsxExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            // Clauses
            case 277 /* CaseClause */:
                return ts.updateCaseClause(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.statements, visitor, ts.isStatement));
            case 278 /* DefaultClause */:
                return ts.updateDefaultClause(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 279 /* HeritageClause */:
                return ts.updateHeritageClause(node, nodesVisitor(node.types, visitor, ts.isExpressionWithTypeArguments));
            case 280 /* CatchClause */:
                return ts.updateCatchClause(node, visitNode(node.variableDeclaration, visitor, ts.isVariableDeclaration), visitNode(node.block, visitor, ts.isBlock));
            // Property assignments
            case 281 /* PropertyAssignment */:
                return ts.updatePropertyAssignment(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
            case 282 /* ShorthandPropertyAssignment */:
                return ts.updateShorthandPropertyAssignment(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.objectAssignmentInitializer, visitor, ts.isExpression));
            case 283 /* SpreadAssignment */:
                return ts.updateSpreadAssignment(node, visitNode(node.expression, visitor, ts.isExpression));
            // Enum
            case 284 /* EnumMember */:
                return ts.updateEnumMember(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
            // Top-level nodes
            case 290 /* SourceFile */:
                return ts.updateSourceFileNode(node, visitLexicalEnvironment(node.statements, visitor, context));
            // Transformation nodes
            case 326 /* PartiallyEmittedExpression */:
                return ts.updatePartiallyEmittedExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            case 327 /* CommaListExpression */:
                return ts.updateCommaList(node, nodesVisitor(node.elements, visitor, ts.isExpression));
            default:
                // No need to visit nodes with no children.
                return node;
        }
    }
    ts.visitEachChild = visitEachChild;
    /**
     * Extracts the single node from a NodeArray.
     *
     * @param nodes The NodeArray.
     */
    function extractSingleNode(nodes) {
        ts.Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
        return ts.singleOrUndefined(nodes);
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function reduceNode(node, f, initial) {
        return node ? f(initial, node) : initial;
    }
    function reduceNodeArray(nodes, f, initial) {
        return nodes ? f(initial, nodes) : initial;
    }
    /**
     * Similar to `reduceLeft`, performs a reduction against each child of a node.
     * NOTE: Unlike `forEachChild`, this does *not* visit every node.
     *
     * @param node The node containing the children to reduce.
     * @param initial The initial value to supply to the reduction.
     * @param f The callback function
     */
    function reduceEachChild(node, initial, cbNode, cbNodeArray) {
        if (node === undefined) {
            return initial;
        }
        var reduceNodes = cbNodeArray ? reduceNodeArray : ts.reduceLeft;
        var cbNodes = cbNodeArray || cbNode;
        var kind = node.kind;
        // No need to visit nodes with no children.
        if ((kind > 0 /* FirstToken */ && kind <= 152 /* LastToken */)) {
            return initial;
        }
        // We do not yet support types.
        if ((kind >= 168 /* TypePredicate */ && kind <= 187 /* LiteralType */)) {
            return initial;
        }
        var result = initial;
        switch (node.kind) {
            // Leaf nodes
            case 222 /* SemicolonClassElement */:
            case 224 /* EmptyStatement */:
            case 215 /* OmittedExpression */:
            case 241 /* DebuggerStatement */:
            case 325 /* NotEmittedStatement */:
                // No need to visit nodes with no children.
                break;
            // Names
            case 153 /* QualifiedName */:
                result = reduceNode(node.left, cbNode, result);
                result = reduceNode(node.right, cbNode, result);
                break;
            case 154 /* ComputedPropertyName */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Signature elements
            case 156 /* Parameter */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 157 /* Decorator */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Type member
            case 158 /* PropertySignature */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.questionToken, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 159 /* PropertyDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 161 /* MethodDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 162 /* Constructor */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 163 /* GetAccessor */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 164 /* SetAccessor */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            // Binding patterns
            case 189 /* ObjectBindingPattern */:
            case 190 /* ArrayBindingPattern */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 191 /* BindingElement */:
                result = reduceNode(node.propertyName, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            // Expression
            case 192 /* ArrayLiteralExpression */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 193 /* ObjectLiteralExpression */:
                result = reduceNodes(node.properties, cbNodes, result);
                break;
            case 194 /* PropertyAccessExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                break;
            case 195 /* ElementAccessExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.argumentExpression, cbNode, result);
                break;
            case 196 /* CallExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNodes(node.arguments, cbNodes, result);
                break;
            case 197 /* NewExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNodes(node.arguments, cbNodes, result);
                break;
            case 198 /* TaggedTemplateExpression */:
                result = reduceNode(node.tag, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNode(node.template, cbNode, result);
                break;
            case 199 /* TypeAssertionExpression */:
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 201 /* FunctionExpression */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 202 /* ArrowFunction */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 200 /* ParenthesizedExpression */:
            case 203 /* DeleteExpression */:
            case 204 /* TypeOfExpression */:
            case 205 /* VoidExpression */:
            case 206 /* AwaitExpression */:
            case 212 /* YieldExpression */:
            case 213 /* SpreadElement */:
            case 218 /* NonNullExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 207 /* PrefixUnaryExpression */:
            case 208 /* PostfixUnaryExpression */:
                result = reduceNode(node.operand, cbNode, result);
                break;
            case 209 /* BinaryExpression */:
                result = reduceNode(node.left, cbNode, result);
                result = reduceNode(node.right, cbNode, result);
                break;
            case 210 /* ConditionalExpression */:
                result = reduceNode(node.condition, cbNode, result);
                result = reduceNode(node.whenTrue, cbNode, result);
                result = reduceNode(node.whenFalse, cbNode, result);
                break;
            case 211 /* TemplateExpression */:
                result = reduceNode(node.head, cbNode, result);
                result = reduceNodes(node.templateSpans, cbNodes, result);
                break;
            case 214 /* ClassExpression */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.heritageClauses, cbNodes, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 216 /* ExpressionWithTypeArguments */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                break;
            case 217 /* AsExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                break;
            // Misc
            case 221 /* TemplateSpan */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.literal, cbNode, result);
                break;
            // Element
            case 223 /* Block */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 225 /* VariableStatement */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.declarationList, cbNode, result);
                break;
            case 226 /* ExpressionStatement */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 227 /* IfStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.thenStatement, cbNode, result);
                result = reduceNode(node.elseStatement, cbNode, result);
                break;
            case 228 /* DoStatement */:
                result = reduceNode(node.statement, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 229 /* WhileStatement */:
            case 236 /* WithStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 230 /* ForStatement */:
                result = reduceNode(node.initializer, cbNode, result);
                result = reduceNode(node.condition, cbNode, result);
                result = reduceNode(node.incrementor, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
                result = reduceNode(node.initializer, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 235 /* ReturnStatement */:
            case 239 /* ThrowStatement */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 237 /* SwitchStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.caseBlock, cbNode, result);
                break;
            case 238 /* LabeledStatement */:
                result = reduceNode(node.label, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 240 /* TryStatement */:
                result = reduceNode(node.tryBlock, cbNode, result);
                result = reduceNode(node.catchClause, cbNode, result);
                result = reduceNode(node.finallyBlock, cbNode, result);
                break;
            case 242 /* VariableDeclaration */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 243 /* VariableDeclarationList */:
                result = reduceNodes(node.declarations, cbNodes, result);
                break;
            case 244 /* FunctionDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 245 /* ClassDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.heritageClauses, cbNodes, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 248 /* EnumDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 249 /* ModuleDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 250 /* ModuleBlock */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 251 /* CaseBlock */:
                result = reduceNodes(node.clauses, cbNodes, result);
                break;
            case 253 /* ImportEqualsDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.moduleReference, cbNode, result);
                break;
            case 254 /* ImportDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.importClause, cbNode, result);
                result = reduceNode(node.moduleSpecifier, cbNode, result);
                break;
            case 255 /* ImportClause */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.namedBindings, cbNode, result);
                break;
            case 256 /* NamespaceImport */:
                result = reduceNode(node.name, cbNode, result);
                break;
            case 262 /* NamespaceExport */:
                result = reduceNode(node.name, cbNode, result);
                break;
            case 257 /* NamedImports */:
            case 261 /* NamedExports */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
                result = reduceNode(node.propertyName, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                break;
            case 259 /* ExportAssignment */:
                result = ts.reduceLeft(node.decorators, cbNode, result);
                result = ts.reduceLeft(node.modifiers, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 260 /* ExportDeclaration */:
                result = ts.reduceLeft(node.decorators, cbNode, result);
                result = ts.reduceLeft(node.modifiers, cbNode, result);
                result = reduceNode(node.exportClause, cbNode, result);
                result = reduceNode(node.moduleSpecifier, cbNode, result);
                break;
            // Module references
            case 265 /* ExternalModuleReference */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // JSX
            case 266 /* JsxElement */:
                result = reduceNode(node.openingElement, cbNode, result);
                result = ts.reduceLeft(node.children, cbNode, result);
                result = reduceNode(node.closingElement, cbNode, result);
                break;
            case 270 /* JsxFragment */:
                result = reduceNode(node.openingFragment, cbNode, result);
                result = ts.reduceLeft(node.children, cbNode, result);
                result = reduceNode(node.closingFragment, cbNode, result);
                break;
            case 267 /* JsxSelfClosingElement */:
            case 268 /* JsxOpeningElement */:
                result = reduceNode(node.tagName, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNode, result);
                result = reduceNode(node.attributes, cbNode, result);
                break;
            case 274 /* JsxAttributes */:
                result = reduceNodes(node.properties, cbNodes, result);
                break;
            case 269 /* JsxClosingElement */:
                result = reduceNode(node.tagName, cbNode, result);
                break;
            case 273 /* JsxAttribute */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 275 /* JsxSpreadAttribute */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 276 /* JsxExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Clauses
            case 277 /* CaseClause */:
                result = reduceNode(node.expression, cbNode, result);
            // falls through
            case 278 /* DefaultClause */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 279 /* HeritageClause */:
                result = reduceNodes(node.types, cbNodes, result);
                break;
            case 280 /* CatchClause */:
                result = reduceNode(node.variableDeclaration, cbNode, result);
                result = reduceNode(node.block, cbNode, result);
                break;
            // Property assignments
            case 281 /* PropertyAssignment */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 282 /* ShorthandPropertyAssignment */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.objectAssignmentInitializer, cbNode, result);
                break;
            case 283 /* SpreadAssignment */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Enum
            case 284 /* EnumMember */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            // Top-level nodes
            case 290 /* SourceFile */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            // Transformation nodes
            case 326 /* PartiallyEmittedExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 327 /* CommaListExpression */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            default:
                break;
        }
        return result;
    }
    ts.reduceEachChild = reduceEachChild;
    function findSpanEnd(array, test, start) {
        var i = start;
        while (i < array.length && test(array[i])) {
            i++;
        }
        return i;
    }
    function mergeLexicalEnvironment(statements, declarations) {
        if (!ts.some(declarations)) {
            return statements;
        }
        // When we merge new lexical statements into an existing statement list, we merge them in the following manner:
        //
        // Given:
        //
        // | Left                               | Right                               |
        // |------------------------------------|-------------------------------------|
        // | [standard prologues (left)]        | [standard prologues (right)]        |
        // | [hoisted functions (left)]         | [hoisted functions (right)]         |
        // | [hoisted variables (left)]         | [hoisted variables (right)]         |
        // | [lexical init statements (left)]   | [lexical init statements (right)]   |
        // | [other statements (left)]          |                                     |
        //
        // The resulting statement list will be:
        //
        // | Result                              |
        // |-------------------------------------|
        // | [standard prologues (right)]        |
        // | [standard prologues (left)]         |
        // | [hoisted functions (right)]         |
        // | [hoisted functions (left)]          |
        // | [hoisted variables (right)]         |
        // | [hoisted variables (left)]          |
        // | [lexical init statements (right)]   |
        // | [lexical init statements (left)]    |
        // | [other statements (left)]           |
        //
        // NOTE: It is expected that new lexical init statements must be evaluated before existing lexical init statements,
        // as the prior transformation may depend on the evaluation of the lexical init statements to be in the correct state.
        // find standard prologues on left in the following order: standard directives, hoisted functions, hoisted variables, other custom
        var leftStandardPrologueEnd = findSpanEnd(statements, ts.isPrologueDirective, 0);
        var leftHoistedFunctionsEnd = findSpanEnd(statements, ts.isHoistedFunction, leftStandardPrologueEnd);
        var leftHoistedVariablesEnd = findSpanEnd(statements, ts.isHoistedVariableStatement, leftHoistedFunctionsEnd);
        // find standard prologues on right in the following order: standard directives, hoisted functions, hoisted variables, other custom
        var rightStandardPrologueEnd = findSpanEnd(declarations, ts.isPrologueDirective, 0);
        var rightHoistedFunctionsEnd = findSpanEnd(declarations, ts.isHoistedFunction, rightStandardPrologueEnd);
        var rightHoistedVariablesEnd = findSpanEnd(declarations, ts.isHoistedVariableStatement, rightHoistedFunctionsEnd);
        var rightCustomPrologueEnd = findSpanEnd(declarations, ts.isCustomPrologue, rightHoistedVariablesEnd);
        ts.Debug.assert(rightCustomPrologueEnd === declarations.length, "Expected declarations to be valid standard or custom prologues");
        // splice prologues from the right into the left. We do this in reverse order
        // so that we don't need to recompute the index on the left when we insert items.
        var left = ts.isNodeArray(statements) ? statements.slice() : statements;
        // splice other custom prologues from right into left
        if (rightCustomPrologueEnd > rightHoistedVariablesEnd) {
            left.splice.apply(left, __spreadArrays([leftHoistedVariablesEnd, 0], declarations.slice(rightHoistedVariablesEnd, rightCustomPrologueEnd)));
        }
        // splice hoisted variables from right into left
        if (rightHoistedVariablesEnd > rightHoistedFunctionsEnd) {
            left.splice.apply(left, __spreadArrays([leftHoistedFunctionsEnd, 0], declarations.slice(rightHoistedFunctionsEnd, rightHoistedVariablesEnd)));
        }
        // splice hoisted functions from right into left
        if (rightHoistedFunctionsEnd > rightStandardPrologueEnd) {
            left.splice.apply(left, __spreadArrays([leftStandardPrologueEnd, 0], declarations.slice(rightStandardPrologueEnd, rightHoistedFunctionsEnd)));
        }
        // splice standard prologues from right into left (that are not already in left)
        if (rightStandardPrologueEnd > 0) {
            if (leftStandardPrologueEnd === 0) {
                left.splice.apply(left, __spreadArrays([0, 0], declarations.slice(0, rightStandardPrologueEnd)));
            }
            else {
                var leftPrologues = ts.createMap();
                for (var i = 0; i < leftStandardPrologueEnd; i++) {
                    var leftPrologue = statements[i];
                    leftPrologues.set(leftPrologue.expression.text, true);
                }
                for (var i = rightStandardPrologueEnd - 1; i >= 0; i--) {
                    var rightPrologue = declarations[i];
                    if (!leftPrologues.has(rightPrologue.expression.text)) {
                        left.unshift(rightPrologue);
                    }
                }
            }
        }
        if (ts.isNodeArray(statements)) {
            return ts.setTextRange(ts.createNodeArray(left, statements.hasTrailingComma), statements);
        }
        return statements;
    }
    ts.mergeLexicalEnvironment = mergeLexicalEnvironment;
    /**
     * Lifts a NodeArray containing only Statement nodes to a block.
     *
     * @param nodes The NodeArray.
     */
    function liftToBlock(nodes) {
        ts.Debug.assert(ts.every(nodes, ts.isStatement), "Cannot lift nodes to a Block.");
        return ts.singleOrUndefined(nodes) || ts.createBlock(nodes);
    }
    ts.liftToBlock = liftToBlock;
    /**
     * Aggregates the TransformFlags for a Node and its subtree.
     */
    function aggregateTransformFlags(node) {
        aggregateTransformFlagsForNode(node);
        return node;
    }
    ts.aggregateTransformFlags = aggregateTransformFlags;
    /**
     * Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are
     * computed first, then the transform flags for the current node are computed from the subtree
     * flags and the state of the current node. Finally, the transform flags of the node are
     * returned, excluding any flags that should not be included in its parent node's subtree
     * flags.
     */
    function aggregateTransformFlagsForNode(node) {
        if (node === undefined) {
            return 0 /* None */;
        }
        if (node.transformFlags & 536870912 /* HasComputedFlags */) {
            return node.transformFlags & ~ts.getTransformFlagsSubtreeExclusions(node.kind);
        }
        var subtreeFlags = aggregateTransformFlagsForSubtree(node);
        return ts.computeTransformFlagsForNode(node, subtreeFlags);
    }
    function aggregateTransformFlagsForNodeArray(nodes) {
        if (nodes === undefined) {
            return 0 /* None */;
        }
        var subtreeFlags = 0 /* None */;
        var nodeArrayFlags = 0 /* None */;
        for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
            var node = nodes_3[_i];
            subtreeFlags |= aggregateTransformFlagsForNode(node);
            nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
        }
        nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
        return subtreeFlags;
    }
    /**
     * Aggregates the transform flags for the subtree of a node.
     */
    function aggregateTransformFlagsForSubtree(node) {
        // We do not transform ambient declarations or types, so there is no need to
        // recursively aggregate transform flags.
        if (ts.hasModifier(node, 2 /* Ambient */) || (ts.isTypeNode(node) && node.kind !== 216 /* ExpressionWithTypeArguments */)) {
            return 0 /* None */;
        }
        // Aggregate the transform flags of each child.
        return reduceEachChild(node, 0 /* None */, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes);
    }
    /**
     * Aggregates the TransformFlags of a child node with the TransformFlags of its
     * siblings.
     */
    function aggregateTransformFlagsForChildNode(transformFlags, node) {
        return transformFlags | aggregateTransformFlagsForNode(node);
    }
    function aggregateTransformFlagsForChildNodes(transformFlags, nodes) {
        return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function createSourceMapGenerator(host, file, sourceRoot, sourcesDirectoryPath, generatorOptions) {
        var _a = generatorOptions.extendedDiagnostics
            ? ts.performance.createTimer("Source Map", "beforeSourcemap", "afterSourcemap")
            : ts.performance.nullTimer, enter = _a.enter, exit = _a.exit;
        // Current source map file and its index in the sources list
        var rawSources = [];
        var sources = [];
        var sourceToSourceIndexMap = ts.createMap();
        var sourcesContent;
        var names = [];
        var nameToNameIndexMap;
        var mappings = "";
        // Last recorded and encoded mappings
        var lastGeneratedLine = 0;
        var lastGeneratedCharacter = 0;
        var lastSourceIndex = 0;
        var lastSourceLine = 0;
        var lastSourceCharacter = 0;
        var lastNameIndex = 0;
        var hasLast = false;
        var pendingGeneratedLine = 0;
        var pendingGeneratedCharacter = 0;
        var pendingSourceIndex = 0;
        var pendingSourceLine = 0;
        var pendingSourceCharacter = 0;
        var pendingNameIndex = 0;
        var hasPending = false;
        var hasPendingSource = false;
        var hasPendingName = false;
        return {
            getSources: function () { return rawSources; },
            addSource: addSource,
            setSourceContent: setSourceContent,
            addName: addName,
            addMapping: addMapping,
            appendSourceMap: appendSourceMap,
            toJSON: toJSON,
            toString: function () { return JSON.stringify(toJSON()); }
        };
        function addSource(fileName) {
            enter();
            var source = ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, fileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
            /*isAbsolutePathAnUrl*/ true);
            var sourceIndex = sourceToSourceIndexMap.get(source);
            if (sourceIndex === undefined) {
                sourceIndex = sources.length;
                sources.push(source);
                rawSources.push(fileName);
                sourceToSourceIndexMap.set(source, sourceIndex);
            }
            exit();
            return sourceIndex;
        }
        /* eslint-disable boolean-trivia, no-null/no-null */
        function setSourceContent(sourceIndex, content) {
            enter();
            if (content !== null) {
                if (!sourcesContent)
                    sourcesContent = [];
                while (sourcesContent.length < sourceIndex) {
                    sourcesContent.push(null);
                }
                sourcesContent[sourceIndex] = content;
            }
            exit();
        }
        /* eslint-enable boolean-trivia, no-null/no-null */
        function addName(name) {
            enter();
            if (!nameToNameIndexMap)
                nameToNameIndexMap = ts.createMap();
            var nameIndex = nameToNameIndexMap.get(name);
            if (nameIndex === undefined) {
                nameIndex = names.length;
                names.push(name);
                nameToNameIndexMap.set(name, nameIndex);
            }
            exit();
            return nameIndex;
        }
        function isNewGeneratedPosition(generatedLine, generatedCharacter) {
            return !hasPending
                || pendingGeneratedLine !== generatedLine
                || pendingGeneratedCharacter !== generatedCharacter;
        }
        function isBacktrackingSourcePosition(sourceIndex, sourceLine, sourceCharacter) {
            return sourceIndex !== undefined
                && sourceLine !== undefined
                && sourceCharacter !== undefined
                && pendingSourceIndex === sourceIndex
                && (pendingSourceLine > sourceLine
                    || pendingSourceLine === sourceLine && pendingSourceCharacter > sourceCharacter);
        }
        function addMapping(generatedLine, generatedCharacter, sourceIndex, sourceLine, sourceCharacter, nameIndex) {
            ts.Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack");
            ts.Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative");
            ts.Debug.assert(sourceIndex === undefined || sourceIndex >= 0, "sourceIndex cannot be negative");
            ts.Debug.assert(sourceLine === undefined || sourceLine >= 0, "sourceLine cannot be negative");
            ts.Debug.assert(sourceCharacter === undefined || sourceCharacter >= 0, "sourceCharacter cannot be negative");
            enter();
            // If this location wasn't recorded or the location in source is going backwards, record the mapping
            if (isNewGeneratedPosition(generatedLine, generatedCharacter) ||
                isBacktrackingSourcePosition(sourceIndex, sourceLine, sourceCharacter)) {
                commitPendingMapping();
                pendingGeneratedLine = generatedLine;
                pendingGeneratedCharacter = generatedCharacter;
                hasPendingSource = false;
                hasPendingName = false;
                hasPending = true;
            }
            if (sourceIndex !== undefined && sourceLine !== undefined && sourceCharacter !== undefined) {
                pendingSourceIndex = sourceIndex;
                pendingSourceLine = sourceLine;
                pendingSourceCharacter = sourceCharacter;
                hasPendingSource = true;
                if (nameIndex !== undefined) {
                    pendingNameIndex = nameIndex;
                    hasPendingName = true;
                }
            }
            exit();
        }
        function appendSourceMap(generatedLine, generatedCharacter, map, sourceMapPath, start, end) {
            ts.Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack");
            ts.Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative");
            enter();
            // First, decode the old component sourcemap
            var sourceIndexToNewSourceIndexMap = [];
            var nameIndexToNewNameIndexMap;
            var mappingIterator = decodeMappings(map.mappings);
            for (var iterResult = mappingIterator.next(); !iterResult.done; iterResult = mappingIterator.next()) {
                var raw = iterResult.value;
                if (end && (raw.generatedLine > end.line ||
                    (raw.generatedLine === end.line && raw.generatedCharacter > end.character))) {
                    break;
                }
                if (start && (raw.generatedLine < start.line ||
                    (start.line === raw.generatedLine && raw.generatedCharacter < start.character))) {
                    continue;
                }
                // Then reencode all the updated mappings into the overall map
                var newSourceIndex = void 0;
                var newSourceLine = void 0;
                var newSourceCharacter = void 0;
                var newNameIndex = void 0;
                if (raw.sourceIndex !== undefined) {
                    newSourceIndex = sourceIndexToNewSourceIndexMap[raw.sourceIndex];
                    if (newSourceIndex === undefined) {
                        // Apply offsets to each position and fixup source entries
                        var rawPath = map.sources[raw.sourceIndex];
                        var relativePath = map.sourceRoot ? ts.combinePaths(map.sourceRoot, rawPath) : rawPath;
                        var combinedPath = ts.combinePaths(ts.getDirectoryPath(sourceMapPath), relativePath);
                        sourceIndexToNewSourceIndexMap[raw.sourceIndex] = newSourceIndex = addSource(combinedPath);
                        if (map.sourcesContent && typeof map.sourcesContent[raw.sourceIndex] === "string") {
                            setSourceContent(newSourceIndex, map.sourcesContent[raw.sourceIndex]);
                        }
                    }
                    newSourceLine = raw.sourceLine;
                    newSourceCharacter = raw.sourceCharacter;
                    if (map.names && raw.nameIndex !== undefined) {
                        if (!nameIndexToNewNameIndexMap)
                            nameIndexToNewNameIndexMap = [];
                        newNameIndex = nameIndexToNewNameIndexMap[raw.nameIndex];
                        if (newNameIndex === undefined) {
                            nameIndexToNewNameIndexMap[raw.nameIndex] = newNameIndex = addName(map.names[raw.nameIndex]);
                        }
                    }
                }
                var rawGeneratedLine = raw.generatedLine - (start ? start.line : 0);
                var newGeneratedLine = rawGeneratedLine + generatedLine;
                var rawGeneratedCharacter = start && start.line === raw.generatedLine ? raw.generatedCharacter - start.character : raw.generatedCharacter;
                var newGeneratedCharacter = rawGeneratedLine === 0 ? rawGeneratedCharacter + generatedCharacter : rawGeneratedCharacter;
                addMapping(newGeneratedLine, newGeneratedCharacter, newSourceIndex, newSourceLine, newSourceCharacter, newNameIndex);
            }
            exit();
        }
        function shouldCommitMapping() {
            return !hasLast
                || lastGeneratedLine !== pendingGeneratedLine
                || lastGeneratedCharacter !== pendingGeneratedCharacter
                || lastSourceIndex !== pendingSourceIndex
                || lastSourceLine !== pendingSourceLine
                || lastSourceCharacter !== pendingSourceCharacter
                || lastNameIndex !== pendingNameIndex;
        }
        function commitPendingMapping() {
            if (!hasPending || !shouldCommitMapping()) {
                return;
            }
            enter();
            // Line/Comma delimiters
            if (lastGeneratedLine < pendingGeneratedLine) {
                // Emit line delimiters
                do {
                    mappings += ";";
                    lastGeneratedLine++;
                    lastGeneratedCharacter = 0;
                } while (lastGeneratedLine < pendingGeneratedLine);
            }
            else {
                ts.Debug.assertEqual(lastGeneratedLine, pendingGeneratedLine, "generatedLine cannot backtrack");
                // Emit comma to separate the entry
                if (hasLast) {
                    mappings += ",";
                }
            }
            // 1. Relative generated character
            mappings += base64VLQFormatEncode(pendingGeneratedCharacter - lastGeneratedCharacter);
            lastGeneratedCharacter = pendingGeneratedCharacter;
            if (hasPendingSource) {
                // 2. Relative sourceIndex
                mappings += base64VLQFormatEncode(pendingSourceIndex - lastSourceIndex);
                lastSourceIndex = pendingSourceIndex;
                // 3. Relative source line
                mappings += base64VLQFormatEncode(pendingSourceLine - lastSourceLine);
                lastSourceLine = pendingSourceLine;
                // 4. Relative source character
                mappings += base64VLQFormatEncode(pendingSourceCharacter - lastSourceCharacter);
                lastSourceCharacter = pendingSourceCharacter;
                if (hasPendingName) {
                    // 5. Relative nameIndex
                    mappings += base64VLQFormatEncode(pendingNameIndex - lastNameIndex);
                    lastNameIndex = pendingNameIndex;
                }
            }
            hasLast = true;
            exit();
        }
        function toJSON() {
            commitPendingMapping();
            return {
                version: 3,
                file: file,
                sourceRoot: sourceRoot,
                sources: sources,
                names: names,
                mappings: mappings,
                sourcesContent: sourcesContent,
            };
        }
    }
    ts.createSourceMapGenerator = createSourceMapGenerator;
    // Sometimes tools can see the following line as a source mapping url comment, so we mangle it a bit (the [M])
    var sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\s*$/;
    var whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;
    function getLineInfo(text, lineStarts) {
        return {
            getLineCount: function () { return lineStarts.length; },
            getLineText: function (line) { return text.substring(lineStarts[line], lineStarts[line + 1]); }
        };
    }
    ts.getLineInfo = getLineInfo;
    /**
     * Tries to find the sourceMappingURL comment at the end of a file.
     */
    function tryGetSourceMappingURL(lineInfo) {
        for (var index = lineInfo.getLineCount() - 1; index >= 0; index--) {
            var line = lineInfo.getLineText(index);
            var comment = sourceMapCommentRegExp.exec(line);
            if (comment) {
                return comment[1];
            }
            // If we see a non-whitespace/map comment-like line, break, to avoid scanning up the entire file
            else if (!line.match(whitespaceOrMapCommentRegExp)) {
                break;
            }
        }
    }
    ts.tryGetSourceMappingURL = tryGetSourceMappingURL;
    /* eslint-disable no-null/no-null */
    function isStringOrNull(x) {
        return typeof x === "string" || x === null;
    }
    function isRawSourceMap(x) {
        return x !== null
            && typeof x === "object"
            && x.version === 3
            && typeof x.file === "string"
            && typeof x.mappings === "string"
            && ts.isArray(x.sources) && ts.every(x.sources, ts.isString)
            && (x.sourceRoot === undefined || x.sourceRoot === null || typeof x.sourceRoot === "string")
            && (x.sourcesContent === undefined || x.sourcesContent === null || ts.isArray(x.sourcesContent) && ts.every(x.sourcesContent, isStringOrNull))
            && (x.names === undefined || x.names === null || ts.isArray(x.names) && ts.every(x.names, ts.isString));
    }
    ts.isRawSourceMap = isRawSourceMap;
    /* eslint-enable no-null/no-null */
    function tryParseRawSourceMap(text) {
        try {
            var parsed = JSON.parse(text);
            if (isRawSourceMap(parsed)) {
                return parsed;
            }
        }
        catch (_a) {
            // empty
        }
        return undefined;
    }
    ts.tryParseRawSourceMap = tryParseRawSourceMap;
    function decodeMappings(mappings) {
        var done = false;
        var pos = 0;
        var generatedLine = 0;
        var generatedCharacter = 0;
        var sourceIndex = 0;
        var sourceLine = 0;
        var sourceCharacter = 0;
        var nameIndex = 0;
        var error;
        return {
            get pos() { return pos; },
            get error() { return error; },
            get state() { return captureMapping(/*hasSource*/ true, /*hasName*/ true); },
            next: function () {
                while (!done && pos < mappings.length) {
                    var ch = mappings.charCodeAt(pos);
                    if (ch === 59 /* semicolon */) {
                        // new line
                        generatedLine++;
                        generatedCharacter = 0;
                        pos++;
                        continue;
                    }
                    if (ch === 44 /* comma */) {
                        // Next entry is on same line - no action needed
                        pos++;
                        continue;
                    }
                    var hasSource = false;
                    var hasName = false;
                    generatedCharacter += base64VLQFormatDecode();
                    if (hasReportedError())
                        return stopIterating();
                    if (generatedCharacter < 0)
                        return setErrorAndStopIterating("Invalid generatedCharacter found");
                    if (!isSourceMappingSegmentEnd()) {
                        hasSource = true;
                        sourceIndex += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceIndex < 0)
                            return setErrorAndStopIterating("Invalid sourceIndex found");
                        if (isSourceMappingSegmentEnd())
                            return setErrorAndStopIterating("Unsupported Format: No entries after sourceIndex");
                        sourceLine += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceLine < 0)
                            return setErrorAndStopIterating("Invalid sourceLine found");
                        if (isSourceMappingSegmentEnd())
                            return setErrorAndStopIterating("Unsupported Format: No entries after sourceLine");
                        sourceCharacter += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceCharacter < 0)
                            return setErrorAndStopIterating("Invalid sourceCharacter found");
                        if (!isSourceMappingSegmentEnd()) {
                            hasName = true;
                            nameIndex += base64VLQFormatDecode();
                            if (hasReportedError())
                                return stopIterating();
                            if (nameIndex < 0)
                                return setErrorAndStopIterating("Invalid nameIndex found");
                            if (!isSourceMappingSegmentEnd())
                                return setErrorAndStopIterating("Unsupported Error Format: Entries after nameIndex");
                        }
                    }
                    return { value: captureMapping(hasSource, hasName), done: done };
                }
                return stopIterating();
            }
        };
        function captureMapping(hasSource, hasName) {
            return {
                generatedLine: generatedLine,
                generatedCharacter: generatedCharacter,
                sourceIndex: hasSource ? sourceIndex : undefined,
                sourceLine: hasSource ? sourceLine : undefined,
                sourceCharacter: hasSource ? sourceCharacter : undefined,
                nameIndex: hasName ? nameIndex : undefined
            };
        }
        function stopIterating() {
            done = true;
            return { value: undefined, done: true };
        }
        function setError(message) {
            if (error === undefined) {
                error = message;
            }
        }
        function setErrorAndStopIterating(message) {
            setError(message);
            return stopIterating();
        }
        function hasReportedError() {
            return error !== undefined;
        }
        function isSourceMappingSegmentEnd() {
            return (pos === mappings.length ||
                mappings.charCodeAt(pos) === 44 /* comma */ ||
                mappings.charCodeAt(pos) === 59 /* semicolon */);
        }
        function base64VLQFormatDecode() {
            var moreDigits = true;
            var shiftCount = 0;
            var value = 0;
            for (; moreDigits; pos++) {
                if (pos >= mappings.length)
                    return setError("Error in decoding base64VLQFormatDecode, past the mapping string"), -1;
                // 6 digit number
                var currentByte = base64FormatDecode(mappings.charCodeAt(pos));
                if (currentByte === -1)
                    return setError("Invalid character in VLQ"), -1;
                // If msb is set, we still have more bits to continue
                moreDigits = (currentByte & 32) !== 0;
                // least significant 5 bits are the next msbs in the final value.
                value = value | ((currentByte & 31) << shiftCount);
                shiftCount += 5;
            }
            // Least significant bit if 1 represents negative and rest of the msb is actual absolute value
            if ((value & 1) === 0) {
                // + number
                value = value >> 1;
            }
            else {
                // - number
                value = value >> 1;
                value = -value;
            }
            return value;
        }
    }
    ts.decodeMappings = decodeMappings;
    function sameMapping(left, right) {
        return left === right
            || left.generatedLine === right.generatedLine
                && left.generatedCharacter === right.generatedCharacter
                && left.sourceIndex === right.sourceIndex
                && left.sourceLine === right.sourceLine
                && left.sourceCharacter === right.sourceCharacter
                && left.nameIndex === right.nameIndex;
    }
    ts.sameMapping = sameMapping;
    function isSourceMapping(mapping) {
        return mapping.sourceIndex !== undefined
            && mapping.sourceLine !== undefined
            && mapping.sourceCharacter !== undefined;
    }
    ts.isSourceMapping = isSourceMapping;
    function base64FormatEncode(value) {
        return value >= 0 && value < 26 ? 65 /* A */ + value :
            value >= 26 && value < 52 ? 97 /* a */ + value - 26 :
                value >= 52 && value < 62 ? 48 /* _0 */ + value - 52 :
                    value === 62 ? 43 /* plus */ :
                        value === 63 ? 47 /* slash */ :
                            ts.Debug.fail(value + ": not a base64 value");
    }
    function base64FormatDecode(ch) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ ? ch - 65 /* A */ :
            ch >= 97 /* a */ && ch <= 122 /* z */ ? ch - 97 /* a */ + 26 :
                ch >= 48 /* _0 */ && ch <= 57 /* _9 */ ? ch - 48 /* _0 */ + 52 :
                    ch === 43 /* plus */ ? 62 :
                        ch === 47 /* slash */ ? 63 :
                            -1;
    }
    function base64VLQFormatEncode(inValue) {
        // Add a new least significant bit that has the sign of the value.
        // if negative number the least significant bit that gets added to the number has value 1
        // else least significant bit value that gets added is 0
        // eg. -1 changes to binary : 01 [1] => 3
        //     +1 changes to binary : 01 [0] => 2
        if (inValue < 0) {
            inValue = ((-inValue) << 1) + 1;
        }
        else {
            inValue = inValue << 1;
        }
        // Encode 5 bits at a time starting from least significant bits
        var encodedStr = "";
        do {
            var currentDigit = inValue & 31; // 11111
            inValue = inValue >> 5;
            if (inValue > 0) {
                // There are still more digits to decode, set the msb (6th bit)
                currentDigit = currentDigit | 32;
            }
            encodedStr = encodedStr + String.fromCharCode(base64FormatEncode(currentDigit));
        } while (inValue > 0);
        return encodedStr;
    }
    function isSourceMappedPosition(value) {
        return value.sourceIndex !== undefined
            && value.sourcePosition !== undefined;
    }
    function sameMappedPosition(left, right) {
        return left.generatedPosition === right.generatedPosition
            && left.sourceIndex === right.sourceIndex
            && left.sourcePosition === right.sourcePosition;
    }
    function compareSourcePositions(left, right) {
        // Compares sourcePosition without comparing sourceIndex
        // since the mappings are grouped by sourceIndex
        ts.Debug.assert(left.sourceIndex === right.sourceIndex);
        return ts.compareValues(left.sourcePosition, right.sourcePosition);
    }
    function compareGeneratedPositions(left, right) {
        return ts.compareValues(left.generatedPosition, right.generatedPosition);
    }
    function getSourcePositionOfMapping(value) {
        return value.sourcePosition;
    }
    function getGeneratedPositionOfMapping(value) {
        return value.generatedPosition;
    }
    function createDocumentPositionMapper(host, map, mapPath) {
        var mapDirectory = ts.getDirectoryPath(mapPath);
        var sourceRoot = map.sourceRoot ? ts.getNormalizedAbsolutePath(map.sourceRoot, mapDirectory) : mapDirectory;
        var generatedAbsoluteFilePath = ts.getNormalizedAbsolutePath(map.file, mapDirectory);
        var generatedFile = host.getSourceFileLike(generatedAbsoluteFilePath);
        var sourceFileAbsolutePaths = map.sources.map(function (source) { return ts.getNormalizedAbsolutePath(source, sourceRoot); });
        var sourceToSourceIndexMap = ts.createMapFromEntries(sourceFileAbsolutePaths.map(function (source, i) { return [host.getCanonicalFileName(source), i]; }));
        var decodedMappings;
        var generatedMappings;
        var sourceMappings;
        return {
            getSourcePosition: getSourcePosition,
            getGeneratedPosition: getGeneratedPosition
        };
        function processMapping(mapping) {
            var generatedPosition = generatedFile !== undefined
                ? ts.getPositionOfLineAndCharacter(generatedFile, mapping.generatedLine, mapping.generatedCharacter, /*allowEdits*/ true)
                : -1;
            var source;
            var sourcePosition;
            if (isSourceMapping(mapping)) {
                var sourceFile = host.getSourceFileLike(sourceFileAbsolutePaths[mapping.sourceIndex]);
                source = map.sources[mapping.sourceIndex];
                sourcePosition = sourceFile !== undefined
                    ? ts.getPositionOfLineAndCharacter(sourceFile, mapping.sourceLine, mapping.sourceCharacter, /*allowEdits*/ true)
                    : -1;
            }
            return {
                generatedPosition: generatedPosition,
                source: source,
                sourceIndex: mapping.sourceIndex,
                sourcePosition: sourcePosition,
                nameIndex: mapping.nameIndex
            };
        }
        function getDecodedMappings() {
            if (decodedMappings === undefined) {
                var decoder = decodeMappings(map.mappings);
                var mappings = ts.arrayFrom(decoder, processMapping);
                if (decoder.error !== undefined) {
                    if (host.log) {
                        host.log("Encountered error while decoding sourcemap: " + decoder.error);
                    }
                    decodedMappings = ts.emptyArray;
                }
                else {
                    decodedMappings = mappings;
                }
            }
            return decodedMappings;
        }
        function getSourceMappings(sourceIndex) {
            if (sourceMappings === undefined) {
                var lists = [];
                for (var _i = 0, _a = getDecodedMappings(); _i < _a.length; _i++) {
                    var mapping = _a[_i];
                    if (!isSourceMappedPosition(mapping))
                        continue;
                    var list = lists[mapping.sourceIndex];
                    if (!list)
                        lists[mapping.sourceIndex] = list = [];
                    list.push(mapping);
                }
                sourceMappings = lists.map(function (list) { return ts.sortAndDeduplicate(list, compareSourcePositions, sameMappedPosition); });
            }
            return sourceMappings[sourceIndex];
        }
        function getGeneratedMappings() {
            if (generatedMappings === undefined) {
                var list = [];
                for (var _i = 0, _a = getDecodedMappings(); _i < _a.length; _i++) {
                    var mapping = _a[_i];
                    list.push(mapping);
                }
                generatedMappings = ts.sortAndDeduplicate(list, compareGeneratedPositions, sameMappedPosition);
            }
            return generatedMappings;
        }
        function getGeneratedPosition(loc) {
            var sourceIndex = sourceToSourceIndexMap.get(host.getCanonicalFileName(loc.fileName));
            if (sourceIndex === undefined)
                return loc;
            var sourceMappings = getSourceMappings(sourceIndex);
            if (!ts.some(sourceMappings))
                return loc;
            var targetIndex = ts.binarySearchKey(sourceMappings, loc.pos, getSourcePositionOfMapping, ts.compareValues);
            if (targetIndex < 0) {
                // if no exact match, closest is 2's complement of result
                targetIndex = ~targetIndex;
            }
            var mapping = sourceMappings[targetIndex];
            if (mapping === undefined || mapping.sourceIndex !== sourceIndex) {
                return loc;
            }
            return { fileName: generatedAbsoluteFilePath, pos: mapping.generatedPosition }; // Closest pos
        }
        function getSourcePosition(loc) {
            var generatedMappings = getGeneratedMappings();
            if (!ts.some(generatedMappings))
                return loc;
            var targetIndex = ts.binarySearchKey(generatedMappings, loc.pos, getGeneratedPositionOfMapping, ts.compareValues);
            if (targetIndex < 0) {
                // if no exact match, closest is 2's complement of result
                targetIndex = ~targetIndex;
            }
            var mapping = generatedMappings[targetIndex];
            if (mapping === undefined || !isSourceMappedPosition(mapping)) {
                return loc;
            }
            return { fileName: sourceFileAbsolutePaths[mapping.sourceIndex], pos: mapping.sourcePosition }; // Closest pos
        }
    }
    ts.createDocumentPositionMapper = createDocumentPositionMapper;
    ts.identitySourceMapConsumer = {
        getSourcePosition: ts.identity,
        getGeneratedPosition: ts.identity
    };
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getOriginalNodeId(node) {
        node = ts.getOriginalNode(node);
        return node ? ts.getNodeId(node) : 0;
    }
    ts.getOriginalNodeId = getOriginalNodeId;
    function containsDefaultReference(node) {
        if (!node)
            return false;
        if (!ts.isNamedImports(node))
            return false;
        return ts.some(node.elements, isNamedDefaultReference);
    }
    function isNamedDefaultReference(e) {
        return e.propertyName !== undefined && e.propertyName.escapedText === "default" /* Default */;
    }
    function chainBundle(transformSourceFile) {
        return transformSourceFileOrBundle;
        function transformSourceFileOrBundle(node) {
            return node.kind === 290 /* SourceFile */ ? transformSourceFile(node) : transformBundle(node);
        }
        function transformBundle(node) {
            return ts.createBundle(ts.map(node.sourceFiles, transformSourceFile), node.prepends);
        }
    }
    ts.chainBundle = chainBundle;
    function getExportNeedsImportStarHelper(node) {
        return !!ts.getNamespaceDeclarationNode(node);
    }
    ts.getExportNeedsImportStarHelper = getExportNeedsImportStarHelper;
    function getImportNeedsImportStarHelper(node) {
        if (!!ts.getNamespaceDeclarationNode(node)) {
            return true;
        }
        var bindings = node.importClause && node.importClause.namedBindings;
        if (!bindings) {
            return false;
        }
        if (!ts.isNamedImports(bindings))
            return false;
        var defaultRefCount = 0;
        for (var _i = 0, _a = bindings.elements; _i < _a.length; _i++) {
            var binding = _a[_i];
            if (isNamedDefaultReference(binding)) {
                defaultRefCount++;
            }
        }
        // Import star is required if there's default named refs mixed with non-default refs, or if theres non-default refs and it has a default import
        return (defaultRefCount > 0 && defaultRefCount !== bindings.elements.length) || (!!(bindings.elements.length - defaultRefCount) && ts.isDefaultImport(node));
    }
    ts.getImportNeedsImportStarHelper = getImportNeedsImportStarHelper;
    function getImportNeedsImportDefaultHelper(node) {
        // Import default is needed if there's a default import or a default ref and no other refs (meaning an import star helper wasn't requested)
        return !getImportNeedsImportStarHelper(node) && (ts.isDefaultImport(node) || (!!node.importClause && ts.isNamedImports(node.importClause.namedBindings) && containsDefaultReference(node.importClause.namedBindings))); // TODO: GH#18217
    }
    ts.getImportNeedsImportDefaultHelper = getImportNeedsImportDefaultHelper;
    function collectExternalModuleInfo(sourceFile, resolver, compilerOptions) {
        var externalImports = [];
        var exportSpecifiers = ts.createMultiMap();
        var exportedBindings = [];
        var uniqueExports = ts.createMap();
        var exportedNames;
        var hasExportDefault = false;
        var exportEquals;
        var hasExportStarsToExportValues = false;
        var hasImportStar = false;
        var hasImportDefault = false;
        for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
            var node = _a[_i];
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    // import "mod"
                    // import x from "mod"
                    // import * as x from "mod"
                    // import { x, y } from "mod"
                    externalImports.push(node);
                    if (!hasImportStar && getImportNeedsImportStarHelper(node)) {
                        hasImportStar = true;
                    }
                    if (!hasImportDefault && getImportNeedsImportDefaultHelper(node)) {
                        hasImportDefault = true;
                    }
                    break;
                case 253 /* ImportEqualsDeclaration */:
                    if (node.moduleReference.kind === 265 /* ExternalModuleReference */) {
                        // import x = require("mod")
                        externalImports.push(node);
                    }
                    break;
                case 260 /* ExportDeclaration */:
                    if (node.moduleSpecifier) {
                        if (!node.exportClause) {
                            // export * from "mod"
                            externalImports.push(node);
                            hasExportStarsToExportValues = true;
                        }
                        else {
                            // export * as ns from "mod"
                            // export { x, y } from "mod"
                            externalImports.push(node);
                        }
                    }
                    else {
                        // export { x, y }
                        for (var _b = 0, _c = ts.cast(node.exportClause, ts.isNamedExports).elements; _b < _c.length; _b++) {
                            var specifier = _c[_b];
                            if (!uniqueExports.get(ts.idText(specifier.name))) {
                                var name = specifier.propertyName || specifier.name;
                                exportSpecifiers.add(ts.idText(name), specifier);
                                var decl = resolver.getReferencedImportDeclaration(name)
                                    || resolver.getReferencedValueDeclaration(name);
                                if (decl) {
                                    multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
                                }
                                uniqueExports.set(ts.idText(specifier.name), true);
                                exportedNames = ts.append(exportedNames, specifier.name);
                            }
                        }
                    }
                    break;
                case 259 /* ExportAssignment */:
                    if (node.isExportEquals && !exportEquals) {
                        // export = x
                        exportEquals = node;
                    }
                    break;
                case 225 /* VariableStatement */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        for (var _d = 0, _e = node.declarationList.declarations; _d < _e.length; _d++) {
                            var decl = _e[_d];
                            exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames);
                        }
                    }
                    break;
                case 244 /* FunctionDeclaration */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        if (ts.hasModifier(node, 512 /* Default */)) {
                            // export default function() { }
                            if (!hasExportDefault) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
                                hasExportDefault = true;
                            }
                        }
                        else {
                            // export function x() { }
                            var name = node.name;
                            if (!uniqueExports.get(ts.idText(name))) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                uniqueExports.set(ts.idText(name), true);
                                exportedNames = ts.append(exportedNames, name);
                            }
                        }
                    }
                    break;
                case 245 /* ClassDeclaration */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        if (ts.hasModifier(node, 512 /* Default */)) {
                            // export default class { }
                            if (!hasExportDefault) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
                                hasExportDefault = true;
                            }
                        }
                        else {
                            // export class x { }
                            var name = node.name;
                            if (name && !uniqueExports.get(ts.idText(name))) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                uniqueExports.set(ts.idText(name), true);
                                exportedNames = ts.append(exportedNames, name);
                            }
                        }
                    }
                    break;
            }
        }
        var externalHelpersImportDeclaration = ts.createExternalHelpersImportDeclarationIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar, hasImportDefault);
        if (externalHelpersImportDeclaration) {
            externalImports.unshift(externalHelpersImportDeclaration);
        }
        return { externalImports: externalImports, exportSpecifiers: exportSpecifiers, exportEquals: exportEquals, hasExportStarsToExportValues: hasExportStarsToExportValues, exportedBindings: exportedBindings, exportedNames: exportedNames, externalHelpersImportDeclaration: externalHelpersImportDeclaration };
    }
    ts.collectExternalModuleInfo = collectExternalModuleInfo;
    function collectExportedVariableInfo(decl, uniqueExports, exportedNames) {
        if (ts.isBindingPattern(decl.name)) {
            for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (!ts.isOmittedExpression(element)) {
                    exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames);
                }
            }
        }
        else if (!ts.isGeneratedIdentifier(decl.name)) {
            var text = ts.idText(decl.name);
            if (!uniqueExports.get(text)) {
                uniqueExports.set(text, true);
                exportedNames = ts.append(exportedNames, decl.name);
            }
        }
        return exportedNames;
    }
    /** Use a sparse array as a multi-map. */
    function multiMapSparseArrayAdd(map, key, value) {
        var values = map[key];
        if (values) {
            values.push(value);
        }
        else {
            map[key] = values = [value];
        }
        return values;
    }
    /**
     * Used in the module transformer to check if an expression is reasonably without sideeffect,
     *  and thus better to copy into multiple places rather than to cache in a temporary variable
     *  - this is mostly subjective beyond the requirement that the expression not be sideeffecting
     */
    function isSimpleCopiableExpression(expression) {
        return ts.isStringLiteralLike(expression) ||
            expression.kind === 8 /* NumericLiteral */ ||
            ts.isKeyword(expression.kind) ||
            ts.isIdentifier(expression);
    }
    ts.isSimpleCopiableExpression = isSimpleCopiableExpression;
    /**
     * A simple inlinable expression is an expression which can be copied into multiple locations
     * without risk of repeating any sideeffects and whose value could not possibly change between
     * any such locations
     */
    function isSimpleInlineableExpression(expression) {
        return !ts.isIdentifier(expression) && isSimpleCopiableExpression(expression) ||
            ts.isWellKnownSymbolSyntactically(expression);
    }
    ts.isSimpleInlineableExpression = isSimpleInlineableExpression;
    function isCompoundAssignment(kind) {
        return kind >= 63 /* FirstCompoundAssignment */
            && kind <= 74 /* LastCompoundAssignment */;
    }
    ts.isCompoundAssignment = isCompoundAssignment;
    function getNonAssignmentOperatorForCompoundAssignment(kind) {
        switch (kind) {
            case 63 /* PlusEqualsToken */: return 39 /* PlusToken */;
            case 64 /* MinusEqualsToken */: return 40 /* MinusToken */;
            case 65 /* AsteriskEqualsToken */: return 41 /* AsteriskToken */;
            case 66 /* AsteriskAsteriskEqualsToken */: return 42 /* AsteriskAsteriskToken */;
            case 67 /* SlashEqualsToken */: return 43 /* SlashToken */;
            case 68 /* PercentEqualsToken */: return 44 /* PercentToken */;
            case 69 /* LessThanLessThanEqualsToken */: return 47 /* LessThanLessThanToken */;
            case 70 /* GreaterThanGreaterThanEqualsToken */: return 48 /* GreaterThanGreaterThanToken */;
            case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */: return 49 /* GreaterThanGreaterThanGreaterThanToken */;
            case 72 /* AmpersandEqualsToken */: return 50 /* AmpersandToken */;
            case 73 /* BarEqualsToken */: return 51 /* BarToken */;
            case 74 /* CaretEqualsToken */: return 52 /* CaretToken */;
        }
    }
    ts.getNonAssignmentOperatorForCompoundAssignment = getNonAssignmentOperatorForCompoundAssignment;
    /**
     * Adds super call and preceding prologue directives into the list of statements.
     *
     * @param ctor The constructor node.
     * @param result The list of statements.
     * @param visitor The visitor to apply to each node added to the result array.
     * @returns index of the statement that follows super call
     */
    function addPrologueDirectivesAndInitialSuperCall(ctor, result, visitor) {
        if (ctor.body) {
            var statements = ctor.body.statements;
            // add prologue directives to the list (if any)
            var index = ts.addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
            if (index === statements.length) {
                // list contains nothing but prologue directives (or empty) - exit
                return index;
            }
            var superIndex = ts.findIndex(statements, function (s) { return ts.isExpressionStatement(s) && ts.isSuperCall(s.expression); }, index);
            if (superIndex > -1) {
                for (var i = index; i <= superIndex; i++) {
                    result.push(ts.visitNode(statements[i], visitor, ts.isStatement));
                }
                return superIndex + 1;
            }
            return index;
        }
        return 0;
    }
    ts.addPrologueDirectivesAndInitialSuperCall = addPrologueDirectivesAndInitialSuperCall;
    /**
     * @param input Template string input strings
     * @param args Names which need to be made file-level unique
     */
    function helperString(input) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return function (uniqueName) {
            var result = "";
            for (var i = 0; i < args.length; i++) {
                result += input[i];
                result += uniqueName(args[i]);
            }
            result += input[input.length - 1];
            return result;
        };
    }
    ts.helperString = helperString;
    /**
     * Gets all the static or all the instance property declarations of a class
     *
     * @param node The class node.
     * @param isStatic A value indicating whether to get properties from the static or instance side of the class.
     */
    function getProperties(node, requireInitializer, isStatic) {
        return ts.filter(node.members, function (m) { return isInitializedOrStaticProperty(m, requireInitializer, isStatic); });
    }
    ts.getProperties = getProperties;
    /**
     * Is a class element either a static or an instance property declaration with an initializer?
     *
     * @param member The class element node.
     * @param isStatic A value indicating whether the member should be a static or instance member.
     */
    function isInitializedOrStaticProperty(member, requireInitializer, isStatic) {
        return ts.isPropertyDeclaration(member)
            && (!!member.initializer || !requireInitializer)
            && ts.hasStaticModifier(member) === isStatic;
    }
    /**
     * Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.
     *
     * @param member The class element node.
     * @param isStatic A value indicating whether the member should be a static or instance member.
     */
    function isInitializedProperty(member) {
        return member.kind === 159 /* PropertyDeclaration */
            && member.initializer !== undefined;
    }
    ts.isInitializedProperty = isInitializedProperty;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var FlattenLevel;
    (function (FlattenLevel) {
        FlattenLevel[FlattenLevel["All"] = 0] = "All";
        FlattenLevel[FlattenLevel["ObjectRest"] = 1] = "ObjectRest";
    })(FlattenLevel = ts.FlattenLevel || (ts.FlattenLevel = {}));
    /**
     * Flattens a DestructuringAssignment or a VariableDeclaration to an expression.
     *
     * @param node The node to flatten.
     * @param visitor An optional visitor used to visit initializers.
     * @param context The transformation context.
     * @param level Indicates the extent to which flattening should occur.
     * @param needsValue An optional value indicating whether the value from the right-hand-side of
     * the destructuring assignment is needed as part of a larger expression.
     * @param createAssignmentCallback An optional callback used to create the assignment expression.
     */
    function flattenDestructuringAssignment(node, visitor, context, level, needsValue, createAssignmentCallback) {
        var location = node;
        var value;
        if (ts.isDestructuringAssignment(node)) {
            value = node.right;
            while (ts.isEmptyArrayLiteral(node.left) || ts.isEmptyObjectLiteral(node.left)) {
                if (ts.isDestructuringAssignment(value)) {
                    location = node = value;
                    value = node.right;
                }
                else {
                    return ts.visitNode(value, visitor, ts.isExpression);
                }
            }
        }
        var expressions;
        var flattenContext = {
            context: context,
            level: level,
            downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
            hoistTempVariables: true,
            emitExpression: emitExpression,
            emitBindingOrAssignment: emitBindingOrAssignment,
            createArrayBindingOrAssignmentPattern: makeArrayAssignmentPattern,
            createObjectBindingOrAssignmentPattern: makeObjectAssignmentPattern,
            createArrayBindingOrAssignmentElement: makeAssignmentElement,
            visitor: visitor
        };
        if (value) {
            value = ts.visitNode(value, visitor, ts.isExpression);
            if (ts.isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText) ||
                bindingOrAssignmentElementContainsNonLiteralComputedName(node)) {
                // If the right-hand value of the assignment is also an assignment target then
                // we need to cache the right-hand value.
                value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ false, location);
            }
            else if (needsValue) {
                // If the right-hand value of the destructuring assignment needs to be preserved (as
                // is the case when the destructuring assignment is part of a larger expression),
                // then we need to cache the right-hand value.
                //
                // The source map location for the assignment should point to the entire binary
                // expression.
                value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
            }
            else if (ts.nodeIsSynthesized(node)) {
                // Generally, the source map location for a destructuring assignment is the root
                // expression.
                //
                // However, if the root expression is synthesized (as in the case
                // of the initializer when transforming a ForOfStatement), then the source map
                // location should point to the right-hand value of the expression.
                location = value;
            }
        }
        flattenBindingOrAssignmentElement(flattenContext, node, value, location, /*skipInitializer*/ ts.isDestructuringAssignment(node));
        if (value && needsValue) {
            if (!ts.some(expressions)) {
                return value;
            }
            expressions.push(value);
        }
        return ts.aggregateTransformFlags(ts.inlineExpressions(expressions)) || ts.createOmittedExpression();
        function emitExpression(expression) {
            ts.aggregateTransformFlags(expression);
            expressions = ts.append(expressions, expression);
        }
        function emitBindingOrAssignment(target, value, location, original) {
            ts.Debug.assertNode(target, createAssignmentCallback ? ts.isIdentifier : ts.isExpression);
            var expression = createAssignmentCallback
                ? createAssignmentCallback(target, value, location)
                : ts.setTextRange(ts.createAssignment(ts.visitNode(target, visitor, ts.isExpression), value), location);
            expression.original = original;
            emitExpression(expression);
        }
    }
    ts.flattenDestructuringAssignment = flattenDestructuringAssignment;
    function bindingOrAssignmentElementAssignsToName(element, escapedName) {
        var target = ts.getTargetOfBindingOrAssignmentElement(element); // TODO: GH#18217
        if (ts.isBindingOrAssignmentPattern(target)) {
            return bindingOrAssignmentPatternAssignsToName(target, escapedName);
        }
        else if (ts.isIdentifier(target)) {
            return target.escapedText === escapedName;
        }
        return false;
    }
    function bindingOrAssignmentPatternAssignsToName(pattern, escapedName) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        for (var _i = 0, elements_3 = elements; _i < elements_3.length; _i++) {
            var element = elements_3[_i];
            if (bindingOrAssignmentElementAssignsToName(element, escapedName)) {
                return true;
            }
        }
        return false;
    }
    function bindingOrAssignmentElementContainsNonLiteralComputedName(element) {
        var propertyName = ts.tryGetPropertyNameOfBindingOrAssignmentElement(element);
        if (propertyName && ts.isComputedPropertyName(propertyName) && !ts.isLiteralExpression(propertyName.expression)) {
            return true;
        }
        var target = ts.getTargetOfBindingOrAssignmentElement(element);
        return !!target && ts.isBindingOrAssignmentPattern(target) && bindingOrAssignmentPatternContainsNonLiteralComputedName(target);
    }
    function bindingOrAssignmentPatternContainsNonLiteralComputedName(pattern) {
        return !!ts.forEach(ts.getElementsOfBindingOrAssignmentPattern(pattern), bindingOrAssignmentElementContainsNonLiteralComputedName);
    }
    /**
     * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations.
     *
     * @param node The node to flatten.
     * @param visitor An optional visitor used to visit initializers.
     * @param context The transformation context.
     * @param boundValue The value bound to the declaration.
     * @param skipInitializer A value indicating whether to ignore the initializer of `node`.
     * @param hoistTempVariables Indicates whether temporary variables should not be recorded in-line.
     * @param level Indicates the extent to which flattening should occur.
     */
    function flattenDestructuringBinding(node, visitor, context, level, rval, hoistTempVariables, skipInitializer) {
        if (hoistTempVariables === void 0) { hoistTempVariables = false; }
        var pendingExpressions;
        var pendingDeclarations = [];
        var declarations = [];
        var flattenContext = {
            context: context,
            level: level,
            downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
            hoistTempVariables: hoistTempVariables,
            emitExpression: emitExpression,
            emitBindingOrAssignment: emitBindingOrAssignment,
            createArrayBindingOrAssignmentPattern: makeArrayBindingPattern,
            createObjectBindingOrAssignmentPattern: makeObjectBindingPattern,
            createArrayBindingOrAssignmentElement: makeBindingElement,
            visitor: visitor
        };
        if (ts.isVariableDeclaration(node)) {
            var initializer = ts.getInitializerOfBindingOrAssignmentElement(node);
            if (initializer && (ts.isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText) ||
                bindingOrAssignmentElementContainsNonLiteralComputedName(node))) {
                // If the right-hand value of the assignment is also an assignment target then
                // we need to cache the right-hand value.
                initializer = ensureIdentifier(flattenContext, initializer, /*reuseIdentifierExpressions*/ false, initializer);
                node = ts.updateVariableDeclaration(node, node.name, node.type, initializer);
            }
        }
        flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer);
        if (pendingExpressions) {
            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
            if (hoistTempVariables) {
                var value = ts.inlineExpressions(pendingExpressions);
                pendingExpressions = undefined;
                emitBindingOrAssignment(temp, value, /*location*/ undefined, /*original*/ undefined);
            }
            else {
                context.hoistVariableDeclaration(temp);
                var pendingDeclaration = ts.last(pendingDeclarations);
                pendingDeclaration.pendingExpressions = ts.append(pendingDeclaration.pendingExpressions, ts.createAssignment(temp, pendingDeclaration.value));
                ts.addRange(pendingDeclaration.pendingExpressions, pendingExpressions);
                pendingDeclaration.value = temp;
            }
        }
        for (var _i = 0, pendingDeclarations_1 = pendingDeclarations; _i < pendingDeclarations_1.length; _i++) {
            var _a = pendingDeclarations_1[_i], pendingExpressions_1 = _a.pendingExpressions, name = _a.name, value = _a.value, location = _a.location, original = _a.original;
            var variable = ts.createVariableDeclaration(name, 
            /*type*/ undefined, pendingExpressions_1 ? ts.inlineExpressions(ts.append(pendingExpressions_1, value)) : value);
            variable.original = original;
            ts.setTextRange(variable, location);
            ts.aggregateTransformFlags(variable);
            declarations.push(variable);
        }
        return declarations;
        function emitExpression(value) {
            pendingExpressions = ts.append(pendingExpressions, value);
        }
        function emitBindingOrAssignment(target, value, location, original) {
            ts.Debug.assertNode(target, ts.isBindingName);
            if (pendingExpressions) {
                value = ts.inlineExpressions(ts.append(pendingExpressions, value));
                pendingExpressions = undefined;
            }
            pendingDeclarations.push({ pendingExpressions: pendingExpressions, name: target, value: value, location: location, original: original });
        }
    }
    ts.flattenDestructuringBinding = flattenDestructuringBinding;
    /**
     * Flattens a BindingOrAssignmentElement into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param element The element to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     * @param skipInitializer An optional value indicating whether to include the initializer
     * for the element.
     */
    function flattenBindingOrAssignmentElement(flattenContext, element, value, location, skipInitializer) {
        if (!skipInitializer) {
            var initializer = ts.visitNode(ts.getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, ts.isExpression);
            if (initializer) {
                // Combine value and initializer
                value = value ? createDefaultValueCheck(flattenContext, value, initializer, location) : initializer;
            }
            else if (!value) {
                // Use 'void 0' in absence of value and initializer
                value = ts.createVoidZero();
            }
        }
        var bindingTarget = ts.getTargetOfBindingOrAssignmentElement(element); // TODO: GH#18217
        if (ts.isObjectBindingOrAssignmentPattern(bindingTarget)) {
            flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
        }
        else if (ts.isArrayBindingOrAssignmentPattern(bindingTarget)) {
            flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
        }
        else {
            flattenContext.emitBindingOrAssignment(bindingTarget, value, location, /*original*/ element); // TODO: GH#18217
        }
    }
    /**
     * Flattens an ObjectBindingOrAssignmentPattern into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param parent The parent element of the pattern.
     * @param pattern The ObjectBindingOrAssignmentPattern to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     */
    function flattenObjectBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        var numElements = elements.length;
        if (numElements !== 1) {
            // For anything other than a single-element destructuring we need to generate a temporary
            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
            // so in that case, we'll intentionally create that temporary.
            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
        }
        var bindingElements;
        var computedTempVariables;
        for (var i = 0; i < numElements; i++) {
            var element = elements[i];
            if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
                var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(element);
                if (flattenContext.level >= 1 /* ObjectRest */
                    && !(element.transformFlags & (8192 /* ContainsRestOrSpread */ | 16384 /* ContainsObjectRestOrSpread */))
                    && !(ts.getTargetOfBindingOrAssignmentElement(element).transformFlags & (8192 /* ContainsRestOrSpread */ | 16384 /* ContainsObjectRestOrSpread */))
                    && !ts.isComputedPropertyName(propertyName)) {
                    bindingElements = ts.append(bindingElements, ts.visitNode(element, flattenContext.visitor));
                }
                else {
                    if (bindingElements) {
                        flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
                        bindingElements = undefined;
                    }
                    var rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName);
                    if (ts.isComputedPropertyName(propertyName)) {
                        computedTempVariables = ts.append(computedTempVariables, rhsValue.argumentExpression);
                    }
                    flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
                }
            }
            else if (i === numElements - 1) {
                if (bindingElements) {
                    flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
                    bindingElements = undefined;
                }
                var rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables, pattern); // TODO: GH#18217
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element);
            }
        }
        if (bindingElements) {
            flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        }
    }
    /**
     * Flattens an ArrayBindingOrAssignmentPattern into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param parent The parent element of the pattern.
     * @param pattern The ArrayBindingOrAssignmentPattern to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     */
    function flattenArrayBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        var numElements = elements.length;
        if (flattenContext.level < 1 /* ObjectRest */ && flattenContext.downlevelIteration) {
            // Read the elements of the iterable into an array
            value = ensureIdentifier(flattenContext, ts.createReadHelper(flattenContext.context, value, numElements > 0 && ts.getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1])
                ? undefined
                : numElements, location), 
            /*reuseIdentifierExpressions*/ false, location);
        }
        else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0)
            || ts.every(elements, ts.isOmittedExpression)) {
            // For anything other than a single-element destructuring we need to generate a temporary
            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
            // so in that case, we'll intentionally create that temporary.
            // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]",
            // then we will create temporary variable.
            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
        }
        var bindingElements;
        var restContainingElements;
        for (var i = 0; i < numElements; i++) {
            var element = elements[i];
            if (flattenContext.level >= 1 /* ObjectRest */) {
                // If an array pattern contains an ObjectRest, we must cache the result so that we
                // can perform the ObjectRest destructuring in a different declaration
                if (element.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                    var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                    if (flattenContext.hoistTempVariables) {
                        flattenContext.context.hoistVariableDeclaration(temp);
                    }
                    restContainingElements = ts.append(restContainingElements, [temp, element]);
                    bindingElements = ts.append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp));
                }
                else {
                    bindingElements = ts.append(bindingElements, element);
                }
            }
            else if (ts.isOmittedExpression(element)) {
                continue;
            }
            else if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
                var rhsValue = ts.createElementAccess(value, i);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
            }
            else if (i === numElements - 1) {
                var rhsValue = ts.createArraySlice(value, i);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
            }
        }
        if (bindingElements) {
            flattenContext.emitBindingOrAssignment(flattenContext.createArrayBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        }
        if (restContainingElements) {
            for (var _i = 0, restContainingElements_1 = restContainingElements; _i < restContainingElements_1.length; _i++) {
                var _a = restContainingElements_1[_i], id = _a[0], element = _a[1];
                flattenBindingOrAssignmentElement(flattenContext, element, id, element);
            }
        }
    }
    /**
     * Creates an expression used to provide a default value if a value is `undefined` at runtime.
     *
     * @param flattenContext Options used to control flattening.
     * @param value The RHS value to test.
     * @param defaultValue The default value to use if `value` is `undefined` at runtime.
     * @param location The location to use for source maps and comments.
     */
    function createDefaultValueCheck(flattenContext, value, defaultValue, location) {
        value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
        return ts.createConditional(ts.createTypeCheck(value, "undefined"), defaultValue, value);
    }
    /**
     * Creates either a PropertyAccessExpression or an ElementAccessExpression for the
     * right-hand side of a transformed destructuring assignment.
     *
     * @link https://tc39.github.io/ecma262/#sec-runtime-semantics-keyeddestructuringassignmentevaluation
     *
     * @param flattenContext Options used to control flattening.
     * @param value The RHS value that is the source of the property.
     * @param propertyName The destructuring property name.
     */
    function createDestructuringPropertyAccess(flattenContext, value, propertyName) {
        if (ts.isComputedPropertyName(propertyName)) {
            var argumentExpression = ensureIdentifier(flattenContext, ts.visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
            return ts.createElementAccess(value, argumentExpression);
        }
        else if (ts.isStringOrNumericLiteralLike(propertyName)) {
            var argumentExpression = ts.getSynthesizedClone(propertyName);
            argumentExpression.text = argumentExpression.text;
            return ts.createElementAccess(value, argumentExpression);
        }
        else {
            var name = ts.createIdentifier(ts.idText(propertyName));
            return ts.createPropertyAccess(value, name);
        }
    }
    /**
     * Ensures that there exists a declared identifier whose value holds the given expression.
     * This function is useful to ensure that the expression's value can be read from in subsequent expressions.
     * Unless 'reuseIdentifierExpressions' is false, 'value' will be returned if it is just an identifier.
     *
     * @param flattenContext Options used to control flattening.
     * @param value the expression whose value needs to be bound.
     * @param reuseIdentifierExpressions true if identifier expressions can simply be returned;
     * false if it is necessary to always emit an identifier.
     * @param location The location to use for source maps and comments.
     */
    function ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location) {
        if (ts.isIdentifier(value) && reuseIdentifierExpressions) {
            return value;
        }
        else {
            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
            if (flattenContext.hoistTempVariables) {
                flattenContext.context.hoistVariableDeclaration(temp);
                flattenContext.emitExpression(ts.setTextRange(ts.createAssignment(temp, value), location));
            }
            else {
                flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined);
            }
            return temp;
        }
    }
    function makeArrayBindingPattern(elements) {
        ts.Debug.assertEachNode(elements, ts.isArrayBindingElement);
        return ts.createArrayBindingPattern(elements);
    }
    function makeArrayAssignmentPattern(elements) {
        return ts.createArrayLiteral(ts.map(elements, ts.convertToArrayAssignmentElement));
    }
    function makeObjectBindingPattern(elements) {
        ts.Debug.assertEachNode(elements, ts.isBindingElement);
        return ts.createObjectBindingPattern(elements);
    }
    function makeObjectAssignmentPattern(elements) {
        return ts.createObjectLiteral(ts.map(elements, ts.convertToObjectAssignmentElement));
    }
    function makeBindingElement(name) {
        return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name);
    }
    function makeAssignmentElement(name) {
        return name;
    }
    ts.restHelper = {
        name: "typescript:rest",
        importName: "__rest",
        scoped: false,
        text: "\n            var __rest = (this && this.__rest) || function (s, e) {\n                var t = {};\n                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n                    t[p] = s[p];\n                if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n                    for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n                        if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n                            t[p[i]] = s[p[i]];\n                    }\n                return t;\n            };"
    };
    /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
     * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`
     */
    function createRestCall(context, value, elements, computedTempVariables, location) {
        context.requestEmitHelper(ts.restHelper);
        var propertyNames = [];
        var computedTempVariableOffset = 0;
        for (var i = 0; i < elements.length - 1; i++) {
            var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(elements[i]);
            if (propertyName) {
                if (ts.isComputedPropertyName(propertyName)) {
                    var temp = computedTempVariables[computedTempVariableOffset];
                    computedTempVariableOffset++;
                    // typeof _tmp === "symbol" ? _tmp : _tmp + ""
                    propertyNames.push(ts.createConditional(ts.createTypeCheck(temp, "symbol"), temp, ts.createAdd(temp, ts.createLiteral(""))));
                }
                else {
                    propertyNames.push(ts.createLiteral(propertyName));
                }
            }
        }
        return ts.createCall(ts.getUnscopedHelperName("__rest"), 
        /*typeArguments*/ undefined, [
            value,
            ts.setTextRange(ts.createArrayLiteral(propertyNames), location)
        ]);
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ProcessLevel;
    (function (ProcessLevel) {
        ProcessLevel[ProcessLevel["LiftRestriction"] = 0] = "LiftRestriction";
        ProcessLevel[ProcessLevel["All"] = 1] = "All";
    })(ProcessLevel = ts.ProcessLevel || (ts.ProcessLevel = {}));
    function processTaggedTemplateExpression(context, node, visitor, currentSourceFile, recordTaggedTemplateString, level) {
        // Visit the tag expression
        var tag = ts.visitNode(node.tag, visitor, ts.isExpression);
        // Build up the template arguments and the raw and cooked strings for the template.
        // We start out with 'undefined' for the first argument and revisit later
        // to avoid walking over the template string twice and shifting all our arguments over after the fact.
        var templateArguments = [undefined];
        var cookedStrings = [];
        var rawStrings = [];
        var template = node.template;
        if (level === ProcessLevel.LiftRestriction && !ts.hasInvalidEscape(template))
            return node;
        if (ts.isNoSubstitutionTemplateLiteral(template)) {
            cookedStrings.push(createTemplateCooked(template));
            rawStrings.push(getRawLiteral(template, currentSourceFile));
        }
        else {
            cookedStrings.push(createTemplateCooked(template.head));
            rawStrings.push(getRawLiteral(template.head, currentSourceFile));
            for (var _i = 0, _a = template.templateSpans; _i < _a.length; _i++) {
                var templateSpan = _a[_i];
                cookedStrings.push(createTemplateCooked(templateSpan.literal));
                rawStrings.push(getRawLiteral(templateSpan.literal, currentSourceFile));
                templateArguments.push(ts.visitNode(templateSpan.expression, visitor, ts.isExpression));
            }
        }
        var helperCall = createTemplateObjectHelper(context, ts.createArrayLiteral(cookedStrings), ts.createArrayLiteral(rawStrings));
        // Create a variable to cache the template object if we're in a module.
        // Do not do this in the global scope, as any variable we currently generate could conflict with
        // variables from outside of the current compilation. In the future, we can revisit this behavior.
        if (ts.isExternalModule(currentSourceFile)) {
            var tempVar = ts.createUniqueName("templateObject");
            recordTaggedTemplateString(tempVar);
            templateArguments[0] = ts.createLogicalOr(tempVar, ts.createAssignment(tempVar, helperCall));
        }
        else {
            templateArguments[0] = helperCall;
        }
        return ts.createCall(tag, /*typeArguments*/ undefined, templateArguments);
    }
    ts.processTaggedTemplateExpression = processTaggedTemplateExpression;
    function createTemplateCooked(template) {
        return template.templateFlags ? ts.createIdentifier("undefined") : ts.createLiteral(template.text);
    }
    /**
     * Creates an ES5 compatible literal from an ES6 template literal.
     *
     * @param node The ES6 template literal.
     */
    function getRawLiteral(node, currentSourceFile) {
        // Find original source text, since we need to emit the raw strings of the tagged template.
        // The raw strings contain the (escaped) strings of what the user wrote.
        // Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
        var text = node.rawText;
        if (text === undefined) {
            text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
            // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
            // thus we need to remove those characters.
            // First template piece starts with "`", others with "}"
            // Last template piece ends with "`", others with "${"
            var isLast = node.kind === 14 /* NoSubstitutionTemplateLiteral */ || node.kind === 17 /* TemplateTail */;
            text = text.substring(1, text.length - (isLast ? 1 : 2));
        }
        // Newline normalization:
        // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
        // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
        text = text.replace(/\r\n?/g, "\n");
        return ts.setTextRange(ts.createLiteral(text), node);
    }
    function createTemplateObjectHelper(context, cooked, raw) {
        context.requestEmitHelper(ts.templateObjectHelper);
        return ts.createCall(ts.getUnscopedHelperName("__makeTemplateObject"), 
        /*typeArguments*/ undefined, [
            cooked,
            raw
        ]);
    }
    ts.templateObjectHelper = {
        name: "typescript:makeTemplateObject",
        importName: "__makeTemplateObject",
        scoped: false,
        priority: 0,
        text: "\n            var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {\n                if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n                return cooked;\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /**
     * Indicates whether to emit type metadata in the new format.
     */
    var USE_NEW_TYPE_METADATA_FORMAT = false;
    var TypeScriptSubstitutionFlags;
    (function (TypeScriptSubstitutionFlags) {
        /** Enables substitutions for decorated classes. */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["ClassAliases"] = 1] = "ClassAliases";
        /** Enables substitutions for namespace exports. */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NamespaceExports"] = 2] = "NamespaceExports";
        /* Enables substitutions for unqualified enum members */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NonQualifiedEnumMembers"] = 8] = "NonQualifiedEnumMembers";
    })(TypeScriptSubstitutionFlags || (TypeScriptSubstitutionFlags = {}));
    var ClassFacts;
    (function (ClassFacts) {
        ClassFacts[ClassFacts["None"] = 0] = "None";
        ClassFacts[ClassFacts["HasStaticInitializedProperties"] = 1] = "HasStaticInitializedProperties";
        ClassFacts[ClassFacts["HasConstructorDecorators"] = 2] = "HasConstructorDecorators";
        ClassFacts[ClassFacts["HasMemberDecorators"] = 4] = "HasMemberDecorators";
        ClassFacts[ClassFacts["IsExportOfNamespace"] = 8] = "IsExportOfNamespace";
        ClassFacts[ClassFacts["IsNamedExternalExport"] = 16] = "IsNamedExternalExport";
        ClassFacts[ClassFacts["IsDefaultExternalExport"] = 32] = "IsDefaultExternalExport";
        ClassFacts[ClassFacts["IsDerivedClass"] = 64] = "IsDerivedClass";
        ClassFacts[ClassFacts["UseImmediatelyInvokedFunctionExpression"] = 128] = "UseImmediatelyInvokedFunctionExpression";
        ClassFacts[ClassFacts["HasAnyDecorators"] = 6] = "HasAnyDecorators";
        ClassFacts[ClassFacts["NeedsName"] = 5] = "NeedsName";
        ClassFacts[ClassFacts["MayNeedImmediatelyInvokedFunctionExpression"] = 7] = "MayNeedImmediatelyInvokedFunctionExpression";
        ClassFacts[ClassFacts["IsExported"] = 56] = "IsExported";
    })(ClassFacts || (ClassFacts = {}));
    function transformTypeScript(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks");
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        // Save the previous transformation hooks.
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        // Set new transformation hooks.
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        // Enable substitution for property/element access to emit const enum values.
        context.enableSubstitution(194 /* PropertyAccessExpression */);
        context.enableSubstitution(195 /* ElementAccessExpression */);
        // These variables contain state that changes as we descend into the tree.
        var currentSourceFile;
        var currentNamespace;
        var currentNamespaceContainerName;
        var currentLexicalScope;
        var currentNameScope;
        var currentScopeFirstDeclarationsOfName;
        var currentClassHasParameterProperties;
        /**
         * Keeps track of whether expression substitution has been enabled for specific edge cases.
         * They are persisted between each SourceFile transformation and should not be reset.
         */
        var enabledSubstitutions;
        /**
         * A map that keeps track of aliases created for classes with decorators to avoid issues
         * with the double-binding behavior of classes.
         */
        var classAliases;
        /**
         * Keeps track of whether we are within any containing namespaces when performing
         * just-in-time substitution while printing an expression identifier.
         */
        var applicableSubstitutions;
        return transformSourceFileOrBundle;
        function transformSourceFileOrBundle(node) {
            if (node.kind === 291 /* Bundle */) {
                return transformBundle(node);
            }
            return transformSourceFile(node);
        }
        function transformBundle(node) {
            return ts.createBundle(node.sourceFiles.map(transformSourceFile), ts.mapDefined(node.prepends, function (prepend) {
                if (prepend.kind === 293 /* InputFiles */) {
                    return ts.createUnparsedSourceFile(prepend, "js");
                }
                return prepend;
            }));
        }
        /**
         * Transform TypeScript-specific syntax in a SourceFile.
         *
         * @param node A SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = saveStateAndInvoke(node, visitSourceFile);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            return visited;
        }
        /**
         * Visits a node, saving and restoring state variables on the stack.
         *
         * @param node The node to visit.
         */
        function saveStateAndInvoke(node, f) {
            // Save state
            var savedCurrentScope = currentLexicalScope;
            var savedCurrentNameScope = currentNameScope;
            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
            var savedCurrentClassHasParameterProperties = currentClassHasParameterProperties;
            // Handle state changes before visiting a node.
            onBeforeVisitNode(node);
            var visited = f(node);
            // Restore state
            if (currentLexicalScope !== savedCurrentScope) {
                currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
            }
            currentLexicalScope = savedCurrentScope;
            currentNameScope = savedCurrentNameScope;
            currentClassHasParameterProperties = savedCurrentClassHasParameterProperties;
            return visited;
        }
        /**
         * Performs actions that should always occur immediately before visiting a node.
         *
         * @param node The node to visit.
         */
        function onBeforeVisitNode(node) {
            switch (node.kind) {
                case 290 /* SourceFile */:
                case 251 /* CaseBlock */:
                case 250 /* ModuleBlock */:
                case 223 /* Block */:
                    currentLexicalScope = node;
                    currentNameScope = undefined;
                    currentScopeFirstDeclarationsOfName = undefined;
                    break;
                case 245 /* ClassDeclaration */:
                case 244 /* FunctionDeclaration */:
                    if (ts.hasModifier(node, 2 /* Ambient */)) {
                        break;
                    }
                    // Record these declarations provided that they have a name.
                    if (node.name) {
                        recordEmittedDeclarationInScope(node);
                    }
                    else {
                        // These nodes should always have names unless they are default-exports;
                        // however, class declaration parsing allows for undefined names, so syntactically invalid
                        // programs may also have an undefined name.
                        ts.Debug.assert(node.kind === 245 /* ClassDeclaration */ || ts.hasModifier(node, 512 /* Default */));
                    }
                    if (ts.isClassDeclaration(node)) {
                        // XXX: should probably also cover interfaces and type aliases that can have type variables?
                        currentNameScope = node;
                    }
                    break;
            }
        }
        /**
         * General-purpose node visitor.
         *
         * @param node The node to visit.
         */
        function visitor(node) {
            return saveStateAndInvoke(node, visitorWorker);
        }
        /**
         * Visits and possibly transforms any node.
         *
         * @param node The node to visit.
         */
        function visitorWorker(node) {
            if (node.transformFlags & 1 /* ContainsTypeScript */) {
                return visitTypeScript(node);
            }
            return node;
        }
        /**
         * Specialized visitor that visits the immediate children of a SourceFile.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            return saveStateAndInvoke(node, sourceElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a SourceFile.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitorWorker(node) {
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                case 253 /* ImportEqualsDeclaration */:
                case 259 /* ExportAssignment */:
                case 260 /* ExportDeclaration */:
                    return visitEllidableStatement(node);
                default:
                    return visitorWorker(node);
            }
        }
        function visitEllidableStatement(node) {
            var parsed = ts.getParseTreeNode(node);
            if (parsed !== node) {
                // If the node has been transformed by a `before` transformer, perform no ellision on it
                // As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
                // We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by the switch-case in `visitTypeScript`,
                // and will trigger debug failures when debug verbosity is turned up
                if (node.transformFlags & 1 /* ContainsTypeScript */) {
                    // This node contains TypeScript, so we should visit its children.
                    return ts.visitEachChild(node, visitor, context);
                }
                // Otherwise, we can just return the node
                return node;
            }
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 259 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 260 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                default:
                    ts.Debug.fail("Unhandled ellided statement");
            }
        }
        /**
         * Specialized visitor that visits the immediate children of a namespace.
         *
         * @param node The node to visit.
         */
        function namespaceElementVisitor(node) {
            return saveStateAndInvoke(node, namespaceElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a namespace.
         *
         * @param node The node to visit.
         */
        function namespaceElementVisitorWorker(node) {
            if (node.kind === 260 /* ExportDeclaration */ ||
                node.kind === 254 /* ImportDeclaration */ ||
                node.kind === 255 /* ImportClause */ ||
                (node.kind === 253 /* ImportEqualsDeclaration */ &&
                    node.moduleReference.kind === 265 /* ExternalModuleReference */)) {
                // do not emit ES6 imports and exports since they are illegal inside a namespace
                return undefined;
            }
            else if (node.transformFlags & 1 /* ContainsTypeScript */ || ts.hasModifier(node, 1 /* Export */)) {
                return visitTypeScript(node);
            }
            return node;
        }
        /**
         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
         *
         * @param node The node to visit.
         */
        function classElementVisitor(node) {
            return saveStateAndInvoke(node, classElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
         *
         * @param node The node to visit.
         */
        function classElementVisitorWorker(node) {
            switch (node.kind) {
                case 162 /* Constructor */:
                    return visitConstructor(node);
                case 159 /* PropertyDeclaration */:
                    // Property declarations are not TypeScript syntax, but they must be visited
                    // for the decorator transformation.
                    return visitPropertyDeclaration(node);
                case 167 /* IndexSignature */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 161 /* MethodDeclaration */:
                    // Fallback to the default visit behavior.
                    return visitorWorker(node);
                case 222 /* SemicolonClassElement */:
                    return node;
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function modifierVisitor(node) {
            if (ts.modifierToFlag(node.kind) & 2270 /* TypeScriptModifier */) {
                return undefined;
            }
            else if (currentNamespace && node.kind === 89 /* ExportKeyword */) {
                return undefined;
            }
            return node;
        }
        /**
         * Branching visitor, visits a TypeScript syntax node.
         *
         * @param node The node to visit.
         */
        function visitTypeScript(node) {
            if (ts.isStatement(node) && ts.hasModifier(node, 2 /* Ambient */)) {
                // TypeScript ambient declarations are elided, but some comments may be preserved.
                // See the implementation of `getLeadingComments` in comments.ts for more details.
                return ts.createNotEmittedStatement(node);
            }
            switch (node.kind) {
                case 89 /* ExportKeyword */:
                case 84 /* DefaultKeyword */:
                    // ES6 export and default modifiers are elided when inside a namespace.
                    return currentNamespace ? undefined : node;
                case 119 /* PublicKeyword */:
                case 117 /* PrivateKeyword */:
                case 118 /* ProtectedKeyword */:
                case 122 /* AbstractKeyword */:
                case 81 /* ConstKeyword */:
                case 130 /* DeclareKeyword */:
                case 138 /* ReadonlyKeyword */:
                // TypeScript accessibility and readonly modifiers are elided
                // falls through
                case 174 /* ArrayType */:
                case 175 /* TupleType */:
                case 176 /* OptionalType */:
                case 177 /* RestType */:
                case 173 /* TypeLiteral */:
                case 168 /* TypePredicate */:
                case 155 /* TypeParameter */:
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 128 /* BooleanKeyword */:
                case 143 /* StringKeyword */:
                case 140 /* NumberKeyword */:
                case 137 /* NeverKeyword */:
                case 110 /* VoidKeyword */:
                case 144 /* SymbolKeyword */:
                case 171 /* ConstructorType */:
                case 170 /* FunctionType */:
                case 172 /* TypeQuery */:
                case 169 /* TypeReference */:
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                case 180 /* ConditionalType */:
                case 182 /* ParenthesizedType */:
                case 183 /* ThisType */:
                case 184 /* TypeOperator */:
                case 185 /* IndexedAccessType */:
                case 186 /* MappedType */:
                case 187 /* LiteralType */:
                // TypeScript type nodes are elided.
                // falls through
                case 167 /* IndexSignature */:
                // TypeScript index signatures are elided.
                // falls through
                case 157 /* Decorator */:
                // TypeScript decorators are elided. They will be emitted as part of visitClassDeclaration.
                // falls through
                case 247 /* TypeAliasDeclaration */:
                    // TypeScript type-only declarations are elided.
                    return undefined;
                case 159 /* PropertyDeclaration */:
                    // TypeScript property declarations are elided. However their names are still visited, and can potentially be retained if they could have sideeffects
                    return visitPropertyDeclaration(node);
                case 252 /* NamespaceExportDeclaration */:
                    // TypeScript namespace export declarations are elided.
                    return undefined;
                case 162 /* Constructor */:
                    return visitConstructor(node);
                case 246 /* InterfaceDeclaration */:
                    // TypeScript interfaces are elided, but some comments may be preserved.
                    // See the implementation of `getLeadingComments` in comments.ts for more details.
                    return ts.createNotEmittedStatement(node);
                case 245 /* ClassDeclaration */:
                    // This may be a class declaration with TypeScript syntax extensions.
                    //
                    // TypeScript class syntax extensions include:
                    // - decorators
                    // - optional `implements` heritage clause
                    // - parameter property assignments in the constructor
                    // - index signatures
                    // - method overload signatures
                    return visitClassDeclaration(node);
                case 214 /* ClassExpression */:
                    // This may be a class expression with TypeScript syntax extensions.
                    //
                    // TypeScript class syntax extensions include:
                    // - decorators
                    // - optional `implements` heritage clause
                    // - parameter property assignments in the constructor
                    // - index signatures
                    // - method overload signatures
                    return visitClassExpression(node);
                case 279 /* HeritageClause */:
                    // This may be a heritage clause with TypeScript syntax extensions.
                    //
                    // TypeScript heritage clause extensions include:
                    // - `implements` clause
                    return visitHeritageClause(node);
                case 216 /* ExpressionWithTypeArguments */:
                    // TypeScript supports type arguments on an expression in an `extends` heritage clause.
                    return visitExpressionWithTypeArguments(node);
                case 161 /* MethodDeclaration */:
                    // TypeScript method declarations may have decorators, modifiers
                    // or type annotations.
                    return visitMethodDeclaration(node);
                case 163 /* GetAccessor */:
                    // Get Accessors can have TypeScript modifiers, decorators, and type annotations.
                    return visitGetAccessor(node);
                case 164 /* SetAccessor */:
                    // Set Accessors can have TypeScript modifiers and type annotations.
                    return visitSetAccessor(node);
                case 244 /* FunctionDeclaration */:
                    // Typescript function declarations can have modifiers, decorators, and type annotations.
                    return visitFunctionDeclaration(node);
                case 201 /* FunctionExpression */:
                    // TypeScript function expressions can have modifiers and type annotations.
                    return visitFunctionExpression(node);
                case 202 /* ArrowFunction */:
                    // TypeScript arrow functions can have modifiers and type annotations.
                    return visitArrowFunction(node);
                case 156 /* Parameter */:
                    // This may be a parameter declaration with TypeScript syntax extensions.
                    //
                    // TypeScript parameter declaration syntax extensions include:
                    // - decorators
                    // - accessibility modifiers
                    // - the question mark (?) token for optional parameters
                    // - type annotations
                    // - this parameters
                    return visitParameter(node);
                case 200 /* ParenthesizedExpression */:
                    // ParenthesizedExpressions are TypeScript if their expression is a
                    // TypeAssertion or AsExpression
                    return visitParenthesizedExpression(node);
                case 199 /* TypeAssertionExpression */:
                case 217 /* AsExpression */:
                    // TypeScript type assertions are removed, but their subtrees are preserved.
                    return visitAssertionExpression(node);
                case 196 /* CallExpression */:
                    return visitCallExpression(node);
                case 197 /* NewExpression */:
                    return visitNewExpression(node);
                case 198 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 218 /* NonNullExpression */:
                    // TypeScript non-null expressions are removed, but their subtrees are preserved.
                    return visitNonNullExpression(node);
                case 248 /* EnumDeclaration */:
                    // TypeScript enum declarations do not exist in ES6 and must be rewritten.
                    return visitEnumDeclaration(node);
                case 225 /* VariableStatement */:
                    // TypeScript namespace exports for variable statements must be transformed.
                    return visitVariableStatement(node);
                case 242 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 249 /* ModuleDeclaration */:
                    // TypeScript namespace declarations must be transformed.
                    return visitModuleDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    // TypeScript namespace or external module import.
                    return visitImportEqualsDeclaration(node);
                case 267 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node);
                case 268 /* JsxOpeningElement */:
                    return visitJsxJsxOpeningElement(node);
                default:
                    // node contains some other TypeScript syntax
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitSourceFile(node) {
            var alwaysStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") &&
                !(ts.isExternalModule(node) && moduleKind >= ts.ModuleKind.ES2015) &&
                !ts.isJsonSourceFile(node);
            return ts.updateSourceFileNode(node, ts.visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
        }
        /**
         * Tests whether we should emit a __decorate call for a class declaration.
         */
        function shouldEmitDecorateCallForClass(node) {
            if (node.decorators && node.decorators.length > 0) {
                return true;
            }
            var constructor = ts.getFirstConstructorWithBody(node);
            if (constructor) {
                return ts.forEach(constructor.parameters, shouldEmitDecorateCallForParameter);
            }
            return false;
        }
        /**
         * Tests whether we should emit a __decorate call for a parameter declaration.
         */
        function shouldEmitDecorateCallForParameter(parameter) {
            return parameter.decorators !== undefined && parameter.decorators.length > 0;
        }
        function getClassFacts(node, staticProperties) {
            var facts = 0 /* None */;
            if (ts.some(staticProperties))
                facts |= 1 /* HasStaticInitializedProperties */;
            var extendsClauseElement = ts.getEffectiveBaseTypeNode(node);
            if (extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 100 /* NullKeyword */)
                facts |= 64 /* IsDerivedClass */;
            if (shouldEmitDecorateCallForClass(node))
                facts |= 2 /* HasConstructorDecorators */;
            if (ts.childIsDecorated(node))
                facts |= 4 /* HasMemberDecorators */;
            if (isExportOfNamespace(node))
                facts |= 8 /* IsExportOfNamespace */;
            else if (isDefaultExternalModuleExport(node))
                facts |= 32 /* IsDefaultExternalExport */;
            else if (isNamedExternalModuleExport(node))
                facts |= 16 /* IsNamedExternalExport */;
            if (languageVersion <= 1 /* ES5 */ && (facts & 7 /* MayNeedImmediatelyInvokedFunctionExpression */))
                facts |= 128 /* UseImmediatelyInvokedFunctionExpression */;
            return facts;
        }
        function hasTypeScriptClassSyntax(node) {
            return !!(node.transformFlags & 2048 /* ContainsTypeScriptClassSyntax */);
        }
        function isClassLikeDeclarationWithTypeScriptSyntax(node) {
            return ts.some(node.decorators)
                || ts.some(node.typeParameters)
                || ts.some(node.heritageClauses, hasTypeScriptClassSyntax)
                || ts.some(node.members, hasTypeScriptClassSyntax);
        }
        function visitClassDeclaration(node) {
            if (!isClassLikeDeclarationWithTypeScriptSyntax(node) && !(currentNamespace && ts.hasModifier(node, 1 /* Export */))) {
                return ts.visitEachChild(node, visitor, context);
            }
            var staticProperties = ts.getProperties(node, /*requireInitializer*/ true, /*isStatic*/ true);
            var facts = getClassFacts(node, staticProperties);
            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
                context.startLexicalEnvironment();
            }
            var name = node.name || (facts & 5 /* NeedsName */ ? ts.getGeneratedNameForNode(node) : undefined);
            var classStatement = facts & 2 /* HasConstructorDecorators */
                ? createClassDeclarationHeadWithDecorators(node, name)
                : createClassDeclarationHeadWithoutDecorators(node, name, facts);
            var statements = [classStatement];
            // Write any decorators of the node.
            addClassElementDecorationStatements(statements, node, /*isStatic*/ false);
            addClassElementDecorationStatements(statements, node, /*isStatic*/ true);
            addConstructorDecorationStatement(statements, node);
            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
                // When we emit a TypeScript class down to ES5, we must wrap it in an IIFE so that the
                // 'es2015' transformer can properly nest static initializers and decorators. The result
                // looks something like:
                //
                //  var C = function () {
                //      class C {
                //      }
                //      C.static_prop = 1;
                //      return C;
                //  }();
                //
                var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentSourceFile.text, node.members.end), 19 /* CloseBraceToken */);
                var localName = ts.getInternalName(node);
                // The following partially-emitted expression exists purely to align our sourcemap
                // emit with the original emitter.
                var outer = ts.createPartiallyEmittedExpression(localName);
                outer.end = closingBraceLocation.end;
                ts.setEmitFlags(outer, 1536 /* NoComments */);
                var statement = ts.createReturn(outer);
                statement.pos = closingBraceLocation.pos;
                ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
                statements.push(statement);
                ts.insertStatementsAfterStandardPrologue(statements, context.endLexicalEnvironment());
                var iife = ts.createImmediatelyInvokedArrowFunction(statements);
                ts.setEmitFlags(iife, 33554432 /* TypeScriptClassWrapper */);
                var varStatement = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), 
                    /*type*/ undefined, iife)
                ]));
                ts.setOriginalNode(varStatement, node);
                ts.setCommentRange(varStatement, node);
                ts.setSourceMapRange(varStatement, ts.moveRangePastDecorators(node));
                ts.startOnNewLine(varStatement);
                statements = [varStatement];
            }
            // If the class is exported as part of a TypeScript namespace, emit the namespace export.
            // Otherwise, if the class was exported at the top level and was decorated, emit an export
            // declaration or export default for the class.
            if (facts & 8 /* IsExportOfNamespace */) {
                addExportMemberAssignment(statements, node);
            }
            else if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */ || facts & 2 /* HasConstructorDecorators */) {
                if (facts & 32 /* IsDefaultExternalExport */) {
                    statements.push(ts.createExportDefault(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
                }
                else if (facts & 16 /* IsNamedExternalExport */) {
                    statements.push(ts.createExternalModuleExport(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
                }
            }
            if (statements.length > 1) {
                // Add a DeclarationMarker as a marker for the end of the declaration
                statements.push(ts.createEndOfDeclarationMarker(node));
                ts.setEmitFlags(classStatement, ts.getEmitFlags(classStatement) | 4194304 /* HasEndOfDeclarationMarker */);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Transforms a non-decorated class declaration and appends the resulting statements.
         *
         * @param node A ClassDeclaration node.
         * @param name The name of the class.
         * @param facts Precomputed facts about the class.
         */
        function createClassDeclarationHeadWithoutDecorators(node, name, facts) {
            //  ${modifiers} class ${name} ${heritageClauses} {
            //      ${members}
            //  }
            // we do not emit modifiers on the declaration if we are emitting an IIFE
            var modifiers = !(facts & 128 /* UseImmediatelyInvokedFunctionExpression */)
                ? ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier)
                : undefined;
            var classDeclaration = ts.createClassDeclaration(
            /*decorators*/ undefined, modifiers, name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node));
            // To better align with the old emitter, we should not emit a trailing source map
            // entry if the class has static properties.
            var emitFlags = ts.getEmitFlags(node);
            if (facts & 1 /* HasStaticInitializedProperties */) {
                emitFlags |= 32 /* NoTrailingSourceMap */;
            }
            ts.aggregateTransformFlags(classDeclaration);
            ts.setTextRange(classDeclaration, node);
            ts.setOriginalNode(classDeclaration, node);
            ts.setEmitFlags(classDeclaration, emitFlags);
            return classDeclaration;
        }
        /**
         * Transforms a decorated class declaration and appends the resulting statements. If
         * the class requires an alias to avoid issues with double-binding, the alias is returned.
         */
        function createClassDeclarationHeadWithDecorators(node, name) {
            // When we emit an ES6 class that has a class decorator, we must tailor the
            // emit to certain specific cases.
            //
            // In the simplest case, we emit the class declaration as a let declaration, and
            // evaluate decorators after the close of the class body:
            //
            //  [Example 1]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  class C {                       | }
            //  }                               | C = __decorate([dec], C);
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export class C {                | }
            //  }                               | C = __decorate([dec], C);
            //                                  | export { C };
            //  ---------------------------------------------------------------------
            //
            // If a class declaration contains a reference to itself *inside* of the class body,
            // this introduces two bindings to the class: One outside of the class body, and one
            // inside of the class body. If we apply decorators as in [Example 1] above, there
            // is the possibility that the decorator `dec` will return a new value for the
            // constructor, which would result in the binding inside of the class no longer
            // pointing to the same reference as the binding outside of the class.
            //
            // As a result, we must instead rewrite all references to the class *inside* of the
            // class body to instead point to a local temporary alias for the class:
            //
            //  [Example 2]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = C_1 = class C {
            //  class C {                       |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export class C {                |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | export { C };
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //
            // If a class declaration is the default export of a module, we instead emit
            // the export after the decorated declaration:
            //
            //  [Example 3]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let default_1 = class {
            //  export default class {          | }
            //  }                               | default_1 = __decorate([dec], default_1);
            //                                  | export default default_1;
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export default class C {        | }
            //  }                               | C = __decorate([dec], C);
            //                                  | export default C;
            //  ---------------------------------------------------------------------
            //
            // If the class declaration is the default export and a reference to itself
            // inside of the class body, we must emit both an alias for the class *and*
            // move the export after the declaration:
            //
            //  [Example 4]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export default class C {        |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | export default C;
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //
            var location = ts.moveRangePastDecorators(node);
            var classAlias = getClassAliasIfNeeded(node);
            var declName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  ... = class ${name} ${heritageClauses} {
            //      ${members}
            //  }
            var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause);
            var members = transformClassMembers(node);
            var classExpression = ts.createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members);
            ts.aggregateTransformFlags(classExpression);
            ts.setOriginalNode(classExpression, node);
            ts.setTextRange(classExpression, location);
            //  let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
            //                                         or decoratedClassAlias if the class contain self-reference.
            var statement = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(declName, 
                /*type*/ undefined, classAlias ? ts.createAssignment(classAlias, classExpression) : classExpression)
            ], 1 /* Let */));
            ts.setOriginalNode(statement, node);
            ts.setTextRange(statement, location);
            ts.setCommentRange(statement, node);
            return statement;
        }
        function visitClassExpression(node) {
            if (!isClassLikeDeclarationWithTypeScriptSyntax(node)) {
                return ts.visitEachChild(node, visitor, context);
            }
            var classExpression = ts.createClassExpression(
            /*modifiers*/ undefined, node.name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node));
            ts.aggregateTransformFlags(classExpression);
            ts.setOriginalNode(classExpression, node);
            ts.setTextRange(classExpression, node);
            return classExpression;
        }
        /**
         * Transforms the members of a class.
         *
         * @param node The current class.
         */
        function transformClassMembers(node) {
            var members = [];
            var constructor = ts.getFirstConstructorWithBody(node);
            var parametersWithPropertyAssignments = constructor &&
                ts.filter(constructor.parameters, function (p) { return ts.isParameterPropertyDeclaration(p, constructor); });
            if (parametersWithPropertyAssignments) {
                for (var _i = 0, parametersWithPropertyAssignments_1 = parametersWithPropertyAssignments; _i < parametersWithPropertyAssignments_1.length; _i++) {
                    var parameter = parametersWithPropertyAssignments_1[_i];
                    if (ts.isIdentifier(parameter.name)) {
                        members.push(ts.setOriginalNode(ts.aggregateTransformFlags(ts.createProperty(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, parameter.name, 
                        /*questionOrExclamationToken*/ undefined, 
                        /*type*/ undefined, 
                        /*initializer*/ undefined)), parameter));
                    }
                }
            }
            ts.addRange(members, ts.visitNodes(node.members, classElementVisitor, ts.isClassElement));
            return ts.setTextRange(ts.createNodeArray(members), /*location*/ node.members);
        }
        /**
         * Gets either the static or instance members of a class that are decorated, or have
         * parameters that are decorated.
         *
         * @param node The class containing the member.
         * @param isStatic A value indicating whether to retrieve static or instance members of
         *                 the class.
         */
        function getDecoratedClassElements(node, isStatic) {
            return ts.filter(node.members, isStatic ? function (m) { return isStaticDecoratedClassElement(m, node); } : function (m) { return isInstanceDecoratedClassElement(m, node); });
        }
        /**
         * Determines whether a class member is a static member of a class that is decorated, or
         * has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isStaticDecoratedClassElement(member, parent) {
            return isDecoratedClassElement(member, /*isStatic*/ true, parent);
        }
        /**
         * Determines whether a class member is an instance member of a class that is decorated,
         * or has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isInstanceDecoratedClassElement(member, parent) {
            return isDecoratedClassElement(member, /*isStatic*/ false, parent);
        }
        /**
         * Determines whether a class member is either a static or an instance member of a class
         * that is decorated, or has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isDecoratedClassElement(member, isStatic, parent) {
            return ts.nodeOrChildIsDecorated(member, parent)
                && isStatic === ts.hasModifier(member, 32 /* Static */);
        }
        /**
         * Gets an array of arrays of decorators for the parameters of a function-like node.
         * The offset into the result array should correspond to the offset of the parameter.
         *
         * @param node The function-like node.
         */
        function getDecoratorsOfParameters(node) {
            var decorators;
            if (node) {
                var parameters = node.parameters;
                var firstParameterIsThis = parameters.length > 0 && ts.parameterIsThisKeyword(parameters[0]);
                var firstParameterOffset = firstParameterIsThis ? 1 : 0;
                var numParameters = firstParameterIsThis ? parameters.length - 1 : parameters.length;
                for (var i = 0; i < numParameters; i++) {
                    var parameter = parameters[i + firstParameterOffset];
                    if (decorators || parameter.decorators) {
                        if (!decorators) {
                            decorators = new Array(numParameters);
                        }
                        decorators[i] = parameter.decorators;
                    }
                }
            }
            return decorators;
        }
        /**
         * Gets an AllDecorators object containing the decorators for the class and the decorators for the
         * parameters of the constructor of the class.
         *
         * @param node The class node.
         */
        function getAllDecoratorsOfConstructor(node) {
            var decorators = node.decorators;
            var parameters = getDecoratorsOfParameters(ts.getFirstConstructorWithBody(node));
            if (!decorators && !parameters) {
                return undefined;
            }
            return {
                decorators: decorators,
                parameters: parameters
            };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the member and its parameters.
         *
         * @param node The class node that contains the member.
         * @param member The class member.
         */
        function getAllDecoratorsOfClassElement(node, member) {
            switch (member.kind) {
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return getAllDecoratorsOfAccessors(node, member);
                case 161 /* MethodDeclaration */:
                    return getAllDecoratorsOfMethod(member);
                case 159 /* PropertyDeclaration */:
                    return getAllDecoratorsOfProperty(member);
                default:
                    return undefined;
            }
        }
        /**
         * Gets an AllDecorators object containing the decorators for the accessor and its parameters.
         *
         * @param node The class node that contains the accessor.
         * @param accessor The class accessor member.
         */
        function getAllDecoratorsOfAccessors(node, accessor) {
            if (!accessor.body) {
                return undefined;
            }
            var _a = ts.getAllAccessorDeclarations(node.members, accessor), firstAccessor = _a.firstAccessor, secondAccessor = _a.secondAccessor, setAccessor = _a.setAccessor;
            var firstAccessorWithDecorators = firstAccessor.decorators ? firstAccessor : secondAccessor && secondAccessor.decorators ? secondAccessor : undefined;
            if (!firstAccessorWithDecorators || accessor !== firstAccessorWithDecorators) {
                return undefined;
            }
            var decorators = firstAccessorWithDecorators.decorators;
            var parameters = getDecoratorsOfParameters(setAccessor);
            if (!decorators && !parameters) {
                return undefined;
            }
            return { decorators: decorators, parameters: parameters };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the method and its parameters.
         *
         * @param method The class method member.
         */
        function getAllDecoratorsOfMethod(method) {
            if (!method.body) {
                return undefined;
            }
            var decorators = method.decorators;
            var parameters = getDecoratorsOfParameters(method);
            if (!decorators && !parameters) {
                return undefined;
            }
            return { decorators: decorators, parameters: parameters };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the property.
         *
         * @param property The class property member.
         */
        function getAllDecoratorsOfProperty(property) {
            var decorators = property.decorators;
            if (!decorators) {
                return undefined;
            }
            return { decorators: decorators };
        }
        /**
         * Transforms all of the decorators for a declaration into an array of expressions.
         *
         * @param node The declaration node.
         * @param allDecorators An object containing all of the decorators for the declaration.
         */
        function transformAllDecoratorsOfDeclaration(node, container, allDecorators) {
            if (!allDecorators) {
                return undefined;
            }
            var decoratorExpressions = [];
            ts.addRange(decoratorExpressions, ts.map(allDecorators.decorators, transformDecorator));
            ts.addRange(decoratorExpressions, ts.flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
            addTypeMetadata(node, container, decoratorExpressions);
            return decoratorExpressions;
        }
        /**
         * Generates statements used to apply decorators to either the static or instance members
         * of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to generate statements for static or
         *                 instance members.
         */
        function addClassElementDecorationStatements(statements, node, isStatic) {
            ts.addRange(statements, ts.map(generateClassElementDecorationExpressions(node, isStatic), expressionToStatement));
        }
        /**
         * Generates expressions used to apply decorators to either the static or instance members
         * of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to generate expressions for static or
         *                 instance members.
         */
        function generateClassElementDecorationExpressions(node, isStatic) {
            var members = getDecoratedClassElements(node, isStatic);
            var expressions;
            for (var _i = 0, members_6 = members; _i < members_6.length; _i++) {
                var member = members_6[_i];
                var expression = generateClassElementDecorationExpression(node, member);
                if (expression) {
                    if (!expressions) {
                        expressions = [expression];
                    }
                    else {
                        expressions.push(expression);
                    }
                }
            }
            return expressions;
        }
        /**
         * Generates an expression used to evaluate class element decorators at runtime.
         *
         * @param node The class node that contains the member.
         * @param member The class member.
         */
        function generateClassElementDecorationExpression(node, member) {
            var allDecorators = getAllDecoratorsOfClassElement(node, member);
            var decoratorExpressions = transformAllDecoratorsOfDeclaration(member, node, allDecorators);
            if (!decoratorExpressions) {
                return undefined;
            }
            // Emit the call to __decorate. Given the following:
            //
            //   class C {
            //     @dec method(@dec2 x) {}
            //     @dec get accessor() {}
            //     @dec prop;
            //   }
            //
            // The emit for a method is:
            //
            //   __decorate([
            //       dec,
            //       __param(0, dec2),
            //       __metadata("design:type", Function),
            //       __metadata("design:paramtypes", [Object]),
            //       __metadata("design:returntype", void 0)
            //   ], C.prototype, "method", null);
            //
            // The emit for an accessor is:
            //
            //   __decorate([
            //       dec
            //   ], C.prototype, "accessor", null);
            //
            // The emit for a property is:
            //
            //   __decorate([
            //       dec
            //   ], C.prototype, "prop");
            //
            var prefix = getClassMemberPrefix(node, member);
            var memberName = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ true);
            var descriptor = languageVersion > 0 /* ES3 */
                ? member.kind === 159 /* PropertyDeclaration */
                    // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it
                    // should not invoke `Object.getOwnPropertyDescriptor`.
                    ? ts.createVoidZero()
                    // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly.
                    // We have this extra argument here so that we can inject an explicit property descriptor at a later date.
                    : ts.createNull()
                : undefined;
            var helper = createDecorateHelper(context, decoratorExpressions, prefix, memberName, descriptor, ts.moveRangePastDecorators(member));
            ts.setEmitFlags(helper, 1536 /* NoComments */);
            return helper;
        }
        /**
         * Generates a __decorate helper call for a class constructor.
         *
         * @param node The class node.
         */
        function addConstructorDecorationStatement(statements, node) {
            var expression = generateConstructorDecorationExpression(node);
            if (expression) {
                statements.push(ts.setOriginalNode(ts.createExpressionStatement(expression), node));
            }
        }
        /**
         * Generates a __decorate helper call for a class constructor.
         *
         * @param node The class node.
         */
        function generateConstructorDecorationExpression(node) {
            var allDecorators = getAllDecoratorsOfConstructor(node);
            var decoratorExpressions = transformAllDecoratorsOfDeclaration(node, node, allDecorators);
            if (!decoratorExpressions) {
                return undefined;
            }
            var classAlias = classAliases && classAliases[ts.getOriginalNodeId(node)];
            var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            var decorate = createDecorateHelper(context, decoratorExpressions, localName);
            var expression = ts.createAssignment(localName, classAlias ? ts.createAssignment(classAlias, decorate) : decorate);
            ts.setEmitFlags(expression, 1536 /* NoComments */);
            ts.setSourceMapRange(expression, ts.moveRangePastDecorators(node));
            return expression;
        }
        /**
         * Transforms a decorator into an expression.
         *
         * @param decorator The decorator node.
         */
        function transformDecorator(decorator) {
            return ts.visitNode(decorator.expression, visitor, ts.isExpression);
        }
        /**
         * Transforms the decorators of a parameter.
         *
         * @param decorators The decorators for the parameter at the provided offset.
         * @param parameterOffset The offset of the parameter.
         */
        function transformDecoratorsOfParameter(decorators, parameterOffset) {
            var expressions;
            if (decorators) {
                expressions = [];
                for (var _i = 0, decorators_1 = decorators; _i < decorators_1.length; _i++) {
                    var decorator = decorators_1[_i];
                    var helper = createParamHelper(context, transformDecorator(decorator), parameterOffset, 
                    /*location*/ decorator.expression);
                    ts.setEmitFlags(helper, 1536 /* NoComments */);
                    expressions.push(helper);
                }
            }
            return expressions;
        }
        /**
         * Adds optional type metadata for a declaration.
         *
         * @param node The declaration node.
         * @param decoratorExpressions The destination array to which to add new decorator expressions.
         */
        function addTypeMetadata(node, container, decoratorExpressions) {
            if (USE_NEW_TYPE_METADATA_FORMAT) {
                addNewTypeMetadata(node, container, decoratorExpressions);
            }
            else {
                addOldTypeMetadata(node, container, decoratorExpressions);
            }
        }
        function addOldTypeMetadata(node, container, decoratorExpressions) {
            if (compilerOptions.emitDecoratorMetadata) {
                if (shouldAddTypeMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node)));
                }
                if (shouldAddParamTypesMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node, container)));
                }
                if (shouldAddReturnTypeMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node)));
                }
            }
        }
        function addNewTypeMetadata(node, container, decoratorExpressions) {
            if (compilerOptions.emitDecoratorMetadata) {
                var properties = void 0;
                if (shouldAddTypeMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("type", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(38 /* EqualsGreaterThanToken */), serializeTypeOfNode(node))));
                }
                if (shouldAddParamTypesMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("paramTypes", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(38 /* EqualsGreaterThanToken */), serializeParameterTypesOfNode(node, container))));
                }
                if (shouldAddReturnTypeMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("returnType", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(38 /* EqualsGreaterThanToken */), serializeReturnTypeOfNode(node))));
                }
                if (properties) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", ts.createObjectLiteral(properties, /*multiLine*/ true)));
                }
            }
        }
        /**
         * Determines whether to emit the "design:type" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddTypeMetadata(node) {
            var kind = node.kind;
            return kind === 161 /* MethodDeclaration */
                || kind === 163 /* GetAccessor */
                || kind === 164 /* SetAccessor */
                || kind === 159 /* PropertyDeclaration */;
        }
        /**
         * Determines whether to emit the "design:returntype" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddReturnTypeMetadata(node) {
            return node.kind === 161 /* MethodDeclaration */;
        }
        /**
         * Determines whether to emit the "design:paramtypes" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddParamTypesMetadata(node) {
            switch (node.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return ts.getFirstConstructorWithBody(node) !== undefined;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return true;
            }
            return false;
        }
        function getAccessorTypeNode(node) {
            var accessors = resolver.getAllAccessorDeclarations(node);
            return accessors.setAccessor && ts.getSetAccessorTypeAnnotationNode(accessors.setAccessor)
                || accessors.getAccessor && ts.getEffectiveReturnTypeNode(accessors.getAccessor);
        }
        /**
         * Serializes the type of a node for use with decorator type metadata.
         *
         * @param node The node that should have its type serialized.
         */
        function serializeTypeOfNode(node) {
            switch (node.kind) {
                case 159 /* PropertyDeclaration */:
                case 156 /* Parameter */:
                    return serializeTypeNode(node.type);
                case 164 /* SetAccessor */:
                case 163 /* GetAccessor */:
                    return serializeTypeNode(getAccessorTypeNode(node));
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                case 161 /* MethodDeclaration */:
                    return ts.createIdentifier("Function");
                default:
                    return ts.createVoidZero();
            }
        }
        /**
         * Serializes the types of the parameters of a node for use with decorator type metadata.
         *
         * @param node The node that should have its parameter types serialized.
         */
        function serializeParameterTypesOfNode(node, container) {
            var valueDeclaration = ts.isClassLike(node)
                ? ts.getFirstConstructorWithBody(node)
                : ts.isFunctionLike(node) && ts.nodeIsPresent(node.body)
                    ? node
                    : undefined;
            var expressions = [];
            if (valueDeclaration) {
                var parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container);
                var numParameters = parameters.length;
                for (var i = 0; i < numParameters; i++) {
                    var parameter = parameters[i];
                    if (i === 0 && ts.isIdentifier(parameter.name) && parameter.name.escapedText === "this") {
                        continue;
                    }
                    if (parameter.dotDotDotToken) {
                        expressions.push(serializeTypeNode(ts.getRestParameterElementType(parameter.type)));
                    }
                    else {
                        expressions.push(serializeTypeOfNode(parameter));
                    }
                }
            }
            return ts.createArrayLiteral(expressions);
        }
        function getParametersOfDecoratedDeclaration(node, container) {
            if (container && node.kind === 163 /* GetAccessor */) {
                var setAccessor = ts.getAllAccessorDeclarations(container.members, node).setAccessor;
                if (setAccessor) {
                    return setAccessor.parameters;
                }
            }
            return node.parameters;
        }
        /**
         * Serializes the return type of a node for use with decorator type metadata.
         *
         * @param node The node that should have its return type serialized.
         */
        function serializeReturnTypeOfNode(node) {
            if (ts.isFunctionLike(node) && node.type) {
                return serializeTypeNode(node.type);
            }
            else if (ts.isAsyncFunction(node)) {
                return ts.createIdentifier("Promise");
            }
            return ts.createVoidZero();
        }
        /**
         * Serializes a type node for use with decorator type metadata.
         *
         * Types are serialized in the following fashion:
         * - Void types point to "undefined" (e.g. "void 0")
         * - Function and Constructor types point to the global "Function" constructor.
         * - Interface types with a call or construct signature types point to the global
         *   "Function" constructor.
         * - Array and Tuple types point to the global "Array" constructor.
         * - Type predicates and booleans point to the global "Boolean" constructor.
         * - String literal types and strings point to the global "String" constructor.
         * - Enum and number types point to the global "Number" constructor.
         * - Symbol types point to the global "Symbol" constructor.
         * - Type references to classes (or class-like variables) point to the constructor for the class.
         * - Anything else points to the global "Object" constructor.
         *
         * @param node The type node to serialize.
         */
        function serializeTypeNode(node) {
            if (node === undefined) {
                return ts.createIdentifier("Object");
            }
            switch (node.kind) {
                case 110 /* VoidKeyword */:
                case 146 /* UndefinedKeyword */:
                case 100 /* NullKeyword */:
                case 137 /* NeverKeyword */:
                    return ts.createVoidZero();
                case 182 /* ParenthesizedType */:
                    return serializeTypeNode(node.type);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */:
                    return ts.createIdentifier("Function");
                case 174 /* ArrayType */:
                case 175 /* TupleType */:
                    return ts.createIdentifier("Array");
                case 168 /* TypePredicate */:
                case 128 /* BooleanKeyword */:
                    return ts.createIdentifier("Boolean");
                case 143 /* StringKeyword */:
                    return ts.createIdentifier("String");
                case 141 /* ObjectKeyword */:
                    return ts.createIdentifier("Object");
                case 187 /* LiteralType */:
                    switch (node.literal.kind) {
                        case 10 /* StringLiteral */:
                            return ts.createIdentifier("String");
                        case 207 /* PrefixUnaryExpression */:
                        case 8 /* NumericLiteral */:
                            return ts.createIdentifier("Number");
                        case 9 /* BigIntLiteral */:
                            return getGlobalBigIntNameWithFallback();
                        case 106 /* TrueKeyword */:
                        case 91 /* FalseKeyword */:
                            return ts.createIdentifier("Boolean");
                        default:
                            return ts.Debug.failBadSyntaxKind(node.literal);
                    }
                case 140 /* NumberKeyword */:
                    return ts.createIdentifier("Number");
                case 151 /* BigIntKeyword */:
                    return getGlobalBigIntNameWithFallback();
                case 144 /* SymbolKeyword */:
                    return languageVersion < 2 /* ES2015 */
                        ? getGlobalSymbolNameWithFallback()
                        : ts.createIdentifier("Symbol");
                case 169 /* TypeReference */:
                    return serializeTypeReferenceNode(node);
                case 179 /* IntersectionType */:
                case 178 /* UnionType */:
                    return serializeTypeList(node.types);
                case 180 /* ConditionalType */:
                    return serializeTypeList([node.trueType, node.falseType]);
                case 184 /* TypeOperator */:
                    if (node.operator === 138 /* ReadonlyKeyword */) {
                        return serializeTypeNode(node.type);
                    }
                    break;
                case 172 /* TypeQuery */:
                case 185 /* IndexedAccessType */:
                case 186 /* MappedType */:
                case 173 /* TypeLiteral */:
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 183 /* ThisType */:
                case 188 /* ImportType */:
                    break;
                // handle JSDoc types from an invalid parse
                case 295 /* JSDocAllType */:
                case 296 /* JSDocUnknownType */:
                case 300 /* JSDocFunctionType */:
                case 301 /* JSDocVariadicType */:
                case 302 /* JSDocNamepathType */:
                    break;
                case 297 /* JSDocNullableType */:
                case 298 /* JSDocNonNullableType */:
                case 299 /* JSDocOptionalType */:
                    return serializeTypeNode(node.type);
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
            return ts.createIdentifier("Object");
        }
        function serializeTypeList(types) {
            // Note when updating logic here also update getEntityNameForDecoratorMetadata
            // so that aliases can be marked as referenced
            var serializedUnion;
            for (var _i = 0, types_21 = types; _i < types_21.length; _i++) {
                var typeNode = types_21[_i];
                while (typeNode.kind === 182 /* ParenthesizedType */) {
                    typeNode = typeNode.type; // Skip parens if need be
                }
                if (typeNode.kind === 137 /* NeverKeyword */) {
                    continue; // Always elide `never` from the union/intersection if possible
                }
                if (!strictNullChecks && (typeNode.kind === 100 /* NullKeyword */ || typeNode.kind === 146 /* UndefinedKeyword */)) {
                    continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
                }
                var serializedIndividual = serializeTypeNode(typeNode);
                if (ts.isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") {
                    // One of the individual is global object, return immediately
                    return serializedIndividual;
                }
                // If there exists union that is not void 0 expression, check if the the common type is identifier.
                // anything more complex and we will just default to Object
                else if (serializedUnion) {
                    // Different types
                    if (!ts.isIdentifier(serializedUnion) ||
                        !ts.isIdentifier(serializedIndividual) ||
                        serializedUnion.escapedText !== serializedIndividual.escapedText) {
                        return ts.createIdentifier("Object");
                    }
                }
                else {
                    // Initialize the union type
                    serializedUnion = serializedIndividual;
                }
            }
            // If we were able to find common type, use it
            return serializedUnion || ts.createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never
        }
        /**
         * Serializes a TypeReferenceNode to an appropriate JS constructor value for use with
         * decorator type metadata.
         *
         * @param node The type reference node.
         */
        function serializeTypeReferenceNode(node) {
            var kind = resolver.getTypeReferenceSerializationKind(node.typeName, currentNameScope || currentLexicalScope);
            switch (kind) {
                case ts.TypeReferenceSerializationKind.Unknown:
                    // From conditional type type reference that cannot be resolved is Similar to any or unknown
                    if (ts.findAncestor(node, function (n) { return n.parent && ts.isConditionalTypeNode(n.parent) && (n.parent.trueType === n || n.parent.falseType === n); })) {
                        return ts.createIdentifier("Object");
                    }
                    var serialized = serializeEntityNameAsExpressionFallback(node.typeName);
                    var temp = ts.createTempVariable(hoistVariableDeclaration);
                    return ts.createConditional(ts.createTypeCheck(ts.createAssignment(temp, serialized), "function"), temp, ts.createIdentifier("Object"));
                case ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
                    return serializeEntityNameAsExpression(node.typeName);
                case ts.TypeReferenceSerializationKind.VoidNullableOrNeverType:
                    return ts.createVoidZero();
                case ts.TypeReferenceSerializationKind.BigIntLikeType:
                    return getGlobalBigIntNameWithFallback();
                case ts.TypeReferenceSerializationKind.BooleanType:
                    return ts.createIdentifier("Boolean");
                case ts.TypeReferenceSerializationKind.NumberLikeType:
                    return ts.createIdentifier("Number");
                case ts.TypeReferenceSerializationKind.StringLikeType:
                    return ts.createIdentifier("String");
                case ts.TypeReferenceSerializationKind.ArrayLikeType:
                    return ts.createIdentifier("Array");
                case ts.TypeReferenceSerializationKind.ESSymbolType:
                    return languageVersion < 2 /* ES2015 */
                        ? getGlobalSymbolNameWithFallback()
                        : ts.createIdentifier("Symbol");
                case ts.TypeReferenceSerializationKind.TypeWithCallSignature:
                    return ts.createIdentifier("Function");
                case ts.TypeReferenceSerializationKind.Promise:
                    return ts.createIdentifier("Promise");
                case ts.TypeReferenceSerializationKind.ObjectType:
                    return ts.createIdentifier("Object");
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function createCheckedValue(left, right) {
            return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(left), ts.createLiteral("undefined")), right);
        }
        /**
         * Serializes an entity name which may not exist at runtime, but whose access shouldn't throw
         *
         * @param node The entity name to serialize.
         */
        function serializeEntityNameAsExpressionFallback(node) {
            if (node.kind === 75 /* Identifier */) {
                // A -> typeof A !== undefined && A
                var copied = serializeEntityNameAsExpression(node);
                return createCheckedValue(copied, copied);
            }
            if (node.left.kind === 75 /* Identifier */) {
                // A.B -> typeof A !== undefined && A.B
                return createCheckedValue(serializeEntityNameAsExpression(node.left), serializeEntityNameAsExpression(node));
            }
            // A.B.C -> typeof A !== undefined && (_a = A.B) !== void 0 && _a.C
            var left = serializeEntityNameAsExpressionFallback(node.left);
            var temp = ts.createTempVariable(hoistVariableDeclaration);
            return ts.createLogicalAnd(ts.createLogicalAnd(left.left, ts.createStrictInequality(ts.createAssignment(temp, left.right), ts.createVoidZero())), ts.createPropertyAccess(temp, node.right));
        }
        /**
         * Serializes an entity name as an expression for decorator type metadata.
         *
         * @param node The entity name to serialize.
         */
        function serializeEntityNameAsExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    // Create a clone of the name with a new parent, and treat it as if it were
                    // a source tree node for the purposes of the checker.
                    var name = ts.getMutableClone(node);
                    name.flags &= ~8 /* Synthesized */;
                    name.original = undefined;
                    name.parent = ts.getParseTreeNode(currentLexicalScope); // ensure the parent is set to a parse tree node.
                    return name;
                case 153 /* QualifiedName */:
                    return serializeQualifiedNameAsExpression(node);
            }
        }
        /**
         * Serializes an qualified name as an expression for decorator type metadata.
         *
         * @param node The qualified name to serialize.
         * @param useFallback A value indicating whether to use logical operators to test for the
         *                    qualified name at runtime.
         */
        function serializeQualifiedNameAsExpression(node) {
            return ts.createPropertyAccess(serializeEntityNameAsExpression(node.left), node.right);
        }
        /**
         * Gets an expression that points to the global "Symbol" constructor at runtime if it is
         * available.
         */
        function getGlobalSymbolNameWithFallback() {
            return ts.createConditional(ts.createTypeCheck(ts.createIdentifier("Symbol"), "function"), ts.createIdentifier("Symbol"), ts.createIdentifier("Object"));
        }
        /**
         * Gets an expression that points to the global "BigInt" constructor at runtime if it is
         * available.
         */
        function getGlobalBigIntNameWithFallback() {
            return languageVersion < 99 /* ESNext */
                ? ts.createConditional(ts.createTypeCheck(ts.createIdentifier("BigInt"), "function"), ts.createIdentifier("BigInt"), ts.createIdentifier("Object"))
                : ts.createIdentifier("BigInt");
        }
        /**
         * Gets an expression that represents a property name (for decorated properties or enums).
         * For a computed property, a name is generated for the node.
         *
         * @param member The member whose name should be converted into an expression.
         */
        function getExpressionForPropertyName(member, generateNameForComputedPropertyName) {
            var name = member.name;
            if (ts.isPrivateIdentifier(name)) {
                return ts.createIdentifier("");
            }
            else if (ts.isComputedPropertyName(name)) {
                return generateNameForComputedPropertyName && !ts.isSimpleInlineableExpression(name.expression)
                    ? ts.getGeneratedNameForNode(name)
                    : name.expression;
            }
            else if (ts.isIdentifier(name)) {
                return ts.createLiteral(ts.idText(name));
            }
            else {
                return ts.getSynthesizedClone(name);
            }
        }
        /**
         * Visits the property name of a class element, for use when emitting property
         * initializers. For a computed property on a node with decorators, a temporary
         * value is stored for later use.
         *
         * @param member The member whose name should be visited.
         */
        function visitPropertyNameOfClassElement(member) {
            var name = member.name;
            // Computed property names need to be transformed into a hoisted variable when they are used more than once.
            // The names are used more than once when:
            //   - the property is non-static and its initializer is moved to the constructor (when there are parameter property assignments).
            //   - the property has a decorator.
            if (ts.isComputedPropertyName(name) && ((!ts.hasStaticModifier(member) && currentClassHasParameterProperties) || ts.some(member.decorators))) {
                var expression = ts.visitNode(name.expression, visitor, ts.isExpression);
                var innerExpression = ts.skipPartiallyEmittedExpressions(expression);
                if (!ts.isSimpleInlineableExpression(innerExpression)) {
                    var generatedName = ts.getGeneratedNameForNode(name);
                    hoistVariableDeclaration(generatedName);
                    return ts.updateComputedPropertyName(name, ts.createAssignment(generatedName, expression));
                }
            }
            return ts.visitNode(name, visitor, ts.isPropertyName);
        }
        /**
         * Transforms a HeritageClause with TypeScript syntax.
         *
         * This function will only be called when one of the following conditions are met:
         * - The node is a non-`extends` heritage clause that should be elided.
         * - The node is an `extends` heritage clause that should be visited, but only allow a single type.
         *
         * @param node The HeritageClause to transform.
         */
        function visitHeritageClause(node) {
            if (node.token === 113 /* ImplementsKeyword */) {
                // implements clauses are elided
                return undefined;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Transforms an ExpressionWithTypeArguments with TypeScript syntax.
         *
         * This function will only be called when one of the following conditions are met:
         * - The node contains type arguments that should be elided.
         *
         * @param node The ExpressionWithTypeArguments to transform.
         */
        function visitExpressionWithTypeArguments(node) {
            return ts.updateExpressionWithTypeArguments(node, 
            /*typeArguments*/ undefined, ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
        }
        /**
         * Determines whether to emit a function-like declaration. We should not emit the
         * declaration if it does not have a body.
         *
         * @param node The declaration node.
         */
        function shouldEmitFunctionLikeDeclaration(node) {
            return !ts.nodeIsMissing(node.body);
        }
        function visitPropertyDeclaration(node) {
            if (node.flags & 8388608 /* Ambient */) {
                return undefined;
            }
            var updated = ts.updateProperty(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), visitPropertyNameOfClassElement(node), 
            /*questionOrExclamationToken*/ undefined, 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        function visitConstructor(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return undefined;
            }
            return ts.updateConstructor(node, 
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, ts.visitParameterList(node.parameters, visitor, context), transformConstructorBody(node.body, node));
        }
        function transformConstructorBody(body, constructor) {
            var parametersWithPropertyAssignments = constructor &&
                ts.filter(constructor.parameters, function (p) { return ts.isParameterPropertyDeclaration(p, constructor); });
            if (!ts.some(parametersWithPropertyAssignments)) {
                return ts.visitFunctionBody(body, visitor, context);
            }
            var statements = [];
            var indexOfFirstStatement = 0;
            resumeLexicalEnvironment();
            indexOfFirstStatement = ts.addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor);
            // Add parameters with property assignments. Transforms this:
            //
            //  constructor (public x, public y) {
            //  }
            //
            // Into this:
            //
            //  constructor (x, y) {
            //      this.x = x;
            //      this.y = y;
            //  }
            //
            ts.addRange(statements, ts.map(parametersWithPropertyAssignments, transformParameterWithPropertyAssignment));
            // Add the existing statements, skipping the initial super call.
            ts.addRange(statements, ts.visitNodes(body.statements, visitor, ts.isStatement, indexOfFirstStatement));
            // End the lexical environment.
            statements = ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), body.statements), /*multiLine*/ true);
            ts.setTextRange(block, /*location*/ body);
            ts.setOriginalNode(block, body);
            return block;
        }
        /**
         * Transforms a parameter into a property assignment statement.
         *
         * @param node The parameter declaration.
         */
        function transformParameterWithPropertyAssignment(node) {
            var name = node.name;
            if (!ts.isIdentifier(name)) {
                return undefined;
            }
            var propertyName = ts.getMutableClone(name);
            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 48 /* NoSourceMap */);
            var localName = ts.getMutableClone(name);
            ts.setEmitFlags(localName, 1536 /* NoComments */);
            return ts.startOnNewLine(ts.removeAllComments(ts.setTextRange(ts.setOriginalNode(ts.createExpressionStatement(ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createThis(), propertyName), node.name), localName)), node), ts.moveRangePos(node, -1))));
        }
        function visitMethodDeclaration(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateMethod(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, visitPropertyNameOfClassElement(node), 
            /*questionToken*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        /**
         * Determines whether to emit an accessor declaration. We should not emit the
         * declaration if it does not have a body and is abstract.
         *
         * @param node The declaration node.
         */
        function shouldEmitAccessorDeclaration(node) {
            return !(ts.nodeIsMissing(node.body) && ts.hasModifier(node, 128 /* Abstract */));
        }
        function visitGetAccessor(node) {
            if (!shouldEmitAccessorDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateGetAccessor(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        function visitSetAccessor(node) {
            if (!shouldEmitAccessorDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateSetAccessor(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        function visitFunctionDeclaration(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            var updated = ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (isExportOfNamespace(node)) {
                var statements = [updated];
                addExportMemberAssignment(statements, node);
                return statements;
            }
            return updated;
        }
        function visitFunctionExpression(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return ts.createOmittedExpression();
            }
            var updated = ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            return updated;
        }
        function visitArrowFunction(node) {
            var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context));
            return updated;
        }
        function visitParameter(node) {
            if (ts.parameterIsThisKeyword(node)) {
                return undefined;
            }
            var updated = ts.updateParameter(node, 
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, node.dotDotDotToken, ts.visitNode(node.name, visitor, ts.isBindingName), 
            /*questionToken*/ undefined, 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setTextRange(updated, ts.moveRangePastModifiers(node));
                ts.setSourceMapRange(updated, ts.moveRangePastModifiers(node));
                ts.setEmitFlags(updated.name, 32 /* NoTrailingSourceMap */);
            }
            return updated;
        }
        function visitVariableStatement(node) {
            if (isExportOfNamespace(node)) {
                var variables = ts.getInitializedVariables(node.declarationList);
                if (variables.length === 0) {
                    // elide statement if there are no initialized variables.
                    return undefined;
                }
                return ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformInitializedVariable(node) {
            var name = node.name;
            if (ts.isBindingPattern(name)) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, 
                /*needsValue*/ false, createNamespaceExportExpression);
            }
            else {
                return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), ts.visitNode(node.initializer, visitor, ts.isExpression)), 
                /*location*/ node);
            }
        }
        function visitVariableDeclaration(node) {
            return ts.updateTypeScriptVariableDeclaration(node, ts.visitNode(node.name, visitor, ts.isBindingName), 
            /*exclaimationToken*/ undefined, 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
        }
        function visitParenthesizedExpression(node) {
            var innerExpression = ts.skipOuterExpressions(node.expression, ~6 /* Assertions */);
            if (ts.isAssertionExpression(innerExpression)) {
                // Make sure we consider all nested cast expressions, e.g.:
                // (<any><number><any>-A).x;
                var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
                // We have an expression of the form: (<Type>SubExpr). Emitting this as (SubExpr)
                // is really not desirable. We would like to emit the subexpression as-is. Omitting
                // the parentheses, however, could cause change in the semantics of the generated
                // code if the casted expression has a lower precedence than the rest of the
                // expression.
                //
                // To preserve comments, we return a "PartiallyEmittedExpression" here which will
                // preserve the position information of the original expression.
                //
                // Due to the auto-parenthesization rules used by the visitor and factory functions
                // we can safely elide the parentheses here, as a new synthetic
                // ParenthesizedExpression will be inserted if we remove parentheses too
                // aggressively.
                // HOWEVER - if there are leading comments on the expression itself, to handle ASI
                // correctly for return and throw, we must keep the parenthesis
                if (ts.length(ts.getLeadingCommentRangesOfNode(expression, currentSourceFile))) {
                    return ts.updateParen(node, expression);
                }
                return ts.createPartiallyEmittedExpression(expression, node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitAssertionExpression(node) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            return ts.createPartiallyEmittedExpression(expression, node);
        }
        function visitNonNullExpression(node) {
            var expression = ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression);
            return ts.createPartiallyEmittedExpression(expression, node);
        }
        function visitCallExpression(node) {
            return ts.updateCall(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitNewExpression(node) {
            return ts.updateNew(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitTaggedTemplateExpression(node) {
            return ts.updateTaggedTemplate(node, ts.visitNode(node.tag, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNode(node.template, visitor, ts.isExpression));
        }
        function visitJsxSelfClosingElement(node) {
            return ts.updateJsxSelfClosingElement(node, ts.visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), 
            /*typeArguments*/ undefined, ts.visitNode(node.attributes, visitor, ts.isJsxAttributes));
        }
        function visitJsxJsxOpeningElement(node) {
            return ts.updateJsxOpeningElement(node, ts.visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), 
            /*typeArguments*/ undefined, ts.visitNode(node.attributes, visitor, ts.isJsxAttributes));
        }
        /**
         * Determines whether to emit an enum declaration.
         *
         * @param node The enum declaration node.
         */
        function shouldEmitEnumDeclaration(node) {
            return !ts.isEnumConst(node)
                || compilerOptions.preserveConstEnums
                || compilerOptions.isolatedModules;
        }
        /**
         * Visits an enum declaration.
         *
         * This function will be called any time a TypeScript enum is encountered.
         *
         * @param node The enum declaration node.
         */
        function visitEnumDeclaration(node) {
            if (!shouldEmitEnumDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            var statements = [];
            // We request to be advised when the printer is about to print this node. This allows
            // us to set up the correct state for later substitutions.
            var emitFlags = 2 /* AdviseOnEmitNode */;
            // If needed, we should emit a variable declaration for the enum. If we emit
            // a leading variable declaration, we should not emit leading comments for the
            // enum body.
            var varAdded = addVarForEnumOrModuleDeclaration(statements, node);
            if (varAdded) {
                // We should still emit the comments if we are emitting a system module.
                if (moduleKind !== ts.ModuleKind.System || currentLexicalScope !== currentSourceFile) {
                    emitFlags |= 512 /* NoLeadingComments */;
                }
            }
            // `parameterName` is the declaration name used inside of the enum.
            var parameterName = getNamespaceParameterName(node);
            // `containerName` is the expression used inside of the enum for assignments.
            var containerName = getNamespaceContainerName(node);
            // `exportName` is the expression used within this node's container for any exported references.
            var exportName = ts.hasModifier(node, 1 /* Export */)
                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  x || (x = {})
            //  exports.x || (exports.x = {})
            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
            if (hasNamespaceQualifiedExportName(node)) {
                // `localName` is the expression used within this node's containing scope for any local references.
                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
                //  x = (exports.x || (exports.x = {}))
                moduleArg = ts.createAssignment(localName, moduleArg);
            }
            //  (function (x) {
            //      x[x["y"] = 0] = "y";
            //      ...
            //  })(x || (x = {}));
            var enumStatement = ts.createExpressionStatement(ts.createCall(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
            /*type*/ undefined, transformEnumBody(node, containerName)), 
            /*typeArguments*/ undefined, [moduleArg]));
            ts.setOriginalNode(enumStatement, node);
            if (varAdded) {
                // If a variable was added, synthetic comments are emitted on it, not on the moduleStatement.
                ts.setSyntheticLeadingComments(enumStatement, undefined);
                ts.setSyntheticTrailingComments(enumStatement, undefined);
            }
            ts.setTextRange(enumStatement, node);
            ts.addEmitFlags(enumStatement, emitFlags);
            statements.push(enumStatement);
            // Add a DeclarationMarker for the enum to preserve trailing comments and mark
            // the end of the declaration.
            statements.push(ts.createEndOfDeclarationMarker(node));
            return statements;
        }
        /**
         * Transforms the body of an enum declaration.
         *
         * @param node The enum declaration node.
         */
        function transformEnumBody(node, localName) {
            var savedCurrentNamespaceLocalName = currentNamespaceContainerName;
            currentNamespaceContainerName = localName;
            var statements = [];
            startLexicalEnvironment();
            var members = ts.map(node.members, transformEnumMember);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            ts.addRange(statements, members);
            currentNamespaceContainerName = savedCurrentNamespaceLocalName;
            return ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), 
            /*multiLine*/ true);
        }
        /**
         * Transforms an enum member into a statement.
         *
         * @param member The enum member node.
         */
        function transformEnumMember(member) {
            // enums don't support computed properties
            // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes
            // old emitter always generate 'expression' part of the name as-is.
            var name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false);
            var valueExpression = transformEnumMemberDeclarationValue(member);
            var innerAssignment = ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, name), valueExpression);
            var outerAssignment = valueExpression.kind === 10 /* StringLiteral */ ?
                innerAssignment :
                ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, innerAssignment), name);
            return ts.setTextRange(ts.createExpressionStatement(ts.setTextRange(outerAssignment, member)), member);
        }
        /**
         * Transforms the value of an enum member.
         *
         * @param member The enum member node.
         */
        function transformEnumMemberDeclarationValue(member) {
            var value = resolver.getConstantValue(member);
            if (value !== undefined) {
                return ts.createLiteral(value);
            }
            else {
                enableSubstitutionForNonQualifiedEnumMembers();
                if (member.initializer) {
                    return ts.visitNode(member.initializer, visitor, ts.isExpression);
                }
                else {
                    return ts.createVoidZero();
                }
            }
        }
        /**
         * Determines whether to elide a module declaration.
         *
         * @param node The module declaration node.
         */
        function shouldEmitModuleDeclaration(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isModuleDeclaration);
            if (!node) {
                // If we can't find a parse tree node, assume the node is instantiated.
                return true;
            }
            return ts.isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules);
        }
        /**
         * Determines whether an exported declaration will have a qualified export name (e.g. `f.x`
         * or `exports.x`).
         */
        function hasNamespaceQualifiedExportName(node) {
            return isExportOfNamespace(node)
                || (isExternalModuleExport(node)
                    && moduleKind !== ts.ModuleKind.ES2015
                    && moduleKind !== ts.ModuleKind.ES2020
                    && moduleKind !== ts.ModuleKind.ESNext
                    && moduleKind !== ts.ModuleKind.System);
        }
        /**
         * Records that a declaration was emitted in the current scope, if it was the first
         * declaration for the provided symbol.
         */
        function recordEmittedDeclarationInScope(node) {
            if (!currentScopeFirstDeclarationsOfName) {
                currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap();
            }
            var name = declaredNameInScope(node);
            if (!currentScopeFirstDeclarationsOfName.has(name)) {
                currentScopeFirstDeclarationsOfName.set(name, node);
            }
        }
        /**
         * Determines whether a declaration is the first declaration with
         * the same name emitted in the current scope.
         */
        function isFirstEmittedDeclarationInScope(node) {
            if (currentScopeFirstDeclarationsOfName) {
                var name = declaredNameInScope(node);
                return currentScopeFirstDeclarationsOfName.get(name) === node;
            }
            return true;
        }
        function declaredNameInScope(node) {
            ts.Debug.assertNode(node.name, ts.isIdentifier);
            return node.name.escapedText;
        }
        /**
         * Adds a leading VariableStatement for a enum or module declaration.
         */
        function addVarForEnumOrModuleDeclaration(statements, node) {
            // Emit a variable statement for the module. We emit top-level enums as a `var`
            // declaration to avoid static errors in global scripts scripts due to redeclaration.
            // enums in any other scope are emitted as a `let` declaration.
            var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
                ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))
            ], currentLexicalScope.kind === 290 /* SourceFile */ ? 0 /* None */ : 1 /* Let */));
            ts.setOriginalNode(statement, node);
            recordEmittedDeclarationInScope(node);
            if (isFirstEmittedDeclarationInScope(node)) {
                // Adjust the source map emit to match the old emitter.
                if (node.kind === 248 /* EnumDeclaration */) {
                    ts.setSourceMapRange(statement.declarationList, node);
                }
                else {
                    ts.setSourceMapRange(statement, node);
                }
                // Trailing comments for module declaration should be emitted after the function closure
                // instead of the variable statement:
                //
                //     /** Module comment*/
                //     module m1 {
                //         function foo4Export() {
                //         }
                //     } // trailing comment module
                //
                // Should emit:
                //
                //     /** Module comment*/
                //     var m1;
                //     (function (m1) {
                //         function foo4Export() {
                //         }
                //     })(m1 || (m1 = {})); // trailing comment module
                //
                ts.setCommentRange(statement, node);
                ts.addEmitFlags(statement, 1024 /* NoTrailingComments */ | 4194304 /* HasEndOfDeclarationMarker */);
                statements.push(statement);
                return true;
            }
            else {
                // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
                // declaration we do not emit a leading variable declaration. To preserve the
                // begin/end semantics of the declararation and to properly handle exports
                // we wrap the leading variable declaration in a `MergeDeclarationMarker`.
                var mergeMarker = ts.createMergeDeclarationMarker(statement);
                ts.setEmitFlags(mergeMarker, 1536 /* NoComments */ | 4194304 /* HasEndOfDeclarationMarker */);
                statements.push(mergeMarker);
                return false;
            }
        }
        /**
         * Visits a module declaration node.
         *
         * This function will be called any time a TypeScript namespace (ModuleDeclaration) is encountered.
         *
         * @param node The module declaration node.
         */
        function visitModuleDeclaration(node) {
            if (!shouldEmitModuleDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name.");
            enableSubstitutionForNamespaceExports();
            var statements = [];
            // We request to be advised when the printer is about to print this node. This allows
            // us to set up the correct state for later substitutions.
            var emitFlags = 2 /* AdviseOnEmitNode */;
            // If needed, we should emit a variable declaration for the module. If we emit
            // a leading variable declaration, we should not emit leading comments for the
            // module body.
            var varAdded = addVarForEnumOrModuleDeclaration(statements, node);
            if (varAdded) {
                // We should still emit the comments if we are emitting a system module.
                if (moduleKind !== ts.ModuleKind.System || currentLexicalScope !== currentSourceFile) {
                    emitFlags |= 512 /* NoLeadingComments */;
                }
            }
            // `parameterName` is the declaration name used inside of the namespace.
            var parameterName = getNamespaceParameterName(node);
            // `containerName` is the expression used inside of the namespace for exports.
            var containerName = getNamespaceContainerName(node);
            // `exportName` is the expression used within this node's container for any exported references.
            var exportName = ts.hasModifier(node, 1 /* Export */)
                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  x || (x = {})
            //  exports.x || (exports.x = {})
            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
            if (hasNamespaceQualifiedExportName(node)) {
                // `localName` is the expression used within this node's containing scope for any local references.
                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
                //  x = (exports.x || (exports.x = {}))
                moduleArg = ts.createAssignment(localName, moduleArg);
            }
            //  (function (x_1) {
            //      x_1.y = ...;
            //  })(x || (x = {}));
            var moduleStatement = ts.createExpressionStatement(ts.createCall(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
            /*type*/ undefined, transformModuleBody(node, containerName)), 
            /*typeArguments*/ undefined, [moduleArg]));
            ts.setOriginalNode(moduleStatement, node);
            if (varAdded) {
                // If a variable was added, synthetic comments are emitted on it, not on the moduleStatement.
                ts.setSyntheticLeadingComments(moduleStatement, undefined);
                ts.setSyntheticTrailingComments(moduleStatement, undefined);
            }
            ts.setTextRange(moduleStatement, node);
            ts.addEmitFlags(moduleStatement, emitFlags);
            statements.push(moduleStatement);
            // Add a DeclarationMarker for the namespace to preserve trailing comments and mark
            // the end of the declaration.
            statements.push(ts.createEndOfDeclarationMarker(node));
            return statements;
        }
        /**
         * Transforms the body of a module declaration.
         *
         * @param node The module declaration node.
         */
        function transformModuleBody(node, namespaceLocalName) {
            var savedCurrentNamespaceContainerName = currentNamespaceContainerName;
            var savedCurrentNamespace = currentNamespace;
            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
            currentNamespaceContainerName = namespaceLocalName;
            currentNamespace = node;
            currentScopeFirstDeclarationsOfName = undefined;
            var statements = [];
            startLexicalEnvironment();
            var statementsLocation;
            var blockLocation;
            if (node.body) {
                if (node.body.kind === 250 /* ModuleBlock */) {
                    saveStateAndInvoke(node.body, function (body) { return ts.addRange(statements, ts.visitNodes(body.statements, namespaceElementVisitor, ts.isStatement)); });
                    statementsLocation = node.body.statements;
                    blockLocation = node.body;
                }
                else {
                    var result = visitModuleDeclaration(node.body);
                    if (result) {
                        if (ts.isArray(result)) {
                            ts.addRange(statements, result);
                        }
                        else {
                            statements.push(result);
                        }
                    }
                    var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
                    statementsLocation = ts.moveRangePos(moduleBlock.statements, -1);
                }
            }
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            currentNamespaceContainerName = savedCurrentNamespaceContainerName;
            currentNamespace = savedCurrentNamespace;
            currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ statementsLocation), 
            /*multiLine*/ true);
            ts.setTextRange(block, blockLocation);
            // namespace hello.hi.world {
            //      function foo() {}
            //
            //      // TODO, blah
            // }
            //
            // should be emitted as
            //
            // var hello;
            // (function (hello) {
            //     var hi;
            //     (function (hi) {
            //         var world;
            //         (function (world) {
            //             function foo() { }
            //             // TODO, blah
            //         })(world = hi.world || (hi.world = {}));
            //     })(hi = hello.hi || (hello.hi = {}));
            // })(hello || (hello = {}));
            // We only want to emit comment on the namespace which contains block body itself, not the containing namespaces.
            if (!node.body || node.body.kind !== 250 /* ModuleBlock */) {
                ts.setEmitFlags(block, ts.getEmitFlags(block) | 1536 /* NoComments */);
            }
            return block;
        }
        function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
            if (moduleDeclaration.body.kind === 249 /* ModuleDeclaration */) {
                var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
                return recursiveInnerModule || moduleDeclaration.body;
            }
        }
        /**
         * Visits an import declaration, eliding it if it is not referenced and `importsNotUsedAsValues` is not 'preserve'.
         *
         * @param node The import declaration node.
         */
        function visitImportDeclaration(node) {
            if (!node.importClause) {
                // Do not elide a side-effect only import declaration.
                //  import "foo";
                return node;
            }
            if (node.importClause.isTypeOnly) {
                // Always elide type-only imports
                return undefined;
            }
            // Elide the declaration if the import clause was elided.
            var importClause = ts.visitNode(node.importClause, visitImportClause, ts.isImportClause);
            return importClause ||
                compilerOptions.importsNotUsedAsValues === 1 /* Preserve */ ||
                compilerOptions.importsNotUsedAsValues === 2 /* Error */
                ? ts.updateImportDeclaration(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, importClause, node.moduleSpecifier)
                : undefined;
        }
        /**
         * Visits an import clause, eliding it if it is not referenced.
         *
         * @param node The import clause node.
         */
        function visitImportClause(node) {
            if (node.isTypeOnly) {
                return undefined;
            }
            // Elide the import clause if we elide both its name and its named bindings.
            var name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
            var namedBindings = ts.visitNode(node.namedBindings, visitNamedImportBindings, ts.isNamedImportBindings);
            return (name || namedBindings) ? ts.updateImportClause(node, name, namedBindings, /*isTypeOnly*/ false) : undefined;
        }
        /**
         * Visits named import bindings, eliding it if it is not referenced.
         *
         * @param node The named import bindings node.
         */
        function visitNamedImportBindings(node) {
            if (node.kind === 256 /* NamespaceImport */) {
                // Elide a namespace import if it is not referenced.
                return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
            }
            else {
                // Elide named imports if all of its import specifiers are elided.
                var elements = ts.visitNodes(node.elements, visitImportSpecifier, ts.isImportSpecifier);
                return ts.some(elements) ? ts.updateNamedImports(node, elements) : undefined;
            }
        }
        /**
         * Visits an import specifier, eliding it if it is not referenced.
         *
         * @param node The import specifier node.
         */
        function visitImportSpecifier(node) {
            // Elide an import specifier if it is not referenced.
            return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
        }
        /**
         * Visits an export assignment, eliding it if it does not contain a clause that resolves
         * to a value.
         *
         * @param node The export assignment node.
         */
        function visitExportAssignment(node) {
            // Elide the export assignment if it does not reference a value.
            return resolver.isValueAliasDeclaration(node)
                ? ts.visitEachChild(node, visitor, context)
                : undefined;
        }
        /**
         * Visits an export declaration, eliding it if it does not contain a clause that resolves
         * to a value.
         *
         * @param node The export declaration node.
         */
        function visitExportDeclaration(node) {
            if (node.isTypeOnly) {
                return undefined;
            }
            if (!node.exportClause || ts.isNamespaceExport(node.exportClause)) {
                // never elide `export <whatever> from <whereever>` declarations -
                // they should be kept for sideffects/untyped exports, even when the
                // type checker doesn't know about any exports
                return node;
            }
            if (!resolver.isValueAliasDeclaration(node)) {
                // Elide the export declaration if it does not export a value.
                return undefined;
            }
            // Elide the export declaration if all of its named exports are elided.
            var exportClause = ts.visitNode(node.exportClause, visitNamedExportBindings, ts.isNamedExportBindings);
            return exportClause
                ? ts.updateExportDeclaration(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, exportClause, node.moduleSpecifier, node.isTypeOnly)
                : undefined;
        }
        /**
         * Visits named exports, eliding it if it does not contain an export specifier that
         * resolves to a value.
         *
         * @param node The named exports node.
         */
        function visitNamedExports(node) {
            // Elide the named exports if all of its export specifiers were elided.
            var elements = ts.visitNodes(node.elements, visitExportSpecifier, ts.isExportSpecifier);
            return ts.some(elements) ? ts.updateNamedExports(node, elements) : undefined;
        }
        function visitNamespaceExports(node) {
            return ts.updateNamespaceExport(node, ts.visitNode(node.name, visitor, ts.isIdentifier));
        }
        function visitNamedExportBindings(node) {
            return ts.isNamespaceExport(node) ? visitNamespaceExports(node) : visitNamedExports(node);
        }
        /**
         * Visits an export specifier, eliding it if it does not resolve to a value.
         *
         * @param node The export specifier node.
         */
        function visitExportSpecifier(node) {
            // Elide an export specifier if it does not reference a value.
            return resolver.isValueAliasDeclaration(node) ? node : undefined;
        }
        /**
         * Determines whether to emit an import equals declaration.
         *
         * @param node The import equals declaration node.
         */
        function shouldEmitImportEqualsDeclaration(node) {
            // preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
            // - current file is not external module
            // - import declaration is top level and target is value imported by entity name
            return resolver.isReferencedAliasDeclaration(node)
                || (!ts.isExternalModule(currentSourceFile)
                    && resolver.isTopLevelValueImportEqualsWithEntityName(node));
        }
        /**
         * Visits an import equals declaration.
         *
         * @param node The import equals declaration node.
         */
        function visitImportEqualsDeclaration(node) {
            if (ts.isExternalModuleImportEqualsDeclaration(node)) {
                var isReferenced = resolver.isReferencedAliasDeclaration(node);
                // If the alias is unreferenced but we want to keep the import, replace with 'import "mod"'.
                if (!isReferenced && compilerOptions.importsNotUsedAsValues === 1 /* Preserve */) {
                    return ts.setOriginalNode(ts.setTextRange(ts.createImportDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*importClause*/ undefined, node.moduleReference.expression), node), node);
                }
                return isReferenced ? ts.visitEachChild(node, visitor, context) : undefined;
            }
            if (!shouldEmitImportEqualsDeclaration(node)) {
                return undefined;
            }
            var moduleReference = ts.createExpressionFromEntityName(node.moduleReference);
            ts.setEmitFlags(moduleReference, 1536 /* NoComments */ | 2048 /* NoNestedComments */);
            if (isNamedExternalModuleExport(node) || !isExportOfNamespace(node)) {
                //  export var ${name} = ${moduleReference};
                //  var ${name} = ${moduleReference};
                return ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
                    ts.setOriginalNode(ts.createVariableDeclaration(node.name, 
                    /*type*/ undefined, moduleReference), node)
                ])), node), node);
            }
            else {
                // exports.${name} = ${moduleReference};
                return ts.setOriginalNode(createNamespaceExport(node.name, moduleReference, node), node);
            }
        }
        /**
         * Gets a value indicating whether the node is exported from a namespace.
         *
         * @param node The node to test.
         */
        function isExportOfNamespace(node) {
            return currentNamespace !== undefined && ts.hasModifier(node, 1 /* Export */);
        }
        /**
         * Gets a value indicating whether the node is exported from an external module.
         *
         * @param node The node to test.
         */
        function isExternalModuleExport(node) {
            return currentNamespace === undefined && ts.hasModifier(node, 1 /* Export */);
        }
        /**
         * Gets a value indicating whether the node is a named export from an external module.
         *
         * @param node The node to test.
         */
        function isNamedExternalModuleExport(node) {
            return isExternalModuleExport(node)
                && !ts.hasModifier(node, 512 /* Default */);
        }
        /**
         * Gets a value indicating whether the node is the default export of an external module.
         *
         * @param node The node to test.
         */
        function isDefaultExternalModuleExport(node) {
            return isExternalModuleExport(node)
                && ts.hasModifier(node, 512 /* Default */);
        }
        /**
         * Creates a statement for the provided expression. This is used in calls to `map`.
         */
        function expressionToStatement(expression) {
            return ts.createExpressionStatement(expression);
        }
        function addExportMemberAssignment(statements, node) {
            var expression = ts.createAssignment(ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true), ts.getLocalName(node));
            ts.setSourceMapRange(expression, ts.createRange(node.name ? node.name.pos : node.pos, node.end));
            var statement = ts.createExpressionStatement(expression);
            ts.setSourceMapRange(statement, ts.createRange(-1, node.end));
            statements.push(statement);
        }
        function createNamespaceExport(exportName, exportValue, location) {
            return ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(ts.getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), exportValue)), location);
        }
        function createNamespaceExportExpression(exportName, exportValue, location) {
            return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location);
        }
        function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name) {
            return ts.getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true);
        }
        /**
         * Gets the declaration name used inside of a namespace or enum.
         */
        function getNamespaceParameterName(node) {
            var name = ts.getGeneratedNameForNode(node);
            ts.setSourceMapRange(name, node.name);
            return name;
        }
        /**
         * Gets the expression used to refer to a namespace or enum within the body
         * of its declaration.
         */
        function getNamespaceContainerName(node) {
            return ts.getGeneratedNameForNode(node);
        }
        /**
         * Gets a local alias for a class declaration if it is a decorated class with an internal
         * reference to the static side of the class. This is necessary to avoid issues with
         * double-binding semantics for the class name.
         */
        function getClassAliasIfNeeded(node) {
            if (resolver.getNodeCheckFlags(node) & 16777216 /* ClassWithConstructorReference */) {
                enableSubstitutionForClassAliases();
                var classAlias = ts.createUniqueName(node.name && !ts.isGeneratedIdentifier(node.name) ? ts.idText(node.name) : "default");
                classAliases[ts.getOriginalNodeId(node)] = classAlias;
                hoistVariableDeclaration(classAlias);
                return classAlias;
            }
        }
        function getClassPrototype(node) {
            return ts.createPropertyAccess(ts.getDeclarationName(node), "prototype");
        }
        function getClassMemberPrefix(node, member) {
            return ts.hasModifier(member, 32 /* Static */)
                ? ts.getDeclarationName(node)
                : getClassPrototype(node);
        }
        function enableSubstitutionForNonQualifiedEnumMembers() {
            if ((enabledSubstitutions & 8 /* NonQualifiedEnumMembers */) === 0) {
                enabledSubstitutions |= 8 /* NonQualifiedEnumMembers */;
                context.enableSubstitution(75 /* Identifier */);
            }
        }
        function enableSubstitutionForClassAliases() {
            if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) {
                enabledSubstitutions |= 1 /* ClassAliases */;
                // We need to enable substitutions for identifiers. This allows us to
                // substitute class names inside of a class declaration.
                context.enableSubstitution(75 /* Identifier */);
                // Keep track of class aliases.
                classAliases = [];
            }
        }
        function enableSubstitutionForNamespaceExports() {
            if ((enabledSubstitutions & 2 /* NamespaceExports */) === 0) {
                enabledSubstitutions |= 2 /* NamespaceExports */;
                // We need to enable substitutions for identifiers and shorthand property assignments. This allows us to
                // substitute the names of exported members of a namespace.
                context.enableSubstitution(75 /* Identifier */);
                context.enableSubstitution(282 /* ShorthandPropertyAssignment */);
                // We need to be notified when entering and exiting namespaces.
                context.enableEmitNotification(249 /* ModuleDeclaration */);
            }
        }
        function isTransformedModuleDeclaration(node) {
            return ts.getOriginalNode(node).kind === 249 /* ModuleDeclaration */;
        }
        function isTransformedEnumDeclaration(node) {
            return ts.getOriginalNode(node).kind === 248 /* EnumDeclaration */;
        }
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            var savedApplicableSubstitutions = applicableSubstitutions;
            var savedCurrentSourceFile = currentSourceFile;
            if (ts.isSourceFile(node)) {
                currentSourceFile = node;
            }
            if (enabledSubstitutions & 2 /* NamespaceExports */ && isTransformedModuleDeclaration(node)) {
                applicableSubstitutions |= 2 /* NamespaceExports */;
            }
            if (enabledSubstitutions & 8 /* NonQualifiedEnumMembers */ && isTransformedEnumDeclaration(node)) {
                applicableSubstitutions |= 8 /* NonQualifiedEnumMembers */;
            }
            previousOnEmitNode(hint, node, emitCallback);
            applicableSubstitutions = savedApplicableSubstitutions;
            currentSourceFile = savedCurrentSourceFile;
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        function substituteShorthandPropertyAssignment(node) {
            if (enabledSubstitutions & 2 /* NamespaceExports */) {
                var name = node.name;
                var exportedName = trySubstituteNamespaceExportedName(name);
                if (exportedName) {
                    // A shorthand property with an assignment initializer is probably part of a
                    // destructuring assignment
                    if (node.objectAssignmentInitializer) {
                        var initializer = ts.createAssignment(exportedName, node.objectAssignmentInitializer);
                        return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
                    }
                    return ts.setTextRange(ts.createPropertyAssignment(name, exportedName), node);
                }
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 194 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 195 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            return trySubstituteClassAlias(node)
                || trySubstituteNamespaceExportedName(node)
                || node;
        }
        function trySubstituteClassAlias(node) {
            if (enabledSubstitutions & 1 /* ClassAliases */) {
                if (resolver.getNodeCheckFlags(node) & 33554432 /* ConstructorReferenceInClass */) {
                    // Due to the emit for class decorators, any reference to the class from inside of the class body
                    // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                    // behavior of class names in ES6.
                    // Also, when emitting statics for class expressions, we must substitute a class alias for
                    // constructor references in static property initializers.
                    var declaration = resolver.getReferencedValueDeclaration(node);
                    if (declaration) {
                        var classAlias = classAliases[declaration.id]; // TODO: GH#18217
                        if (classAlias) {
                            var clone_1 = ts.getSynthesizedClone(classAlias);
                            ts.setSourceMapRange(clone_1, node);
                            ts.setCommentRange(clone_1, node);
                            return clone_1;
                        }
                    }
                }
            }
            return undefined;
        }
        function trySubstituteNamespaceExportedName(node) {
            // If this is explicitly a local name, do not substitute.
            if (enabledSubstitutions & applicableSubstitutions && !ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                // If we are nested within a namespace declaration, we may need to qualifiy
                // an identifier that is exported from a merged namespace.
                var container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false);
                if (container && container.kind !== 290 /* SourceFile */) {
                    var substitute = (applicableSubstitutions & 2 /* NamespaceExports */ && container.kind === 249 /* ModuleDeclaration */) ||
                        (applicableSubstitutions & 8 /* NonQualifiedEnumMembers */ && container.kind === 248 /* EnumDeclaration */);
                    if (substitute) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(container), node), 
                        /*location*/ node);
                    }
                }
            }
            return undefined;
        }
        function substitutePropertyAccessExpression(node) {
            return substituteConstantValue(node);
        }
        function substituteElementAccessExpression(node) {
            return substituteConstantValue(node);
        }
        function substituteConstantValue(node) {
            var constantValue = tryGetConstEnumValue(node);
            if (constantValue !== undefined) {
                // track the constant value on the node for the printer in needsDotDotForPropertyAccess
                ts.setConstantValue(node, constantValue);
                var substitute = ts.createLiteral(constantValue);
                if (!compilerOptions.removeComments) {
                    var originalNode = ts.getOriginalNode(node, ts.isAccessExpression);
                    var propertyName = ts.isPropertyAccessExpression(originalNode)
                        ? ts.declarationNameToString(originalNode.name)
                        : ts.getTextOfNode(originalNode.argumentExpression);
                    ts.addSyntheticTrailingComment(substitute, 3 /* MultiLineCommentTrivia */, " " + propertyName + " ");
                }
                return substitute;
            }
            return node;
        }
        function tryGetConstEnumValue(node) {
            if (compilerOptions.isolatedModules) {
                return undefined;
            }
            return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined;
        }
    }
    ts.transformTypeScript = transformTypeScript;
    function createDecorateHelper(context, decoratorExpressions, target, memberName, descriptor, location) {
        var argumentsArray = [];
        argumentsArray.push(ts.createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
        argumentsArray.push(target);
        if (memberName) {
            argumentsArray.push(memberName);
            if (descriptor) {
                argumentsArray.push(descriptor);
            }
        }
        context.requestEmitHelper(ts.decorateHelper);
        return ts.setTextRange(ts.createCall(ts.getUnscopedHelperName("__decorate"), 
        /*typeArguments*/ undefined, argumentsArray), location);
    }
    ts.decorateHelper = {
        name: "typescript:decorate",
        importName: "__decorate",
        scoped: false,
        priority: 2,
        text: "\n            var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n                var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n                if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n                else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n                return c > 3 && r && Object.defineProperty(target, key, r), r;\n            };"
    };
    function createMetadataHelper(context, metadataKey, metadataValue) {
        context.requestEmitHelper(ts.metadataHelper);
        return ts.createCall(ts.getUnscopedHelperName("__metadata"), 
        /*typeArguments*/ undefined, [
            ts.createLiteral(metadataKey),
            metadataValue
        ]);
    }
    ts.metadataHelper = {
        name: "typescript:metadata",
        importName: "__metadata",
        scoped: false,
        priority: 3,
        text: "\n            var __metadata = (this && this.__metadata) || function (k, v) {\n                if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(k, v);\n            };"
    };
    function createParamHelper(context, expression, parameterOffset, location) {
        context.requestEmitHelper(ts.paramHelper);
        return ts.setTextRange(ts.createCall(ts.getUnscopedHelperName("__param"), 
        /*typeArguments*/ undefined, [
            ts.createLiteral(parameterOffset),
            expression
        ]), location);
    }
    ts.paramHelper = {
        name: "typescript:param",
        importName: "__param",
        scoped: false,
        priority: 4,
        text: "\n            var __param = (this && this.__param) || function (paramIndex, decorator) {\n                return function (target, key) { decorator(target, key, paramIndex); }\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ClassPropertySubstitutionFlags;
    (function (ClassPropertySubstitutionFlags) {
        /**
         * Enables substitutions for class expressions with static fields
         * which have initializers that reference the class name.
         */
        ClassPropertySubstitutionFlags[ClassPropertySubstitutionFlags["ClassAliases"] = 1] = "ClassAliases";
    })(ClassPropertySubstitutionFlags || (ClassPropertySubstitutionFlags = {}));
    var PrivateIdentifierPlacement;
    (function (PrivateIdentifierPlacement) {
        PrivateIdentifierPlacement[PrivateIdentifierPlacement["InstanceField"] = 0] = "InstanceField";
    })(PrivateIdentifierPlacement || (PrivateIdentifierPlacement = {}));
    /**
     * Transforms ECMAScript Class Syntax.
     * TypeScript parameter property syntax is transformed in the TypeScript transformer.
     * For now, this transforms public field declarations using TypeScript class semantics,
     * where declarations are elided and initializers are transformed as assignments in the constructor.
     * When --useDefineForClassFields is on, this transforms to ECMAScript semantics, with Object.defineProperty.
     */
    function transformClassFields(context) {
        var hoistVariableDeclaration = context.hoistVariableDeclaration, endLexicalEnvironment = context.endLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var shouldTransformPrivateFields = languageVersion < 99 /* ESNext */;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var enabledSubstitutions;
        var classAliases;
        /**
         * Tracks what computed name expressions originating from elided names must be inlined
         * at the next execution site, in document order
         */
        var pendingExpressions;
        /**
         * Tracks what computed name expression statements and static property initializers must be
         * emitted at the next execution site, in document order (for decorated classes).
         */
        var pendingStatements;
        var privateIdentifierEnvironmentStack = [];
        var currentPrivateIdentifierEnvironment;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            var options = context.getCompilerOptions();
            if (node.isDeclarationFile
                || options.useDefineForClassFields && options.target === 99 /* ESNext */) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            if (!(node.transformFlags & 4194304 /* ContainsClassFields */))
                return node;
            switch (node.kind) {
                case 214 /* ClassExpression */:
                case 245 /* ClassDeclaration */:
                    return visitClassLike(node);
                case 159 /* PropertyDeclaration */:
                    return visitPropertyDeclaration(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 154 /* ComputedPropertyName */:
                    return visitComputedPropertyName(node);
                case 194 /* PropertyAccessExpression */:
                    return visitPropertyAccessExpression(node);
                case 207 /* PrefixUnaryExpression */:
                    return visitPrefixUnaryExpression(node);
                case 208 /* PostfixUnaryExpression */:
                    return visitPostfixUnaryExpression(node, /*valueIsDiscarded*/ false);
                case 196 /* CallExpression */:
                    return visitCallExpression(node);
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                case 76 /* PrivateIdentifier */:
                    return visitPrivateIdentifier(node);
                case 226 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 230 /* ForStatement */:
                    return visitForStatement(node);
                case 198 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitorDestructuringTarget(node) {
            switch (node.kind) {
                case 193 /* ObjectLiteralExpression */:
                case 192 /* ArrayLiteralExpression */:
                    return visitAssignmentPattern(node);
                default:
                    return visitor(node);
            }
        }
        /**
         * If we visit a private name, this means it is an undeclared private name.
         * Replace it with an empty identifier to indicate a problem with the code.
         */
        function visitPrivateIdentifier(node) {
            if (!shouldTransformPrivateFields) {
                return node;
            }
            return ts.setOriginalNode(ts.createIdentifier(""), node);
        }
        /**
         * Visits the members of a class that has fields.
         *
         * @param node The node to visit.
         */
        function classElementVisitor(node) {
            switch (node.kind) {
                case 162 /* Constructor */:
                    // Constructors for classes using class fields are transformed in
                    // `visitClassDeclaration` or `visitClassExpression`.
                    return undefined;
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 161 /* MethodDeclaration */:
                    // Visit the name of the member (if it's a computed property name).
                    return ts.visitEachChild(node, classElementVisitor, context);
                case 159 /* PropertyDeclaration */:
                    return visitPropertyDeclaration(node);
                case 154 /* ComputedPropertyName */:
                    return visitComputedPropertyName(node);
                case 222 /* SemicolonClassElement */:
                    return node;
                default:
                    return visitor(node);
            }
        }
        function visitVariableStatement(node) {
            var savedPendingStatements = pendingStatements;
            pendingStatements = [];
            var visitedNode = ts.visitEachChild(node, visitor, context);
            var statement = ts.some(pendingStatements) ? __spreadArrays([visitedNode], pendingStatements) :
                visitedNode;
            pendingStatements = savedPendingStatements;
            return statement;
        }
        function visitComputedPropertyName(name) {
            var node = ts.visitEachChild(name, visitor, context);
            if (ts.some(pendingExpressions)) {
                var expressions = pendingExpressions;
                expressions.push(name.expression);
                pendingExpressions = [];
                node = ts.updateComputedPropertyName(node, ts.inlineExpressions(expressions));
            }
            return node;
        }
        function visitPropertyDeclaration(node) {
            ts.Debug.assert(!ts.some(node.decorators));
            if (!shouldTransformPrivateFields && ts.isPrivateIdentifier(node.name)) {
                // Initializer is elided as the field is initialized in transformConstructor.
                return ts.updateProperty(node, 
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.name, 
                /*questionOrExclamationToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined);
            }
            // Create a temporary variable to store a computed property name (if necessary).
            // If it's not inlineable, then we emit an expression after the class which assigns
            // the property name to the temporary variable.
            var expr = getPropertyNameExpressionIfNeeded(node.name, !!node.initializer || !!context.getCompilerOptions().useDefineForClassFields);
            if (expr && !ts.isSimpleInlineableExpression(expr)) {
                (pendingExpressions || (pendingExpressions = [])).push(expr);
            }
            return undefined;
        }
        function createPrivateIdentifierAccess(info, receiver) {
            receiver = ts.visitNode(receiver, visitor, ts.isExpression);
            switch (info.placement) {
                case 0 /* InstanceField */:
                    return createClassPrivateFieldGetHelper(context, ts.nodeIsSynthesized(receiver) ? receiver : ts.getSynthesizedClone(receiver), info.weakMapName);
                default: return ts.Debug.fail("Unexpected private identifier placement");
            }
        }
        function visitPropertyAccessExpression(node) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifier(node.name)) {
                var privateIdentifierInfo = accessPrivateIdentifier(node.name);
                if (privateIdentifierInfo) {
                    return ts.setOriginalNode(createPrivateIdentifierAccess(privateIdentifierInfo, node.expression), node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitPrefixUnaryExpression(node) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyAccessExpression(node.operand)) {
                var operator = node.operator === 45 /* PlusPlusToken */ ?
                    39 /* PlusToken */ : node.operator === 46 /* MinusMinusToken */ ?
                    40 /* MinusToken */ : undefined;
                var info = void 0;
                if (operator && (info = accessPrivateIdentifier(node.operand.name))) {
                    var receiver = ts.visitNode(node.operand.expression, visitor, ts.isExpression);
                    var _a = createCopiableReceiverExpr(receiver), readExpression = _a.readExpression, initializeExpression = _a.initializeExpression;
                    var existingValue = ts.createPrefix(39 /* PlusToken */, createPrivateIdentifierAccess(info, readExpression));
                    return ts.setOriginalNode(createPrivateIdentifierAssignment(info, initializeExpression || readExpression, ts.createBinary(existingValue, operator, ts.createLiteral(1)), 62 /* EqualsToken */), node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitPostfixUnaryExpression(node, valueIsDiscarded) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyAccessExpression(node.operand)) {
                var operator = node.operator === 45 /* PlusPlusToken */ ?
                    39 /* PlusToken */ : node.operator === 46 /* MinusMinusToken */ ?
                    40 /* MinusToken */ : undefined;
                var info = void 0;
                if (operator && (info = accessPrivateIdentifier(node.operand.name))) {
                    var receiver = ts.visitNode(node.operand.expression, visitor, ts.isExpression);
                    var _a = createCopiableReceiverExpr(receiver), readExpression = _a.readExpression, initializeExpression = _a.initializeExpression;
                    var existingValue = ts.createPrefix(39 /* PlusToken */, createPrivateIdentifierAccess(info, readExpression));
                    // Create a temporary variable to store the value returned by the expression.
                    var returnValue = valueIsDiscarded ? undefined : ts.createTempVariable(hoistVariableDeclaration);
                    return ts.setOriginalNode(ts.inlineExpressions(ts.compact([
                        createPrivateIdentifierAssignment(info, initializeExpression || readExpression, ts.createBinary(returnValue ? ts.createAssignment(returnValue, existingValue) : existingValue, operator, ts.createLiteral(1)), 62 /* EqualsToken */),
                        returnValue
                    ])), node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForStatement(node) {
            if (node.incrementor && ts.isPostfixUnaryExpression(node.incrementor)) {
                return ts.updateFor(node, ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), visitPostfixUnaryExpression(node.incrementor, /*valueIsDiscarded*/ true), ts.visitNode(node.statement, visitor, ts.isStatement));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitExpressionStatement(node) {
            if (ts.isPostfixUnaryExpression(node.expression)) {
                return ts.updateExpressionStatement(node, visitPostfixUnaryExpression(node.expression, /*valueIsDiscarded*/ true));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function createCopiableReceiverExpr(receiver) {
            var clone = ts.nodeIsSynthesized(receiver) ? receiver : ts.getSynthesizedClone(receiver);
            if (ts.isSimpleInlineableExpression(receiver)) {
                return { readExpression: clone, initializeExpression: undefined };
            }
            var readExpression = ts.createTempVariable(hoistVariableDeclaration);
            var initializeExpression = ts.createAssignment(readExpression, clone);
            return { readExpression: readExpression, initializeExpression: initializeExpression };
        }
        function visitCallExpression(node) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyAccessExpression(node.expression)) {
                // Transform call expressions of private names to properly bind the `this` parameter.
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion), thisArg = _a.thisArg, target = _a.target;
                return ts.updateCall(node, ts.createPropertyAccess(ts.visitNode(target, visitor), "call"), 
                /*typeArguments*/ undefined, __spreadArrays([ts.visitNode(thisArg, visitor, ts.isExpression)], ts.visitNodes(node.arguments, visitor, ts.isExpression)));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitTaggedTemplateExpression(node) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyAccessExpression(node.tag)) {
                // Bind the `this` correctly for tagged template literals when the tag is a private identifier property access.
                var _a = ts.createCallBinding(node.tag, hoistVariableDeclaration, languageVersion), thisArg = _a.thisArg, target = _a.target;
                return ts.updateTaggedTemplate(node, ts.createCall(ts.createPropertyAccess(ts.visitNode(target, visitor), "bind"), 
                /*typeArguments*/ undefined, [ts.visitNode(thisArg, visitor, ts.isExpression)]), ts.visitNode(node.template, visitor, ts.isTemplateLiteral));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitBinaryExpression(node) {
            if (shouldTransformPrivateFields) {
                if (ts.isDestructuringAssignment(node)) {
                    var savedPendingExpressions = pendingExpressions;
                    pendingExpressions = undefined;
                    node = ts.updateBinary(node, ts.visitNode(node.left, visitorDestructuringTarget), ts.visitNode(node.right, visitor), node.operatorToken);
                    var expr = ts.some(pendingExpressions) ?
                        ts.inlineExpressions(ts.compact(__spreadArrays(pendingExpressions, [node]))) :
                        node;
                    pendingExpressions = savedPendingExpressions;
                    return expr;
                }
                if (ts.isAssignmentExpression(node) && ts.isPrivateIdentifierPropertyAccessExpression(node.left)) {
                    var info = accessPrivateIdentifier(node.left.name);
                    if (info) {
                        return ts.setOriginalNode(createPrivateIdentifierAssignment(info, node.left.expression, node.right, node.operatorToken.kind), node);
                    }
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function createPrivateIdentifierAssignment(info, receiver, right, operator) {
            switch (info.placement) {
                case 0 /* InstanceField */: {
                    return createPrivateIdentifierInstanceFieldAssignment(info, receiver, right, operator);
                }
                default: return ts.Debug.fail("Unexpected private identifier placement");
            }
        }
        function createPrivateIdentifierInstanceFieldAssignment(info, receiver, right, operator) {
            receiver = ts.visitNode(receiver, visitor, ts.isExpression);
            right = ts.visitNode(right, visitor, ts.isExpression);
            if (ts.isCompoundAssignment(operator)) {
                var _a = createCopiableReceiverExpr(receiver), readExpression = _a.readExpression, initializeExpression = _a.initializeExpression;
                return createClassPrivateFieldSetHelper(context, initializeExpression || readExpression, info.weakMapName, ts.createBinary(createClassPrivateFieldGetHelper(context, readExpression, info.weakMapName), ts.getNonAssignmentOperatorForCompoundAssignment(operator), right));
            }
            else {
                return createClassPrivateFieldSetHelper(context, receiver, info.weakMapName, right);
            }
        }
        /**
         * Set up the environment for a class.
         */
        function visitClassLike(node) {
            var savedPendingExpressions = pendingExpressions;
            pendingExpressions = undefined;
            if (shouldTransformPrivateFields) {
                startPrivateIdentifierEnvironment();
            }
            var result = ts.isClassDeclaration(node) ?
                visitClassDeclaration(node) :
                visitClassExpression(node);
            if (shouldTransformPrivateFields) {
                endPrivateIdentifierEnvironment();
            }
            pendingExpressions = savedPendingExpressions;
            return result;
        }
        function doesClassElementNeedTransform(node) {
            return ts.isPropertyDeclaration(node) || (shouldTransformPrivateFields && node.name && ts.isPrivateIdentifier(node.name));
        }
        function visitClassDeclaration(node) {
            if (!ts.forEach(node.members, doesClassElementNeedTransform)) {
                return ts.visitEachChild(node, visitor, context);
            }
            var extendsClauseElement = ts.getEffectiveBaseTypeNode(node);
            var isDerivedClass = !!(extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 100 /* NullKeyword */);
            var statements = [
                ts.updateClassDeclaration(node, 
                /*decorators*/ undefined, node.modifiers, node.name, 
                /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node, isDerivedClass))
            ];
            // Write any pending expressions from elided or moved computed property names
            if (ts.some(pendingExpressions)) {
                statements.push(ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions)));
            }
            // Emit static property assignment. Because classDeclaration is lexically evaluated,
            // it is safe to emit static property assignment after classDeclaration
            // From ES6 specification:
            //      HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
            //                                  a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
            var staticProperties = ts.getProperties(node, /*requireInitializer*/ true, /*isStatic*/ true);
            if (ts.some(staticProperties)) {
                addPropertyStatements(statements, staticProperties, ts.getInternalName(node));
            }
            return statements;
        }
        function visitClassExpression(node) {
            if (!ts.forEach(node.members, doesClassElementNeedTransform)) {
                return ts.visitEachChild(node, visitor, context);
            }
            // If this class expression is a transformation of a decorated class declaration,
            // then we want to output the pendingExpressions as statements, not as inlined
            // expressions with the class statement.
            //
            // In this case, we use pendingStatements to produce the same output as the
            // class declaration transformation. The VariableStatement visitor will insert
            // these statements after the class expression variable statement.
            var isDecoratedClassDeclaration = ts.isClassDeclaration(ts.getOriginalNode(node));
            var staticProperties = ts.getProperties(node, /*requireInitializer*/ true, /*isStatic*/ true);
            var extendsClauseElement = ts.getEffectiveBaseTypeNode(node);
            var isDerivedClass = !!(extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 100 /* NullKeyword */);
            var classExpression = ts.updateClassExpression(node, node.modifiers, node.name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node, isDerivedClass));
            if (ts.some(staticProperties) || ts.some(pendingExpressions)) {
                if (isDecoratedClassDeclaration) {
                    ts.Debug.assertIsDefined(pendingStatements, "Decorated classes transformed by TypeScript are expected to be within a variable declaration.");
                    // Write any pending expressions from elided or moved computed property names
                    if (pendingStatements && pendingExpressions && ts.some(pendingExpressions)) {
                        pendingStatements.push(ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions)));
                    }
                    if (pendingStatements && ts.some(staticProperties)) {
                        addPropertyStatements(pendingStatements, staticProperties, ts.getInternalName(node));
                    }
                    return classExpression;
                }
                else {
                    var expressions = [];
                    var isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & 16777216 /* ClassWithConstructorReference */;
                    var temp = ts.createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference);
                    if (isClassWithConstructorReference) {
                        // record an alias as the class name is not in scope for statics.
                        enableSubstitutionForClassAliases();
                        var alias = ts.getSynthesizedClone(temp);
                        alias.autoGenerateFlags &= ~8 /* ReservedInNestedScopes */;
                        classAliases[ts.getOriginalNodeId(node)] = alias;
                    }
                    // To preserve the behavior of the old emitter, we explicitly indent
                    // the body of a class with static initializers.
                    ts.setEmitFlags(classExpression, 65536 /* Indented */ | ts.getEmitFlags(classExpression));
                    expressions.push(ts.startOnNewLine(ts.createAssignment(temp, classExpression)));
                    // Add any pending expressions leftover from elided or relocated computed property names
                    ts.addRange(expressions, ts.map(pendingExpressions, ts.startOnNewLine));
                    ts.addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp));
                    expressions.push(ts.startOnNewLine(temp));
                    return ts.inlineExpressions(expressions);
                }
            }
            return classExpression;
        }
        function transformClassMembers(node, isDerivedClass) {
            if (shouldTransformPrivateFields) {
                // Declare private names.
                for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    if (ts.isPrivateIdentifierPropertyDeclaration(member)) {
                        addPrivateIdentifierToEnvironment(member.name);
                    }
                }
            }
            var members = [];
            var constructor = transformConstructor(node, isDerivedClass);
            if (constructor) {
                members.push(constructor);
            }
            ts.addRange(members, ts.visitNodes(node.members, classElementVisitor, ts.isClassElement));
            return ts.setTextRange(ts.createNodeArray(members), /*location*/ node.members);
        }
        function isPropertyDeclarationThatRequiresConstructorStatement(member) {
            if (!ts.isPropertyDeclaration(member) || ts.hasStaticModifier(member)) {
                return false;
            }
            if (context.getCompilerOptions().useDefineForClassFields) {
                // If we are using define semantics and targeting ESNext or higher,
                // then we don't need to transform any class properties.
                return languageVersion < 99 /* ESNext */;
            }
            return ts.isInitializedProperty(member) || shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyDeclaration(member);
        }
        function transformConstructor(node, isDerivedClass) {
            var constructor = ts.visitNode(ts.getFirstConstructorWithBody(node), visitor, ts.isConstructorDeclaration);
            var properties = node.members.filter(isPropertyDeclarationThatRequiresConstructorStatement);
            if (!ts.some(properties)) {
                return constructor;
            }
            var parameters = ts.visitParameterList(constructor ? constructor.parameters : undefined, visitor, context);
            var body = transformConstructorBody(node, constructor, isDerivedClass);
            if (!body) {
                return undefined;
            }
            return ts.startOnNewLine(ts.setOriginalNode(ts.setTextRange(ts.createConstructor(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, parameters !== null && parameters !== void 0 ? parameters : [], body), constructor || node), constructor));
        }
        function transformConstructorBody(node, constructor, isDerivedClass) {
            var useDefineForClassFields = context.getCompilerOptions().useDefineForClassFields;
            var properties = ts.getProperties(node, /*requireInitializer*/ false, /*isStatic*/ false);
            if (!useDefineForClassFields) {
                properties = ts.filter(properties, function (property) { return !!property.initializer || ts.isPrivateIdentifier(property.name); });
            }
            // Only generate synthetic constructor when there are property initializers to move.
            if (!constructor && !ts.some(properties)) {
                return ts.visitFunctionBody(/*node*/ undefined, visitor, context);
            }
            resumeLexicalEnvironment();
            var indexOfFirstStatement = 0;
            var statements = [];
            if (!constructor && isDerivedClass) {
                // Add a synthetic `super` call:
                //
                //  super(...arguments);
                //
                statements.push(ts.createExpressionStatement(ts.createCall(ts.createSuper(), 
                /*typeArguments*/ undefined, [ts.createSpread(ts.createIdentifier("arguments"))])));
            }
            if (constructor) {
                indexOfFirstStatement = ts.addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor);
            }
            // Add the property initializers. Transforms this:
            //
            //  public x = 1;
            //
            // Into this:
            //
            //  constructor() {
            //      this.x = 1;
            //  }
            //
            if (constructor === null || constructor === void 0 ? void 0 : constructor.body) {
                var afterParameterProperties = ts.findIndex(constructor.body.statements, function (s) { return !ts.isParameterPropertyDeclaration(ts.getOriginalNode(s), constructor); }, indexOfFirstStatement);
                if (afterParameterProperties === -1) {
                    afterParameterProperties = constructor.body.statements.length;
                }
                if (afterParameterProperties > indexOfFirstStatement) {
                    if (!useDefineForClassFields) {
                        ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatement, afterParameterProperties - indexOfFirstStatement));
                    }
                    indexOfFirstStatement = afterParameterProperties;
                }
            }
            addPropertyStatements(statements, properties, ts.createThis());
            // Add existing statements, skipping the initial super call.
            if (constructor) {
                ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatement));
            }
            statements = ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            return ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ constructor ? constructor.body.statements : node.members), 
            /*multiLine*/ true), 
            /*location*/ constructor ? constructor.body : undefined);
        }
        /**
         * Generates assignment statements for property initializers.
         *
         * @param properties An array of property declarations to transform.
         * @param receiver The receiver on which each property should be assigned.
         */
        function addPropertyStatements(statements, properties, receiver) {
            for (var _i = 0, properties_8 = properties; _i < properties_8.length; _i++) {
                var property = properties_8[_i];
                var expression = transformProperty(property, receiver);
                if (!expression) {
                    continue;
                }
                var statement = ts.createExpressionStatement(expression);
                ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property));
                ts.setCommentRange(statement, property);
                ts.setOriginalNode(statement, property);
                statements.push(statement);
            }
        }
        /**
         * Generates assignment expressions for property initializers.
         *
         * @param properties An array of property declarations to transform.
         * @param receiver The receiver on which each property should be assigned.
         */
        function generateInitializedPropertyExpressions(properties, receiver) {
            var expressions = [];
            for (var _i = 0, properties_9 = properties; _i < properties_9.length; _i++) {
                var property = properties_9[_i];
                var expression = transformProperty(property, receiver);
                if (!expression) {
                    continue;
                }
                ts.startOnNewLine(expression);
                ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property));
                ts.setCommentRange(expression, property);
                ts.setOriginalNode(expression, property);
                expressions.push(expression);
            }
            return expressions;
        }
        /**
         * Transforms a property initializer into an assignment statement.
         *
         * @param property The property declaration.
         * @param receiver The object receiving the property assignment.
         */
        function transformProperty(property, receiver) {
            // We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name)
            var emitAssignment = !context.getCompilerOptions().useDefineForClassFields;
            var propertyName = ts.isComputedPropertyName(property.name) && !ts.isSimpleInlineableExpression(property.name.expression)
                ? ts.updateComputedPropertyName(property.name, ts.getGeneratedNameForNode(property.name))
                : property.name;
            if (shouldTransformPrivateFields && ts.isPrivateIdentifier(propertyName)) {
                var privateIdentifierInfo = accessPrivateIdentifier(propertyName);
                if (privateIdentifierInfo) {
                    switch (privateIdentifierInfo.placement) {
                        case 0 /* InstanceField */: {
                            return createPrivateInstanceFieldInitializer(receiver, ts.visitNode(property.initializer, visitor, ts.isExpression), privateIdentifierInfo.weakMapName);
                        }
                    }
                }
                else {
                    ts.Debug.fail("Undeclared private name for property declaration.");
                }
            }
            if (ts.isPrivateIdentifier(propertyName) && !property.initializer) {
                return undefined;
            }
            if (ts.isPrivateIdentifier(propertyName) && !property.initializer) {
                return undefined;
            }
            var propertyOriginalNode = ts.getOriginalNode(property);
            var initializer = property.initializer || emitAssignment ? ts.visitNode(property.initializer, visitor, ts.isExpression)
                : ts.isParameterPropertyDeclaration(propertyOriginalNode, propertyOriginalNode.parent) && ts.isIdentifier(propertyName) ? propertyName
                    : ts.createVoidZero();
            if (emitAssignment || ts.isPrivateIdentifier(propertyName)) {
                var memberAccess = ts.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
                return ts.createAssignment(memberAccess, initializer);
            }
            else {
                var name = ts.isComputedPropertyName(propertyName) ? propertyName.expression
                    : ts.isIdentifier(propertyName) ? ts.createStringLiteral(ts.unescapeLeadingUnderscores(propertyName.escapedText))
                        : propertyName;
                var descriptor = ts.createPropertyDescriptor({ value: initializer, configurable: true, writable: true, enumerable: true });
                return ts.createObjectDefinePropertyCall(receiver, name, descriptor);
            }
        }
        function enableSubstitutionForClassAliases() {
            if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) {
                enabledSubstitutions |= 1 /* ClassAliases */;
                // We need to enable substitutions for identifiers. This allows us to
                // substitute class names inside of a class declaration.
                context.enableSubstitution(75 /* Identifier */);
                // Keep track of class aliases.
                classAliases = [];
            }
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            return trySubstituteClassAlias(node) || node;
        }
        function trySubstituteClassAlias(node) {
            if (enabledSubstitutions & 1 /* ClassAliases */) {
                if (resolver.getNodeCheckFlags(node) & 33554432 /* ConstructorReferenceInClass */) {
                    // Due to the emit for class decorators, any reference to the class from inside of the class body
                    // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                    // behavior of class names in ES6.
                    // Also, when emitting statics for class expressions, we must substitute a class alias for
                    // constructor references in static property initializers.
                    var declaration = resolver.getReferencedValueDeclaration(node);
                    if (declaration) {
                        var classAlias = classAliases[declaration.id]; // TODO: GH#18217
                        if (classAlias) {
                            var clone_2 = ts.getSynthesizedClone(classAlias);
                            ts.setSourceMapRange(clone_2, node);
                            ts.setCommentRange(clone_2, node);
                            return clone_2;
                        }
                    }
                }
            }
            return undefined;
        }
        /**
         * If the name is a computed property, this function transforms it, then either returns an expression which caches the
         * value of the result or the expression itself if the value is either unused or safe to inline into multiple locations
         * @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator)
         */
        function getPropertyNameExpressionIfNeeded(name, shouldHoist) {
            if (ts.isComputedPropertyName(name)) {
                var expression = ts.visitNode(name.expression, visitor, ts.isExpression);
                var innerExpression = ts.skipPartiallyEmittedExpressions(expression);
                var inlinable = ts.isSimpleInlineableExpression(innerExpression);
                var alreadyTransformed = ts.isAssignmentExpression(innerExpression) && ts.isGeneratedIdentifier(innerExpression.left);
                if (!alreadyTransformed && !inlinable && shouldHoist) {
                    var generatedName = ts.getGeneratedNameForNode(name);
                    hoistVariableDeclaration(generatedName);
                    return ts.createAssignment(generatedName, expression);
                }
                return (inlinable || ts.isIdentifier(innerExpression)) ? undefined : expression;
            }
        }
        function startPrivateIdentifierEnvironment() {
            privateIdentifierEnvironmentStack.push(currentPrivateIdentifierEnvironment);
            currentPrivateIdentifierEnvironment = undefined;
        }
        function endPrivateIdentifierEnvironment() {
            currentPrivateIdentifierEnvironment = privateIdentifierEnvironmentStack.pop();
        }
        function addPrivateIdentifierToEnvironment(name) {
            var text = ts.getTextOfPropertyName(name);
            var weakMapName = ts.createOptimisticUniqueName("_" + text.substring(1));
            weakMapName.autoGenerateFlags |= 8 /* ReservedInNestedScopes */;
            hoistVariableDeclaration(weakMapName);
            (currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = ts.createUnderscoreEscapedMap()))
                .set(name.escapedText, { placement: 0 /* InstanceField */, weakMapName: weakMapName });
            (pendingExpressions || (pendingExpressions = [])).push(ts.createAssignment(weakMapName, ts.createNew(ts.createIdentifier("WeakMap"), 
            /*typeArguments*/ undefined, [])));
        }
        function accessPrivateIdentifier(name) {
            if (currentPrivateIdentifierEnvironment) {
                var info = currentPrivateIdentifierEnvironment.get(name.escapedText);
                if (info) {
                    return info;
                }
            }
            for (var i = privateIdentifierEnvironmentStack.length - 1; i >= 0; --i) {
                var env = privateIdentifierEnvironmentStack[i];
                if (!env) {
                    continue;
                }
                var info = env.get(name.escapedText);
                if (info) {
                    return info;
                }
            }
            return undefined;
        }
        function wrapPrivateIdentifierForDestructuringTarget(node) {
            var parameter = ts.getGeneratedNameForNode(node);
            var info = accessPrivateIdentifier(node.name);
            if (!info) {
                return ts.visitEachChild(node, visitor, context);
            }
            var receiver = node.expression;
            // We cannot copy `this` or `super` into the function because they will be bound
            // differently inside the function.
            if (ts.isThisProperty(node) || ts.isSuperProperty(node) || !ts.isSimpleCopiableExpression(node.expression)) {
                receiver = ts.createTempVariable(hoistVariableDeclaration);
                receiver.autoGenerateFlags |= 8 /* ReservedInNestedScopes */;
                (pendingExpressions || (pendingExpressions = [])).push(ts.createBinary(receiver, 62 /* EqualsToken */, node.expression));
            }
            return ts.createPropertyAccess(
            // Explicit parens required because of v8 regression (https://bugs.chromium.org/p/v8/issues/detail?id=9560)
            ts.createParen(ts.createObjectLiteral([
                ts.createSetAccessor(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, "value", [ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, parameter, 
                    /*questionToken*/ undefined, 
                    /*type*/ undefined, 
                    /*initializer*/ undefined)], ts.createBlock([ts.createExpressionStatement(createPrivateIdentifierAssignment(info, receiver, parameter, 62 /* EqualsToken */))]))
            ])), "value");
        }
        function visitArrayAssignmentTarget(node) {
            var target = ts.getTargetOfBindingOrAssignmentElement(node);
            if (target && ts.isPrivateIdentifierPropertyAccessExpression(target)) {
                var wrapped = wrapPrivateIdentifierForDestructuringTarget(target);
                if (ts.isAssignmentExpression(node)) {
                    return ts.updateBinary(node, wrapped, ts.visitNode(node.right, visitor, ts.isExpression), node.operatorToken);
                }
                else if (ts.isSpreadElement(node)) {
                    return ts.updateSpread(node, wrapped);
                }
                else {
                    return wrapped;
                }
            }
            return ts.visitNode(node, visitorDestructuringTarget);
        }
        function visitObjectAssignmentTarget(node) {
            if (ts.isPropertyAssignment(node)) {
                var target = ts.getTargetOfBindingOrAssignmentElement(node);
                if (target && ts.isPrivateIdentifierPropertyAccessExpression(target)) {
                    var initializer = ts.getInitializerOfBindingOrAssignmentElement(node);
                    var wrapped = wrapPrivateIdentifierForDestructuringTarget(target);
                    return ts.updatePropertyAssignment(node, ts.visitNode(node.name, visitor), initializer ? ts.createAssignment(wrapped, ts.visitNode(initializer, visitor)) : wrapped);
                }
                return ts.updatePropertyAssignment(node, ts.visitNode(node.name, visitor), ts.visitNode(node.initializer, visitorDestructuringTarget));
            }
            return ts.visitNode(node, visitor);
        }
        function visitAssignmentPattern(node) {
            if (ts.isArrayLiteralExpression(node)) {
                // Transforms private names in destructuring assignment array bindings.
                //
                // Source:
                // ([ this.#myProp ] = [ "hello" ]);
                //
                // Transformation:
                // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ];
                return ts.updateArrayLiteral(node, ts.visitNodes(node.elements, visitArrayAssignmentTarget, ts.isExpression));
            }
            else {
                // Transforms private names in destructuring assignment object bindings.
                //
                // Source:
                // ({ stringProperty: this.#myProp } = { stringProperty: "hello" });
                //
                // Transformation:
                // ({ stringProperty: { set value(x) { this.#myProp = x; } }.value }) = { stringProperty: "hello" };
                return ts.updateObjectLiteral(node, ts.visitNodes(node.properties, visitObjectAssignmentTarget, ts.isObjectLiteralElementLike));
            }
        }
    }
    ts.transformClassFields = transformClassFields;
    function createPrivateInstanceFieldInitializer(receiver, initializer, weakMapName) {
        return ts.createCall(ts.createPropertyAccess(weakMapName, "set"), 
        /*typeArguments*/ undefined, [receiver, initializer || ts.createVoidZero()]);
    }
    ts.classPrivateFieldGetHelper = {
        name: "typescript:classPrivateFieldGet",
        scoped: false,
        text: "\n            var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n                if (!privateMap.has(receiver)) {\n                    throw new TypeError(\"attempted to get private field on non-instance\");\n                }\n                return privateMap.get(receiver);\n            };"
    };
    function createClassPrivateFieldGetHelper(context, receiver, privateField) {
        context.requestEmitHelper(ts.classPrivateFieldGetHelper);
        return ts.createCall(ts.getUnscopedHelperName("__classPrivateFieldGet"), /* typeArguments */ undefined, [receiver, privateField]);
    }
    ts.classPrivateFieldSetHelper = {
        name: "typescript:classPrivateFieldSet",
        scoped: false,
        text: "\n            var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n                if (!privateMap.has(receiver)) {\n                    throw new TypeError(\"attempted to set private field on non-instance\");\n                }\n                privateMap.set(receiver, value);\n                return value;\n            };"
    };
    function createClassPrivateFieldSetHelper(context, receiver, privateField, value) {
        context.requestEmitHelper(ts.classPrivateFieldSetHelper);
        return ts.createCall(ts.getUnscopedHelperName("__classPrivateFieldSet"), /* typeArguments */ undefined, [receiver, privateField, value]);
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ES2017SubstitutionFlags;
    (function (ES2017SubstitutionFlags) {
        /** Enables substitutions for async methods with `super` calls. */
        ES2017SubstitutionFlags[ES2017SubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
    })(ES2017SubstitutionFlags || (ES2017SubstitutionFlags = {}));
    var ContextFlags;
    (function (ContextFlags) {
        ContextFlags[ContextFlags["NonTopLevel"] = 1] = "NonTopLevel";
        ContextFlags[ContextFlags["HasLexicalThis"] = 2] = "HasLexicalThis";
    })(ContextFlags || (ContextFlags = {}));
    function transformES2017(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        /**
         * Keeps track of whether expression substitution has been enabled for specific edge cases.
         * They are persisted between each SourceFile transformation and should not be reset.
         */
        var enabledSubstitutions;
        /**
         * This keeps track of containers where `super` is valid, for use with
         * just-in-time substitution for `super` expressions inside of async methods.
         */
        var enclosingSuperContainerFlags = 0;
        var enclosingFunctionParameterNames;
        /**
         * Keeps track of property names accessed on super (`super.x`) within async functions.
         */
        var capturedSuperProperties;
        /** Whether the async function contains an element access on super (`super[x]`). */
        var hasSuperElementAccess;
        /** A set of node IDs for generated super accessors (variable statements). */
        var substitutedSuperAccessors = [];
        var contextFlags = 0;
        // Save the previous transformation hooks.
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        // Set new transformation hooks.
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            setContextFlag(1 /* NonTopLevel */, false);
            setContextFlag(2 /* HasLexicalThis */, !ts.isEffectiveStrictModeSourceFile(node, compilerOptions));
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function setContextFlag(flag, val) {
            contextFlags = val ? contextFlags | flag : contextFlags & ~flag;
        }
        function inContext(flags) {
            return (contextFlags & flags) !== 0;
        }
        function inTopLevelContext() {
            return !inContext(1 /* NonTopLevel */);
        }
        function inHasLexicalThisContext() {
            return inContext(2 /* HasLexicalThis */);
        }
        function doWithContext(flags, cb, value) {
            var contextFlagsToSet = flags & ~contextFlags;
            if (contextFlagsToSet) {
                setContextFlag(contextFlagsToSet, /*val*/ true);
                var result = cb(value);
                setContextFlag(contextFlagsToSet, /*val*/ false);
                return result;
            }
            return cb(value);
        }
        function visitDefault(node) {
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 64 /* ContainsES2017 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 126 /* AsyncKeyword */:
                    // ES2017 async modifier should be elided for targets < ES2017
                    return undefined;
                case 206 /* AwaitExpression */:
                    return visitAwaitExpression(node);
                case 161 /* MethodDeclaration */:
                    return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitMethodDeclaration, node);
                case 244 /* FunctionDeclaration */:
                    return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitFunctionDeclaration, node);
                case 201 /* FunctionExpression */:
                    return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitFunctionExpression, node);
                case 202 /* ArrowFunction */:
                    return doWithContext(1 /* NonTopLevel */, visitArrowFunction, node);
                case 194 /* PropertyAccessExpression */:
                    if (capturedSuperProperties && ts.isPropertyAccessExpression(node) && node.expression.kind === 102 /* SuperKeyword */) {
                        capturedSuperProperties.set(node.name.escapedText, true);
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 195 /* ElementAccessExpression */:
                    if (capturedSuperProperties && node.expression.kind === 102 /* SuperKeyword */) {
                        hasSuperElementAccess = true;
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 162 /* Constructor */:
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitDefault, node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function asyncBodyVisitor(node) {
            if (ts.isNodeWithPossibleHoistedDeclaration(node)) {
                switch (node.kind) {
                    case 225 /* VariableStatement */:
                        return visitVariableStatementInAsyncBody(node);
                    case 230 /* ForStatement */:
                        return visitForStatementInAsyncBody(node);
                    case 231 /* ForInStatement */:
                        return visitForInStatementInAsyncBody(node);
                    case 232 /* ForOfStatement */:
                        return visitForOfStatementInAsyncBody(node);
                    case 280 /* CatchClause */:
                        return visitCatchClauseInAsyncBody(node);
                    case 223 /* Block */:
                    case 237 /* SwitchStatement */:
                    case 251 /* CaseBlock */:
                    case 277 /* CaseClause */:
                    case 278 /* DefaultClause */:
                    case 240 /* TryStatement */:
                    case 228 /* DoStatement */:
                    case 229 /* WhileStatement */:
                    case 227 /* IfStatement */:
                    case 236 /* WithStatement */:
                    case 238 /* LabeledStatement */:
                        return ts.visitEachChild(node, asyncBodyVisitor, context);
                    default:
                        return ts.Debug.assertNever(node, "Unhandled node.");
                }
            }
            return visitor(node);
        }
        function visitCatchClauseInAsyncBody(node) {
            var catchClauseNames = ts.createUnderscoreEscapedMap();
            recordDeclarationName(node.variableDeclaration, catchClauseNames); // TODO: GH#18217
            // names declared in a catch variable are block scoped
            var catchClauseUnshadowedNames;
            catchClauseNames.forEach(function (_, escapedName) {
                if (enclosingFunctionParameterNames.has(escapedName)) {
                    if (!catchClauseUnshadowedNames) {
                        catchClauseUnshadowedNames = ts.cloneMap(enclosingFunctionParameterNames);
                    }
                    catchClauseUnshadowedNames.delete(escapedName);
                }
            });
            if (catchClauseUnshadowedNames) {
                var savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
                enclosingFunctionParameterNames = catchClauseUnshadowedNames;
                var result = ts.visitEachChild(node, asyncBodyVisitor, context);
                enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
                return result;
            }
            else {
                return ts.visitEachChild(node, asyncBodyVisitor, context);
            }
        }
        function visitVariableStatementInAsyncBody(node) {
            if (isVariableDeclarationListWithCollidingName(node.declarationList)) {
                var expression = visitVariableDeclarationListWithCollidingNames(node.declarationList, /*hasReceiver*/ false);
                return expression ? ts.createExpressionStatement(expression) : undefined;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForInStatementInAsyncBody(node) {
            return ts.updateForIn(node, isVariableDeclarationListWithCollidingName(node.initializer)
                ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        function visitForOfStatementInAsyncBody(node) {
            return ts.updateForOf(node, ts.visitNode(node.awaitModifier, visitor, ts.isToken), isVariableDeclarationListWithCollidingName(node.initializer)
                ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        function visitForStatementInAsyncBody(node) {
            var initializer = node.initializer; // TODO: GH#18217
            return ts.updateFor(node, isVariableDeclarationListWithCollidingName(initializer)
                ? visitVariableDeclarationListWithCollidingNames(initializer, /*hasReceiver*/ false)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits an AwaitExpression node.
         *
         * This function will be called any time a ES2017 await expression is encountered.
         *
         * @param node The node to visit.
         */
        function visitAwaitExpression(node) {
            // do not downlevel a top-level await as it is module syntax...
            if (inTopLevelContext()) {
                return ts.visitEachChild(node, visitor, context);
            }
            return ts.setOriginalNode(ts.setTextRange(ts.createYield(
            /*asteriskToken*/ undefined, ts.visitNode(node.expression, visitor, ts.isExpression)), node), node);
        }
        /**
         * Visits a MethodDeclaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked as async
         *
         * @param node The node to visit.
         */
        function visitMethodDeclaration(node) {
            return ts.updateMethod(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*questionToken*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            return ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a FunctionExpression node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitFunctionExpression(node) {
            return ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits an ArrowFunction.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitArrowFunction(node) {
            return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        function recordDeclarationName(_a, names) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                names.set(name.escapedText, true);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element)) {
                        recordDeclarationName(element, names);
                    }
                }
            }
        }
        function isVariableDeclarationListWithCollidingName(node) {
            return !!node
                && ts.isVariableDeclarationList(node)
                && !(node.flags & 3 /* BlockScoped */)
                && node.declarations.some(collidesWithParameterName);
        }
        function visitVariableDeclarationListWithCollidingNames(node, hasReceiver) {
            hoistVariableDeclarationList(node);
            var variables = ts.getInitializedVariables(node);
            if (variables.length === 0) {
                if (hasReceiver) {
                    return ts.visitNode(ts.convertToAssignmentElementTarget(node.declarations[0].name), visitor, ts.isExpression);
                }
                return undefined;
            }
            return ts.inlineExpressions(ts.map(variables, transformInitializedVariable));
        }
        function hoistVariableDeclarationList(node) {
            ts.forEach(node.declarations, hoistVariable);
        }
        function hoistVariable(_a) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                hoistVariableDeclaration(name);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element)) {
                        hoistVariable(element);
                    }
                }
            }
        }
        function transformInitializedVariable(node) {
            var converted = ts.setSourceMapRange(ts.createAssignment(ts.convertToAssignmentElementTarget(node.name), node.initializer), node);
            return ts.visitNode(converted, visitor, ts.isExpression);
        }
        function collidesWithParameterName(_a) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                return enclosingFunctionParameterNames.has(name.escapedText);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element) && collidesWithParameterName(element)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function transformAsyncFunctionBody(node) {
            resumeLexicalEnvironment();
            var original = ts.getOriginalNode(node, ts.isFunctionLike);
            var nodeType = original.type;
            var promiseConstructor = languageVersion < 2 /* ES2015 */ ? getPromiseConstructor(nodeType) : undefined;
            var isArrowFunction = node.kind === 202 /* ArrowFunction */;
            var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 8192 /* CaptureArguments */) !== 0;
            // An async function is emit as an outer function that calls an inner
            // generator function. To preserve lexical bindings, we pass the current
            // `this` and `arguments` objects to `__awaiter`. The generator function
            // passed to `__awaiter` is executed inside of the callback to the
            // promise constructor.
            var savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
            enclosingFunctionParameterNames = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                recordDeclarationName(parameter, enclosingFunctionParameterNames);
            }
            var savedCapturedSuperProperties = capturedSuperProperties;
            var savedHasSuperElementAccess = hasSuperElementAccess;
            if (!isArrowFunction) {
                capturedSuperProperties = ts.createUnderscoreEscapedMap();
                hasSuperElementAccess = false;
            }
            var result;
            if (!isArrowFunction) {
                var statements = [];
                var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
                statements.push(ts.createReturn(createAwaiterHelper(context, inHasLexicalThisContext(), hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body, statementOffset))));
                ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
                // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
                // This step isn't needed if we eventually transform this to ES5.
                var emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && resolver.getNodeCheckFlags(node) & (4096 /* AsyncMethodWithSuperBinding */ | 2048 /* AsyncMethodWithSuper */);
                if (emitSuperHelpers) {
                    enableSubstitutionForAsyncMethodsWithSuper();
                    if (ts.hasEntries(capturedSuperProperties)) {
                        var variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
                        substitutedSuperAccessors[ts.getNodeId(variableStatement)] = true;
                        ts.insertStatementsAfterStandardPrologue(statements, [variableStatement]);
                    }
                }
                var block = ts.createBlock(statements, /*multiLine*/ true);
                ts.setTextRange(block, node.body);
                if (emitSuperHelpers && hasSuperElementAccess) {
                    // Emit helpers for super element access expressions (`super[x]`).
                    if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                        ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
                    }
                    else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                        ts.addEmitHelper(block, ts.asyncSuperHelper);
                    }
                }
                result = block;
            }
            else {
                var expression = createAwaiterHelper(context, inHasLexicalThisContext(), hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body));
                var declarations = endLexicalEnvironment();
                if (ts.some(declarations)) {
                    var block = ts.convertToFunctionBody(expression);
                    result = ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(ts.concatenate(declarations, block.statements)), block.statements));
                }
                else {
                    result = expression;
                }
            }
            enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
            if (!isArrowFunction) {
                capturedSuperProperties = savedCapturedSuperProperties;
                hasSuperElementAccess = savedHasSuperElementAccess;
            }
            return result;
        }
        function transformAsyncFunctionBodyWorker(body, start) {
            if (ts.isBlock(body)) {
                return ts.updateBlock(body, ts.visitNodes(body.statements, asyncBodyVisitor, ts.isStatement, start));
            }
            else {
                return ts.convertToFunctionBody(ts.visitNode(body, asyncBodyVisitor, ts.isConciseBody));
            }
        }
        function getPromiseConstructor(type) {
            var typeName = type && ts.getEntityNameFromTypeNode(type);
            if (typeName && ts.isEntityName(typeName)) {
                var serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
                if (serializationKind === ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
                    || serializationKind === ts.TypeReferenceSerializationKind.Unknown) {
                    return typeName;
                }
            }
            return undefined;
        }
        function enableSubstitutionForAsyncMethodsWithSuper() {
            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
                // We need to enable substitutions for call, property access, and element access
                // if we need to rewrite super calls.
                context.enableSubstitution(196 /* CallExpression */);
                context.enableSubstitution(194 /* PropertyAccessExpression */);
                context.enableSubstitution(195 /* ElementAccessExpression */);
                // We need to be notified when entering and exiting declarations that bind super.
                context.enableEmitNotification(245 /* ClassDeclaration */);
                context.enableEmitNotification(161 /* MethodDeclaration */);
                context.enableEmitNotification(163 /* GetAccessor */);
                context.enableEmitNotification(164 /* SetAccessor */);
                context.enableEmitNotification(162 /* Constructor */);
                // We need to be notified when entering the generated accessor arrow functions.
                context.enableEmitNotification(225 /* VariableStatement */);
            }
        }
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            // If we need to support substitutions for `super` in an async method,
            // we should track it here.
            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
                if (superContainerFlags !== enclosingSuperContainerFlags) {
                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                    enclosingSuperContainerFlags = superContainerFlags;
                    previousOnEmitNode(hint, node, emitCallback);
                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                    return;
                }
            }
            // Disable substitution in the generated super accessor itself.
            else if (enabledSubstitutions && substitutedSuperAccessors[ts.getNodeId(node)]) {
                var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                enclosingSuperContainerFlags = 0;
                previousOnEmitNode(hint, node, emitCallback);
                enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 195 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
                case 196 /* CallExpression */:
                    return substituteCallExpression(node);
            }
            return node;
        }
        function substitutePropertyAccessExpression(node) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), node.name), node);
            }
            return node;
        }
        function substituteElementAccessExpression(node) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return createSuperElementAccessInAsyncMethod(node.argumentExpression, node);
            }
            return node;
        }
        function substituteCallExpression(node) {
            var expression = node.expression;
            if (ts.isSuperProperty(expression)) {
                var argumentExpression = ts.isPropertyAccessExpression(expression)
                    ? substitutePropertyAccessExpression(expression)
                    : substituteElementAccessExpression(expression);
                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
                /*typeArguments*/ undefined, __spreadArrays([
                    ts.createThis()
                ], node.arguments));
            }
            return node;
        }
        function isSuperContainer(node) {
            var kind = node.kind;
            return kind === 245 /* ClassDeclaration */
                || kind === 162 /* Constructor */
                || kind === 161 /* MethodDeclaration */
                || kind === 163 /* GetAccessor */
                || kind === 164 /* SetAccessor */;
        }
        function createSuperElementAccessInAsyncMethod(argumentExpression, location) {
            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createFileLevelUniqueName("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
            }
            else {
                return ts.setTextRange(ts.createCall(ts.createFileLevelUniqueName("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), location);
            }
        }
    }
    ts.transformES2017 = transformES2017;
    /** Creates a variable named `_super` with accessor properties for the given property names. */
    function createSuperAccessVariableStatement(resolver, node, names) {
        // Create a variable declaration with a getter/setter (if binding) definition for each name:
        //   const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... });
        var hasBinding = (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) !== 0;
        var accessors = [];
        names.forEach(function (_, key) {
            var name = ts.unescapeLeadingUnderscores(key);
            var getterAndSetter = [];
            getterAndSetter.push(ts.createPropertyAssignment("get", ts.createArrowFunction(
            /* modifiers */ undefined, 
            /* typeParameters */ undefined, 
            /* parameters */ [], 
            /* type */ undefined, 
            /* equalsGreaterThanToken */ undefined, ts.setEmitFlags(ts.createPropertyAccess(ts.setEmitFlags(ts.createSuper(), 4 /* NoSubstitution */), name), 4 /* NoSubstitution */))));
            if (hasBinding) {
                getterAndSetter.push(ts.createPropertyAssignment("set", ts.createArrowFunction(
                /* modifiers */ undefined, 
                /* typeParameters */ undefined, 
                /* parameters */ [
                    ts.createParameter(
                    /* decorators */ undefined, 
                    /* modifiers */ undefined, 
                    /* dotDotDotToken */ undefined, "v", 
                    /* questionToken */ undefined, 
                    /* type */ undefined, 
                    /* initializer */ undefined)
                ], 
                /* type */ undefined, 
                /* equalsGreaterThanToken */ undefined, ts.createAssignment(ts.setEmitFlags(ts.createPropertyAccess(ts.setEmitFlags(ts.createSuper(), 4 /* NoSubstitution */), name), 4 /* NoSubstitution */), ts.createIdentifier("v")))));
            }
            accessors.push(ts.createPropertyAssignment(name, ts.createObjectLiteral(getterAndSetter)));
        });
        return ts.createVariableStatement(
        /* modifiers */ undefined, ts.createVariableDeclarationList([
            ts.createVariableDeclaration(ts.createFileLevelUniqueName("_super"), 
            /* type */ undefined, ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "create"), 
            /* typeArguments */ undefined, [
                ts.createNull(),
                ts.createObjectLiteral(accessors, /* multiline */ true)
            ]))
        ], 2 /* Const */));
    }
    ts.createSuperAccessVariableStatement = createSuperAccessVariableStatement;
    ts.awaiterHelper = {
        name: "typescript:awaiter",
        importName: "__awaiter",
        scoped: false,
        priority: 5,
        text: "\n            var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n                function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n                return new (P || (P = Promise))(function (resolve, reject) {\n                    function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n                    function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n                    function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n                    step((generator = generator.apply(thisArg, _arguments || [])).next());\n                });\n            };"
    };
    function createAwaiterHelper(context, hasLexicalThis, hasLexicalArguments, promiseConstructor, body) {
        context.requestEmitHelper(ts.awaiterHelper);
        var generatorFunc = ts.createFunctionExpression(
        /*modifiers*/ undefined, ts.createToken(41 /* AsteriskToken */), 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ [], 
        /*type*/ undefined, body);
        // Mark this node as originally an async function
        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */ | 524288 /* ReuseTempVariableScope */;
        return ts.createCall(ts.getUnscopedHelperName("__awaiter"), 
        /*typeArguments*/ undefined, [
            hasLexicalThis ? ts.createThis() : ts.createVoidZero(),
            hasLexicalArguments ? ts.createIdentifier("arguments") : ts.createVoidZero(),
            promiseConstructor ? ts.createExpressionFromEntityName(promiseConstructor) : ts.createVoidZero(),
            generatorFunc
        ]);
    }
    ts.asyncSuperHelper = {
        name: "typescript:async-super",
        scoped: true,
        text: ts.helperString(__makeTemplateObject(["\n            const ", " = name => super[name];"], ["\n            const ", " = name => super[name];"]), "_superIndex")
    };
    ts.advancedAsyncSuperHelper = {
        name: "typescript:advanced-async-super",
        scoped: true,
        text: ts.helperString(__makeTemplateObject(["\n            const ", " = (function (geti, seti) {\n                const cache = Object.create(null);\n                return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n            })(name => super[name], (name, value) => super[name] = value);"], ["\n            const ", " = (function (geti, seti) {\n                const cache = Object.create(null);\n                return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n            })(name => super[name], (name, value) => super[name] = value);"]), "_superIndex")
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ESNextSubstitutionFlags;
    (function (ESNextSubstitutionFlags) {
        /** Enables substitutions for async methods with `super` calls. */
        ESNextSubstitutionFlags[ESNextSubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
    })(ESNextSubstitutionFlags || (ESNextSubstitutionFlags = {}));
    // Facts we track as we traverse the tree
    var HierarchyFacts;
    (function (HierarchyFacts) {
        HierarchyFacts[HierarchyFacts["None"] = 0] = "None";
        //
        // Ancestor facts
        //
        HierarchyFacts[HierarchyFacts["HasLexicalThis"] = 1] = "HasLexicalThis";
        HierarchyFacts[HierarchyFacts["IterationContainer"] = 2] = "IterationContainer";
        // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below.
        //
        // Ancestor masks
        //
        HierarchyFacts[HierarchyFacts["AncestorFactsMask"] = 3] = "AncestorFactsMask";
        HierarchyFacts[HierarchyFacts["SourceFileIncludes"] = 1] = "SourceFileIncludes";
        HierarchyFacts[HierarchyFacts["SourceFileExcludes"] = 2] = "SourceFileExcludes";
        HierarchyFacts[HierarchyFacts["StrictModeSourceFileIncludes"] = 0] = "StrictModeSourceFileIncludes";
        HierarchyFacts[HierarchyFacts["ClassOrFunctionIncludes"] = 1] = "ClassOrFunctionIncludes";
        HierarchyFacts[HierarchyFacts["ClassOrFunctionExcludes"] = 2] = "ClassOrFunctionExcludes";
        HierarchyFacts[HierarchyFacts["ArrowFunctionIncludes"] = 0] = "ArrowFunctionIncludes";
        HierarchyFacts[HierarchyFacts["ArrowFunctionExcludes"] = 2] = "ArrowFunctionExcludes";
        HierarchyFacts[HierarchyFacts["IterationStatementIncludes"] = 2] = "IterationStatementIncludes";
        HierarchyFacts[HierarchyFacts["IterationStatementExcludes"] = 0] = "IterationStatementExcludes";
    })(HierarchyFacts || (HierarchyFacts = {}));
    function transformES2018(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var previousOnEmitNode = context.onEmitNode;
        context.onEmitNode = onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var exportedVariableStatement = false;
        var enabledSubstitutions;
        var enclosingFunctionFlags;
        var enclosingSuperContainerFlags = 0;
        var hierarchyFacts = 0;
        var currentSourceFile;
        var taggedTemplateStringDeclarations;
        /** Keeps track of property names accessed on super (`super.x`) within async functions. */
        var capturedSuperProperties;
        /** Whether the async function contains an element access on super (`super[x]`). */
        var hasSuperElementAccess;
        /** A set of node IDs for generated super accessors. */
        var substitutedSuperAccessors = [];
        return ts.chainBundle(transformSourceFile);
        function affectsSubtree(excludeFacts, includeFacts) {
            return hierarchyFacts !== (hierarchyFacts & ~excludeFacts | includeFacts);
        }
        /**
         * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification.
         * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree.
         * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree.
         */
        function enterSubtree(excludeFacts, includeFacts) {
            var ancestorFacts = hierarchyFacts;
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 3 /* AncestorFactsMask */;
            return ancestorFacts;
        }
        /**
         * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's
         * subtree.
         * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree.
         */
        function exitSubtree(ancestorFacts) {
            hierarchyFacts = ancestorFacts;
        }
        function recordTaggedTemplateString(temp) {
            taggedTemplateStringDeclarations = ts.append(taggedTemplateStringDeclarations, ts.createVariableDeclaration(temp));
        }
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = visitSourceFile(node);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            taggedTemplateStringDeclarations = undefined;
            return visited;
        }
        function visitor(node) {
            return visitorWorker(node, /*noDestructuringValue*/ false);
        }
        function visitorNoDestructuringValue(node) {
            return visitorWorker(node, /*noDestructuringValue*/ true);
        }
        function visitorNoAsyncModifier(node) {
            if (node.kind === 126 /* AsyncKeyword */) {
                return undefined;
            }
            return node;
        }
        function doWithHierarchyFacts(cb, value, excludeFacts, includeFacts) {
            if (affectsSubtree(excludeFacts, includeFacts)) {
                var ancestorFacts = enterSubtree(excludeFacts, includeFacts);
                var result = cb(value);
                exitSubtree(ancestorFacts);
                return result;
            }
            return cb(value);
        }
        function visitDefault(node) {
            return ts.visitEachChild(node, visitor, context);
        }
        function visitorWorker(node, noDestructuringValue) {
            if ((node.transformFlags & 32 /* ContainsES2018 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 206 /* AwaitExpression */:
                    return visitAwaitExpression(node);
                case 212 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 235 /* ReturnStatement */:
                    return visitReturnStatement(node);
                case 238 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 193 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node, noDestructuringValue);
                case 280 /* CatchClause */:
                    return visitCatchClause(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 242 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                case 231 /* ForInStatement */:
                    return doWithHierarchyFacts(visitDefault, node, 0 /* IterationStatementExcludes */, 2 /* IterationStatementIncludes */);
                case 232 /* ForOfStatement */:
                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
                case 230 /* ForStatement */:
                    return doWithHierarchyFacts(visitForStatement, node, 0 /* IterationStatementExcludes */, 2 /* IterationStatementIncludes */);
                case 205 /* VoidExpression */:
                    return visitVoidExpression(node);
                case 162 /* Constructor */:
                    return doWithHierarchyFacts(visitConstructorDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 161 /* MethodDeclaration */:
                    return doWithHierarchyFacts(visitMethodDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 163 /* GetAccessor */:
                    return doWithHierarchyFacts(visitGetAccessorDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 164 /* SetAccessor */:
                    return doWithHierarchyFacts(visitSetAccessorDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 244 /* FunctionDeclaration */:
                    return doWithHierarchyFacts(visitFunctionDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 201 /* FunctionExpression */:
                    return doWithHierarchyFacts(visitFunctionExpression, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 202 /* ArrowFunction */:
                    return doWithHierarchyFacts(visitArrowFunction, node, 2 /* ArrowFunctionExcludes */, 0 /* ArrowFunctionIncludes */);
                case 156 /* Parameter */:
                    return visitParameter(node);
                case 226 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 200 /* ParenthesizedExpression */:
                    return visitParenthesizedExpression(node, noDestructuringValue);
                case 198 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 194 /* PropertyAccessExpression */:
                    if (capturedSuperProperties && ts.isPropertyAccessExpression(node) && node.expression.kind === 102 /* SuperKeyword */) {
                        capturedSuperProperties.set(node.name.escapedText, true);
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 195 /* ElementAccessExpression */:
                    if (capturedSuperProperties && node.expression.kind === 102 /* SuperKeyword */) {
                        hasSuperElementAccess = true;
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return doWithHierarchyFacts(visitDefault, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitAwaitExpression(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.visitNode(node.expression, visitor, ts.isExpression))), 
                /*location*/ node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitYieldExpression(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                if (node.asteriskToken) {
                    var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
                    return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.updateYield(node, node.asteriskToken, createAsyncDelegatorHelper(context, createAsyncValuesHelper(context, expression, expression), expression)))), node), node);
                }
                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createDownlevelAwait(node.expression
                    ? ts.visitNode(node.expression, visitor, ts.isExpression)
                    : ts.createVoidZero())), node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitReturnStatement(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                return ts.updateReturn(node, createDownlevelAwait(node.expression ? ts.visitNode(node.expression, visitor, ts.isExpression) : ts.createVoidZero()));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitLabeledStatement(node) {
            if (enclosingFunctionFlags & 2 /* Async */) {
                var statement = ts.unwrapInnermostStatementOfLabel(node);
                if (statement.kind === 232 /* ForOfStatement */ && statement.awaitModifier) {
                    return visitForOfStatement(statement, node);
                }
                return ts.restoreEnclosingLabel(ts.visitNode(statement, visitor, ts.isStatement, ts.liftToBlock), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function chunkObjectLiteralElements(elements) {
            var chunkObject;
            var objects = [];
            for (var _i = 0, elements_4 = elements; _i < elements_4.length; _i++) {
                var e = elements_4[_i];
                if (e.kind === 283 /* SpreadAssignment */) {
                    if (chunkObject) {
                        objects.push(ts.createObjectLiteral(chunkObject));
                        chunkObject = undefined;
                    }
                    var target = e.expression;
                    objects.push(ts.visitNode(target, visitor, ts.isExpression));
                }
                else {
                    chunkObject = ts.append(chunkObject, e.kind === 281 /* PropertyAssignment */
                        ? ts.createPropertyAssignment(e.name, ts.visitNode(e.initializer, visitor, ts.isExpression))
                        : ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                }
            }
            if (chunkObject) {
                objects.push(ts.createObjectLiteral(chunkObject));
            }
            return objects;
        }
        function visitObjectLiteralExpression(node) {
            if (node.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                // spread elements emit like so:
                // non-spread elements are chunked together into object literals, and then all are passed to __assign:
                //     { a, ...o, b } => __assign(__assign({a}, o), {b});
                // If the first element is a spread element, then the first argument to __assign is {}:
                //     { ...o, a, b, ...o2 } => __assign(__assign(__assign({}, o), {a, b}), o2)
                //
                // We cannot call __assign with more than two elements, since any element could cause side effects. For
                // example:
                //      var k = { a: 1, b: 2 };
                //      var o = { a: 3, ...k, b: k.a++ };
                //      // expected: { a: 1, b: 1 }
                // If we translate the above to `__assign({ a: 3 }, k, { b: k.a++ })`, the `k.a++` will evaluate before
                // `k` is spread and we end up with `{ a: 2, b: 1 }`.
                //
                // This also occurs for spread elements, not just property assignments:
                //      var k = { a: 1, get b() { l = { z: 9 }; return 2; } };
                //      var l = { c: 3 };
                //      var o = { ...k, ...l };
                //      // expected: { a: 1, b: 2, z: 9 }
                // If we translate the above to `__assign({}, k, l)`, the `l` will evaluate before `k` is spread and we
                // end up with `{ a: 1, b: 2, c: 3 }`
                var objects = chunkObjectLiteralElements(node.properties);
                if (objects.length && objects[0].kind !== 193 /* ObjectLiteralExpression */) {
                    objects.unshift(ts.createObjectLiteral());
                }
                var expression = objects[0];
                if (objects.length > 1) {
                    for (var i = 1; i < objects.length; i++) {
                        expression = createAssignHelper(context, [expression, objects[i]]);
                    }
                    return expression;
                }
                else {
                    return createAssignHelper(context, objects);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitExpressionStatement(node) {
            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
        }
        function visitParenthesizedExpression(node, noDestructuringValue) {
            return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
        }
        function visitSourceFile(node) {
            var ancestorFacts = enterSubtree(2 /* SourceFileExcludes */, ts.isEffectiveStrictModeSourceFile(node, compilerOptions) ?
                0 /* StrictModeSourceFileIncludes */ :
                1 /* SourceFileIncludes */);
            exportedVariableStatement = false;
            var visited = ts.visitEachChild(node, visitor, context);
            var statement = ts.concatenate(visited.statements, taggedTemplateStringDeclarations && [
                ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(taggedTemplateStringDeclarations))
            ]);
            var result = ts.updateSourceFileNode(visited, ts.setTextRange(ts.createNodeArray(statement), node.statements));
            exitSubtree(ancestorFacts);
            return result;
        }
        function visitTaggedTemplateExpression(node) {
            return ts.processTaggedTemplateExpression(context, node, visitor, currentSourceFile, recordTaggedTemplateString, ts.ProcessLevel.LiftRestriction);
        }
        /**
         * Visits a BinaryExpression that contains a destructuring assignment.
         *
         * @param node A BinaryExpression node.
         */
        function visitBinaryExpression(node, noDestructuringValue) {
            if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 1 /* ObjectRest */, !noDestructuringValue);
            }
            else if (node.operatorToken.kind === 27 /* CommaToken */) {
                return ts.updateBinary(node, ts.visitNode(node.left, visitorNoDestructuringValue, ts.isExpression), ts.visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, ts.isExpression));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCatchClause(node) {
            if (node.variableDeclaration &&
                ts.isBindingPattern(node.variableDeclaration.name) &&
                node.variableDeclaration.name.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                var name = ts.getGeneratedNameForNode(node.variableDeclaration.name);
                var updatedDecl = ts.updateVariableDeclaration(node.variableDeclaration, node.variableDeclaration.name, /*type*/ undefined, name);
                var visitedBindings = ts.flattenDestructuringBinding(updatedDecl, visitor, context, 1 /* ObjectRest */);
                var block = ts.visitNode(node.block, visitor, ts.isBlock);
                if (ts.some(visitedBindings)) {
                    block = ts.updateBlock(block, __spreadArrays([
                        ts.createVariableStatement(/*modifiers*/ undefined, visitedBindings)
                    ], block.statements));
                }
                return ts.updateCatchClause(node, ts.updateVariableDeclaration(node.variableDeclaration, name, /*type*/ undefined, /*initializer*/ undefined), block);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitVariableStatement(node) {
            if (ts.hasModifier(node, 1 /* Export */)) {
                var savedExportedVariableStatement = exportedVariableStatement;
                exportedVariableStatement = true;
                var visited = ts.visitEachChild(node, visitor, context);
                exportedVariableStatement = savedExportedVariableStatement;
                return visited;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a VariableDeclaration node with a binding pattern.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclaration(node) {
            if (exportedVariableStatement) {
                var savedExportedVariableStatement = exportedVariableStatement;
                exportedVariableStatement = false;
                var visited = visitVariableDeclarationWorker(node, /*exportedVariableStatement*/ true);
                exportedVariableStatement = savedExportedVariableStatement;
                return visited;
            }
            return visitVariableDeclarationWorker(node, /*exportedVariableStatement*/ false);
        }
        function visitVariableDeclarationWorker(node, exportedVariableStatement) {
            // If we are here it is because the name contains a binding pattern with a rest somewhere in it.
            if (ts.isBindingPattern(node.name) && node.name.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                return ts.flattenDestructuringBinding(node, visitor, context, 1 /* ObjectRest */, 
                /*rval*/ undefined, exportedVariableStatement);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForStatement(node) {
            return ts.updateFor(node, ts.visitNode(node.initializer, visitorNoDestructuringValue, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement));
        }
        function visitVoidExpression(node) {
            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
        }
        /**
         * Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement.
         *
         * @param node A ForOfStatement.
         */
        function visitForOfStatement(node, outermostLabeledStatement) {
            var ancestorFacts = enterSubtree(0 /* IterationStatementExcludes */, 2 /* IterationStatementIncludes */);
            if (node.initializer.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                node = transformForOfStatementWithObjectRest(node);
            }
            var result = node.awaitModifier ?
                transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) :
                ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement);
            exitSubtree(ancestorFacts);
            return result;
        }
        function transformForOfStatementWithObjectRest(node) {
            var initializerWithoutParens = ts.skipParentheses(node.initializer);
            if (ts.isVariableDeclarationList(initializerWithoutParens) || ts.isAssignmentPattern(initializerWithoutParens)) {
                var bodyLocation = void 0;
                var statementsLocation = void 0;
                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                var statements = [ts.createForOfBindingStatement(initializerWithoutParens, temp)];
                if (ts.isBlock(node.statement)) {
                    ts.addRange(statements, node.statement.statements);
                    bodyLocation = node.statement;
                    statementsLocation = node.statement.statements;
                }
                else if (node.statement) {
                    ts.append(statements, node.statement);
                    bodyLocation = node.statement;
                    statementsLocation = node.statement;
                }
                return ts.updateForOf(node, node.awaitModifier, ts.setTextRange(ts.createVariableDeclarationList([
                    ts.setTextRange(ts.createVariableDeclaration(temp), node.initializer)
                ], 1 /* Let */), node.initializer), node.expression, ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
                /*multiLine*/ true), bodyLocation));
            }
            return node;
        }
        function convertForOfStatementHead(node, boundValue) {
            var binding = ts.createForOfBindingStatement(node.initializer, boundValue);
            var bodyLocation;
            var statementsLocation;
            var statements = [ts.visitNode(binding, visitor, ts.isStatement)];
            var statement = ts.visitNode(node.statement, visitor, ts.isStatement);
            if (ts.isBlock(statement)) {
                ts.addRange(statements, statement.statements);
                bodyLocation = statement;
                statementsLocation = statement.statements;
            }
            else {
                statements.push(statement);
            }
            return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
            /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
        }
        function createDownlevelAwait(expression) {
            return enclosingFunctionFlags & 1 /* Generator */
                ? ts.createYield(/*asteriskToken*/ undefined, createAwaitHelper(context, expression))
                : ts.createAwait(expression);
        }
        function transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var errorRecord = ts.createUniqueName("e");
            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
            var callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
            var callNext = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
            var getDone = ts.createPropertyAccess(result, "done");
            var getValue = ts.createPropertyAccess(result, "value");
            var callReturn = ts.createFunctionCall(returnMethod, iterator, []);
            hoistVariableDeclaration(errorRecord);
            hoistVariableDeclaration(returnMethod);
            // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration
            var initializer = ancestorFacts & 2 /* IterationContainer */ ?
                ts.inlineExpressions([ts.createAssignment(errorRecord, ts.createVoidZero()), callValues]) :
                callValues;
            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression),
                ts.createVariableDeclaration(result)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.createComma(ts.createAssignment(result, createDownlevelAwait(callNext)), ts.createLogicalNot(getDone)), 
            /*incrementor*/ undefined, 
            /*statement*/ convertForOfStatementHead(node, getValue)), 
            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
            return ts.createTry(ts.createBlock([
                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement)
            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
                ts.createExpressionStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
                    ts.createPropertyAssignment("error", catchVariable)
                ])))
            ]), 1 /* SingleLine */)), ts.createBlock([
                ts.createTry(
                /*tryBlock*/ ts.createBlock([
                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(getDone)), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createExpressionStatement(createDownlevelAwait(callReturn))), 1 /* SingleLine */)
                ]), 
                /*catchClause*/ undefined, 
                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
                ]), 1 /* SingleLine */))
            ]));
        }
        function visitParameter(node) {
            if (node.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                // Binding patterns are converted into a generated name and are
                // evaluated inside the function body.
                return ts.updateParameter(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, node.dotDotDotToken, ts.getGeneratedNameForNode(node), 
                /*questionToken*/ undefined, 
                /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitConstructorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateConstructor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitGetAccessorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateGetAccessor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitSetAccessorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateSetAccessor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitMethodDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateMethod(node, 
            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitNode(/*questionToken*/ undefined, visitor, ts.isToken), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitFunctionDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitArrowFunction(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateArrowFunction(node, node.modifiers, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitFunctionExpression(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateFunctionExpression(node, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function transformAsyncGeneratorFunctionBody(node) {
            resumeLexicalEnvironment();
            var statements = [];
            var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
            appendObjectRestAssignmentsIfNeeded(statements, node);
            var savedCapturedSuperProperties = capturedSuperProperties;
            var savedHasSuperElementAccess = hasSuperElementAccess;
            capturedSuperProperties = ts.createUnderscoreEscapedMap();
            hasSuperElementAccess = false;
            var returnStatement = ts.createReturn(createAsyncGeneratorHelper(context, ts.createFunctionExpression(
            /*modifiers*/ undefined, ts.createToken(41 /* AsteriskToken */), node.name && ts.getGeneratedNameForNode(node.name), 
            /*typeParameters*/ undefined, 
            /*parameters*/ [], 
            /*type*/ undefined, ts.updateBlock(node.body, ts.visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset))), !!(hierarchyFacts & 1 /* HasLexicalThis */)));
            // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
            // This step isn't needed if we eventually transform this to ES5.
            var emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && resolver.getNodeCheckFlags(node) & (4096 /* AsyncMethodWithSuperBinding */ | 2048 /* AsyncMethodWithSuper */);
            if (emitSuperHelpers) {
                enableSubstitutionForAsyncMethodsWithSuper();
                var variableStatement = ts.createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
                substitutedSuperAccessors[ts.getNodeId(variableStatement)] = true;
                ts.insertStatementsAfterStandardPrologue(statements, [variableStatement]);
            }
            statements.push(returnStatement);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var block = ts.updateBlock(node.body, statements);
            if (emitSuperHelpers && hasSuperElementAccess) {
                if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                    ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
                }
                else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                    ts.addEmitHelper(block, ts.asyncSuperHelper);
                }
            }
            capturedSuperProperties = savedCapturedSuperProperties;
            hasSuperElementAccess = savedHasSuperElementAccess;
            return block;
        }
        function transformFunctionBody(node) {
            resumeLexicalEnvironment();
            var statementOffset = 0;
            var statements = [];
            var body = ts.visitNode(node.body, visitor, ts.isConciseBody);
            if (ts.isBlock(body)) {
                statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
            }
            ts.addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node));
            var leadingStatements = endLexicalEnvironment();
            if (statementOffset > 0 || ts.some(statements) || ts.some(leadingStatements)) {
                var block = ts.convertToFunctionBody(body, /*multiLine*/ true);
                ts.insertStatementsAfterStandardPrologue(statements, leadingStatements);
                ts.addRange(statements, block.statements.slice(statementOffset));
                return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(statements), block.statements));
            }
            return body;
        }
        function appendObjectRestAssignmentsIfNeeded(statements, node) {
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                if (parameter.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                    var temp = ts.getGeneratedNameForNode(parameter);
                    var declarations = ts.flattenDestructuringBinding(parameter, visitor, context, 1 /* ObjectRest */, temp, 
                    /*doNotRecordTempVariablesInLine*/ false, 
                    /*skipInitializer*/ true);
                    if (ts.some(declarations)) {
                        var statement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList(declarations));
                        ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
                        statements = ts.append(statements, statement);
                    }
                }
            }
            return statements;
        }
        function enableSubstitutionForAsyncMethodsWithSuper() {
            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
                // We need to enable substitutions for call, property access, and element access
                // if we need to rewrite super calls.
                context.enableSubstitution(196 /* CallExpression */);
                context.enableSubstitution(194 /* PropertyAccessExpression */);
                context.enableSubstitution(195 /* ElementAccessExpression */);
                // We need to be notified when entering and exiting declarations that bind super.
                context.enableEmitNotification(245 /* ClassDeclaration */);
                context.enableEmitNotification(161 /* MethodDeclaration */);
                context.enableEmitNotification(163 /* GetAccessor */);
                context.enableEmitNotification(164 /* SetAccessor */);
                context.enableEmitNotification(162 /* Constructor */);
                // We need to be notified when entering the generated accessor arrow functions.
                context.enableEmitNotification(225 /* VariableStatement */);
            }
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to be printed.
         * @param emitCallback The callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            // If we need to support substitutions for `super` in an async method,
            // we should track it here.
            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
                if (superContainerFlags !== enclosingSuperContainerFlags) {
                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                    enclosingSuperContainerFlags = superContainerFlags;
                    previousOnEmitNode(hint, node, emitCallback);
                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                    return;
                }
            }
            // Disable substitution in the generated super accessor itself.
            else if (enabledSubstitutions && substitutedSuperAccessors[ts.getNodeId(node)]) {
                var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                enclosingSuperContainerFlags = 0;
                previousOnEmitNode(hint, node, emitCallback);
                enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 195 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
                case 196 /* CallExpression */:
                    return substituteCallExpression(node);
            }
            return node;
        }
        function substitutePropertyAccessExpression(node) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), node.name), node);
            }
            return node;
        }
        function substituteElementAccessExpression(node) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return createSuperElementAccessInAsyncMethod(node.argumentExpression, node);
            }
            return node;
        }
        function substituteCallExpression(node) {
            var expression = node.expression;
            if (ts.isSuperProperty(expression)) {
                var argumentExpression = ts.isPropertyAccessExpression(expression)
                    ? substitutePropertyAccessExpression(expression)
                    : substituteElementAccessExpression(expression);
                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
                /*typeArguments*/ undefined, __spreadArrays([
                    ts.createThis()
                ], node.arguments));
            }
            return node;
        }
        function isSuperContainer(node) {
            var kind = node.kind;
            return kind === 245 /* ClassDeclaration */
                || kind === 162 /* Constructor */
                || kind === 161 /* MethodDeclaration */
                || kind === 163 /* GetAccessor */
                || kind === 164 /* SetAccessor */;
        }
        function createSuperElementAccessInAsyncMethod(argumentExpression, location) {
            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
            }
            else {
                return ts.setTextRange(ts.createCall(ts.createIdentifier("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), location);
            }
        }
    }
    ts.transformES2018 = transformES2018;
    ts.assignHelper = {
        name: "typescript:assign",
        importName: "__assign",
        scoped: false,
        priority: 1,
        text: "\n            var __assign = (this && this.__assign) || function () {\n                __assign = Object.assign || function(t) {\n                    for (var s, i = 1, n = arguments.length; i < n; i++) {\n                        s = arguments[i];\n                        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n                            t[p] = s[p];\n                    }\n                    return t;\n                };\n                return __assign.apply(this, arguments);\n            };"
    };
    function createAssignHelper(context, attributesSegments) {
        if (context.getCompilerOptions().target >= 2 /* ES2015 */) {
            return ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "assign"), /*typeArguments*/ undefined, attributesSegments);
        }
        context.requestEmitHelper(ts.assignHelper);
        return ts.createCall(ts.getUnscopedHelperName("__assign"), 
        /*typeArguments*/ undefined, attributesSegments);
    }
    ts.createAssignHelper = createAssignHelper;
    ts.awaitHelper = {
        name: "typescript:await",
        importName: "__await",
        scoped: false,
        text: "\n            var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }"
    };
    function createAwaitHelper(context, expression) {
        context.requestEmitHelper(ts.awaitHelper);
        return ts.createCall(ts.getUnscopedHelperName("__await"), /*typeArguments*/ undefined, [expression]);
    }
    ts.asyncGeneratorHelper = {
        name: "typescript:asyncGenerator",
        importName: "__asyncGenerator",
        scoped: false,
        dependencies: [ts.awaitHelper],
        text: "\n            var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var g = generator.apply(thisArg, _arguments || []), i, q = [];\n                return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n                function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n                function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n                function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n                function fulfill(value) { resume(\"next\", value); }\n                function reject(value) { resume(\"throw\", value); }\n                function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n            };"
    };
    function createAsyncGeneratorHelper(context, generatorFunc, hasLexicalThis) {
        context.requestEmitHelper(ts.asyncGeneratorHelper);
        // Mark this node as originally an async function
        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */ | 524288 /* ReuseTempVariableScope */;
        return ts.createCall(ts.getUnscopedHelperName("__asyncGenerator"), 
        /*typeArguments*/ undefined, [
            hasLexicalThis ? ts.createThis() : ts.createVoidZero(),
            ts.createIdentifier("arguments"),
            generatorFunc
        ]);
    }
    ts.asyncDelegator = {
        name: "typescript:asyncDelegator",
        importName: "__asyncDelegator",
        scoped: false,
        dependencies: [ts.awaitHelper],
        text: "\n            var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {\n                var i, p;\n                return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n                function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\n            };"
    };
    function createAsyncDelegatorHelper(context, expression, location) {
        context.requestEmitHelper(ts.asyncDelegator);
        return ts.setTextRange(ts.createCall(ts.getUnscopedHelperName("__asyncDelegator"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
    ts.asyncValues = {
        name: "typescript:asyncValues",
        importName: "__asyncValues",
        scoped: false,
        text: "\n            var __asyncValues = (this && this.__asyncValues) || function (o) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var m = o[Symbol.asyncIterator], i;\n                return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n                function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n                function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n            };"
    };
    function createAsyncValuesHelper(context, expression, location) {
        context.requestEmitHelper(ts.asyncValues);
        return ts.setTextRange(ts.createCall(ts.getUnscopedHelperName("__asyncValues"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2019(context) {
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 16 /* ContainsES2019 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 280 /* CatchClause */:
                    return visitCatchClause(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitCatchClause(node) {
            if (!node.variableDeclaration) {
                return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(/*recordTempVariable*/ undefined)), ts.visitNode(node.block, visitor, ts.isBlock));
            }
            return ts.visitEachChild(node, visitor, context);
        }
    }
    ts.transformES2019 = transformES2019;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2020(context) {
        var hoistVariableDeclaration = context.hoistVariableDeclaration;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 8 /* ContainsES2020 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                case 196 /* CallExpression */:
                    if (node.flags & 32 /* OptionalChain */) {
                        var updated = visitOptionalExpression(node, /*captureThisArg*/ false, /*isDelete*/ false);
                        ts.Debug.assertNotNode(updated, ts.isSyntheticReference);
                        return updated;
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 209 /* BinaryExpression */:
                    if (node.operatorToken.kind === 60 /* QuestionQuestionToken */) {
                        return transformNullishCoalescingExpression(node);
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 203 /* DeleteExpression */:
                    return visitDeleteExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function flattenChain(chain) {
            ts.Debug.assertNotNode(chain, ts.isNonNullChain);
            var links = [chain];
            while (!chain.questionDotToken && !ts.isTaggedTemplateExpression(chain)) {
                chain = ts.cast(ts.skipPartiallyEmittedExpressions(chain.expression), ts.isOptionalChain);
                ts.Debug.assertNotNode(chain, ts.isNonNullChain);
                links.unshift(chain);
            }
            return { expression: chain.expression, chain: links };
        }
        function visitNonOptionalParenthesizedExpression(node, captureThisArg, isDelete) {
            var expression = visitNonOptionalExpression(node.expression, captureThisArg, isDelete);
            if (ts.isSyntheticReference(expression)) {
                // `(a.b)` -> { expression `((_a = a).b)`, thisArg: `_a` }
                // `(a[b])` -> { expression `((_a = a)[b])`, thisArg: `_a` }
                return ts.createSyntheticReferenceExpression(ts.updateParen(node, expression.expression), expression.thisArg);
            }
            return ts.updateParen(node, expression);
        }
        function visitNonOptionalPropertyOrElementAccessExpression(node, captureThisArg, isDelete) {
            if (ts.isOptionalChain(node)) {
                // If `node` is an optional chain, then it is the outermost chain of an optional expression.
                return visitOptionalExpression(node, captureThisArg, isDelete);
            }
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            ts.Debug.assertNotNode(expression, ts.isSyntheticReference);
            var thisArg;
            if (captureThisArg) {
                if (shouldCaptureInTempVariable(expression)) {
                    thisArg = ts.createTempVariable(hoistVariableDeclaration);
                    expression = ts.createAssignment(thisArg, expression);
                    // if (inParameterInitializer) tempVariableInParameter = true;
                }
                else {
                    thisArg = expression;
                }
            }
            expression = node.kind === 194 /* PropertyAccessExpression */
                ? ts.updatePropertyAccess(node, expression, ts.visitNode(node.name, visitor, ts.isIdentifier))
                : ts.updateElementAccess(node, expression, ts.visitNode(node.argumentExpression, visitor, ts.isExpression));
            return thisArg ? ts.createSyntheticReferenceExpression(expression, thisArg) : expression;
        }
        function visitNonOptionalCallExpression(node, captureThisArg) {
            if (ts.isOptionalChain(node)) {
                // If `node` is an optional chain, then it is the outermost chain of an optional expression.
                return visitOptionalExpression(node, captureThisArg, /*isDelete*/ false);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitNonOptionalExpression(node, captureThisArg, isDelete) {
            switch (node.kind) {
                case 200 /* ParenthesizedExpression */: return visitNonOptionalParenthesizedExpression(node, captureThisArg, isDelete);
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */: return visitNonOptionalPropertyOrElementAccessExpression(node, captureThisArg, isDelete);
                case 196 /* CallExpression */: return visitNonOptionalCallExpression(node, captureThisArg);
                default: return ts.visitNode(node, visitor, ts.isExpression);
            }
        }
        function visitOptionalExpression(node, captureThisArg, isDelete) {
            var _a = flattenChain(node), expression = _a.expression, chain = _a.chain;
            var left = visitNonOptionalExpression(expression, ts.isCallChain(chain[0]), /*isDelete*/ false);
            var leftThisArg = ts.isSyntheticReference(left) ? left.thisArg : undefined;
            var leftExpression = ts.isSyntheticReference(left) ? left.expression : left;
            var capturedLeft = leftExpression;
            if (shouldCaptureInTempVariable(leftExpression)) {
                capturedLeft = ts.createTempVariable(hoistVariableDeclaration);
                leftExpression = ts.createAssignment(capturedLeft, leftExpression);
                // if (inParameterInitializer) tempVariableInParameter = true;
            }
            var rightExpression = capturedLeft;
            var thisArg;
            for (var i = 0; i < chain.length; i++) {
                var segment = chain[i];
                switch (segment.kind) {
                    case 194 /* PropertyAccessExpression */:
                    case 195 /* ElementAccessExpression */:
                        if (i === chain.length - 1 && captureThisArg) {
                            if (shouldCaptureInTempVariable(rightExpression)) {
                                thisArg = ts.createTempVariable(hoistVariableDeclaration);
                                rightExpression = ts.createAssignment(thisArg, rightExpression);
                                // if (inParameterInitializer) tempVariableInParameter = true;
                            }
                            else {
                                thisArg = rightExpression;
                            }
                        }
                        rightExpression = segment.kind === 194 /* PropertyAccessExpression */
                            ? ts.createPropertyAccess(rightExpression, ts.visitNode(segment.name, visitor, ts.isIdentifier))
                            : ts.createElementAccess(rightExpression, ts.visitNode(segment.argumentExpression, visitor, ts.isExpression));
                        break;
                    case 196 /* CallExpression */:
                        if (i === 0 && leftThisArg) {
                            rightExpression = ts.createFunctionCall(rightExpression, leftThisArg.kind === 102 /* SuperKeyword */ ? ts.createThis() : leftThisArg, ts.visitNodes(segment.arguments, visitor, ts.isExpression));
                        }
                        else {
                            rightExpression = ts.createCall(rightExpression, 
                            /*typeArguments*/ undefined, ts.visitNodes(segment.arguments, visitor, ts.isExpression));
                        }
                        break;
                }
                ts.setOriginalNode(rightExpression, segment);
            }
            var target = isDelete
                ? ts.createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), ts.createTrue(), ts.createDelete(rightExpression))
                : ts.createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), ts.createVoidZero(), rightExpression);
            return thisArg ? ts.createSyntheticReferenceExpression(target, thisArg) : target;
        }
        function createNotNullCondition(left, right, invert) {
            return ts.createBinary(ts.createBinary(left, ts.createToken(invert ? 36 /* EqualsEqualsEqualsToken */ : 37 /* ExclamationEqualsEqualsToken */), ts.createNull()), ts.createToken(invert ? 56 /* BarBarToken */ : 55 /* AmpersandAmpersandToken */), ts.createBinary(right, ts.createToken(invert ? 36 /* EqualsEqualsEqualsToken */ : 37 /* ExclamationEqualsEqualsToken */), ts.createVoidZero()));
        }
        function transformNullishCoalescingExpression(node) {
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = left;
            if (shouldCaptureInTempVariable(left)) {
                right = ts.createTempVariable(hoistVariableDeclaration);
                left = ts.createAssignment(right, left);
                // if (inParameterInitializer) tempVariableInParameter = true;
            }
            return ts.createConditional(createNotNullCondition(left, right), right, ts.visitNode(node.right, visitor, ts.isExpression));
        }
        function shouldCaptureInTempVariable(expression) {
            // don't capture identifiers and `this` in a temporary variable
            // `super` cannot be captured as it's no real variable
            return !ts.isIdentifier(expression) &&
                expression.kind !== 104 /* ThisKeyword */ &&
                expression.kind !== 102 /* SuperKeyword */;
        }
        function visitDeleteExpression(node) {
            return ts.isOptionalChain(ts.skipParentheses(node.expression))
                ? ts.setOriginalNode(visitNonOptionalExpression(node.expression, /*captureThisArg*/ false, /*isDelete*/ true), node)
                : ts.updateDelete(node, ts.visitNode(node.expression, visitor, ts.isExpression));
        }
    }
    ts.transformES2020 = transformES2020;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformESNext(context) {
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 4 /* ContainsESNext */) === 0) {
                return node;
            }
            switch (node.kind) {
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
    }
    ts.transformESNext = transformESNext;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformJsx(context) {
        var compilerOptions = context.getCompilerOptions();
        var currentSourceFile;
        return ts.chainBundle(transformSourceFile);
        /**
         * Transform JSX-specific syntax in a SourceFile.
         *
         * @param node A SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            if (node.transformFlags & 2 /* ContainsJsx */) {
                return visitorWorker(node);
            }
            else {
                return node;
            }
        }
        function visitorWorker(node) {
            switch (node.kind) {
                case 266 /* JsxElement */:
                    return visitJsxElement(node, /*isChild*/ false);
                case 267 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node, /*isChild*/ false);
                case 270 /* JsxFragment */:
                    return visitJsxFragment(node, /*isChild*/ false);
                case 276 /* JsxExpression */:
                    return visitJsxExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformJsxChildToExpression(node) {
            switch (node.kind) {
                case 11 /* JsxText */:
                    return visitJsxText(node);
                case 276 /* JsxExpression */:
                    return visitJsxExpression(node);
                case 266 /* JsxElement */:
                    return visitJsxElement(node, /*isChild*/ true);
                case 267 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node, /*isChild*/ true);
                case 270 /* JsxFragment */:
                    return visitJsxFragment(node, /*isChild*/ true);
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function visitJsxElement(node, isChild) {
            return visitJsxOpeningLikeElement(node.openingElement, node.children, isChild, /*location*/ node);
        }
        function visitJsxSelfClosingElement(node, isChild) {
            return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
        }
        function visitJsxFragment(node, isChild) {
            return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node);
        }
        function visitJsxOpeningLikeElement(node, children, isChild, location) {
            var tagName = getTagName(node);
            var objectProperties;
            var attrs = node.attributes.properties;
            if (attrs.length === 0) {
                // When there are no attributes, React wants "null"
                objectProperties = ts.createNull();
            }
            else {
                // Map spans of JsxAttribute nodes into object literals and spans
                // of JsxSpreadAttribute nodes into expressions.
                var segments = ts.flatten(ts.spanMap(attrs, ts.isJsxSpreadAttribute, function (attrs, isSpread) { return isSpread
                    ? ts.map(attrs, transformJsxSpreadAttributeToExpression)
                    : ts.createObjectLiteral(ts.map(attrs, transformJsxAttributeToObjectLiteralElement)); }));
                if (ts.isJsxSpreadAttribute(attrs[0])) {
                    // We must always emit at least one object literal before a spread
                    // argument.
                    segments.unshift(ts.createObjectLiteral());
                }
                // Either emit one big object literal (no spread attribs), or
                // a call to the __assign helper.
                objectProperties = ts.singleOrUndefined(segments);
                if (!objectProperties) {
                    objectProperties = ts.createAssignHelper(context, segments);
                }
            }
            var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(currentSourceFile), compilerOptions.reactNamespace, // TODO: GH#18217
            tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location);
            if (isChild) {
                ts.startOnNewLine(element);
            }
            return element;
        }
        function visitJsxOpeningFragment(node, children, isChild, location) {
            var element = ts.createExpressionForJsxFragment(context.getEmitResolver().getJsxFactoryEntity(currentSourceFile), compilerOptions.reactNamespace, // TODO: GH#18217
            ts.mapDefined(children, transformJsxChildToExpression), node, location);
            if (isChild) {
                ts.startOnNewLine(element);
            }
            return element;
        }
        function transformJsxSpreadAttributeToExpression(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        function transformJsxAttributeToObjectLiteralElement(node) {
            var name = getAttributeName(node);
            var expression = transformJsxAttributeInitializer(node.initializer);
            return ts.createPropertyAssignment(name, expression);
        }
        function transformJsxAttributeInitializer(node) {
            if (node === undefined) {
                return ts.createTrue();
            }
            else if (node.kind === 10 /* StringLiteral */) {
                // Always recreate the literal to escape any escape sequences or newlines which may be in the original jsx string and which
                // Need to be escaped to be handled correctly in a normal string
                var literal = ts.createLiteral(tryDecodeEntities(node.text) || node.text);
                literal.singleQuote = node.singleQuote !== undefined ? node.singleQuote : !ts.isStringDoubleQuoted(node, currentSourceFile);
                return ts.setTextRange(literal, node);
            }
            else if (node.kind === 276 /* JsxExpression */) {
                if (node.expression === undefined) {
                    return ts.createTrue();
                }
                return visitJsxExpression(node);
            }
            else {
                return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function visitJsxText(node) {
            var fixed = fixupWhitespaceAndDecodeEntities(node.text);
            return fixed === undefined ? undefined : ts.createLiteral(fixed);
        }
        /**
         * JSX trims whitespace at the end and beginning of lines, except that the
         * start/end of a tag is considered a start/end of a line only if that line is
         * on the same line as the closing tag. See examples in
         * tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
         * See also https://www.w3.org/TR/html4/struct/text.html#h-9.1 and https://www.w3.org/TR/CSS2/text.html#white-space-model
         *
         * An equivalent algorithm would be:
         * - If there is only one line, return it.
         * - If there is only whitespace (but multiple lines), return `undefined`.
         * - Split the text into lines.
         * - 'trimRight' the first line, 'trimLeft' the last line, 'trim' middle lines.
         * - Decode entities on each line (individually).
         * - Remove empty lines and join the rest with " ".
         */
        function fixupWhitespaceAndDecodeEntities(text) {
            var acc;
            // First non-whitespace character on this line.
            var firstNonWhitespace = 0;
            // Last non-whitespace character on this line.
            var lastNonWhitespace = -1;
            // These initial values are special because the first line is:
            // firstNonWhitespace = 0 to indicate that we want leading whitsepace,
            // but lastNonWhitespace = -1 as a special flag to indicate that we *don't* include the line if it's all whitespace.
            for (var i = 0; i < text.length; i++) {
                var c = text.charCodeAt(i);
                if (ts.isLineBreak(c)) {
                    // If we've seen any non-whitespace characters on this line, add the 'trim' of the line.
                    // (lastNonWhitespace === -1 is a special flag to detect whether the first line is all whitespace.)
                    if (firstNonWhitespace !== -1 && lastNonWhitespace !== -1) {
                        acc = addLineOfJsxText(acc, text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1));
                    }
                    // Reset firstNonWhitespace for the next line.
                    // Don't bother to reset lastNonWhitespace because we ignore it if firstNonWhitespace = -1.
                    firstNonWhitespace = -1;
                }
                else if (!ts.isWhiteSpaceSingleLine(c)) {
                    lastNonWhitespace = i;
                    if (firstNonWhitespace === -1) {
                        firstNonWhitespace = i;
                    }
                }
            }
            return firstNonWhitespace !== -1
                // Last line had a non-whitespace character. Emit the 'trimLeft', meaning keep trailing whitespace.
                ? addLineOfJsxText(acc, text.substr(firstNonWhitespace))
                // Last line was all whitespace, so ignore it
                : acc;
        }
        function addLineOfJsxText(acc, trimmedLine) {
            // We do not escape the string here as that is handled by the printer
            // when it emits the literal. We do, however, need to decode JSX entities.
            var decoded = decodeEntities(trimmedLine);
            return acc === undefined ? decoded : acc + " " + decoded;
        }
        /**
         * Replace entities like "&nbsp;", "&#123;", and "&#xDEADBEEF;" with the characters they encode.
         * See https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
         */
        function decodeEntities(text) {
            return text.replace(/&((#((\d+)|x([\da-fA-F]+)))|(\w+));/g, function (match, _all, _number, _digits, decimal, hex, word) {
                if (decimal) {
                    return ts.utf16EncodeAsString(parseInt(decimal, 10));
                }
                else if (hex) {
                    return ts.utf16EncodeAsString(parseInt(hex, 16));
                }
                else {
                    var ch = entities.get(word);
                    // If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace)
                    return ch ? ts.utf16EncodeAsString(ch) : match;
                }
            });
        }
        /** Like `decodeEntities` but returns `undefined` if there were no entities to decode. */
        function tryDecodeEntities(text) {
            var decoded = decodeEntities(text);
            return decoded === text ? undefined : decoded;
        }
        function getTagName(node) {
            if (node.kind === 266 /* JsxElement */) {
                return getTagName(node.openingElement);
            }
            else {
                var name = node.tagName;
                if (ts.isIdentifier(name) && ts.isIntrinsicJsxName(name.escapedText)) {
                    return ts.createLiteral(ts.idText(name));
                }
                else {
                    return ts.createExpressionFromEntityName(name);
                }
            }
        }
        /**
         * Emit an attribute name, which is quoted if it needs to be quoted. Because
         * these emit into an object literal property name, we don't need to be worried
         * about keywords, just non-identifier characters
         */
        function getAttributeName(node) {
            var name = node.name;
            var text = ts.idText(name);
            if (/^[A-Za-z_]\w*$/.test(text)) {
                return name;
            }
            else {
                return ts.createLiteral(text);
            }
        }
        function visitJsxExpression(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
    }
    ts.transformJsx = transformJsx;
    var entities = ts.createMapFromTemplate({
        quot: 0x0022,
        amp: 0x0026,
        apos: 0x0027,
        lt: 0x003C,
        gt: 0x003E,
        nbsp: 0x00A0,
        iexcl: 0x00A1,
        cent: 0x00A2,
        pound: 0x00A3,
        curren: 0x00A4,
        yen: 0x00A5,
        brvbar: 0x00A6,
        sect: 0x00A7,
        uml: 0x00A8,
        copy: 0x00A9,
        ordf: 0x00AA,
        laquo: 0x00AB,
        not: 0x00AC,
        shy: 0x00AD,
        reg: 0x00AE,
        macr: 0x00AF,
        deg: 0x00B0,
        plusmn: 0x00B1,
        sup2: 0x00B2,
        sup3: 0x00B3,
        acute: 0x00B4,
        micro: 0x00B5,
        para: 0x00B6,
        middot: 0x00B7,
        cedil: 0x00B8,
        sup1: 0x00B9,
        ordm: 0x00BA,
        raquo: 0x00BB,
        frac14: 0x00BC,
        frac12: 0x00BD,
        frac34: 0x00BE,
        iquest: 0x00BF,
        Agrave: 0x00C0,
        Aacute: 0x00C1,
        Acirc: 0x00C2,
        Atilde: 0x00C3,
        Auml: 0x00C4,
        Aring: 0x00C5,
        AElig: 0x00C6,
        Ccedil: 0x00C7,
        Egrave: 0x00C8,
        Eacute: 0x00C9,
        Ecirc: 0x00CA,
        Euml: 0x00CB,
        Igrave: 0x00CC,
        Iacute: 0x00CD,
        Icirc: 0x00CE,
        Iuml: 0x00CF,
        ETH: 0x00D0,
        Ntilde: 0x00D1,
        Ograve: 0x00D2,
        Oacute: 0x00D3,
        Ocirc: 0x00D4,
        Otilde: 0x00D5,
        Ouml: 0x00D6,
        times: 0x00D7,
        Oslash: 0x00D8,
        Ugrave: 0x00D9,
        Uacute: 0x00DA,
        Ucirc: 0x00DB,
        Uuml: 0x00DC,
        Yacute: 0x00DD,
        THORN: 0x00DE,
        szlig: 0x00DF,
        agrave: 0x00E0,
        aacute: 0x00E1,
        acirc: 0x00E2,
        atilde: 0x00E3,
        auml: 0x00E4,
        aring: 0x00E5,
        aelig: 0x00E6,
        ccedil: 0x00E7,
        egrave: 0x00E8,
        eacute: 0x00E9,
        ecirc: 0x00EA,
        euml: 0x00EB,
        igrave: 0x00EC,
        iacute: 0x00ED,
        icirc: 0x00EE,
        iuml: 0x00EF,
        eth: 0x00F0,
        ntilde: 0x00F1,
        ograve: 0x00F2,
        oacute: 0x00F3,
        ocirc: 0x00F4,
        otilde: 0x00F5,
        ouml: 0x00F6,
        divide: 0x00F7,
        oslash: 0x00F8,
        ugrave: 0x00F9,
        uacute: 0x00FA,
        ucirc: 0x00FB,
        uuml: 0x00FC,
        yacute: 0x00FD,
        thorn: 0x00FE,
        yuml: 0x00FF,
        OElig: 0x0152,
        oelig: 0x0153,
        Scaron: 0x0160,
        scaron: 0x0161,
        Yuml: 0x0178,
        fnof: 0x0192,
        circ: 0x02C6,
        tilde: 0x02DC,
        Alpha: 0x0391,
        Beta: 0x0392,
        Gamma: 0x0393,
        Delta: 0x0394,
        Epsilon: 0x0395,
        Zeta: 0x0396,
        Eta: 0x0397,
        Theta: 0x0398,
        Iota: 0x0399,
        Kappa: 0x039A,
        Lambda: 0x039B,
        Mu: 0x039C,
        Nu: 0x039D,
        Xi: 0x039E,
        Omicron: 0x039F,
        Pi: 0x03A0,
        Rho: 0x03A1,
        Sigma: 0x03A3,
        Tau: 0x03A4,
        Upsilon: 0x03A5,
        Phi: 0x03A6,
        Chi: 0x03A7,
        Psi: 0x03A8,
        Omega: 0x03A9,
        alpha: 0x03B1,
        beta: 0x03B2,
        gamma: 0x03B3,
        delta: 0x03B4,
        epsilon: 0x03B5,
        zeta: 0x03B6,
        eta: 0x03B7,
        theta: 0x03B8,
        iota: 0x03B9,
        kappa: 0x03BA,
        lambda: 0x03BB,
        mu: 0x03BC,
        nu: 0x03BD,
        xi: 0x03BE,
        omicron: 0x03BF,
        pi: 0x03C0,
        rho: 0x03C1,
        sigmaf: 0x03C2,
        sigma: 0x03C3,
        tau: 0x03C4,
        upsilon: 0x03C5,
        phi: 0x03C6,
        chi: 0x03C7,
        psi: 0x03C8,
        omega: 0x03C9,
        thetasym: 0x03D1,
        upsih: 0x03D2,
        piv: 0x03D6,
        ensp: 0x2002,
        emsp: 0x2003,
        thinsp: 0x2009,
        zwnj: 0x200C,
        zwj: 0x200D,
        lrm: 0x200E,
        rlm: 0x200F,
        ndash: 0x2013,
        mdash: 0x2014,
        lsquo: 0x2018,
        rsquo: 0x2019,
        sbquo: 0x201A,
        ldquo: 0x201C,
        rdquo: 0x201D,
        bdquo: 0x201E,
        dagger: 0x2020,
        Dagger: 0x2021,
        bull: 0x2022,
        hellip: 0x2026,
        permil: 0x2030,
        prime: 0x2032,
        Prime: 0x2033,
        lsaquo: 0x2039,
        rsaquo: 0x203A,
        oline: 0x203E,
        frasl: 0x2044,
        euro: 0x20AC,
        image: 0x2111,
        weierp: 0x2118,
        real: 0x211C,
        trade: 0x2122,
        alefsym: 0x2135,
        larr: 0x2190,
        uarr: 0x2191,
        rarr: 0x2192,
        darr: 0x2193,
        harr: 0x2194,
        crarr: 0x21B5,
        lArr: 0x21D0,
        uArr: 0x21D1,
        rArr: 0x21D2,
        dArr: 0x21D3,
        hArr: 0x21D4,
        forall: 0x2200,
        part: 0x2202,
        exist: 0x2203,
        empty: 0x2205,
        nabla: 0x2207,
        isin: 0x2208,
        notin: 0x2209,
        ni: 0x220B,
        prod: 0x220F,
        sum: 0x2211,
        minus: 0x2212,
        lowast: 0x2217,
        radic: 0x221A,
        prop: 0x221D,
        infin: 0x221E,
        ang: 0x2220,
        and: 0x2227,
        or: 0x2228,
        cap: 0x2229,
        cup: 0x222A,
        int: 0x222B,
        there4: 0x2234,
        sim: 0x223C,
        cong: 0x2245,
        asymp: 0x2248,
        ne: 0x2260,
        equiv: 0x2261,
        le: 0x2264,
        ge: 0x2265,
        sub: 0x2282,
        sup: 0x2283,
        nsub: 0x2284,
        sube: 0x2286,
        supe: 0x2287,
        oplus: 0x2295,
        otimes: 0x2297,
        perp: 0x22A5,
        sdot: 0x22C5,
        lceil: 0x2308,
        rceil: 0x2309,
        lfloor: 0x230A,
        rfloor: 0x230B,
        lang: 0x2329,
        rang: 0x232A,
        loz: 0x25CA,
        spades: 0x2660,
        clubs: 0x2663,
        hearts: 0x2665,
        diams: 0x2666
    });
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2016(context) {
        var hoistVariableDeclaration = context.hoistVariableDeclaration;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 128 /* ContainsES2016 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitBinaryExpression(node) {
            switch (node.operatorToken.kind) {
                case 66 /* AsteriskAsteriskEqualsToken */:
                    return visitExponentiationAssignmentExpression(node);
                case 42 /* AsteriskAsteriskToken */:
                    return visitExponentiationExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitExponentiationAssignmentExpression(node) {
            var target;
            var value;
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = ts.visitNode(node.right, visitor, ts.isExpression);
            if (ts.isElementAccessExpression(left)) {
                // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                var argumentExpressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                target = ts.setTextRange(ts.createElementAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), ts.setTextRange(ts.createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)), left);
                value = ts.setTextRange(ts.createElementAccess(expressionTemp, argumentExpressionTemp), left);
            }
            else if (ts.isPropertyAccessExpression(left)) {
                // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                target = ts.setTextRange(ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), left.name), left);
                value = ts.setTextRange(ts.createPropertyAccess(expressionTemp, left.name), left);
            }
            else {
                // Transforms `a **= b` into `a = Math.pow(a, b)`
                target = left;
                value = left;
            }
            return ts.setTextRange(ts.createAssignment(target, ts.createMathPow(value, right, /*location*/ node)), node);
        }
        function visitExponentiationExpression(node) {
            // Transforms `a ** b` into `Math.pow(a, b)`
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = ts.visitNode(node.right, visitor, ts.isExpression);
            return ts.createMathPow(left, right, /*location*/ node);
        }
    }
    ts.transformES2016 = transformES2016;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ES2015SubstitutionFlags;
    (function (ES2015SubstitutionFlags) {
        /** Enables substitutions for captured `this` */
        ES2015SubstitutionFlags[ES2015SubstitutionFlags["CapturedThis"] = 1] = "CapturedThis";
        /** Enables substitutions for block-scoped bindings. */
        ES2015SubstitutionFlags[ES2015SubstitutionFlags["BlockScopedBindings"] = 2] = "BlockScopedBindings";
    })(ES2015SubstitutionFlags || (ES2015SubstitutionFlags = {}));
    var LoopOutParameterFlags;
    (function (LoopOutParameterFlags) {
        LoopOutParameterFlags[LoopOutParameterFlags["Body"] = 1] = "Body";
        LoopOutParameterFlags[LoopOutParameterFlags["Initializer"] = 2] = "Initializer";
    })(LoopOutParameterFlags || (LoopOutParameterFlags = {}));
    var CopyDirection;
    (function (CopyDirection) {
        CopyDirection[CopyDirection["ToOriginal"] = 0] = "ToOriginal";
        CopyDirection[CopyDirection["ToOutParameter"] = 1] = "ToOutParameter";
    })(CopyDirection || (CopyDirection = {}));
    var Jump;
    (function (Jump) {
        Jump[Jump["Break"] = 2] = "Break";
        Jump[Jump["Continue"] = 4] = "Continue";
        Jump[Jump["Return"] = 8] = "Return";
    })(Jump || (Jump = {}));
    // Facts we track as we traverse the tree
    var HierarchyFacts;
    (function (HierarchyFacts) {
        HierarchyFacts[HierarchyFacts["None"] = 0] = "None";
        //
        // Ancestor facts
        //
        HierarchyFacts[HierarchyFacts["Function"] = 1] = "Function";
        HierarchyFacts[HierarchyFacts["ArrowFunction"] = 2] = "ArrowFunction";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBody"] = 4] = "AsyncFunctionBody";
        HierarchyFacts[HierarchyFacts["NonStaticClassElement"] = 8] = "NonStaticClassElement";
        HierarchyFacts[HierarchyFacts["CapturesThis"] = 16] = "CapturesThis";
        HierarchyFacts[HierarchyFacts["ExportedVariableStatement"] = 32] = "ExportedVariableStatement";
        HierarchyFacts[HierarchyFacts["TopLevel"] = 64] = "TopLevel";
        HierarchyFacts[HierarchyFacts["Block"] = 128] = "Block";
        HierarchyFacts[HierarchyFacts["IterationStatement"] = 256] = "IterationStatement";
        HierarchyFacts[HierarchyFacts["IterationStatementBlock"] = 512] = "IterationStatementBlock";
        HierarchyFacts[HierarchyFacts["IterationContainer"] = 1024] = "IterationContainer";
        HierarchyFacts[HierarchyFacts["ForStatement"] = 2048] = "ForStatement";
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatement"] = 4096] = "ForInOrForOfStatement";
        HierarchyFacts[HierarchyFacts["ConstructorWithCapturedSuper"] = 8192] = "ConstructorWithCapturedSuper";
        // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below.
        // NOTE: when adding a new ancestor flag, be sure to update the subtree flags below.
        //
        // Ancestor masks
        //
        HierarchyFacts[HierarchyFacts["AncestorFactsMask"] = 16383] = "AncestorFactsMask";
        // We are always in *some* kind of block scope, but only specific block-scope containers are
        // top-level or Blocks.
        HierarchyFacts[HierarchyFacts["BlockScopeIncludes"] = 0] = "BlockScopeIncludes";
        HierarchyFacts[HierarchyFacts["BlockScopeExcludes"] = 7104] = "BlockScopeExcludes";
        // A source file is a top-level block scope.
        HierarchyFacts[HierarchyFacts["SourceFileIncludes"] = 64] = "SourceFileIncludes";
        HierarchyFacts[HierarchyFacts["SourceFileExcludes"] = 8064] = "SourceFileExcludes";
        // Functions, methods, and accessors are both new lexical scopes and new block scopes.
        HierarchyFacts[HierarchyFacts["FunctionIncludes"] = 65] = "FunctionIncludes";
        HierarchyFacts[HierarchyFacts["FunctionExcludes"] = 16286] = "FunctionExcludes";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyIncludes"] = 69] = "AsyncFunctionBodyIncludes";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyExcludes"] = 16278] = "AsyncFunctionBodyExcludes";
        // Arrow functions are lexically scoped to their container, but are new block scopes.
        HierarchyFacts[HierarchyFacts["ArrowFunctionIncludes"] = 66] = "ArrowFunctionIncludes";
        HierarchyFacts[HierarchyFacts["ArrowFunctionExcludes"] = 15232] = "ArrowFunctionExcludes";
        // Constructors are both new lexical scopes and new block scopes. Constructors are also
        // always considered non-static members of a class.
        HierarchyFacts[HierarchyFacts["ConstructorIncludes"] = 73] = "ConstructorIncludes";
        HierarchyFacts[HierarchyFacts["ConstructorExcludes"] = 16278] = "ConstructorExcludes";
        // 'do' and 'while' statements are not block scopes. We track that the subtree is contained
        // within an IterationStatement to indicate whether the embedded statement is an
        // IterationStatementBlock.
        HierarchyFacts[HierarchyFacts["DoOrWhileStatementIncludes"] = 1280] = "DoOrWhileStatementIncludes";
        HierarchyFacts[HierarchyFacts["DoOrWhileStatementExcludes"] = 0] = "DoOrWhileStatementExcludes";
        // 'for' statements are new block scopes and have special handling for 'let' declarations.
        HierarchyFacts[HierarchyFacts["ForStatementIncludes"] = 3328] = "ForStatementIncludes";
        HierarchyFacts[HierarchyFacts["ForStatementExcludes"] = 5056] = "ForStatementExcludes";
        // 'for-in' and 'for-of' statements are new block scopes and have special handling for
        // 'let' declarations.
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementIncludes"] = 5376] = "ForInOrForOfStatementIncludes";
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementExcludes"] = 3008] = "ForInOrForOfStatementExcludes";
        // Blocks (other than function bodies) are new block scopes.
        HierarchyFacts[HierarchyFacts["BlockIncludes"] = 128] = "BlockIncludes";
        HierarchyFacts[HierarchyFacts["BlockExcludes"] = 6976] = "BlockExcludes";
        HierarchyFacts[HierarchyFacts["IterationStatementBlockIncludes"] = 512] = "IterationStatementBlockIncludes";
        HierarchyFacts[HierarchyFacts["IterationStatementBlockExcludes"] = 7104] = "IterationStatementBlockExcludes";
        //
        // Subtree facts
        //
        HierarchyFacts[HierarchyFacts["NewTarget"] = 16384] = "NewTarget";
        HierarchyFacts[HierarchyFacts["CapturedLexicalThis"] = 32768] = "CapturedLexicalThis";
        //
        // Subtree masks
        //
        HierarchyFacts[HierarchyFacts["SubtreeFactsMask"] = -16384] = "SubtreeFactsMask";
        HierarchyFacts[HierarchyFacts["ArrowFunctionSubtreeExcludes"] = 0] = "ArrowFunctionSubtreeExcludes";
        HierarchyFacts[HierarchyFacts["FunctionSubtreeExcludes"] = 49152] = "FunctionSubtreeExcludes";
    })(HierarchyFacts || (HierarchyFacts = {}));
    function transformES2015(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        var currentSourceFile;
        var currentText;
        var hierarchyFacts;
        var taggedTemplateStringDeclarations;
        function recordTaggedTemplateString(temp) {
            taggedTemplateStringDeclarations = ts.append(taggedTemplateStringDeclarations, ts.createVariableDeclaration(temp));
        }
        /**
         * Used to track if we are emitting body of the converted loop
         */
        var convertedLoopState;
        /**
         * Keeps track of whether substitutions have been enabled for specific cases.
         * They are persisted between each SourceFile transformation and should not
         * be reset.
         */
        var enabledSubstitutions;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            currentText = node.text;
            var visited = visitSourceFile(node);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            currentText = undefined;
            taggedTemplateStringDeclarations = undefined;
            hierarchyFacts = 0 /* None */;
            return visited;
        }
        /**
         * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification.
         * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree.
         * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree.
         */
        function enterSubtree(excludeFacts, includeFacts) {
            var ancestorFacts = hierarchyFacts;
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 16383 /* AncestorFactsMask */;
            return ancestorFacts;
        }
        /**
         * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's
         * subtree, propagating specific facts from the subtree.
         * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree.
         * @param excludeFacts The existing `HierarchyFacts` of the subtree that should not be propagated.
         * @param includeFacts The new `HierarchyFacts` of the subtree that should be propagated.
         */
        function exitSubtree(ancestorFacts, excludeFacts, includeFacts) {
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & -16384 /* SubtreeFactsMask */ | ancestorFacts;
        }
        function isReturnVoidStatementInConstructorWithCapturedSuper(node) {
            return (hierarchyFacts & 8192 /* ConstructorWithCapturedSuper */) !== 0
                && node.kind === 235 /* ReturnStatement */
                && !node.expression;
        }
        function shouldVisitNode(node) {
            return (node.transformFlags & 256 /* ContainsES2015 */) !== 0
                || convertedLoopState !== undefined
                || (hierarchyFacts & 8192 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 223 /* Block */)))
                || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatement(node))
                || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0;
        }
        function visitor(node) {
            if (shouldVisitNode(node)) {
                return visitJavaScript(node);
            }
            else {
                return node;
            }
        }
        function callExpressionVisitor(node) {
            if (node.kind === 102 /* SuperKeyword */) {
                return visitSuperKeyword(/*isExpressionOfCall*/ true);
            }
            return visitor(node);
        }
        function visitJavaScript(node) {
            switch (node.kind) {
                case 120 /* StaticKeyword */:
                    return undefined; // elide static keyword
                case 245 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 214 /* ClassExpression */:
                    return visitClassExpression(node);
                case 156 /* Parameter */:
                    return visitParameter(node);
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 202 /* ArrowFunction */:
                    return visitArrowFunction(node);
                case 201 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 242 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 75 /* Identifier */:
                    return visitIdentifier(node);
                case 243 /* VariableDeclarationList */:
                    return visitVariableDeclarationList(node);
                case 237 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 251 /* CaseBlock */:
                    return visitCaseBlock(node);
                case 223 /* Block */:
                    return visitBlock(node, /*isFunctionBody*/ false);
                case 234 /* BreakStatement */:
                case 233 /* ContinueStatement */:
                    return visitBreakOrContinueStatement(node);
                case 238 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                    return visitDoOrWhileStatement(node, /*outermostLabeledStatement*/ undefined);
                case 230 /* ForStatement */:
                    return visitForStatement(node, /*outermostLabeledStatement*/ undefined);
                case 231 /* ForInStatement */:
                    return visitForInStatement(node, /*outermostLabeledStatement*/ undefined);
                case 232 /* ForOfStatement */:
                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
                case 226 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 193 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 280 /* CatchClause */:
                    return visitCatchClause(node);
                case 282 /* ShorthandPropertyAssignment */:
                    return visitShorthandPropertyAssignment(node);
                case 154 /* ComputedPropertyName */:
                    return visitComputedPropertyName(node);
                case 192 /* ArrayLiteralExpression */:
                    return visitArrayLiteralExpression(node);
                case 196 /* CallExpression */:
                    return visitCallExpression(node);
                case 197 /* NewExpression */:
                    return visitNewExpression(node);
                case 200 /* ParenthesizedExpression */:
                    return visitParenthesizedExpression(node, /*needsDestructuringValue*/ true);
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node, /*needsDestructuringValue*/ true);
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 15 /* TemplateHead */:
                case 16 /* TemplateMiddle */:
                case 17 /* TemplateTail */:
                    return visitTemplateLiteral(node);
                case 10 /* StringLiteral */:
                    return visitStringLiteral(node);
                case 8 /* NumericLiteral */:
                    return visitNumericLiteral(node);
                case 198 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 211 /* TemplateExpression */:
                    return visitTemplateExpression(node);
                case 212 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 213 /* SpreadElement */:
                    return visitSpreadElement(node);
                case 102 /* SuperKeyword */:
                    return visitSuperKeyword(/*isExpressionOfCall*/ false);
                case 104 /* ThisKeyword */:
                    return visitThisKeyword(node);
                case 219 /* MetaProperty */:
                    return visitMetaProperty(node);
                case 161 /* MethodDeclaration */:
                    return visitMethodDeclaration(node);
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return visitAccessorDeclaration(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 235 /* ReturnStatement */:
                    return visitReturnStatement(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitSourceFile(node) {
            var ancestorFacts = enterSubtree(8064 /* SourceFileExcludes */, 64 /* SourceFileIncludes */);
            var prologue = [];
            var statements = [];
            startLexicalEnvironment();
            var statementOffset = ts.addStandardPrologue(prologue, node.statements, /*ensureUseStrict*/ false);
            statementOffset = ts.addCustomPrologue(prologue, node.statements, statementOffset, visitor);
            ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
            if (taggedTemplateStringDeclarations) {
                statements.push(ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(taggedTemplateStringDeclarations)));
            }
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureThisForNodeIfNeeded(prologue, node);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(ts.concatenate(prologue, statements)), node.statements));
        }
        function visitSwitchStatement(node) {
            if (convertedLoopState !== undefined) {
                var savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                // for switch statement allow only non-labeled break
                convertedLoopState.allowedNonLabeledJumps |= 2 /* Break */;
                var result = ts.visitEachChild(node, visitor, context);
                convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
                return result;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCaseBlock(node) {
            var ancestorFacts = enterSubtree(7104 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function returnCapturedThis(node) {
            return ts.setOriginalNode(ts.createReturn(ts.createFileLevelUniqueName("_this")), node);
        }
        function visitReturnStatement(node) {
            if (convertedLoopState) {
                convertedLoopState.nonLocalJumps |= 8 /* Return */;
                if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
                    node = returnCapturedThis(node);
                }
                return ts.createReturn(ts.createObjectLiteral([
                    ts.createPropertyAssignment(ts.createIdentifier("value"), node.expression
                        ? ts.visitNode(node.expression, visitor, ts.isExpression)
                        : ts.createVoidZero())
                ]));
            }
            else if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
                return returnCapturedThis(node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitThisKeyword(node) {
            if (hierarchyFacts & 2 /* ArrowFunction */) {
                hierarchyFacts |= 32768 /* CapturedLexicalThis */;
            }
            if (convertedLoopState) {
                if (hierarchyFacts & 2 /* ArrowFunction */) {
                    // if the enclosing function is an ArrowFunction then we use the captured 'this' keyword.
                    convertedLoopState.containsLexicalThis = true;
                    return node;
                }
                return convertedLoopState.thisName || (convertedLoopState.thisName = ts.createUniqueName("this"));
            }
            return node;
        }
        function visitIdentifier(node) {
            if (!convertedLoopState) {
                return node;
            }
            if (ts.isGeneratedIdentifier(node)) {
                return node;
            }
            if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
                return node;
            }
            return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = ts.createUniqueName("arguments"));
        }
        function visitBreakOrContinueStatement(node) {
            if (convertedLoopState) {
                // check if we can emit break/continue as is
                // it is possible if either
                //   - break/continue is labeled and label is located inside the converted loop
                //   - break/continue is non-labeled and located in non-converted loop/switch statement
                var jump = node.kind === 234 /* BreakStatement */ ? 2 /* Break */ : 4 /* Continue */;
                var canUseBreakOrContinue = (node.label && convertedLoopState.labels && convertedLoopState.labels.get(ts.idText(node.label))) ||
                    (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
                if (!canUseBreakOrContinue) {
                    var labelMarker = void 0;
                    var label = node.label;
                    if (!label) {
                        if (node.kind === 234 /* BreakStatement */) {
                            convertedLoopState.nonLocalJumps |= 2 /* Break */;
                            labelMarker = "break";
                        }
                        else {
                            convertedLoopState.nonLocalJumps |= 4 /* Continue */;
                            // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
                            labelMarker = "continue";
                        }
                    }
                    else {
                        if (node.kind === 234 /* BreakStatement */) {
                            labelMarker = "break-" + label.escapedText;
                            setLabeledJump(convertedLoopState, /*isBreak*/ true, ts.idText(label), labelMarker);
                        }
                        else {
                            labelMarker = "continue-" + label.escapedText;
                            setLabeledJump(convertedLoopState, /*isBreak*/ false, ts.idText(label), labelMarker);
                        }
                    }
                    var returnExpression = ts.createLiteral(labelMarker);
                    if (convertedLoopState.loopOutParameters.length) {
                        var outParams = convertedLoopState.loopOutParameters;
                        var expr = void 0;
                        for (var i = 0; i < outParams.length; i++) {
                            var copyExpr = copyOutParameter(outParams[i], 1 /* ToOutParameter */);
                            if (i === 0) {
                                expr = copyExpr;
                            }
                            else {
                                expr = ts.createBinary(expr, 27 /* CommaToken */, copyExpr);
                            }
                        }
                        returnExpression = ts.createBinary(expr, 27 /* CommaToken */, returnExpression);
                    }
                    return ts.createReturn(returnExpression);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a ClassDeclaration and transforms it into a variable statement.
         *
         * @param node A ClassDeclaration node.
         */
        function visitClassDeclaration(node) {
            // [source]
            //      class C { }
            //
            // [output]
            //      var C = (function () {
            //          function C() {
            //          }
            //          return C;
            //      }());
            var variable = ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ true), 
            /*type*/ undefined, transformClassLikeDeclarationToExpression(node));
            ts.setOriginalNode(variable, node);
            var statements = [];
            var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([variable]));
            ts.setOriginalNode(statement, node);
            ts.setTextRange(statement, node);
            ts.startOnNewLine(statement);
            statements.push(statement);
            // Add an `export default` statement for default exports (for `--target es5 --module es6`)
            if (ts.hasModifier(node, 1 /* Export */)) {
                var exportStatement = ts.hasModifier(node, 512 /* Default */)
                    ? ts.createExportDefault(ts.getLocalName(node))
                    : ts.createExternalModuleExport(ts.getLocalName(node));
                ts.setOriginalNode(exportStatement, statement);
                statements.push(exportStatement);
            }
            var emitFlags = ts.getEmitFlags(node);
            if ((emitFlags & 4194304 /* HasEndOfDeclarationMarker */) === 0) {
                // Add a DeclarationMarker as a marker for the end of the declaration
                statements.push(ts.createEndOfDeclarationMarker(node));
                ts.setEmitFlags(statement, emitFlags | 4194304 /* HasEndOfDeclarationMarker */);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a ClassExpression and transforms it into an expression.
         *
         * @param node A ClassExpression node.
         */
        function visitClassExpression(node) {
            // [source]
            //      C = class { }
            //
            // [output]
            //      C = (function () {
            //          function class_1() {
            //          }
            //          return class_1;
            //      }())
            return transformClassLikeDeclarationToExpression(node);
        }
        /**
         * Transforms a ClassExpression or ClassDeclaration into an expression.
         *
         * @param node A ClassExpression or ClassDeclaration node.
         */
        function transformClassLikeDeclarationToExpression(node) {
            // [source]
            //      class C extends D {
            //          constructor() {}
            //          method() {}
            //          get prop() {}
            //          set prop(v) {}
            //      }
            //
            // [output]
            //      (function (_super) {
            //          __extends(C, _super);
            //          function C() {
            //          }
            //          C.prototype.method = function () {}
            //          Object.defineProperty(C.prototype, "prop", {
            //              get: function() {},
            //              set: function() {},
            //              enumerable: true,
            //              configurable: true
            //          });
            //          return C;
            //      }(D))
            if (node.name) {
                enableSubstitutionsForBlockScopedBindings();
            }
            var extendsClauseElement = ts.getClassExtendsHeritageElement(node);
            var classFunction = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, extendsClauseElement ? [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, ts.createFileLevelUniqueName("_super"))] : [], 
            /*type*/ undefined, transformClassBody(node, extendsClauseElement));
            // To preserve the behavior of the old emitter, we explicitly indent
            // the body of the function here if it was requested in an earlier
            // transformation.
            ts.setEmitFlags(classFunction, (ts.getEmitFlags(node) & 65536 /* Indented */) | 524288 /* ReuseTempVariableScope */);
            // "inner" and "outer" below are added purely to preserve source map locations from
            // the old emitter
            var inner = ts.createPartiallyEmittedExpression(classFunction);
            inner.end = node.end;
            ts.setEmitFlags(inner, 1536 /* NoComments */);
            var outer = ts.createPartiallyEmittedExpression(inner);
            outer.end = ts.skipTrivia(currentText, node.pos);
            ts.setEmitFlags(outer, 1536 /* NoComments */);
            var result = ts.createParen(ts.createCall(outer, 
            /*typeArguments*/ undefined, extendsClauseElement
                ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)]
                : []));
            ts.addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class ");
            return result;
        }
        /**
         * Transforms a ClassExpression or ClassDeclaration into a function body.
         *
         * @param node A ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function transformClassBody(node, extendsClauseElement) {
            var statements = [];
            startLexicalEnvironment();
            addExtendsHelperIfNeeded(statements, node, extendsClauseElement);
            addConstructor(statements, node, extendsClauseElement);
            addClassMembers(statements, node);
            // Create a synthetic text range for the return statement.
            var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentText, node.members.end), 19 /* CloseBraceToken */);
            var localName = ts.getInternalName(node);
            // The following partially-emitted expression exists purely to align our sourcemap
            // emit with the original emitter.
            var outer = ts.createPartiallyEmittedExpression(localName);
            outer.end = closingBraceLocation.end;
            ts.setEmitFlags(outer, 1536 /* NoComments */);
            var statement = ts.createReturn(outer);
            statement.pos = closingBraceLocation.pos;
            ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
            statements.push(statement);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
            ts.setEmitFlags(block, 1536 /* NoComments */);
            return block;
        }
        /**
         * Adds a call to the `__extends` helper if needed for a class.
         *
         * @param statements The statements of the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function addExtendsHelperIfNeeded(statements, node, extendsClauseElement) {
            if (extendsClauseElement) {
                statements.push(ts.setTextRange(ts.createExpressionStatement(createExtendsHelper(context, ts.getInternalName(node))), 
                /*location*/ extendsClauseElement));
            }
        }
        /**
         * Adds the constructor of the class to a class body function.
         *
         * @param statements The statements of the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function addConstructor(statements, node, extendsClauseElement) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16278 /* ConstructorExcludes */, 73 /* ConstructorIncludes */);
            var constructor = ts.getFirstConstructorWithBody(node);
            var hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined);
            var constructorFunction = ts.createFunctionDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, ts.getInternalName(node), 
            /*typeParameters*/ undefined, transformConstructorParameters(constructor, hasSynthesizedSuper), 
            /*type*/ undefined, transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper));
            ts.setTextRange(constructorFunction, constructor || node);
            if (extendsClauseElement) {
                ts.setEmitFlags(constructorFunction, 8 /* CapturesThis */);
            }
            statements.push(constructorFunction);
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
        }
        /**
         * Transforms the parameters of the constructor declaration of a class.
         *
         * @param constructor The constructor for the class.
         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
         *                            synthesized `super` call.
         */
        function transformConstructorParameters(constructor, hasSynthesizedSuper) {
            // If the TypeScript transformer needed to synthesize a constructor for property
            // initializers, it would have also added a synthetic `...args` parameter and
            // `super` call.
            // If this is the case, we do not include the synthetic `...args` parameter and
            // will instead use the `arguments` object in ES5/3.
            return ts.visitParameterList(constructor && !hasSynthesizedSuper ? constructor.parameters : undefined, visitor, context)
                || [];
        }
        function createDefaultConstructorBody(node, isDerivedClass) {
            // We must be here because the user didn't write a constructor
            // but we needed to call 'super(...args)' anyway as per 14.5.14 of the ES2016 spec.
            // If that's the case we can just immediately return the result of a 'super()' call.
            var statements = [];
            resumeLexicalEnvironment();
            ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            if (isDerivedClass) {
                // return _super !== null && _super.apply(this, arguments) || this;
                statements.push(ts.createReturn(createDefaultSuperCallOrThis()));
            }
            var statementsArray = ts.createNodeArray(statements);
            ts.setTextRange(statementsArray, node.members);
            var block = ts.createBlock(statementsArray, /*multiLine*/ true);
            ts.setTextRange(block, node);
            ts.setEmitFlags(block, 1536 /* NoComments */);
            return block;
        }
        /**
         * Transforms the body of a constructor declaration of a class.
         *
         * @param constructor The constructor for the class.
         * @param node The node which contains the constructor.
         * @param extendsClauseElement The expression for the class `extends` clause.
         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
         *                            synthesized `super` call.
         */
        function transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper) {
            // determine whether the class is known syntactically to be a derived class (e.g. a
            // class that extends a value that is not syntactically known to be `null`).
            var isDerivedClass = !!extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 100 /* NullKeyword */;
            // When the subclass does not have a constructor, we synthesize a *default* constructor using the following
            // representation:
            //
            // ```
            // // es2015 (source)
            // class C extends Base { }
            //
            // // es5 (transformed)
            // var C = (function (_super) {
            //     function C() {
            //         return _super.apply(this, arguments) || this;
            //     }
            //     return C;
            // })(Base);
            // ```
            if (!constructor)
                return createDefaultConstructorBody(node, isDerivedClass);
            // The prologue will contain all leading standard and custom prologue statements added by this transform
            var prologue = [];
            var statements = [];
            resumeLexicalEnvironment();
            // If a super call has already been synthesized,
            // we're going to assume that we should just transform everything after that.
            // The assumption is that no prior step in the pipeline has added any prologue directives.
            var statementOffset = 0;
            if (!hasSynthesizedSuper)
                statementOffset = ts.addStandardPrologue(prologue, constructor.body.statements, /*ensureUseStrict*/ false);
            addDefaultValueAssignmentsIfNeeded(statements, constructor);
            addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
            if (!hasSynthesizedSuper)
                statementOffset = ts.addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor);
            // If the first statement is a call to `super()`, visit the statement directly
            var superCallExpression;
            if (hasSynthesizedSuper) {
                superCallExpression = createDefaultSuperCallOrThis();
            }
            else if (isDerivedClass && statementOffset < constructor.body.statements.length) {
                var firstStatement = constructor.body.statements[statementOffset];
                if (ts.isExpressionStatement(firstStatement) && ts.isSuperCall(firstStatement.expression)) {
                    superCallExpression = visitImmediateSuperCallInBody(firstStatement.expression);
                }
            }
            if (superCallExpression) {
                hierarchyFacts |= 8192 /* ConstructorWithCapturedSuper */;
                statementOffset++; // skip this statement, we will add it after visiting the rest of the body.
            }
            // visit the remaining statements
            ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, /*start*/ statementOffset));
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureNewTargetIfNeeded(prologue, constructor, /*copyOnWrite*/ false);
            if (isDerivedClass) {
                if (superCallExpression && statementOffset === constructor.body.statements.length && !(constructor.body.transformFlags & 4096 /* ContainsLexicalThis */)) {
                    // If the subclass constructor does *not* contain `this` and *ends* with a `super()` call, we will use the
                    // following representation:
                    //
                    // ```
                    // // es2015 (source)
                    // class C extends Base {
                    //     constructor() {
                    //         super("foo");
                    //     }
                    // }
                    //
                    // // es5 (transformed)
                    // var C = (function (_super) {
                    //     function C() {
                    //         return _super.call(this, "foo") || this;
                    //     }
                    //     return C;
                    // })(Base);
                    // ```
                    var superCall = ts.cast(ts.cast(superCallExpression, ts.isBinaryExpression).left, ts.isCallExpression);
                    var returnStatement = ts.createReturn(superCallExpression);
                    ts.setCommentRange(returnStatement, ts.getCommentRange(superCall));
                    ts.setEmitFlags(superCall, 1536 /* NoComments */);
                    statements.push(returnStatement);
                }
                else {
                    // Otherwise, we will use the following transformed representation for calls to `super()` in a constructor:
                    //
                    // ```
                    // // es2015 (source)
                    // class C extends Base {
                    //     constructor() {
                    //         super("foo");
                    //         this.x = 1;
                    //     }
                    // }
                    //
                    // // es5 (transformed)
                    // var C = (function (_super) {
                    //     function C() {
                    //         var _this = _super.call(this, "foo") || this;
                    //         _this.x = 1;
                    //         return _this;
                    //     }
                    //     return C;
                    // })(Base);
                    // ```
                    // Since the `super()` call was the first statement, we insert the `this` capturing call to
                    // `super()` at the top of the list of `statements` (after any pre-existing custom prologues).
                    insertCaptureThisForNode(statements, constructor, superCallExpression || createActualThis());
                    if (!isSufficientlyCoveredByReturnStatements(constructor.body)) {
                        statements.push(ts.createReturn(ts.createFileLevelUniqueName("_this")));
                    }
                }
            }
            else {
                // If a class is not derived from a base class or does not have a call to `super()`, `this` is only
                // captured when necessitated by an arrow function capturing the lexical `this`:
                //
                // ```
                // // es2015
                // class C {}
                //
                // // es5
                // var C = (function () {
                //     function C() {
                //     }
                //     return C;
                // })();
                // ```
                insertCaptureThisForNodeIfNeeded(prologue, constructor);
            }
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(ts.concatenate(prologue, statements)), 
            /*location*/ constructor.body.statements), 
            /*multiLine*/ true);
            ts.setTextRange(block, constructor.body);
            return block;
        }
        /**
         * We want to try to avoid emitting a return statement in certain cases if a user already returned something.
         * It would generate obviously dead code, so we'll try to make things a little bit prettier
         * by doing a minimal check on whether some common patterns always explicitly return.
         */
        function isSufficientlyCoveredByReturnStatements(statement) {
            // A return statement is considered covered.
            if (statement.kind === 235 /* ReturnStatement */) {
                return true;
            }
            // An if-statement with two covered branches is covered.
            else if (statement.kind === 227 /* IfStatement */) {
                var ifStatement = statement;
                if (ifStatement.elseStatement) {
                    return isSufficientlyCoveredByReturnStatements(ifStatement.thenStatement) &&
                        isSufficientlyCoveredByReturnStatements(ifStatement.elseStatement);
                }
            }
            // A block is covered if it has a last statement which is covered.
            else if (statement.kind === 223 /* Block */) {
                var lastStatement = ts.lastOrUndefined(statement.statements);
                if (lastStatement && isSufficientlyCoveredByReturnStatements(lastStatement)) {
                    return true;
                }
            }
            return false;
        }
        function createActualThis() {
            return ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */);
        }
        function createDefaultSuperCallOrThis() {
            return ts.createLogicalOr(ts.createLogicalAnd(ts.createStrictInequality(ts.createFileLevelUniqueName("_super"), ts.createNull()), ts.createFunctionApply(ts.createFileLevelUniqueName("_super"), createActualThis(), ts.createIdentifier("arguments"))), createActualThis());
        }
        /**
         * Visits a parameter declaration.
         *
         * @param node A ParameterDeclaration node.
         */
        function visitParameter(node) {
            if (node.dotDotDotToken) {
                // rest parameters are elided
                return undefined;
            }
            else if (ts.isBindingPattern(node.name)) {
                // Binding patterns are converted into a generated name and are
                // evaluated inside the function body.
                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, ts.getGeneratedNameForNode(node), 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined), 
                /*location*/ node), 
                /*original*/ node);
            }
            else if (node.initializer) {
                // Initializers are elided
                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, node.name, 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined), 
                /*location*/ node), 
                /*original*/ node);
            }
            else {
                return node;
            }
        }
        function hasDefaultValueOrBindingPattern(node) {
            return node.initializer !== undefined
                || ts.isBindingPattern(node.name);
        }
        /**
         * Adds statements to the body of a function-like node if it contains parameters with
         * binding patterns or initializers.
         *
         * @param statements The statements for the new function body.
         * @param node A function-like node.
         */
        function addDefaultValueAssignmentsIfNeeded(statements, node) {
            if (!ts.some(node.parameters, hasDefaultValueOrBindingPattern)) {
                return false;
            }
            var added = false;
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                var name = parameter.name, initializer = parameter.initializer, dotDotDotToken = parameter.dotDotDotToken;
                // A rest parameter cannot have a binding pattern or an initializer,
                // so let's just ignore it.
                if (dotDotDotToken) {
                    continue;
                }
                if (ts.isBindingPattern(name)) {
                    added = insertDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) || added;
                }
                else if (initializer) {
                    insertDefaultValueAssignmentForInitializer(statements, parameter, name, initializer);
                    added = true;
                }
            }
            return added;
        }
        /**
         * Adds statements to the body of a function-like node for parameters with binding patterns
         *
         * @param statements The statements for the new function body.
         * @param parameter The parameter for the function.
         * @param name The name of the parameter.
         * @param initializer The initializer for the parameter.
         */
        function insertDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) {
            // In cases where a binding pattern is simply '[]' or '{}',
            // we usually don't want to emit a var declaration; however, in the presence
            // of an initializer, we must emit that expression to preserve side effects.
            if (name.elements.length > 0) {
                ts.insertStatementAfterCustomPrologue(statements, ts.setEmitFlags(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, ts.getGeneratedNameForNode(parameter)))), 1048576 /* CustomPrologue */));
                return true;
            }
            else if (initializer) {
                ts.insertStatementAfterCustomPrologue(statements, ts.setEmitFlags(ts.createExpressionStatement(ts.createAssignment(ts.getGeneratedNameForNode(parameter), ts.visitNode(initializer, visitor, ts.isExpression))), 1048576 /* CustomPrologue */));
                return true;
            }
            return false;
        }
        /**
         * Adds statements to the body of a function-like node for parameters with initializers.
         *
         * @param statements The statements for the new function body.
         * @param parameter The parameter for the function.
         * @param name The name of the parameter.
         * @param initializer The initializer for the parameter.
         */
        function insertDefaultValueAssignmentForInitializer(statements, parameter, name, initializer) {
            initializer = ts.visitNode(initializer, visitor, ts.isExpression);
            var statement = ts.createIf(ts.createTypeCheck(ts.getSynthesizedClone(name), "undefined"), ts.setEmitFlags(ts.setTextRange(ts.createBlock([
                ts.createExpressionStatement(ts.setEmitFlags(ts.setTextRange(ts.createAssignment(ts.setEmitFlags(ts.getMutableClone(name), 48 /* NoSourceMap */), ts.setEmitFlags(initializer, 48 /* NoSourceMap */ | ts.getEmitFlags(initializer) | 1536 /* NoComments */)), parameter), 1536 /* NoComments */))
            ]), parameter), 1 /* SingleLine */ | 32 /* NoTrailingSourceMap */ | 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */));
            ts.startOnNewLine(statement);
            ts.setTextRange(statement, parameter);
            ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1048576 /* CustomPrologue */ | 1536 /* NoComments */);
            ts.insertStatementAfterCustomPrologue(statements, statement);
        }
        /**
         * Gets a value indicating whether we need to add statements to handle a rest parameter.
         *
         * @param node A ParameterDeclaration node.
         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
         *                                          part of a constructor declaration with a
         *                                          synthesized call to `super`
         */
        function shouldAddRestParameter(node, inConstructorWithSynthesizedSuper) {
            return !!(node && node.dotDotDotToken && !inConstructorWithSynthesizedSuper);
        }
        /**
         * Adds statements to the body of a function-like node if it contains a rest parameter.
         *
         * @param statements The statements for the new function body.
         * @param node A function-like node.
         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
         *                                          part of a constructor declaration with a
         *                                          synthesized call to `super`
         */
        function addRestParameterIfNeeded(statements, node, inConstructorWithSynthesizedSuper) {
            var prologueStatements = [];
            var parameter = ts.lastOrUndefined(node.parameters);
            if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) {
                return false;
            }
            // `declarationName` is the name of the local declaration for the parameter.
            var declarationName = parameter.name.kind === 75 /* Identifier */ ? ts.getMutableClone(parameter.name) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            ts.setEmitFlags(declarationName, 48 /* NoSourceMap */);
            // `expressionName` is the name of the parameter used in expressions.
            var expressionName = parameter.name.kind === 75 /* Identifier */ ? ts.getSynthesizedClone(parameter.name) : declarationName;
            var restIndex = node.parameters.length - 1;
            var temp = ts.createLoopVariable();
            // var param = [];
            prologueStatements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(declarationName, 
                /*type*/ undefined, ts.createArrayLiteral([]))
            ])), 
            /*location*/ parameter), 1048576 /* CustomPrologue */));
            // for (var _i = restIndex; _i < arguments.length; _i++) {
            //   param[_i - restIndex] = arguments[_i];
            // }
            var forStatement = ts.createFor(ts.setTextRange(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(temp, /*type*/ undefined, ts.createLiteral(restIndex))
            ]), parameter), ts.setTextRange(ts.createLessThan(temp, ts.createPropertyAccess(ts.createIdentifier("arguments"), "length")), parameter), ts.setTextRange(ts.createPostfixIncrement(temp), parameter), ts.createBlock([
                ts.startOnNewLine(ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(ts.createElementAccess(expressionName, restIndex === 0
                    ? temp
                    : ts.createSubtract(temp, ts.createLiteral(restIndex))), ts.createElementAccess(ts.createIdentifier("arguments"), temp))), 
                /*location*/ parameter))
            ]));
            ts.setEmitFlags(forStatement, 1048576 /* CustomPrologue */);
            ts.startOnNewLine(forStatement);
            prologueStatements.push(forStatement);
            if (parameter.name.kind !== 75 /* Identifier */) {
                // do the actual destructuring of the rest parameter if necessary
                prologueStatements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, expressionName))), parameter), 1048576 /* CustomPrologue */));
            }
            ts.insertStatementsAfterCustomPrologue(statements, prologueStatements);
            return true;
        }
        /**
         * Adds a statement to capture the `this` of a function declaration if it is needed.
         * NOTE: This must be executed *after* the subtree has been visited.
         *
         * @param statements The statements for the new function body.
         * @param node A node.
         */
        function insertCaptureThisForNodeIfNeeded(statements, node) {
            if (hierarchyFacts & 32768 /* CapturedLexicalThis */ && node.kind !== 202 /* ArrowFunction */) {
                insertCaptureThisForNode(statements, node, ts.createThis());
                return true;
            }
            return false;
        }
        function insertCaptureThisForNode(statements, node, initializer) {
            enableSubstitutionsForCapturedThis();
            var captureThisStatement = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(ts.createFileLevelUniqueName("_this"), 
                /*type*/ undefined, initializer)
            ]));
            ts.setEmitFlags(captureThisStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */);
            ts.setSourceMapRange(captureThisStatement, node);
            ts.insertStatementAfterCustomPrologue(statements, captureThisStatement);
        }
        function insertCaptureNewTargetIfNeeded(statements, node, copyOnWrite) {
            if (hierarchyFacts & 16384 /* NewTarget */) {
                var newTarget = void 0;
                switch (node.kind) {
                    case 202 /* ArrowFunction */:
                        return statements;
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        // Methods and accessors cannot be constructors, so 'new.target' will
                        // always return 'undefined'.
                        newTarget = ts.createVoidZero();
                        break;
                    case 162 /* Constructor */:
                        // Class constructors can only be called with `new`, so `this.constructor`
                        // should be relatively safe to use.
                        newTarget = ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor");
                        break;
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                        // Functions can be called or constructed, and may have a `this` due to
                        // being a member or when calling an imported function via `other_1.f()`.
                        newTarget = ts.createConditional(ts.createLogicalAnd(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), ts.createBinary(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), 98 /* InstanceOfKeyword */, ts.getLocalName(node))), ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor"), ts.createVoidZero());
                        break;
                    default:
                        return ts.Debug.failBadSyntaxKind(node);
                }
                var captureNewTargetStatement = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(ts.createFileLevelUniqueName("_newTarget"), 
                    /*type*/ undefined, newTarget)
                ]));
                ts.setEmitFlags(captureNewTargetStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */);
                if (copyOnWrite) {
                    statements = statements.slice();
                }
                ts.insertStatementAfterCustomPrologue(statements, captureNewTargetStatement);
            }
            return statements;
        }
        /**
         * Adds statements to the class body function for a class to define the members of the
         * class.
         *
         * @param statements The statements for the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         */
        function addClassMembers(statements, node) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                switch (member.kind) {
                    case 222 /* SemicolonClassElement */:
                        statements.push(transformSemicolonClassElementToStatement(member));
                        break;
                    case 161 /* MethodDeclaration */:
                        statements.push(transformClassMethodDeclarationToStatement(getClassMemberPrefix(node, member), member, node));
                        break;
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        var accessors = ts.getAllAccessorDeclarations(node.members, member);
                        if (member === accessors.firstAccessor) {
                            statements.push(transformAccessorsToStatement(getClassMemberPrefix(node, member), accessors, node));
                        }
                        break;
                    case 162 /* Constructor */:
                        // Constructors are handled in visitClassExpression/visitClassDeclaration
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(member, currentSourceFile && currentSourceFile.fileName);
                        break;
                }
            }
        }
        /**
         * Transforms a SemicolonClassElement into a statement for a class body function.
         *
         * @param member The SemicolonClassElement node.
         */
        function transformSemicolonClassElementToStatement(member) {
            return ts.setTextRange(ts.createEmptyStatement(), member);
        }
        /**
         * Transforms a MethodDeclaration into a statement for a class body function.
         *
         * @param receiver The receiver for the member.
         * @param member The MethodDeclaration node.
         */
        function transformClassMethodDeclarationToStatement(receiver, member, container) {
            var commentRange = ts.getCommentRange(member);
            var sourceMapRange = ts.getSourceMapRange(member);
            var memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container);
            var propertyName = ts.visitNode(member.name, visitor, ts.isPropertyName);
            var e;
            if (!ts.isPrivateIdentifier(propertyName) && context.getCompilerOptions().useDefineForClassFields) {
                var name = ts.isComputedPropertyName(propertyName) ? propertyName.expression
                    : ts.isIdentifier(propertyName) ? ts.createStringLiteral(ts.unescapeLeadingUnderscores(propertyName.escapedText))
                        : propertyName;
                e = ts.createObjectDefinePropertyCall(receiver, name, ts.createPropertyDescriptor({ value: memberFunction, enumerable: false, writable: true, configurable: true }));
            }
            else {
                var memberName = ts.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ member.name);
                e = ts.createAssignment(memberName, memberFunction);
            }
            ts.setEmitFlags(memberFunction, 1536 /* NoComments */);
            ts.setSourceMapRange(memberFunction, sourceMapRange);
            var statement = ts.setTextRange(ts.createExpressionStatement(e), /*location*/ member);
            ts.setOriginalNode(statement, member);
            ts.setCommentRange(statement, commentRange);
            // The location for the statement is used to emit comments only.
            // No source map should be emitted for this statement to align with the
            // old emitter.
            ts.setEmitFlags(statement, 48 /* NoSourceMap */);
            return statement;
        }
        /**
         * Transforms a set of related of get/set accessors into a statement for a class body function.
         *
         * @param receiver The receiver for the member.
         * @param accessors The set of related get/set accessors.
         */
        function transformAccessorsToStatement(receiver, accessors, container) {
            var statement = ts.createExpressionStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false));
            // The location for the statement is used to emit source maps only.
            // No comments should be emitted for this statement to align with the
            // old emitter.
            ts.setEmitFlags(statement, 1536 /* NoComments */);
            ts.setSourceMapRange(statement, ts.getSourceMapRange(accessors.firstAccessor));
            return statement;
        }
        /**
         * Transforms a set of related get/set accessors into an expression for either a class
         * body function or an ObjectLiteralExpression with computed properties.
         *
         * @param receiver The receiver for the member.
         */
        function transformAccessorsToExpression(receiver, _a, container, startsOnNewLine) {
            var firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
            // To align with source maps in the old emitter, the receiver and property name
            // arguments are both mapped contiguously to the accessor name.
            var target = ts.getMutableClone(receiver);
            ts.setEmitFlags(target, 1536 /* NoComments */ | 32 /* NoTrailingSourceMap */);
            ts.setSourceMapRange(target, firstAccessor.name);
            var visitedAccessorName = ts.visitNode(firstAccessor.name, visitor, ts.isPropertyName);
            if (ts.isPrivateIdentifier(visitedAccessorName)) {
                return ts.Debug.failBadSyntaxKind(visitedAccessorName, "Encountered unhandled private identifier while transforming ES2015.");
            }
            var propertyName = ts.createExpressionForPropertyName(visitedAccessorName);
            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 16 /* NoLeadingSourceMap */);
            ts.setSourceMapRange(propertyName, firstAccessor.name);
            var properties = [];
            if (getAccessor) {
                var getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined, container);
                ts.setSourceMapRange(getterFunction, ts.getSourceMapRange(getAccessor));
                ts.setEmitFlags(getterFunction, 512 /* NoLeadingComments */);
                var getter = ts.createPropertyAssignment("get", getterFunction);
                ts.setCommentRange(getter, ts.getCommentRange(getAccessor));
                properties.push(getter);
            }
            if (setAccessor) {
                var setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined, container);
                ts.setSourceMapRange(setterFunction, ts.getSourceMapRange(setAccessor));
                ts.setEmitFlags(setterFunction, 512 /* NoLeadingComments */);
                var setter = ts.createPropertyAssignment("set", setterFunction);
                ts.setCommentRange(setter, ts.getCommentRange(setAccessor));
                properties.push(setter);
            }
            properties.push(ts.createPropertyAssignment("enumerable", getAccessor || setAccessor ? ts.createFalse() : ts.createTrue()), ts.createPropertyAssignment("configurable", ts.createTrue()));
            var call = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                target,
                propertyName,
                ts.createObjectLiteral(properties, /*multiLine*/ true)
            ]);
            if (startsOnNewLine) {
                ts.startOnNewLine(call);
            }
            return call;
        }
        /**
         * Visits an ArrowFunction and transforms it into a FunctionExpression.
         *
         * @param node An ArrowFunction node.
         */
        function visitArrowFunction(node) {
            if (node.transformFlags & 4096 /* ContainsLexicalThis */) {
                hierarchyFacts |= 32768 /* CapturedLexicalThis */;
            }
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(15232 /* ArrowFunctionExcludes */, 66 /* ArrowFunctionIncludes */);
            var func = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, transformFunctionBody(node));
            ts.setTextRange(func, node);
            ts.setOriginalNode(func, node);
            ts.setEmitFlags(func, 8 /* CapturesThis */);
            if (hierarchyFacts & 32768 /* CapturedLexicalThis */) {
                enableSubstitutionsForCapturedThis();
            }
            // If an arrow function contains
            exitSubtree(ancestorFacts, 0 /* ArrowFunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return func;
        }
        /**
         * Visits a FunctionExpression node.
         *
         * @param node a FunctionExpression node.
         */
        function visitFunctionExpression(node) {
            var ancestorFacts = ts.getEmitFlags(node) & 262144 /* AsyncFunctionBody */
                ? enterSubtree(16278 /* AsyncFunctionBodyExcludes */, 69 /* AsyncFunctionBodyIncludes */)
                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            var name = hierarchyFacts & 16384 /* NewTarget */
                ? ts.getLocalName(node)
                : node.name;
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.updateFunctionExpression(node, 
            /*modifiers*/ undefined, node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body);
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * @param node a FunctionDeclaration node.
         */
        function visitFunctionDeclaration(node) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            var name = hierarchyFacts & 16384 /* NewTarget */
                ? ts.getLocalName(node)
                : node.name;
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body);
        }
        /**
         * Transforms a function-like node into a FunctionExpression.
         *
         * @param node The function-like node to transform.
         * @param location The source-map location for the new FunctionExpression.
         * @param name The name of the new FunctionExpression.
         */
        function transformFunctionLikeToExpression(node, location, name, container) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = container && ts.isClassLike(container) && !ts.hasModifier(node, 32 /* Static */)
                ? enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */ | 8 /* NonStaticClassElement */)
                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            if (hierarchyFacts & 16384 /* NewTarget */ && !name && (node.kind === 244 /* FunctionDeclaration */ || node.kind === 201 /* FunctionExpression */)) {
                name = ts.getGeneratedNameForNode(node);
            }
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
            /*modifiers*/ undefined, node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body), location), 
            /*original*/ node);
        }
        /**
         * Transforms the body of a function-like node.
         *
         * @param node A function-like node.
         */
        function transformFunctionBody(node) {
            var multiLine = false; // indicates whether the block *must* be emitted as multiple lines
            var singleLine = false; // indicates whether the block *may* be emitted as a single line
            var statementsLocation;
            var closeBraceLocation;
            var prologue = [];
            var statements = [];
            var body = node.body;
            var statementOffset;
            resumeLexicalEnvironment();
            if (ts.isBlock(body)) {
                // ensureUseStrict is false because no new prologue-directive should be added.
                // addStandardPrologue will put already-existing directives at the beginning of the target statement-array
                statementOffset = ts.addStandardPrologue(prologue, body.statements, /*ensureUseStrict*/ false);
                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor, ts.isHoistedFunction);
                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor, ts.isHoistedVariableStatement);
            }
            multiLine = addDefaultValueAssignmentsIfNeeded(statements, node) || multiLine;
            multiLine = addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false) || multiLine;
            if (ts.isBlock(body)) {
                // addCustomPrologue puts already-existing directives at the beginning of the target statement-array
                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor);
                statementsLocation = body.statements;
                ts.addRange(statements, ts.visitNodes(body.statements, visitor, ts.isStatement, statementOffset));
                // If the original body was a multi-line block, this must be a multi-line block.
                if (!multiLine && body.multiLine) {
                    multiLine = true;
                }
            }
            else {
                ts.Debug.assert(node.kind === 202 /* ArrowFunction */);
                // To align with the old emitter, we use a synthetic end position on the location
                // for the statement list we synthesize when we down-level an arrow function with
                // an expression function body. This prevents both comments and source maps from
                // being emitted for the end position only.
                statementsLocation = ts.moveRangeEnd(body, -1);
                var equalsGreaterThanToken = node.equalsGreaterThanToken;
                if (!ts.nodeIsSynthesized(equalsGreaterThanToken) && !ts.nodeIsSynthesized(body)) {
                    if (ts.rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) {
                        singleLine = true;
                    }
                    else {
                        multiLine = true;
                    }
                }
                var expression = ts.visitNode(body, visitor, ts.isExpression);
                var returnStatement = ts.createReturn(expression);
                ts.setTextRange(returnStatement, body);
                ts.moveSyntheticComments(returnStatement, body);
                ts.setEmitFlags(returnStatement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1024 /* NoTrailingComments */);
                statements.push(returnStatement);
                // To align with the source map emit for the old emitter, we set a custom
                // source map location for the close brace.
                closeBraceLocation = body;
            }
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureNewTargetIfNeeded(prologue, node, /*copyOnWrite*/ false);
            insertCaptureThisForNodeIfNeeded(prologue, node);
            // If we added any final generated statements, this must be a multi-line block
            if (ts.some(prologue)) {
                multiLine = true;
            }
            statements.unshift.apply(statements, prologue);
            if (ts.isBlock(body) && ts.arrayIsEqualTo(statements, body.statements)) {
                // no changes were made, preserve the tree
                return body;
            }
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), multiLine);
            ts.setTextRange(block, node.body);
            if (!multiLine && singleLine) {
                ts.setEmitFlags(block, 1 /* SingleLine */);
            }
            if (closeBraceLocation) {
                ts.setTokenSourceMapRange(block, 19 /* CloseBraceToken */, closeBraceLocation);
            }
            ts.setOriginalNode(block, node.body);
            return block;
        }
        function visitBlock(node, isFunctionBody) {
            if (isFunctionBody) {
                // A function body is not a block scope.
                return ts.visitEachChild(node, visitor, context);
            }
            var ancestorFacts = hierarchyFacts & 256 /* IterationStatement */
                ? enterSubtree(7104 /* IterationStatementBlockExcludes */, 512 /* IterationStatementBlockIncludes */)
                : enterSubtree(6976 /* BlockExcludes */, 128 /* BlockIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        /**
         * Visits an ExpressionStatement that contains a destructuring assignment.
         *
         * @param node An ExpressionStatement node.
         */
        function visitExpressionStatement(node) {
            // If we are here it is most likely because our expression is a destructuring assignment.
            switch (node.expression.kind) {
                case 200 /* ParenthesizedExpression */:
                    return ts.updateExpressionStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
                case 209 /* BinaryExpression */:
                    return ts.updateExpressionStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a ParenthesizedExpression that may contain a destructuring assignment.
         *
         * @param node A ParenthesizedExpression node.
         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
         *                                of a destructuring assignment.
         */
        function visitParenthesizedExpression(node, needsDestructuringValue) {
            // If we are here it is most likely because our expression is a destructuring assignment.
            if (!needsDestructuringValue) {
                // By default we always emit the RHS at the end of a flattened destructuring
                // expression. If we are in a state where we do not need the destructuring value,
                // we pass that information along to the children that care about it.
                switch (node.expression.kind) {
                    case 200 /* ParenthesizedExpression */:
                        return ts.updateParen(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
                    case 209 /* BinaryExpression */:
                        return ts.updateParen(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a BinaryExpression that contains a destructuring assignment.
         *
         * @param node A BinaryExpression node.
         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
         *                                of a destructuring assignment.
         */
        function visitBinaryExpression(node, needsDestructuringValue) {
            // If we are here it is because this is a destructuring assignment.
            if (ts.isDestructuringAssignment(node)) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, needsDestructuringValue);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function isVariableStatementOfTypeScriptClassWrapper(node) {
            return node.declarationList.declarations.length === 1
                && !!node.declarationList.declarations[0].initializer
                && !!(ts.getEmitFlags(node.declarationList.declarations[0].initializer) & 33554432 /* TypeScriptClassWrapper */);
        }
        function visitVariableStatement(node) {
            var ancestorFacts = enterSubtree(0 /* None */, ts.hasModifier(node, 1 /* Export */) ? 32 /* ExportedVariableStatement */ : 0 /* None */);
            var updated;
            if (convertedLoopState && (node.declarationList.flags & 3 /* BlockScoped */) === 0 && !isVariableStatementOfTypeScriptClassWrapper(node)) {
                // we are inside a converted loop - hoist variable declarations
                var assignments = void 0;
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl);
                    if (decl.initializer) {
                        var assignment = void 0;
                        if (ts.isBindingPattern(decl.name)) {
                            assignment = ts.flattenDestructuringAssignment(decl, visitor, context, 0 /* All */);
                        }
                        else {
                            assignment = ts.createBinary(decl.name, 62 /* EqualsToken */, ts.visitNode(decl.initializer, visitor, ts.isExpression));
                            ts.setTextRange(assignment, decl);
                        }
                        assignments = ts.append(assignments, assignment);
                    }
                }
                if (assignments) {
                    updated = ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(assignments)), node);
                }
                else {
                    // none of declarations has initializer - the entire variable statement can be deleted
                    updated = undefined;
                }
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        /**
         * Visits a VariableDeclarationList that is block scoped (e.g. `let` or `const`).
         *
         * @param node A VariableDeclarationList node.
         */
        function visitVariableDeclarationList(node) {
            if (node.flags & 3 /* BlockScoped */ || node.transformFlags & 131072 /* ContainsBindingPattern */) {
                if (node.flags & 3 /* BlockScoped */) {
                    enableSubstitutionsForBlockScopedBindings();
                }
                var declarations = ts.flatMap(node.declarations, node.flags & 1 /* Let */
                    ? visitVariableDeclarationInLetDeclarationList
                    : visitVariableDeclaration);
                var declarationList = ts.createVariableDeclarationList(declarations);
                ts.setOriginalNode(declarationList, node);
                ts.setTextRange(declarationList, node);
                ts.setCommentRange(declarationList, node);
                // If the first or last declaration is a binding pattern, we need to modify
                // the source map range for the declaration list.
                if (node.transformFlags & 131072 /* ContainsBindingPattern */
                    && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.last(node.declarations).name))) {
                    ts.setSourceMapRange(declarationList, getRangeUnion(declarations));
                }
                return declarationList;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function getRangeUnion(declarations) {
            // declarations may not be sorted by position.
            // pos should be the minimum* position over all nodes (that's not -1), end should be the maximum end over all nodes.
            var pos = -1, end = -1;
            for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) {
                var node = declarations_10[_i];
                pos = pos === -1 ? node.pos : node.pos === -1 ? pos : Math.min(pos, node.pos);
                end = Math.max(end, node.end);
            }
            return ts.createRange(pos, end);
        }
        /**
         * Gets a value indicating whether we should emit an explicit initializer for a variable
         * declaration in a `let` declaration list.
         *
         * @param node A VariableDeclaration node.
         */
        function shouldEmitExplicitInitializerForLetDeclaration(node) {
            // Nested let bindings might need to be initialized explicitly to preserve
            // ES6 semantic:
            //
            //  { let x = 1; }
            //  { let x; } // x here should be undefined. not 1
            //
            // Top level bindings never collide with anything and thus don't require
            // explicit initialization. As for nested let bindings there are two cases:
            //
            // - Nested let bindings that were not renamed definitely should be
            //   initialized explicitly:
            //
            //    { let x = 1; }
            //    { let x; if (some-condition) { x = 1}; if (x) { /*1*/ } }
            //
            //   Without explicit initialization code in /*1*/ can be executed even if
            //   some-condition is evaluated to false.
            //
            // - Renaming introduces fresh name that should not collide with any
            //   existing names, however renamed bindings sometimes also should be
            //   explicitly initialized. One particular case: non-captured binding
            //   declared inside loop body (but not in loop initializer):
            //
            //    let x;
            //    for (;;) {
            //        let x;
            //    }
            //
            //   In downlevel codegen inner 'x' will be renamed so it won't collide
            //   with outer 'x' however it will should be reset on every iteration as
            //   if it was declared anew.
            //
            //   * Why non-captured binding?
            //     - Because if loop contains block scoped binding captured in some
            //       function then loop body will be rewritten to have a fresh scope
            //       on every iteration so everything will just work.
            //
            //   * Why loop initializer is excluded?
            //     - Since we've introduced a fresh name it already will be undefined.
            var flags = resolver.getNodeCheckFlags(node);
            var isCapturedInFunction = flags & 262144 /* CapturedBlockScopedBinding */;
            var isDeclaredInLoop = flags & 524288 /* BlockScopedBindingInLoop */;
            var emittedAsTopLevel = (hierarchyFacts & 64 /* TopLevel */) !== 0
                || (isCapturedInFunction
                    && isDeclaredInLoop
                    && (hierarchyFacts & 512 /* IterationStatementBlock */) !== 0);
            var emitExplicitInitializer = !emittedAsTopLevel
                && (hierarchyFacts & 4096 /* ForInOrForOfStatement */) === 0
                && (!resolver.isDeclarationWithCollidingName(node)
                    || (isDeclaredInLoop
                        && !isCapturedInFunction
                        && (hierarchyFacts & (2048 /* ForStatement */ | 4096 /* ForInOrForOfStatement */)) === 0));
            return emitExplicitInitializer;
        }
        /**
         * Visits a VariableDeclaration in a `let` declaration list.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclarationInLetDeclarationList(node) {
            // For binding pattern names that lack initializers there is no point to emit
            // explicit initializer since downlevel codegen for destructuring will fail
            // in the absence of initializer so all binding elements will say uninitialized
            var name = node.name;
            if (ts.isBindingPattern(name)) {
                return visitVariableDeclaration(node);
            }
            if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
                var clone_3 = ts.getMutableClone(node);
                clone_3.initializer = ts.createVoidZero();
                return clone_3;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a VariableDeclaration node with a binding pattern.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclaration(node) {
            var ancestorFacts = enterSubtree(32 /* ExportedVariableStatement */, 0 /* None */);
            var updated;
            if (ts.isBindingPattern(node.name)) {
                updated = ts.flattenDestructuringBinding(node, visitor, context, 0 /* All */, 
                /*value*/ undefined, (ancestorFacts & 32 /* ExportedVariableStatement */) !== 0);
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function recordLabel(node) {
            convertedLoopState.labels.set(ts.idText(node.label), true);
        }
        function resetLabel(node) {
            convertedLoopState.labels.set(ts.idText(node.label), false);
        }
        function visitLabeledStatement(node) {
            if (convertedLoopState && !convertedLoopState.labels) {
                convertedLoopState.labels = ts.createMap();
            }
            var statement = ts.unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
            return ts.isIterationStatement(statement, /*lookInLabeledStatements*/ false)
                ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node)
                : ts.restoreEnclosingLabel(ts.visitNode(statement, visitor, ts.isStatement, ts.liftToBlock), node, convertedLoopState && resetLabel);
        }
        function visitIterationStatement(node, outermostLabeledStatement) {
            switch (node.kind) {
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                    return visitDoOrWhileStatement(node, outermostLabeledStatement);
                case 230 /* ForStatement */:
                    return visitForStatement(node, outermostLabeledStatement);
                case 231 /* ForInStatement */:
                    return visitForInStatement(node, outermostLabeledStatement);
                case 232 /* ForOfStatement */:
                    return visitForOfStatement(node, outermostLabeledStatement);
            }
        }
        function visitIterationStatementWithFacts(excludeFacts, includeFacts, node, outermostLabeledStatement, convert) {
            var ancestorFacts = enterSubtree(excludeFacts, includeFacts);
            var updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function visitDoOrWhileStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(0 /* DoOrWhileStatementExcludes */, 1280 /* DoOrWhileStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(5056 /* ForStatementExcludes */, 3328 /* ForStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForInStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(3008 /* ForInOrForOfStatementExcludes */, 5376 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForOfStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(3008 /* ForInOrForOfStatementExcludes */, 5376 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement, compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray);
        }
        function convertForOfStatementHead(node, boundValue, convertedLoopBodyStatements) {
            var statements = [];
            var initializer = node.initializer;
            if (ts.isVariableDeclarationList(initializer)) {
                if (node.initializer.flags & 3 /* BlockScoped */) {
                    enableSubstitutionsForBlockScopedBindings();
                }
                var firstOriginalDeclaration = ts.firstOrUndefined(initializer.declarations);
                if (firstOriginalDeclaration && ts.isBindingPattern(firstOriginalDeclaration.name)) {
                    // This works whether the declaration is a var, let, or const.
                    // It will use rhsIterationValue _a[_i] as the initializer.
                    var declarations = ts.flattenDestructuringBinding(firstOriginalDeclaration, visitor, context, 0 /* All */, boundValue);
                    var declarationList = ts.setTextRange(ts.createVariableDeclarationList(declarations), node.initializer);
                    ts.setOriginalNode(declarationList, node.initializer);
                    // Adjust the source map range for the first declaration to align with the old
                    // emitter.
                    ts.setSourceMapRange(declarationList, ts.createRange(declarations[0].pos, ts.last(declarations).end));
                    statements.push(ts.createVariableStatement(
                    /*modifiers*/ undefined, declarationList));
                }
                else {
                    // The following call does not include the initializer, so we have
                    // to emit it separately.
                    statements.push(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(firstOriginalDeclaration ? firstOriginalDeclaration.name : ts.createTempVariable(/*recordTempVariable*/ undefined), 
                        /*type*/ undefined, boundValue)
                    ]), ts.moveRangePos(initializer, -1)), initializer)), ts.moveRangeEnd(initializer, -1)));
                }
            }
            else {
                // Initializer is an expression. Emit the expression in the body, so that it's
                // evaluated on every iteration.
                var assignment = ts.createAssignment(initializer, boundValue);
                if (ts.isDestructuringAssignment(assignment)) {
                    ts.aggregateTransformFlags(assignment);
                    statements.push(ts.createExpressionStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
                }
                else {
                    assignment.end = initializer.end;
                    statements.push(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(assignment, visitor, ts.isExpression)), ts.moveRangeEnd(initializer, -1)));
                }
            }
            if (convertedLoopBodyStatements) {
                return createSyntheticBlockForConvertedStatements(ts.addRange(statements, convertedLoopBodyStatements));
            }
            else {
                var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
                if (ts.isBlock(statement)) {
                    return ts.updateBlock(statement, ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, statement.statements)), statement.statements));
                }
                else {
                    statements.push(statement);
                    return createSyntheticBlockForConvertedStatements(statements);
                }
            }
        }
        function createSyntheticBlockForConvertedStatements(statements) {
            return ts.setEmitFlags(ts.createBlock(ts.createNodeArray(statements), 
            /*multiLine*/ true), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
        }
        function convertForOfStatementForArray(node, outermostLabeledStatement, convertedLoopBodyStatements) {
            // The following ES6 code:
            //
            //    for (let v of expr) { }
            //
            // should be emitted as
            //
            //    for (var _i = 0, _a = expr; _i < _a.length; _i++) {
            //        var v = _a[_i];
            //    }
            //
            // where _a and _i are temps emitted to capture the RHS and the counter,
            // respectively.
            // When the left hand side is an expression instead of a let declaration,
            // the "let v" is not emitted.
            // When the left hand side is a let/const, the v is renamed if there is
            // another v in scope.
            // Note that all assignments to the LHS are emitted in the body, including
            // all destructuring.
            // Note also that because an extra statement is needed to assign to the LHS,
            // for-of bodies are always emitted as blocks.
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            // In the case where the user wrote an identifier as the RHS, like this:
            //
            //     for (let v of arr) { }
            //
            // we don't want to emit a temporary variable for the RHS, just use it directly.
            var counter = ts.createLoopVariable();
            var rhsReference = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            // The old emitter does not emit source maps for the expression
            ts.setEmitFlags(expression, 48 /* NoSourceMap */ | ts.getEmitFlags(expression));
            var forStatement = ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(counter, /*type*/ undefined, ts.createLiteral(0)), ts.moveRangePos(node.expression, -1)),
                ts.setTextRange(ts.createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.setTextRange(ts.createLessThan(counter, ts.createPropertyAccess(rhsReference, "length")), node.expression), 
            /*incrementor*/ ts.setTextRange(ts.createPostfixIncrement(counter), node.expression), 
            /*statement*/ convertForOfStatementHead(node, ts.createElementAccess(rhsReference, counter), convertedLoopBodyStatements)), 
            /*location*/ node);
            // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
            ts.setEmitFlags(forStatement, 256 /* NoTokenTrailingSourceMaps */);
            ts.setTextRange(forStatement, node);
            return ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
        }
        function convertForOfStatementForIterable(node, outermostLabeledStatement, convertedLoopBodyStatements, ancestorFacts) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var errorRecord = ts.createUniqueName("e");
            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
            var values = ts.createValuesHelper(context, expression, node.expression);
            var next = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
            hoistVariableDeclaration(errorRecord);
            hoistVariableDeclaration(returnMethod);
            // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration
            var initializer = ancestorFacts & 1024 /* IterationContainer */
                ? ts.inlineExpressions([ts.createAssignment(errorRecord, ts.createVoidZero()), values])
                : values;
            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression),
                ts.createVariableDeclaration(result, /*type*/ undefined, next)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.createLogicalNot(ts.createPropertyAccess(result, "done")), 
            /*incrementor*/ ts.createAssignment(result, next), 
            /*statement*/ convertForOfStatementHead(node, ts.createPropertyAccess(result, "value"), convertedLoopBodyStatements)), 
            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
            return ts.createTry(ts.createBlock([
                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel)
            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
                ts.createExpressionStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
                    ts.createPropertyAssignment("error", catchVariable)
                ])))
            ]), 1 /* SingleLine */)), ts.createBlock([
                ts.createTry(
                /*tryBlock*/ ts.createBlock([
                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(ts.createPropertyAccess(result, "done"))), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createExpressionStatement(ts.createFunctionCall(returnMethod, iterator, []))), 1 /* SingleLine */),
                ]), 
                /*catchClause*/ undefined, 
                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
                ]), 1 /* SingleLine */))
            ]));
        }
        /**
         * Visits an ObjectLiteralExpression with computed property names.
         *
         * @param node An ObjectLiteralExpression node.
         */
        function visitObjectLiteralExpression(node) {
            // We are here because a ComputedPropertyName was used somewhere in the expression.
            var properties = node.properties;
            var numProperties = properties.length;
            // Find the first computed property.
            // Everything until that point can be emitted as part of the initial object literal.
            var numInitialProperties = numProperties;
            var numInitialPropertiesWithoutYield = numProperties;
            for (var i = 0; i < numProperties; i++) {
                var property = properties[i];
                if ((property.transformFlags & 262144 /* ContainsYield */ && hierarchyFacts & 4 /* AsyncFunctionBody */)
                    && i < numInitialPropertiesWithoutYield) {
                    numInitialPropertiesWithoutYield = i;
                }
                if (property.name.kind === 154 /* ComputedPropertyName */) {
                    numInitialProperties = i;
                    break;
                }
            }
            if (numInitialProperties !== numProperties) {
                if (numInitialPropertiesWithoutYield < numInitialProperties) {
                    numInitialProperties = numInitialPropertiesWithoutYield;
                }
                // For computed properties, we need to create a unique handle to the object
                // literal so we can modify it without risking internal assignments tainting the object.
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                // Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
                var expressions = [];
                var assignment = ts.createAssignment(temp, ts.setEmitFlags(ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), node.multiLine), 65536 /* Indented */));
                if (node.multiLine) {
                    ts.startOnNewLine(assignment);
                }
                expressions.push(assignment);
                addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
                // We need to clone the temporary identifier so that we can write it on a
                // new line
                expressions.push(node.multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
                return ts.inlineExpressions(expressions);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function shouldConvertPartOfIterationStatement(node) {
            return (resolver.getNodeCheckFlags(node) & 131072 /* ContainsCapturedBlockScopeBinding */) !== 0;
        }
        function shouldConvertInitializerOfForStatement(node) {
            return ts.isForStatement(node) && !!node.initializer && shouldConvertPartOfIterationStatement(node.initializer);
        }
        function shouldConvertConditionOfForStatement(node) {
            return ts.isForStatement(node) && !!node.condition && shouldConvertPartOfIterationStatement(node.condition);
        }
        function shouldConvertIncrementorOfForStatement(node) {
            return ts.isForStatement(node) && !!node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
        }
        function shouldConvertIterationStatement(node) {
            return shouldConvertBodyOfIterationStatement(node)
                || shouldConvertInitializerOfForStatement(node);
        }
        function shouldConvertBodyOfIterationStatement(node) {
            return (resolver.getNodeCheckFlags(node) & 65536 /* LoopWithCapturedBlockScopedBinding */) !== 0;
        }
        /**
         * Records constituents of name for the given variable to be hoisted in the outer scope.
         */
        function hoistVariableDeclarationDeclaredInConvertedLoop(state, node) {
            if (!state.hoistedLocalVariables) {
                state.hoistedLocalVariables = [];
            }
            visit(node.name);
            function visit(node) {
                if (node.kind === 75 /* Identifier */) {
                    state.hoistedLocalVariables.push(node);
                }
                else {
                    for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                        var element = _a[_i];
                        if (!ts.isOmittedExpression(element)) {
                            visit(element.name);
                        }
                    }
                }
            }
        }
        function convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert) {
            if (!shouldConvertIterationStatement(node)) {
                var saveAllowedNonLabeledJumps = void 0;
                if (convertedLoopState) {
                    // we get here if we are trying to emit normal loop loop inside converted loop
                    // set allowedNonLabeledJumps to Break | Continue to mark that break\continue inside the loop should be emitted as is
                    saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                    convertedLoopState.allowedNonLabeledJumps = 2 /* Break */ | 4 /* Continue */;
                }
                var result = convert
                    ? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined, ancestorFacts)
                    : ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel);
                if (convertedLoopState) {
                    convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
                }
                return result;
            }
            var currentState = createConvertedLoopState(node);
            var statements = [];
            var outerConvertedLoopState = convertedLoopState;
            convertedLoopState = currentState;
            var initializerFunction = shouldConvertInitializerOfForStatement(node) ? createFunctionForInitializerOfForStatement(node, currentState) : undefined;
            var bodyFunction = shouldConvertBodyOfIterationStatement(node) ? createFunctionForBodyOfIterationStatement(node, currentState, outerConvertedLoopState) : undefined;
            convertedLoopState = outerConvertedLoopState;
            if (initializerFunction)
                statements.push(initializerFunction.functionDeclaration);
            if (bodyFunction)
                statements.push(bodyFunction.functionDeclaration);
            addExtraDeclarationsForConvertedLoop(statements, currentState, outerConvertedLoopState);
            if (initializerFunction) {
                statements.push(generateCallToConvertedLoopInitializer(initializerFunction.functionName, initializerFunction.containsYield));
            }
            var loop;
            if (bodyFunction) {
                if (convert) {
                    loop = convert(node, outermostLabeledStatement, bodyFunction.part, ancestorFacts);
                }
                else {
                    var clone_4 = convertIterationStatementCore(node, initializerFunction, ts.createBlock(bodyFunction.part, /*multiLine*/ true));
                    ts.aggregateTransformFlags(clone_4);
                    loop = ts.restoreEnclosingLabel(clone_4, outermostLabeledStatement, convertedLoopState && resetLabel);
                }
            }
            else {
                var clone_5 = convertIterationStatementCore(node, initializerFunction, ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
                ts.aggregateTransformFlags(clone_5);
                loop = ts.restoreEnclosingLabel(clone_5, outermostLabeledStatement, convertedLoopState && resetLabel);
            }
            statements.push(loop);
            return statements;
        }
        function convertIterationStatementCore(node, initializerFunction, convertedLoopBody) {
            switch (node.kind) {
                case 230 /* ForStatement */: return convertForStatement(node, initializerFunction, convertedLoopBody);
                case 231 /* ForInStatement */: return convertForInStatement(node, convertedLoopBody);
                case 232 /* ForOfStatement */: return convertForOfStatement(node, convertedLoopBody);
                case 228 /* DoStatement */: return convertDoStatement(node, convertedLoopBody);
                case 229 /* WhileStatement */: return convertWhileStatement(node, convertedLoopBody);
                default: return ts.Debug.failBadSyntaxKind(node, "IterationStatement expected");
            }
        }
        function convertForStatement(node, initializerFunction, convertedLoopBody) {
            var shouldConvertCondition = node.condition && shouldConvertPartOfIterationStatement(node.condition);
            var shouldConvertIncrementor = shouldConvertCondition || node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
            return ts.updateFor(node, ts.visitNode(initializerFunction ? initializerFunction.part : node.initializer, visitor, ts.isForInitializer), ts.visitNode(shouldConvertCondition ? undefined : node.condition, visitor, ts.isExpression), ts.visitNode(shouldConvertIncrementor ? undefined : node.incrementor, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertForOfStatement(node, convertedLoopBody) {
            return ts.updateForOf(node, 
            /*awaitModifier*/ undefined, ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertForInStatement(node, convertedLoopBody) {
            return ts.updateForIn(node, ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertDoStatement(node, convertedLoopBody) {
            return ts.updateDo(node, convertedLoopBody, ts.visitNode(node.expression, visitor, ts.isExpression));
        }
        function convertWhileStatement(node, convertedLoopBody) {
            return ts.updateWhile(node, ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function createConvertedLoopState(node) {
            var loopInitializer;
            switch (node.kind) {
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                    var initializer = node.initializer;
                    if (initializer && initializer.kind === 243 /* VariableDeclarationList */) {
                        loopInitializer = initializer;
                    }
                    break;
            }
            // variables that will be passed to the loop as parameters
            var loopParameters = [];
            // variables declared in the loop initializer that will be changed inside the loop
            var loopOutParameters = [];
            if (loopInitializer && (ts.getCombinedNodeFlags(loopInitializer) & 3 /* BlockScoped */)) {
                var hasCapturedBindingsInForInitializer = shouldConvertInitializerOfForStatement(node);
                for (var _i = 0, _a = loopInitializer.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    processLoopVariableDeclaration(node, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
                }
            }
            var currentState = { loopParameters: loopParameters, loopOutParameters: loopOutParameters };
            if (convertedLoopState) {
                // convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop.
                // if outer converted loop has already accumulated some state - pass it through
                if (convertedLoopState.argumentsName) {
                    // outer loop has already used 'arguments' so we've already have some name to alias it
                    // use the same name in all nested loops
                    currentState.argumentsName = convertedLoopState.argumentsName;
                }
                if (convertedLoopState.thisName) {
                    // outer loop has already used 'this' so we've already have some name to alias it
                    // use the same name in all nested loops
                    currentState.thisName = convertedLoopState.thisName;
                }
                if (convertedLoopState.hoistedLocalVariables) {
                    // we've already collected some non-block scoped variable declarations in enclosing loop
                    // use the same storage in nested loop
                    currentState.hoistedLocalVariables = convertedLoopState.hoistedLocalVariables;
                }
            }
            return currentState;
        }
        function addExtraDeclarationsForConvertedLoop(statements, state, outerState) {
            var extraVariableDeclarations;
            // propagate state from the inner loop to the outer loop if necessary
            if (state.argumentsName) {
                // if alias for arguments is set
                if (outerState) {
                    // pass it to outer converted loop
                    outerState.argumentsName = state.argumentsName;
                }
                else {
                    // this is top level converted loop and we need to create an alias for 'arguments' object
                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(state.argumentsName, 
                    /*type*/ undefined, ts.createIdentifier("arguments")));
                }
            }
            if (state.thisName) {
                // if alias for this is set
                if (outerState) {
                    // pass it to outer converted loop
                    outerState.thisName = state.thisName;
                }
                else {
                    // this is top level converted loop so we need to create an alias for 'this' here
                    // NOTE:
                    // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
                    // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(state.thisName, 
                    /*type*/ undefined, ts.createIdentifier("this")));
                }
            }
            if (state.hoistedLocalVariables) {
                // if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
                if (outerState) {
                    // pass them to outer converted loop
                    outerState.hoistedLocalVariables = state.hoistedLocalVariables;
                }
                else {
                    if (!extraVariableDeclarations) {
                        extraVariableDeclarations = [];
                    }
                    // hoist collected variable declarations
                    for (var _i = 0, _a = state.hoistedLocalVariables; _i < _a.length; _i++) {
                        var identifier = _a[_i];
                        extraVariableDeclarations.push(ts.createVariableDeclaration(identifier));
                    }
                }
            }
            // add extra variables to hold out parameters if necessary
            if (state.loopOutParameters.length) {
                if (!extraVariableDeclarations) {
                    extraVariableDeclarations = [];
                }
                for (var _b = 0, _c = state.loopOutParameters; _b < _c.length; _b++) {
                    var outParam = _c[_b];
                    extraVariableDeclarations.push(ts.createVariableDeclaration(outParam.outParamName));
                }
            }
            if (state.conditionVariable) {
                if (!extraVariableDeclarations) {
                    extraVariableDeclarations = [];
                }
                extraVariableDeclarations.push(ts.createVariableDeclaration(state.conditionVariable, /*type*/ undefined, ts.createFalse()));
            }
            // create variable statement to hold all introduced variable declarations
            if (extraVariableDeclarations) {
                statements.push(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(extraVariableDeclarations)));
            }
        }
        function createOutVariable(p) {
            return ts.createVariableDeclaration(p.originalName, /*type*/ undefined, p.outParamName);
        }
        /**
         * Creates a `_loop_init` function for a `ForStatement` with a block-scoped initializer
         * that is captured in a closure inside of the initializer. The `_loop_init` function is
         * used to preserve the per-iteration environment semantics of
         * [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
         */
        function createFunctionForInitializerOfForStatement(node, currentState) {
            var functionName = ts.createUniqueName("_loop_init");
            var containsYield = (node.initializer.transformFlags & 262144 /* ContainsYield */) !== 0;
            var emitFlags = 0 /* None */;
            if (currentState.containsLexicalThis)
                emitFlags |= 8 /* CapturesThis */;
            if (containsYield && hierarchyFacts & 4 /* AsyncFunctionBody */)
                emitFlags |= 262144 /* AsyncFunctionBody */;
            var statements = [];
            statements.push(ts.createVariableStatement(/*modifiers*/ undefined, node.initializer));
            copyOutParameters(currentState.loopOutParameters, 2 /* Initializer */, 1 /* ToOutParameter */, statements);
            // This transforms the following ES2015 syntax:
            //
            //  for (let i = (setImmediate(() => console.log(i)), 0); i < 2; i++) {
            //      // loop body
            //  }
            //
            // Into the following ES5 syntax:
            //
            //  var _loop_init_1 = function () {
            //      var i = (setImmediate(() => console.log(i)), 0);
            //      out_i_1 = i;
            //  };
            //  var out_i_1;
            //  _loop_init_1();
            //  for (var i = out_i_1; i < 2; i++) {
            //      // loop body
            //  }
            //
            // Which prevents mutations to `i` in the per-iteration environment of the body
            // from affecting the initial value for `i` outside of the per-iteration environment.
            var functionDeclaration = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(functionName, 
                /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression(
                /*modifiers*/ undefined, containsYield ? ts.createToken(41 /* AsteriskToken */) : undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ undefined, 
                /*type*/ undefined, ts.visitNode(ts.createBlock(statements, /*multiLine*/ true), visitor, ts.isBlock)), emitFlags))
            ]), 2097152 /* NoHoisting */));
            var part = ts.createVariableDeclarationList(ts.map(currentState.loopOutParameters, createOutVariable));
            return { functionName: functionName, containsYield: containsYield, functionDeclaration: functionDeclaration, part: part };
        }
        /**
         * Creates a `_loop` function for an `IterationStatement` with a block-scoped initializer
         * that is captured in a closure inside of the loop body. The `_loop` function is used to
         * preserve the per-iteration environment semantics of
         * [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
         */
        function createFunctionForBodyOfIterationStatement(node, currentState, outerState) {
            var functionName = ts.createUniqueName("_loop");
            startLexicalEnvironment();
            var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
            var lexicalEnvironment = endLexicalEnvironment();
            var statements = [];
            if (shouldConvertConditionOfForStatement(node) || shouldConvertIncrementorOfForStatement(node)) {
                // If a block-scoped variable declared in the initializer of `node` is captured in
                // the condition or incrementor, we must move the condition and incrementor into
                // the body of the for loop.
                //
                // This transforms the following ES2015 syntax:
                //
                //  for (let i = 0; setImmediate(() => console.log(i)), i < 2; setImmediate(() => console.log(i)), i++) {
                //      // loop body
                //  }
                //
                // Into the following ES5 syntax:
                //
                //  var _loop_1 = function (i) {
                //      if (inc_1)
                //          setImmediate(() => console.log(i)), i++;
                //      else
                //          inc_1 = true;
                //      if (!(setImmediate(() => console.log(i)), i < 2))
                //          return out_i_1 = i, "break";
                //      // loop body
                //      out_i_1 = i;
                //  }
                //  var out_i_1, inc_1 = false;
                //  for (var i = 0;;) {
                //      var state_1 = _loop_1(i);
                //      i = out_i_1;
                //      if (state_1 === "break")
                //          break;
                //  }
                //
                // Which prevents mutations to `i` in the per-iteration environment of the body
                // from affecting the value of `i` in the previous per-iteration environment.
                //
                // Note that the incrementor of a `for` loop is evaluated in a *new* per-iteration
                // environment that is carried over to the next iteration of the loop. As a result,
                // we must indicate whether this is the first evaluation of the loop body so that
                // we only evaluate the incrementor on subsequent evaluations.
                currentState.conditionVariable = ts.createUniqueName("inc");
                statements.push(ts.createIf(currentState.conditionVariable, ts.createStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), ts.createStatement(ts.createAssignment(currentState.conditionVariable, ts.createTrue()))));
                if (shouldConvertConditionOfForStatement(node)) {
                    statements.push(ts.createIf(ts.createPrefix(53 /* ExclamationToken */, ts.visitNode(node.condition, visitor, ts.isExpression)), ts.visitNode(ts.createBreak(), visitor, ts.isStatement)));
                }
            }
            if (ts.isBlock(statement)) {
                ts.addRange(statements, statement.statements);
            }
            else {
                statements.push(statement);
            }
            copyOutParameters(currentState.loopOutParameters, 1 /* Body */, 1 /* ToOutParameter */, statements);
            ts.insertStatementsAfterStandardPrologue(statements, lexicalEnvironment);
            var loopBody = ts.createBlock(statements, /*multiLine*/ true);
            if (ts.isBlock(statement))
                ts.setOriginalNode(loopBody, statement);
            var containsYield = (node.statement.transformFlags & 262144 /* ContainsYield */) !== 0;
            var emitFlags = 0;
            if (currentState.containsLexicalThis)
                emitFlags |= 8 /* CapturesThis */;
            if (containsYield && (hierarchyFacts & 4 /* AsyncFunctionBody */) !== 0)
                emitFlags |= 262144 /* AsyncFunctionBody */;
            // This transforms the following ES2015 syntax (in addition to other variations):
            //
            //  for (let i = 0; i < 2; i++) {
            //      setImmediate(() => console.log(i));
            //  }
            //
            // Into the following ES5 syntax:
            //
            //  var _loop_1 = function (i) {
            //      setImmediate(() => console.log(i));
            //  };
            //  for (var i = 0; i < 2; i++) {
            //      _loop_1(i);
            //  }
            var functionDeclaration = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(functionName, 
                /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression(
                /*modifiers*/ undefined, containsYield ? ts.createToken(41 /* AsteriskToken */) : undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, currentState.loopParameters, 
                /*type*/ undefined, loopBody), emitFlags))
            ]), 2097152 /* NoHoisting */));
            var part = generateCallToConvertedLoop(functionName, currentState, outerState, containsYield);
            return { functionName: functionName, containsYield: containsYield, functionDeclaration: functionDeclaration, part: part };
        }
        function copyOutParameter(outParam, copyDirection) {
            var source = copyDirection === 0 /* ToOriginal */ ? outParam.outParamName : outParam.originalName;
            var target = copyDirection === 0 /* ToOriginal */ ? outParam.originalName : outParam.outParamName;
            return ts.createBinary(target, 62 /* EqualsToken */, source);
        }
        function copyOutParameters(outParams, partFlags, copyDirection, statements) {
            for (var _i = 0, outParams_1 = outParams; _i < outParams_1.length; _i++) {
                var outParam = outParams_1[_i];
                if (outParam.flags & partFlags) {
                    statements.push(ts.createExpressionStatement(copyOutParameter(outParam, copyDirection)));
                }
            }
        }
        function generateCallToConvertedLoopInitializer(initFunctionExpressionName, containsYield) {
            var call = ts.createCall(initFunctionExpressionName, /*typeArguments*/ undefined, []);
            var callResult = containsYield
                ? ts.createYield(ts.createToken(41 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */))
                : call;
            return ts.createStatement(callResult);
        }
        function generateCallToConvertedLoop(loopFunctionExpressionName, state, outerState, containsYield) {
            var statements = [];
            // loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop
            // simple loops are emitted as just 'loop()';
            // NOTE: if loop uses only 'continue' it still will be emitted as simple loop
            var isSimpleLoop = !(state.nonLocalJumps & ~4 /* Continue */) &&
                !state.labeledNonLocalBreaks &&
                !state.labeledNonLocalContinues;
            var call = ts.createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, ts.map(state.loopParameters, function (p) { return p.name; }));
            var callResult = containsYield
                ? ts.createYield(ts.createToken(41 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */))
                : call;
            if (isSimpleLoop) {
                statements.push(ts.createExpressionStatement(callResult));
                copyOutParameters(state.loopOutParameters, 1 /* Body */, 0 /* ToOriginal */, statements);
            }
            else {
                var loopResultName = ts.createUniqueName("state");
                var stateVariable = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)]));
                statements.push(stateVariable);
                copyOutParameters(state.loopOutParameters, 1 /* Body */, 0 /* ToOriginal */, statements);
                if (state.nonLocalJumps & 8 /* Return */) {
                    var returnStatement = void 0;
                    if (outerState) {
                        outerState.nonLocalJumps |= 8 /* Return */;
                        returnStatement = ts.createReturn(loopResultName);
                    }
                    else {
                        returnStatement = ts.createReturn(ts.createPropertyAccess(loopResultName, "value"));
                    }
                    statements.push(ts.createIf(ts.createBinary(ts.createTypeOf(loopResultName), 36 /* EqualsEqualsEqualsToken */, ts.createLiteral("object")), returnStatement));
                }
                if (state.nonLocalJumps & 2 /* Break */) {
                    statements.push(ts.createIf(ts.createBinary(loopResultName, 36 /* EqualsEqualsEqualsToken */, ts.createLiteral("break")), ts.createBreak()));
                }
                if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
                    var caseClauses = [];
                    processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerState, caseClauses);
                    processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerState, caseClauses);
                    statements.push(ts.createSwitch(loopResultName, ts.createCaseBlock(caseClauses)));
                }
            }
            return statements;
        }
        function setLabeledJump(state, isBreak, labelText, labelMarker) {
            if (isBreak) {
                if (!state.labeledNonLocalBreaks) {
                    state.labeledNonLocalBreaks = ts.createMap();
                }
                state.labeledNonLocalBreaks.set(labelText, labelMarker);
            }
            else {
                if (!state.labeledNonLocalContinues) {
                    state.labeledNonLocalContinues = ts.createMap();
                }
                state.labeledNonLocalContinues.set(labelText, labelMarker);
            }
        }
        function processLabeledJumps(table, isBreak, loopResultName, outerLoop, caseClauses) {
            if (!table) {
                return;
            }
            table.forEach(function (labelMarker, labelText) {
                var statements = [];
                // if there are no outer converted loop or outer label in question is located inside outer converted loop
                // then emit labeled break\continue
                // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
                if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) {
                    var label = ts.createIdentifier(labelText);
                    statements.push(isBreak ? ts.createBreak(label) : ts.createContinue(label));
                }
                else {
                    setLabeledJump(outerLoop, isBreak, labelText, labelMarker);
                    statements.push(ts.createReturn(loopResultName));
                }
                caseClauses.push(ts.createCaseClause(ts.createLiteral(labelMarker), statements));
            });
        }
        function processLoopVariableDeclaration(container, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer) {
            var name = decl.name;
            if (ts.isBindingPattern(name)) {
                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        processLoopVariableDeclaration(container, element, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
                    }
                }
            }
            else {
                loopParameters.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
                var checkFlags = resolver.getNodeCheckFlags(decl);
                if (checkFlags & 4194304 /* NeedsLoopOutParameter */ || hasCapturedBindingsInForInitializer) {
                    var outParamName = ts.createUniqueName("out_" + ts.idText(name));
                    var flags = 0;
                    if (checkFlags & 4194304 /* NeedsLoopOutParameter */) {
                        flags |= 1 /* Body */;
                    }
                    if (ts.isForStatement(container) && container.initializer && resolver.isBindingCapturedByNode(container.initializer, decl)) {
                        flags |= 2 /* Initializer */;
                    }
                    loopOutParameters.push({ flags: flags, originalName: name, outParamName: outParamName });
                }
            }
        }
        /**
         * Adds the members of an object literal to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node An ObjectLiteralExpression node.
         * @param receiver The receiver for members of the ObjectLiteralExpression.
         * @param numInitialNonComputedProperties The number of initial properties without
         *                                        computed property names.
         */
        function addObjectLiteralMembers(expressions, node, receiver, start) {
            var properties = node.properties;
            var numProperties = properties.length;
            for (var i = start; i < numProperties; i++) {
                var property = properties[i];
                switch (property.kind) {
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        var accessors = ts.getAllAccessorDeclarations(node.properties, property);
                        if (property === accessors.firstAccessor) {
                            expressions.push(transformAccessorsToExpression(receiver, accessors, node, !!node.multiLine));
                        }
                        break;
                    case 161 /* MethodDeclaration */:
                        expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine));
                        break;
                    case 281 /* PropertyAssignment */:
                        expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine));
                        break;
                    case 282 /* ShorthandPropertyAssignment */:
                        expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine));
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(node);
                        break;
                }
            }
        }
        /**
         * Transforms a PropertyAssignment node into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the PropertyAssignment.
         * @param property The PropertyAssignment node.
         * @param receiver The receiver for the assignment.
         */
        function transformPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.visitNode(property.initializer, visitor, ts.isExpression));
            ts.setTextRange(expression, property);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        /**
         * Transforms a ShorthandPropertyAssignment node into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the ShorthandPropertyAssignment.
         * @param property The ShorthandPropertyAssignment node.
         * @param receiver The receiver for the assignment.
         */
        function transformShorthandPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.getSynthesizedClone(property.name));
            ts.setTextRange(expression, property);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        /**
         * Transforms a MethodDeclaration of an ObjectLiteralExpression into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the MethodDeclaration.
         * @param method The MethodDeclaration node.
         * @param receiver The receiver for the assignment.
         */
        function transformObjectLiteralMethodDeclarationToExpression(method, receiver, container, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(method.name, visitor, ts.isPropertyName)), transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container));
            ts.setTextRange(expression, method);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        function visitCatchClause(node) {
            var ancestorFacts = enterSubtree(7104 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
            var updated;
            ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015.");
            if (ts.isBindingPattern(node.variableDeclaration.name)) {
                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                var newVariableDeclaration = ts.createVariableDeclaration(temp);
                ts.setTextRange(newVariableDeclaration, node.variableDeclaration);
                var vars = ts.flattenDestructuringBinding(node.variableDeclaration, visitor, context, 0 /* All */, temp);
                var list = ts.createVariableDeclarationList(vars);
                ts.setTextRange(list, node.variableDeclaration);
                var destructure = ts.createVariableStatement(/*modifiers*/ undefined, list);
                updated = ts.updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function addStatementToStartOfBlock(block, statement) {
            var transformedStatements = ts.visitNodes(block.statements, visitor, ts.isStatement);
            return ts.updateBlock(block, __spreadArrays([statement], transformedStatements));
        }
        /**
         * Visits a MethodDeclaration of an ObjectLiteralExpression and transforms it into a
         * PropertyAssignment.
         *
         * @param node A MethodDeclaration node.
         */
        function visitMethodDeclaration(node) {
            // We should only get here for methods on an object literal with regular identifier names.
            // Methods on classes are handled in visitClassDeclaration/visitClassExpression.
            // Methods with computed property names are handled in visitObjectLiteralExpression.
            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
            var functionExpression = transformFunctionLikeToExpression(node, /*location*/ ts.moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined);
            ts.setEmitFlags(functionExpression, 512 /* NoLeadingComments */ | ts.getEmitFlags(functionExpression));
            return ts.setTextRange(ts.createPropertyAssignment(node.name, functionExpression), 
            /*location*/ node);
        }
        /**
         * Visits an AccessorDeclaration of an ObjectLiteralExpression.
         *
         * @param node An AccessorDeclaration node.
         */
        function visitAccessorDeclaration(node) {
            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var updated;
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            if (node.kind === 163 /* GetAccessor */) {
                updated = ts.updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body);
            }
            else {
                updated = ts.updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body);
            }
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return updated;
        }
        /**
         * Visits a ShorthandPropertyAssignment and transforms it into a PropertyAssignment.
         *
         * @param node A ShorthandPropertyAssignment node.
         */
        function visitShorthandPropertyAssignment(node) {
            return ts.setTextRange(ts.createPropertyAssignment(node.name, ts.getSynthesizedClone(node.name)), 
            /*location*/ node);
        }
        function visitComputedPropertyName(node) {
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a YieldExpression node.
         *
         * @param node A YieldExpression node.
         */
        function visitYieldExpression(node) {
            // `yield` expressions are transformed using the generators transformer.
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits an ArrayLiteralExpression that contains a spread element.
         *
         * @param node An ArrayLiteralExpression node.
         */
        function visitArrayLiteralExpression(node) {
            if (ts.some(node.elements, ts.isSpreadElement)) {
                // We are here because we contain a SpreadElementExpression.
                return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, !!node.multiLine, /*hasTrailingComma*/ !!node.elements.hasTrailingComma);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a CallExpression that contains either a spread element or `super`.
         *
         * @param node a CallExpression.
         */
        function visitCallExpression(node) {
            if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) {
                return visitTypeScriptClassWrapper(node);
            }
            var expression = ts.skipOuterExpressions(node.expression);
            if (expression.kind === 102 /* SuperKeyword */ ||
                ts.isSuperProperty(expression) ||
                ts.some(node.arguments, ts.isSpreadElement)) {
                return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true);
            }
            return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitTypeScriptClassWrapper(node) {
            // This is a call to a class wrapper function (an IIFE) created by the 'ts' transformer.
            // The wrapper has a form similar to:
            //
            //  (function() {
            //      class C { // 1
            //      }
            //      C.x = 1; // 2
            //      return C;
            //  }())
            //
            // When we transform the class, we end up with something like this:
            //
            //  (function () {
            //      var C = (function () { // 3
            //          function C() {
            //          }
            //          return C; // 4
            //      }());
            //      C.x = 1;
            //      return C;
            //  }())
            //
            // We want to simplify the two nested IIFEs to end up with something like this:
            //
            //  (function () {
            //      function C() {
            //      }
            //      C.x = 1;
            //      return C;
            //  }())
            // We skip any outer expressions in a number of places to get to the innermost
            // expression, but we will restore them later to preserve comments and source maps.
            var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock);
            // The class statements are the statements generated by visiting the first statement with initializer of the
            // body (1), while all other statements are added to remainingStatements (2)
            var isVariableStatementWithInitializer = function (stmt) { return ts.isVariableStatement(stmt) && !!ts.first(stmt.declarationList.declarations).initializer; };
            // visit the class body statements outside of any converted loop body.
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var bodyStatements = ts.visitNodes(body.statements, visitor, ts.isStatement);
            convertedLoopState = savedConvertedLoopState;
            var classStatements = ts.filter(bodyStatements, isVariableStatementWithInitializer);
            var remainingStatements = ts.filter(bodyStatements, function (stmt) { return !isVariableStatementWithInitializer(stmt); });
            var varStatement = ts.cast(ts.first(classStatements), ts.isVariableStatement);
            // We know there is only one variable declaration here as we verified this in an
            // earlier call to isTypeScriptClassWrapper
            var variable = varStatement.declarationList.declarations[0];
            var initializer = ts.skipOuterExpressions(variable.initializer);
            // Under certain conditions, the 'ts' transformer may introduce a class alias, which
            // we see as an assignment, for example:
            //
            //  (function () {
            //      var C_1;
            //      var C = C_1 = (function () {
            //          function C() {
            //          }
            //          C.x = function () { return C_1; }
            //          return C;
            //      }());
            //      C = C_1 = __decorate([dec], C);
            //      return C;
            //  }())
            //
            var aliasAssignment = ts.tryCast(initializer, ts.isAssignmentExpression);
            // The underlying call (3) is another IIFE that may contain a '_super' argument.
            var call = ts.cast(aliasAssignment ? ts.skipOuterExpressions(aliasAssignment.right) : initializer, ts.isCallExpression);
            var func = ts.cast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
            var funcStatements = func.body.statements;
            var classBodyStart = 0;
            var classBodyEnd = -1;
            var statements = [];
            if (aliasAssignment) {
                // If we have a class alias assignment, we need to move it to the down-level constructor
                // function we generated for the class.
                var extendsCall = ts.tryCast(funcStatements[classBodyStart], ts.isExpressionStatement);
                if (extendsCall) {
                    statements.push(extendsCall);
                    classBodyStart++;
                }
                // The next statement is the function declaration.
                statements.push(funcStatements[classBodyStart]);
                classBodyStart++;
                // Add the class alias following the declaration.
                statements.push(ts.createExpressionStatement(ts.createAssignment(aliasAssignment.left, ts.cast(variable.name, ts.isIdentifier))));
            }
            // Find the trailing 'return' statement (4)
            while (!ts.isReturnStatement(ts.elementAt(funcStatements, classBodyEnd))) {
                classBodyEnd--;
            }
            // When we extract the statements of the inner IIFE, we exclude the 'return' statement (4)
            // as we already have one that has been introduced by the 'ts' transformer.
            ts.addRange(statements, funcStatements, classBodyStart, classBodyEnd);
            if (classBodyEnd < -1) {
                // If there were any hoisted declarations following the return statement, we should
                // append them.
                ts.addRange(statements, funcStatements, classBodyEnd + 1);
            }
            // Add the remaining statements of the outer wrapper.
            ts.addRange(statements, remainingStatements);
            // The 'es2015' class transform may add an end-of-declaration marker. If so we will add it
            // after the remaining statements from the 'ts' transformer.
            ts.addRange(statements, classStatements, /*start*/ 1);
            // Recreate any outer parentheses or partially-emitted expressions to preserve source map
            // and comment locations.
            return ts.recreateOuterExpressions(node.expression, ts.recreateOuterExpressions(variable.initializer, ts.recreateOuterExpressions(aliasAssignment && aliasAssignment.right, ts.updateCall(call, ts.recreateOuterExpressions(call.expression, ts.updateFunctionExpression(func, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, func.parameters, 
            /*type*/ undefined, ts.updateBlock(func.body, statements))), 
            /*typeArguments*/ undefined, call.arguments))));
        }
        function visitImmediateSuperCallInBody(node) {
            return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ false);
        }
        function visitCallExpressionWithPotentialCapturedThisAssignment(node, assignToCapturedThis) {
            // We are here either because SuperKeyword was used somewhere in the expression, or
            // because we contain a SpreadElementExpression.
            if (node.transformFlags & 8192 /* ContainsRestOrSpread */ ||
                node.expression.kind === 102 /* SuperKeyword */ ||
                ts.isSuperProperty(ts.skipOuterExpressions(node.expression))) {
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                if (node.expression.kind === 102 /* SuperKeyword */) {
                    ts.setEmitFlags(thisArg, 4 /* NoSubstitution */);
                }
                var resultingCall = void 0;
                if (node.transformFlags & 8192 /* ContainsRestOrSpread */) {
                    // [source]
                    //      f(...a, b)
                    //      x.m(...a, b)
                    //      super(...a, b)
                    //      super.m(...a, b) // in static
                    //      super.m(...a, b) // in instance
                    //
                    // [output]
                    //      f.apply(void 0, a.concat([b]))
                    //      (_a = x).m.apply(_a, a.concat([b]))
                    //      _super.apply(this, a.concat([b]))
                    //      _super.m.apply(this, a.concat([b]))
                    //      _super.prototype.m.apply(this, a.concat([b]))
                    resultingCall = ts.createFunctionApply(ts.visitNode(target, callExpressionVisitor, ts.isExpression), node.expression.kind === 102 /* SuperKeyword */ ? thisArg : ts.visitNode(thisArg, visitor, ts.isExpression), transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false));
                }
                else {
                    // [source]
                    //      super(a)
                    //      super.m(a) // in static
                    //      super.m(a) // in instance
                    //
                    // [output]
                    //      _super.call(this, a)
                    //      _super.m.call(this, a)
                    //      _super.prototype.m.call(this, a)
                    resultingCall = ts.createFunctionCall(ts.visitNode(target, callExpressionVisitor, ts.isExpression), node.expression.kind === 102 /* SuperKeyword */ ? thisArg : ts.visitNode(thisArg, visitor, ts.isExpression), ts.visitNodes(node.arguments, visitor, ts.isExpression), 
                    /*location*/ node);
                }
                if (node.expression.kind === 102 /* SuperKeyword */) {
                    var initializer = ts.createLogicalOr(resultingCall, createActualThis());
                    resultingCall = assignToCapturedThis
                        ? ts.createAssignment(ts.createFileLevelUniqueName("_this"), initializer)
                        : initializer;
                }
                return ts.setOriginalNode(resultingCall, node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a NewExpression that contains a spread element.
         *
         * @param node A NewExpression node.
         */
        function visitNewExpression(node) {
            if (ts.some(node.arguments, ts.isSpreadElement)) {
                // We are here because we contain a SpreadElementExpression.
                // [source]
                //      new C(...a)
                //
                // [output]
                //      new ((_a = C).bind.apply(_a, [void 0].concat(a)))()
                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                return ts.createNew(ts.createFunctionApply(ts.visitNode(target, visitor, ts.isExpression), thisArg, transformAndSpreadElements(ts.createNodeArray(__spreadArrays([ts.createVoidZero()], node.arguments)), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)), 
                /*typeArguments*/ undefined, []);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Transforms an array of Expression nodes that contains a SpreadExpression.
         *
         * @param elements The array of Expression nodes.
         * @param needsUniqueCopy A value indicating whether to ensure that the result is a fresh array.
         * @param multiLine A value indicating whether the result should be emitted on multiple lines.
         */
        function transformAndSpreadElements(elements, needsUniqueCopy, multiLine, hasTrailingComma) {
            // [source]
            //      [a, ...b, c]
            //
            // [output (downlevelIteration)]
            //      __spread([a], b, [c])
            //
            // [output]
            //      __spreadArrays([a], b, [c])
            // Map spans of spread expressions into their expressions and spans of other
            // expressions into an array literal.
            var numElements = elements.length;
            var segments = ts.flatten(ts.spanMap(elements, partitionSpread, function (partition, visitPartition, _start, end) {
                return visitPartition(partition, multiLine, hasTrailingComma && end === numElements);
            }));
            if (compilerOptions.downlevelIteration) {
                if (segments.length === 1) {
                    var firstSegment = segments[0];
                    if (isCallToHelper(firstSegment, "___spread")) {
                        return segments[0];
                    }
                }
                return ts.createSpreadHelper(context, segments);
            }
            else {
                if (segments.length === 1) {
                    var firstSegment = segments[0];
                    if (!needsUniqueCopy
                        || isPackedArrayLiteral(firstSegment)
                        || isCallToHelper(firstSegment, "___spreadArrays")) {
                        return segments[0];
                    }
                }
                return ts.createSpreadArraysHelper(context, segments);
            }
        }
        function isPackedElement(node) {
            return !ts.isOmittedExpression(node);
        }
        function isPackedArrayLiteral(node) {
            return ts.isArrayLiteralExpression(node) && ts.every(node.elements, isPackedElement);
        }
        function isCallToHelper(firstSegment, helperName) {
            return ts.isCallExpression(firstSegment)
                && ts.isIdentifier(firstSegment.expression)
                && (ts.getEmitFlags(firstSegment.expression) & 4096 /* HelperName */)
                && firstSegment.expression.escapedText === helperName;
        }
        function partitionSpread(node) {
            return ts.isSpreadElement(node)
                ? visitSpanOfSpreads
                : visitSpanOfNonSpreads;
        }
        function visitSpanOfSpreads(chunk) {
            return ts.map(chunk, visitExpressionOfSpread);
        }
        function visitSpanOfNonSpreads(chunk, multiLine, hasTrailingComma) {
            return ts.createArrayLiteral(ts.visitNodes(ts.createNodeArray(chunk, hasTrailingComma), visitor, ts.isExpression), multiLine);
        }
        function visitSpreadElement(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        /**
         * Transforms the expression of a SpreadExpression node.
         *
         * @param node A SpreadExpression node.
         */
        function visitExpressionOfSpread(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        /**
         * Visits a template literal.
         *
         * @param node A template literal.
         */
        function visitTemplateLiteral(node) {
            return ts.setTextRange(ts.createLiteral(node.text), node);
        }
        /**
         * Visits a string literal with an extended unicode escape.
         *
         * @param node A string literal.
         */
        function visitStringLiteral(node) {
            if (node.hasExtendedUnicodeEscape) {
                return ts.setTextRange(ts.createLiteral(node.text), node);
            }
            return node;
        }
        /**
         * Visits a binary or octal (ES6) numeric literal.
         *
         * @param node A string literal.
         */
        function visitNumericLiteral(node) {
            if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) {
                return ts.setTextRange(ts.createNumericLiteral(node.text), node);
            }
            return node;
        }
        /**
         * Visits a TaggedTemplateExpression node.
         *
         * @param node A TaggedTemplateExpression node.
         */
        function visitTaggedTemplateExpression(node) {
            return ts.processTaggedTemplateExpression(context, node, visitor, currentSourceFile, recordTaggedTemplateString, ts.ProcessLevel.All);
        }
        /**
         * Visits a TemplateExpression node.
         *
         * @param node A TemplateExpression node.
         */
        function visitTemplateExpression(node) {
            var expressions = [];
            addTemplateHead(expressions, node);
            addTemplateSpans(expressions, node);
            // createAdd will check if each expression binds less closely than binary '+'.
            // If it does, it wraps the expression in parentheses. Otherwise, something like
            //    `abc${ 1 << 2 }`
            // becomes
            //    "abc" + 1 << 2 + ""
            // which is really
            //    ("abc" + 1) << (2 + "")
            // rather than
            //    "abc" + (1 << 2) + ""
            var expression = ts.reduceLeft(expressions, ts.createAdd);
            if (ts.nodeIsSynthesized(expression)) {
                expression.pos = node.pos;
                expression.end = node.end;
            }
            return expression;
        }
        /**
         * Gets a value indicating whether we need to include the head of a TemplateExpression.
         *
         * @param node A TemplateExpression node.
         */
        function shouldAddTemplateHead(node) {
            // If this expression has an empty head literal and the first template span has a non-empty
            // literal, then emitting the empty head literal is not necessary.
            //     `${ foo } and ${ bar }`
            // can be emitted as
            //     foo + " and " + bar
            // This is because it is only required that one of the first two operands in the emit
            // output must be a string literal, so that the other operand and all following operands
            // are forced into strings.
            //
            // If the first template span has an empty literal, then the head must still be emitted.
            //     `${ foo }${ bar }`
            // must still be emitted as
            //     "" + foo + bar
            // There is always atleast one templateSpan in this code path, since
            // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral()
            ts.Debug.assert(node.templateSpans.length !== 0);
            return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0;
        }
        /**
         * Adds the head of a TemplateExpression to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node A TemplateExpression node.
         */
        function addTemplateHead(expressions, node) {
            if (!shouldAddTemplateHead(node)) {
                return;
            }
            expressions.push(ts.createLiteral(node.head.text));
        }
        /**
         * Visits and adds the template spans of a TemplateExpression to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node A TemplateExpression node.
         */
        function addTemplateSpans(expressions, node) {
            for (var _i = 0, _a = node.templateSpans; _i < _a.length; _i++) {
                var span = _a[_i];
                expressions.push(ts.visitNode(span.expression, visitor, ts.isExpression));
                // Only emit if the literal is non-empty.
                // The binary '+' operator is left-associative, so the first string concatenation
                // with the head will force the result up to this point to be a string.
                // Emitting a '+ ""' has no semantic effect for middles and tails.
                if (span.literal.text.length !== 0) {
                    expressions.push(ts.createLiteral(span.literal.text));
                }
            }
        }
        /**
         * Visits the `super` keyword
         */
        function visitSuperKeyword(isExpressionOfCall) {
            return hierarchyFacts & 8 /* NonStaticClassElement */ && !isExpressionOfCall ? ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), "prototype") :
                ts.createFileLevelUniqueName("_super");
        }
        function visitMetaProperty(node) {
            if (node.keywordToken === 99 /* NewKeyword */ && node.name.escapedText === "target") {
                hierarchyFacts |= 16384 /* NewTarget */;
                return ts.createFileLevelUniqueName("_newTarget");
            }
            return node;
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to be printed.
         * @param emitCallback The callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (enabledSubstitutions & 1 /* CapturedThis */ && ts.isFunctionLike(node)) {
                // If we are tracking a captured `this`, keep track of the enclosing function.
                var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, ts.getEmitFlags(node) & 8 /* CapturesThis */
                    ? 65 /* FunctionIncludes */ | 16 /* CapturesThis */
                    : 65 /* FunctionIncludes */);
                previousOnEmitNode(hint, node, emitCallback);
                exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Enables a more costly code path for substitutions when we determine a source file
         * contains block-scoped bindings (e.g. `let` or `const`).
         */
        function enableSubstitutionsForBlockScopedBindings() {
            if ((enabledSubstitutions & 2 /* BlockScopedBindings */) === 0) {
                enabledSubstitutions |= 2 /* BlockScopedBindings */;
                context.enableSubstitution(75 /* Identifier */);
            }
        }
        /**
         * Enables a more costly code path for substitutions when we determine a source file
         * contains a captured `this`.
         */
        function enableSubstitutionsForCapturedThis() {
            if ((enabledSubstitutions & 1 /* CapturedThis */) === 0) {
                enabledSubstitutions |= 1 /* CapturedThis */;
                context.enableSubstitution(104 /* ThisKeyword */);
                context.enableEmitNotification(162 /* Constructor */);
                context.enableEmitNotification(161 /* MethodDeclaration */);
                context.enableEmitNotification(163 /* GetAccessor */);
                context.enableEmitNotification(164 /* SetAccessor */);
                context.enableEmitNotification(202 /* ArrowFunction */);
                context.enableEmitNotification(201 /* FunctionExpression */);
                context.enableEmitNotification(244 /* FunctionDeclaration */);
            }
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            if (ts.isIdentifier(node)) {
                return substituteIdentifier(node);
            }
            return node;
        }
        /**
         * Hooks substitutions for non-expression identifiers.
         */
        function substituteIdentifier(node) {
            // Only substitute the identifier if we have enabled substitutions for block-scoped
            // bindings.
            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
                var original = ts.getParseTreeNode(node, ts.isIdentifier);
                if (original && isNameOfDeclarationWithCollidingName(original)) {
                    return ts.setTextRange(ts.getGeneratedNameForNode(original), node);
                }
            }
            return node;
        }
        /**
         * Determines whether a name is the name of a declaration with a colliding name.
         * NOTE: This function expects to be called with an original source tree node.
         *
         * @param node An original source tree node.
         */
        function isNameOfDeclarationWithCollidingName(node) {
            switch (node.parent.kind) {
                case 191 /* BindingElement */:
                case 245 /* ClassDeclaration */:
                case 248 /* EnumDeclaration */:
                case 242 /* VariableDeclaration */:
                    return node.parent.name === node
                        && resolver.isDeclarationWithCollidingName(node.parent);
            }
            return false;
        }
        /**
         * Substitutes an expression.
         *
         * @param node An Expression node.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 104 /* ThisKeyword */:
                    return substituteThisKeyword(node);
            }
            return node;
        }
        /**
         * Substitutes an expression identifier.
         *
         * @param node An Identifier node.
         */
        function substituteExpressionIdentifier(node) {
            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
                var declaration = resolver.getReferencedDeclarationWithCollidingName(node);
                if (declaration && !(ts.isClassLike(declaration) && isPartOfClassBody(declaration, node))) {
                    return ts.setTextRange(ts.getGeneratedNameForNode(ts.getNameOfDeclaration(declaration)), node);
                }
            }
            return node;
        }
        function isPartOfClassBody(declaration, node) {
            var currentNode = ts.getParseTreeNode(node);
            if (!currentNode || currentNode === declaration || currentNode.end <= declaration.pos || currentNode.pos >= declaration.end) {
                // if the node has no correlation to a parse tree node, its definitely not
                // part of the body.
                // if the node is outside of the document range of the declaration, its
                // definitely not part of the body.
                return false;
            }
            var blockScope = ts.getEnclosingBlockScopeContainer(declaration);
            while (currentNode) {
                if (currentNode === blockScope || currentNode === declaration) {
                    // if we are in the enclosing block scope of the declaration, we are definitely
                    // not inside the class body.
                    return false;
                }
                if (ts.isClassElement(currentNode) && currentNode.parent === declaration) {
                    return true;
                }
                currentNode = currentNode.parent;
            }
            return false;
        }
        /**
         * Substitutes `this` when contained within an arrow function.
         *
         * @param node The ThisKeyword node.
         */
        function substituteThisKeyword(node) {
            if (enabledSubstitutions & 1 /* CapturedThis */
                && hierarchyFacts & 16 /* CapturesThis */) {
                return ts.setTextRange(ts.createFileLevelUniqueName("_this"), node);
            }
            return node;
        }
        function getClassMemberPrefix(node, member) {
            return ts.hasModifier(member, 32 /* Static */)
                ? ts.getInternalName(node)
                : ts.createPropertyAccess(ts.getInternalName(node), "prototype");
        }
        function hasSynthesizedDefaultSuperCall(constructor, hasExtendsClause) {
            if (!constructor || !hasExtendsClause) {
                return false;
            }
            if (ts.some(constructor.parameters)) {
                return false;
            }
            var statement = ts.firstOrUndefined(constructor.body.statements);
            if (!statement || !ts.nodeIsSynthesized(statement) || statement.kind !== 226 /* ExpressionStatement */) {
                return false;
            }
            var statementExpression = statement.expression;
            if (!ts.nodeIsSynthesized(statementExpression) || statementExpression.kind !== 196 /* CallExpression */) {
                return false;
            }
            var callTarget = statementExpression.expression;
            if (!ts.nodeIsSynthesized(callTarget) || callTarget.kind !== 102 /* SuperKeyword */) {
                return false;
            }
            var callArgument = ts.singleOrUndefined(statementExpression.arguments);
            if (!callArgument || !ts.nodeIsSynthesized(callArgument) || callArgument.kind !== 213 /* SpreadElement */) {
                return false;
            }
            var expression = callArgument.expression;
            return ts.isIdentifier(expression) && expression.escapedText === "arguments";
        }
    }
    ts.transformES2015 = transformES2015;
    function createExtendsHelper(context, name) {
        context.requestEmitHelper(ts.extendsHelper);
        return ts.createCall(ts.getUnscopedHelperName("__extends"), 
        /*typeArguments*/ undefined, [
            name,
            ts.createFileLevelUniqueName("_super")
        ]);
    }
    ts.extendsHelper = {
        name: "typescript:extends",
        importName: "__extends",
        scoped: false,
        priority: 0,
        text: "\n            var __extends = (this && this.__extends) || (function () {\n                var extendStatics = function (d, b) {\n                    extendStatics = Object.setPrototypeOf ||\n                        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n                        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n                    return extendStatics(d, b);\n                };\n\n                return function (d, b) {\n                    extendStatics(d, b);\n                    function __() { this.constructor = d; }\n                    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n                };\n            })();"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /**
     * Transforms ES5 syntax into ES3 syntax.
     *
     * @param context Context and state information for the transformation.
     */
    function transformES5(context) {
        var compilerOptions = context.getCompilerOptions();
        // enable emit notification only if using --jsx preserve or react-native
        var previousOnEmitNode;
        var noSubstitution;
        if (compilerOptions.jsx === 1 /* Preserve */ || compilerOptions.jsx === 3 /* ReactNative */) {
            previousOnEmitNode = context.onEmitNode;
            context.onEmitNode = onEmitNode;
            context.enableEmitNotification(268 /* JsxOpeningElement */);
            context.enableEmitNotification(269 /* JsxClosingElement */);
            context.enableEmitNotification(267 /* JsxSelfClosingElement */);
            noSubstitution = [];
        }
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        context.enableSubstitution(194 /* PropertyAccessExpression */);
        context.enableSubstitution(281 /* PropertyAssignment */);
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms an ES5 source file to ES3.
         *
         * @param node A SourceFile
         */
        function transformSourceFile(node) {
            return node;
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback A callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            switch (node.kind) {
                case 268 /* JsxOpeningElement */:
                case 269 /* JsxClosingElement */:
                case 267 /* JsxSelfClosingElement */:
                    var tagName = node.tagName;
                    noSubstitution[ts.getOriginalNodeId(tagName)] = true;
                    break;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            if (node.id && noSubstitution && noSubstitution[node.id]) {
                return previousOnSubstituteNode(hint, node);
            }
            node = previousOnSubstituteNode(hint, node);
            if (ts.isPropertyAccessExpression(node)) {
                return substitutePropertyAccessExpression(node);
            }
            else if (ts.isPropertyAssignment(node)) {
                return substitutePropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitutes a PropertyAccessExpression whose name is a reserved word.
         *
         * @param node A PropertyAccessExpression
         */
        function substitutePropertyAccessExpression(node) {
            if (ts.isPrivateIdentifier(node.name)) {
                return node;
            }
            var literalName = trySubstituteReservedName(node.name);
            if (literalName) {
                return ts.setTextRange(ts.createElementAccess(node.expression, literalName), node);
            }
            return node;
        }
        /**
         * Substitutes a PropertyAssignment whose name is a reserved word.
         *
         * @param node A PropertyAssignment
         */
        function substitutePropertyAssignment(node) {
            var literalName = ts.isIdentifier(node.name) && trySubstituteReservedName(node.name);
            if (literalName) {
                return ts.updatePropertyAssignment(node, literalName, node.initializer);
            }
            return node;
        }
        /**
         * If an identifier name is a reserved word, returns a string literal for the name.
         *
         * @param name An Identifier
         */
        function trySubstituteReservedName(name) {
            var token = name.originalKeywordKind || (ts.nodeIsSynthesized(name) ? ts.stringToToken(ts.idText(name)) : undefined);
            if (token !== undefined && token >= 77 /* FirstReservedWord */ && token <= 112 /* LastReservedWord */) {
                return ts.setTextRange(ts.createLiteral(name), name);
            }
            return undefined;
        }
    }
    ts.transformES5 = transformES5;
})(ts || (ts = {}));
// Transforms generator functions into a compatible ES5 representation with similar runtime
// semantics. This is accomplished by first transforming the body of each generator
// function into an intermediate representation that is the compiled into a JavaScript
// switch statement.
//
// Many functions in this transformer will contain comments indicating the expected
// intermediate representation. For illustrative purposes, the following intermediate
// language is used to define this intermediate representation:
//
//  .nop                            - Performs no operation.
//  .local NAME, ...                - Define local variable declarations.
//  .mark LABEL                     - Mark the location of a label.
//  .br LABEL                       - Jump to a label. If jumping out of a protected
//                                    region, all .finally blocks are executed.
//  .brtrue LABEL, (x)              - Jump to a label IIF the expression `x` is truthy.
//                                    If jumping out of a protected region, all .finally
//                                    blocks are executed.
//  .brfalse LABEL, (x)             - Jump to a label IIF the expression `x` is falsey.
//                                    If jumping out of a protected region, all .finally
//                                    blocks are executed.
//  .yield (x)                      - Yield the value of the optional expression `x`.
//                                    Resume at the next label.
//  .yieldstar (x)                  - Delegate yield to the value of the optional
//                                    expression `x`. Resume at the next label.
//                                    NOTE: `x` must be an Iterator, not an Iterable.
//  .loop CONTINUE, BREAK           - Marks the beginning of a loop. Any "continue" or
//                                    "break" abrupt completions jump to the CONTINUE or
//                                    BREAK labels, respectively.
//  .endloop                        - Marks the end of a loop.
//  .with (x)                       - Marks the beginning of a WithStatement block, using
//                                    the supplied expression.
//  .endwith                        - Marks the end of a WithStatement.
//  .switch                         - Marks the beginning of a SwitchStatement.
//  .endswitch                      - Marks the end of a SwitchStatement.
//  .labeled NAME                   - Marks the beginning of a LabeledStatement with the
//                                    supplied name.
//  .endlabeled                     - Marks the end of a LabeledStatement.
//  .try TRY, CATCH, FINALLY, END   - Marks the beginning of a protected region, and the
//                                    labels for each block.
//  .catch (x)                      - Marks the beginning of a catch block.
//  .finally                        - Marks the beginning of a finally block.
//  .endfinally                     - Marks the end of a finally block.
//  .endtry                         - Marks the end of a protected region.
//  .throw (x)                      - Throws the value of the expression `x`.
//  .return (x)                     - Returns the value of the expression `x`.
//
// In addition, the illustrative intermediate representation introduces some special
// variables:
//
//  %sent%                          - Either returns the next value sent to the generator,
//                                    returns the result of a delegated yield, or throws
//                                    the exception sent to the generator.
//  %error%                         - Returns the value of the current exception in a
//                                    catch block.
//
// This intermediate representation is then compiled into JavaScript syntax. The resulting
// compilation output looks something like the following:
//
//  function f() {
//      var /*locals*/;
//      /*functions*/
//      return __generator(function (state) {
//          switch (state.label) {
//              /*cases per label*/
//          }
//      });
//  }
//
// Each of the above instructions corresponds to JavaScript emit similar to the following:
//
//  .local NAME                   | var NAME;
// -------------------------------|----------------------------------------------
//  .mark LABEL                   | case LABEL:
// -------------------------------|----------------------------------------------
//  .br LABEL                     |     return [3 /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .brtrue LABEL, (x)            |     if (x) return [3 /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .brfalse LABEL, (x)           |     if (!(x)) return [3, /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .yield (x)                    |     return [4 /*yield*/, x];
//  .mark RESUME                  | case RESUME:
//      a = %sent%;               |     a = state.sent();
// -------------------------------|----------------------------------------------
//  .yieldstar (x)                |     return [5 /*yield**/, x];
//  .mark RESUME                  | case RESUME:
//      a = %sent%;               |     a = state.sent();
// -------------------------------|----------------------------------------------
//  .with (_a)                    |     with (_a) {
//      a();                      |         a();
//                                |     }
//                                |     state.label = LABEL;
//  .mark LABEL                   | case LABEL:
//                                |     with (_a) {
//      b();                      |         b();
//                                |     }
//  .endwith                      |
// -------------------------------|----------------------------------------------
//                                | case 0:
//                                |     state.trys = [];
//                                | ...
//  .try TRY, CATCH, FINALLY, END |
//  .mark TRY                     | case TRY:
//                                |     state.trys.push([TRY, CATCH, FINALLY, END]);
//  .nop                          |
//      a();                      |     a();
//  .br END                       |     return [3 /*break*/, END];
//  .catch (e)                    |
//  .mark CATCH                   | case CATCH:
//                                |     e = state.sent();
//      b();                      |     b();
//  .br END                       |     return [3 /*break*/, END];
//  .finally                      |
//  .mark FINALLY                 | case FINALLY:
//      c();                      |     c();
//  .endfinally                   |     return [7 /*endfinally*/];
//  .endtry                       |
//  .mark END                     | case END:
/*@internal*/
var ts;
(function (ts) {
    var OpCode;
    (function (OpCode) {
        OpCode[OpCode["Nop"] = 0] = "Nop";
        OpCode[OpCode["Statement"] = 1] = "Statement";
        OpCode[OpCode["Assign"] = 2] = "Assign";
        OpCode[OpCode["Break"] = 3] = "Break";
        OpCode[OpCode["BreakWhenTrue"] = 4] = "BreakWhenTrue";
        OpCode[OpCode["BreakWhenFalse"] = 5] = "BreakWhenFalse";
        OpCode[OpCode["Yield"] = 6] = "Yield";
        OpCode[OpCode["YieldStar"] = 7] = "YieldStar";
        OpCode[OpCode["Return"] = 8] = "Return";
        OpCode[OpCode["Throw"] = 9] = "Throw";
        OpCode[OpCode["Endfinally"] = 10] = "Endfinally"; // Marks the end of a `finally` block
    })(OpCode || (OpCode = {}));
    // whether a generated code block is opening or closing at the current operation for a FunctionBuilder
    var BlockAction;
    (function (BlockAction) {
        BlockAction[BlockAction["Open"] = 0] = "Open";
        BlockAction[BlockAction["Close"] = 1] = "Close";
    })(BlockAction || (BlockAction = {}));
    // the kind for a generated code block in a FunctionBuilder
    var CodeBlockKind;
    (function (CodeBlockKind) {
        CodeBlockKind[CodeBlockKind["Exception"] = 0] = "Exception";
        CodeBlockKind[CodeBlockKind["With"] = 1] = "With";
        CodeBlockKind[CodeBlockKind["Switch"] = 2] = "Switch";
        CodeBlockKind[CodeBlockKind["Loop"] = 3] = "Loop";
        CodeBlockKind[CodeBlockKind["Labeled"] = 4] = "Labeled";
    })(CodeBlockKind || (CodeBlockKind = {}));
    // the state for a generated code exception block
    var ExceptionBlockState;
    (function (ExceptionBlockState) {
        ExceptionBlockState[ExceptionBlockState["Try"] = 0] = "Try";
        ExceptionBlockState[ExceptionBlockState["Catch"] = 1] = "Catch";
        ExceptionBlockState[ExceptionBlockState["Finally"] = 2] = "Finally";
        ExceptionBlockState[ExceptionBlockState["Done"] = 3] = "Done";
    })(ExceptionBlockState || (ExceptionBlockState = {}));
    // NOTE: changes to this enum should be reflected in the __generator helper.
    var Instruction;
    (function (Instruction) {
        Instruction[Instruction["Next"] = 0] = "Next";
        Instruction[Instruction["Throw"] = 1] = "Throw";
        Instruction[Instruction["Return"] = 2] = "Return";
        Instruction[Instruction["Break"] = 3] = "Break";
        Instruction[Instruction["Yield"] = 4] = "Yield";
        Instruction[Instruction["YieldStar"] = 5] = "YieldStar";
        Instruction[Instruction["Catch"] = 6] = "Catch";
        Instruction[Instruction["Endfinally"] = 7] = "Endfinally";
    })(Instruction || (Instruction = {}));
    function getInstructionName(instruction) {
        switch (instruction) {
            case 2 /* Return */: return "return";
            case 3 /* Break */: return "break";
            case 4 /* Yield */: return "yield";
            case 5 /* YieldStar */: return "yield*";
            case 7 /* Endfinally */: return "endfinally";
            default: return undefined; // TODO: GH#18217
        }
    }
    function transformGenerators(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistFunctionDeclaration = context.hoistFunctionDeclaration, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var resolver = context.getEmitResolver();
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var renamedCatchVariables;
        var renamedCatchVariableDeclarations;
        var inGeneratorFunctionBody;
        var inStatementContainingYield;
        // The following three arrays store information about generated code blocks.
        // All three arrays are correlated by their index. This approach is used over allocating
        // objects to store the same information to avoid GC overhead.
        //
        var blocks; // Information about the code block
        var blockOffsets; // The operation offset at which a code block begins or ends
        var blockActions; // Whether the code block is opened or closed
        var blockStack; // A stack of currently open code blocks
        // Labels are used to mark locations in the code that can be the target of a Break (jump)
        // operation. These are translated into case clauses in a switch statement.
        // The following two arrays are correlated by their index. This approach is used over
        // allocating objects to store the same information to avoid GC overhead.
        //
        var labelOffsets; // The operation offset at which the label is defined.
        var labelExpressions; // The NumericLiteral nodes bound to each label.
        var nextLabelId = 1; // The next label id to use.
        // Operations store information about generated code for the function body. This
        // Includes things like statements, assignments, breaks (jumps), and yields.
        // The following three arrays are correlated by their index. This approach is used over
        // allocating objects to store the same information to avoid GC overhead.
        //
        var operations; // The operation to perform.
        var operationArguments; // The arguments to the operation.
        var operationLocations; // The source map location for the operation.
        var state; // The name of the state object used by the generator at runtime.
        // The following variables store information used by the `build` function:
        //
        var blockIndex = 0; // The index of the current block.
        var labelNumber = 0; // The current label number.
        var labelNumbers;
        var lastOperationWasAbrupt; // Indicates whether the last operation was abrupt (break/continue).
        var lastOperationWasCompletion; // Indicates whether the last operation was a completion (return/throw).
        var clauses; // The case clauses generated for labels.
        var statements; // The statements for the current label.
        var exceptionBlockStack; // A stack of containing exception blocks.
        var currentExceptionBlock; // The current exception block.
        var withBlockStack; // A stack containing `with` blocks.
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile || (node.transformFlags & 512 /* ContainsGenerator */) === 0) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        /**
         * Visits a node.
         *
         * @param node The node to visit.
         */
        function visitor(node) {
            var transformFlags = node.transformFlags;
            if (inStatementContainingYield) {
                return visitJavaScriptInStatementContainingYield(node);
            }
            else if (inGeneratorFunctionBody) {
                return visitJavaScriptInGeneratorFunctionBody(node);
            }
            else if (ts.isFunctionLikeDeclaration(node) && node.asteriskToken) {
                return visitGenerator(node);
            }
            else if (transformFlags & 512 /* ContainsGenerator */) {
                return ts.visitEachChild(node, visitor, context);
            }
            else {
                return node;
            }
        }
        /**
         * Visits a node that is contained within a statement that contains yield.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptInStatementContainingYield(node) {
            switch (node.kind) {
                case 228 /* DoStatement */:
                    return visitDoStatement(node);
                case 229 /* WhileStatement */:
                    return visitWhileStatement(node);
                case 237 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 238 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                default:
                    return visitJavaScriptInGeneratorFunctionBody(node);
            }
        }
        /**
         * Visits a node that is contained within a generator function.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptInGeneratorFunctionBody(node) {
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 201 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return visitAccessorDeclaration(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 230 /* ForStatement */:
                    return visitForStatement(node);
                case 231 /* ForInStatement */:
                    return visitForInStatement(node);
                case 234 /* BreakStatement */:
                    return visitBreakStatement(node);
                case 233 /* ContinueStatement */:
                    return visitContinueStatement(node);
                case 235 /* ReturnStatement */:
                    return visitReturnStatement(node);
                default:
                    if (node.transformFlags & 262144 /* ContainsYield */) {
                        return visitJavaScriptContainingYield(node);
                    }
                    else if (node.transformFlags & (512 /* ContainsGenerator */ | 1048576 /* ContainsHoistedDeclarationOrCompletion */)) {
                        return ts.visitEachChild(node, visitor, context);
                    }
                    else {
                        return node;
                    }
            }
        }
        /**
         * Visits a node that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptContainingYield(node) {
            switch (node.kind) {
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                case 210 /* ConditionalExpression */:
                    return visitConditionalExpression(node);
                case 212 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 192 /* ArrayLiteralExpression */:
                    return visitArrayLiteralExpression(node);
                case 193 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 195 /* ElementAccessExpression */:
                    return visitElementAccessExpression(node);
                case 196 /* CallExpression */:
                    return visitCallExpression(node);
                case 197 /* NewExpression */:
                    return visitNewExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        /**
         * Visits a generator function.
         *
         * @param node The node to visit.
         */
        function visitGenerator(node) {
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 201 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        /**
         * Visits a function declaration.
         *
         * This will be called when one of the following conditions are met:
         * - The function declaration is a generator function.
         * - The function declaration is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            // Currently, we only support generators that were originally async functions.
            if (node.asteriskToken) {
                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
                /*decorators*/ undefined, node.modifiers, 
                /*asteriskToken*/ undefined, node.name, 
                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
                /*location*/ node), node);
            }
            else {
                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
                var savedInStatementContainingYield = inStatementContainingYield;
                inGeneratorFunctionBody = false;
                inStatementContainingYield = false;
                node = ts.visitEachChild(node, visitor, context);
                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
                inStatementContainingYield = savedInStatementContainingYield;
            }
            if (inGeneratorFunctionBody) {
                // Function declarations in a generator function body are hoisted
                // to the top of the lexical scope and elided from the current statement.
                hoistFunctionDeclaration(node);
                return undefined;
            }
            else {
                return node;
            }
        }
        /**
         * Visits a function expression.
         *
         * This will be called when one of the following conditions are met:
         * - The function expression is a generator function.
         * - The function expression is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitFunctionExpression(node) {
            // Currently, we only support generators that were originally async functions.
            if (node.asteriskToken) {
                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, node.name, 
                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
                /*location*/ node), node);
            }
            else {
                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
                var savedInStatementContainingYield = inStatementContainingYield;
                inGeneratorFunctionBody = false;
                inStatementContainingYield = false;
                node = ts.visitEachChild(node, visitor, context);
                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
                inStatementContainingYield = savedInStatementContainingYield;
            }
            return node;
        }
        /**
         * Visits a get or set accessor declaration.
         *
         * This will be called when one of the following conditions are met:
         * - The accessor is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitAccessorDeclaration(node) {
            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
            var savedInStatementContainingYield = inStatementContainingYield;
            inGeneratorFunctionBody = false;
            inStatementContainingYield = false;
            node = ts.visitEachChild(node, visitor, context);
            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
            inStatementContainingYield = savedInStatementContainingYield;
            return node;
        }
        /**
         * Transforms the body of a generator function declaration.
         *
         * @param node The function body to transform.
         */
        function transformGeneratorFunctionBody(body) {
            // Save existing generator state
            var statements = [];
            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
            var savedInStatementContainingYield = inStatementContainingYield;
            var savedBlocks = blocks;
            var savedBlockOffsets = blockOffsets;
            var savedBlockActions = blockActions;
            var savedBlockStack = blockStack;
            var savedLabelOffsets = labelOffsets;
            var savedLabelExpressions = labelExpressions;
            var savedNextLabelId = nextLabelId;
            var savedOperations = operations;
            var savedOperationArguments = operationArguments;
            var savedOperationLocations = operationLocations;
            var savedState = state;
            // Initialize generator state
            inGeneratorFunctionBody = true;
            inStatementContainingYield = false;
            blocks = undefined;
            blockOffsets = undefined;
            blockActions = undefined;
            blockStack = undefined;
            labelOffsets = undefined;
            labelExpressions = undefined;
            nextLabelId = 1;
            operations = undefined;
            operationArguments = undefined;
            operationLocations = undefined;
            state = ts.createTempVariable(/*recordTempVariable*/ undefined);
            // Build the generator
            resumeLexicalEnvironment();
            var statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
            transformAndEmitStatements(body.statements, statementOffset);
            var buildResult = build();
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            statements.push(ts.createReturn(buildResult));
            // Restore previous generator state
            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
            inStatementContainingYield = savedInStatementContainingYield;
            blocks = savedBlocks;
            blockOffsets = savedBlockOffsets;
            blockActions = savedBlockActions;
            blockStack = savedBlockStack;
            labelOffsets = savedLabelOffsets;
            labelExpressions = savedLabelExpressions;
            nextLabelId = savedNextLabelId;
            operations = savedOperations;
            operationArguments = savedOperationArguments;
            operationLocations = savedOperationLocations;
            state = savedState;
            return ts.setTextRange(ts.createBlock(statements, body.multiLine), body);
        }
        /**
         * Visits a variable statement.
         *
         * This will be called when one of the following conditions are met:
         * - The variable statement is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            if (node.transformFlags & 262144 /* ContainsYield */) {
                transformAndEmitVariableDeclarationList(node.declarationList);
                return undefined;
            }
            else {
                // Do not hoist custom prologues.
                if (ts.getEmitFlags(node) & 1048576 /* CustomPrologue */) {
                    return node;
                }
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                var variables = ts.getInitializedVariables(node.declarationList);
                if (variables.length === 0) {
                    return undefined;
                }
                return ts.setSourceMapRange(ts.createExpressionStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
            }
        }
        /**
         * Visits a binary expression.
         *
         * This will be called when one of the following conditions are met:
         * - The node contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitBinaryExpression(node) {
            var assoc = ts.getExpressionAssociativity(node);
            switch (assoc) {
                case 0 /* Left */:
                    return visitLeftAssociativeBinaryExpression(node);
                case 1 /* Right */:
                    return visitRightAssociativeBinaryExpression(node);
                default:
                    return ts.Debug.assertNever(assoc);
            }
        }
        /**
         * Visits a right-associative binary expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitRightAssociativeBinaryExpression(node) {
            var left = node.left, right = node.right;
            if (containsYield(right)) {
                var target = void 0;
                switch (left.kind) {
                    case 194 /* PropertyAccessExpression */:
                        // [source]
                        //      a.b = yield;
                        //
                        // [intermediate]
                        //  .local _a
                        //      _a = a;
                        //  .yield resumeLabel
                        //  .mark resumeLabel
                        //      _a.b = %sent%;
                        target = ts.updatePropertyAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), left.name);
                        break;
                    case 195 /* ElementAccessExpression */:
                        // [source]
                        //      a[b] = yield;
                        //
                        // [intermediate]
                        //  .local _a, _b
                        //      _a = a;
                        //      _b = b;
                        //  .yield resumeLabel
                        //  .mark resumeLabel
                        //      _a[_b] = %sent%;
                        target = ts.updateElementAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), cacheExpression(ts.visitNode(left.argumentExpression, visitor, ts.isExpression)));
                        break;
                    default:
                        target = ts.visitNode(left, visitor, ts.isExpression);
                        break;
                }
                var operator = node.operatorToken.kind;
                if (ts.isCompoundAssignment(operator)) {
                    return ts.setTextRange(ts.createAssignment(target, ts.setTextRange(ts.createBinary(cacheExpression(target), ts.getNonAssignmentOperatorForCompoundAssignment(operator), ts.visitNode(right, visitor, ts.isExpression)), node)), node);
                }
                else {
                    return ts.updateBinary(node, target, ts.visitNode(right, visitor, ts.isExpression));
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitLeftAssociativeBinaryExpression(node) {
            if (containsYield(node.right)) {
                if (ts.isLogicalOperator(node.operatorToken.kind)) {
                    return visitLogicalBinaryExpression(node);
                }
                else if (node.operatorToken.kind === 27 /* CommaToken */) {
                    return visitCommaExpression(node);
                }
                // [source]
                //      a() + (yield) + c()
                //
                // [intermediate]
                //  .local _a
                //      _a = a();
                //  .yield resumeLabel
                //      _a + %sent% + c()
                var clone_6 = ts.getMutableClone(node);
                clone_6.left = cacheExpression(ts.visitNode(node.left, visitor, ts.isExpression));
                clone_6.right = ts.visitNode(node.right, visitor, ts.isExpression);
                return clone_6;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a logical binary expression containing `yield`.
         *
         * @param node A node to visit.
         */
        function visitLogicalBinaryExpression(node) {
            // Logical binary expressions (`&&` and `||`) are shortcutting expressions and need
            // to be transformed as such:
            //
            // [source]
            //      x = a() && yield;
            //
            // [intermediate]
            //  .local _a
            //      _a = a();
            //  .brfalse resultLabel, (_a)
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .mark resultLabel
            //      x = _a;
            //
            // [source]
            //      x = a() || yield;
            //
            // [intermediate]
            //  .local _a
            //      _a = a();
            //  .brtrue resultLabel, (_a)
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .mark resultLabel
            //      x = _a;
            var resultLabel = defineLabel();
            var resultLocal = declareLocal();
            emitAssignment(resultLocal, ts.visitNode(node.left, visitor, ts.isExpression), /*location*/ node.left);
            if (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */) {
                // Logical `&&` shortcuts when the left-hand operand is falsey.
                emitBreakWhenFalse(resultLabel, resultLocal, /*location*/ node.left);
            }
            else {
                // Logical `||` shortcuts when the left-hand operand is truthy.
                emitBreakWhenTrue(resultLabel, resultLocal, /*location*/ node.left);
            }
            emitAssignment(resultLocal, ts.visitNode(node.right, visitor, ts.isExpression), /*location*/ node.right);
            markLabel(resultLabel);
            return resultLocal;
        }
        /**
         * Visits a comma expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitCommaExpression(node) {
            // [source]
            //      x = a(), yield, b();
            //
            // [intermediate]
            //      a();
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      x = %sent%, b();
            var pendingExpressions = [];
            visit(node.left);
            visit(node.right);
            return ts.inlineExpressions(pendingExpressions);
            function visit(node) {
                if (ts.isBinaryExpression(node) && node.operatorToken.kind === 27 /* CommaToken */) {
                    visit(node.left);
                    visit(node.right);
                }
                else {
                    if (containsYield(node) && pendingExpressions.length > 0) {
                        emitWorker(1 /* Statement */, [ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions))]);
                        pendingExpressions = [];
                    }
                    pendingExpressions.push(ts.visitNode(node, visitor, ts.isExpression));
                }
            }
        }
        /**
         * Visits a conditional expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitConditionalExpression(node) {
            // [source]
            //      x = a() ? yield : b();
            //
            // [intermediate]
            //  .local _a
            //  .brfalse whenFalseLabel, (a())
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .br resultLabel
            //  .mark whenFalseLabel
            //      _a = b();
            //  .mark resultLabel
            //      x = _a;
            // We only need to perform a specific transformation if a `yield` expression exists
            // in either the `whenTrue` or `whenFalse` branches.
            // A `yield` in the condition will be handled by the normal visitor.
            if (containsYield(node.whenTrue) || containsYield(node.whenFalse)) {
                var whenFalseLabel = defineLabel();
                var resultLabel = defineLabel();
                var resultLocal = declareLocal();
                emitBreakWhenFalse(whenFalseLabel, ts.visitNode(node.condition, visitor, ts.isExpression), /*location*/ node.condition);
                emitAssignment(resultLocal, ts.visitNode(node.whenTrue, visitor, ts.isExpression), /*location*/ node.whenTrue);
                emitBreak(resultLabel);
                markLabel(whenFalseLabel);
                emitAssignment(resultLocal, ts.visitNode(node.whenFalse, visitor, ts.isExpression), /*location*/ node.whenFalse);
                markLabel(resultLabel);
                return resultLocal;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a `yield` expression.
         *
         * @param node The node to visit.
         */
        function visitYieldExpression(node) {
            // [source]
            //      x = yield a();
            //
            // [intermediate]
            //  .yield resumeLabel, (a())
            //  .mark resumeLabel
            //      x = %sent%;
            var resumeLabel = defineLabel();
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            if (node.asteriskToken) {
                var iterator = (ts.getEmitFlags(node.expression) & 8388608 /* Iterator */) === 0
                    ? ts.createValuesHelper(context, expression, /*location*/ node)
                    : expression;
                emitYieldStar(iterator, /*location*/ node);
            }
            else {
                emitYield(expression, /*location*/ node);
            }
            markLabel(resumeLabel);
            return createGeneratorResume(/*location*/ node);
        }
        /**
         * Visits an ArrayLiteralExpression that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitArrayLiteralExpression(node) {
            return visitElements(node.elements, /*leadingElement*/ undefined, /*location*/ undefined, node.multiLine);
        }
        /**
         * Visits an array of expressions containing one or more YieldExpression nodes
         * and returns an expression for the resulting value.
         *
         * @param elements The elements to visit.
         * @param multiLine Whether array literals created should be emitted on multiple lines.
         */
        function visitElements(elements, leadingElement, location, multiLine) {
            // [source]
            //      ar = [1, yield, 2];
            //
            // [intermediate]
            //  .local _a
            //      _a = [1];
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      ar = _a.concat([%sent%, 2]);
            var numInitialElements = countInitialNodesWithoutYield(elements);
            var temp;
            if (numInitialElements > 0) {
                temp = declareLocal();
                var initialElements = ts.visitNodes(elements, visitor, ts.isExpression, 0, numInitialElements);
                emitAssignment(temp, ts.createArrayLiteral(leadingElement
                    ? __spreadArrays([leadingElement], initialElements) : initialElements));
                leadingElement = undefined;
            }
            var expressions = ts.reduceLeft(elements, reduceElement, [], numInitialElements);
            return temp
                ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
                : ts.setTextRange(ts.createArrayLiteral(leadingElement ? __spreadArrays([leadingElement], expressions) : expressions, multiLine), location);
            function reduceElement(expressions, element) {
                if (containsYield(element) && expressions.length > 0) {
                    var hasAssignedTemp = temp !== undefined;
                    if (!temp) {
                        temp = declareLocal();
                    }
                    emitAssignment(temp, hasAssignedTemp
                        ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
                        : ts.createArrayLiteral(leadingElement ? __spreadArrays([leadingElement], expressions) : expressions, multiLine));
                    leadingElement = undefined;
                    expressions = [];
                }
                expressions.push(ts.visitNode(element, visitor, ts.isExpression));
                return expressions;
            }
        }
        function visitObjectLiteralExpression(node) {
            // [source]
            //      o = {
            //          a: 1,
            //          b: yield,
            //          c: 2
            //      };
            //
            // [intermediate]
            //  .local _a
            //      _a = {
            //          a: 1
            //      };
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      o = (_a.b = %sent%,
            //          _a.c = 2,
            //          _a);
            var properties = node.properties;
            var multiLine = node.multiLine;
            var numInitialProperties = countInitialNodesWithoutYield(properties);
            var temp = declareLocal();
            emitAssignment(temp, ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), multiLine));
            var expressions = ts.reduceLeft(properties, reduceProperty, [], numInitialProperties);
            expressions.push(multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
            return ts.inlineExpressions(expressions);
            function reduceProperty(expressions, property) {
                if (containsYield(property) && expressions.length > 0) {
                    emitStatement(ts.createExpressionStatement(ts.inlineExpressions(expressions)));
                    expressions = [];
                }
                var expression = ts.createExpressionForObjectLiteralElementLike(node, property, temp);
                var visited = ts.visitNode(expression, visitor, ts.isExpression);
                if (visited) {
                    if (multiLine) {
                        ts.startOnNewLine(visited);
                    }
                    expressions.push(visited);
                }
                return expressions;
            }
        }
        /**
         * Visits an ElementAccessExpression that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitElementAccessExpression(node) {
            if (containsYield(node.argumentExpression)) {
                // [source]
                //      a = x[yield];
                //
                // [intermediate]
                //  .local _a
                //      _a = x;
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      a = _a[%sent%]
                var clone_7 = ts.getMutableClone(node);
                clone_7.expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
                clone_7.argumentExpression = ts.visitNode(node.argumentExpression, visitor, ts.isExpression);
                return clone_7;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCallExpression(node) {
            if (!ts.isImportCall(node) && ts.forEach(node.arguments, containsYield)) {
                // [source]
                //      a.b(1, yield, 2);
                //
                // [intermediate]
                //  .local _a, _b, _c
                //      _b = (_a = a).b;
                //      _c = [1];
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      _b.apply(_a, _c.concat([%sent%, 2]));
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true), target = _a.target, thisArg = _a.thisArg;
                return ts.setOriginalNode(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isLeftHandSideExpression)), thisArg, visitElements(node.arguments), 
                /*location*/ node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitNewExpression(node) {
            if (ts.forEach(node.arguments, containsYield)) {
                // [source]
                //      new a.b(1, yield, 2);
                //
                // [intermediate]
                //  .local _a, _b, _c
                //      _b = (_a = a.b).bind;
                //      _c = [1];
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      new (_b.apply(_a, _c.concat([%sent%, 2])));
                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                return ts.setOriginalNode(ts.setTextRange(ts.createNew(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isExpression)), thisArg, visitElements(node.arguments, 
                /*leadingElement*/ ts.createVoidZero())), 
                /*typeArguments*/ undefined, []), node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitStatements(statements, start) {
            if (start === void 0) { start = 0; }
            var numStatements = statements.length;
            for (var i = start; i < numStatements; i++) {
                transformAndEmitStatement(statements[i]);
            }
        }
        function transformAndEmitEmbeddedStatement(node) {
            if (ts.isBlock(node)) {
                transformAndEmitStatements(node.statements);
            }
            else {
                transformAndEmitStatement(node);
            }
        }
        function transformAndEmitStatement(node) {
            var savedInStatementContainingYield = inStatementContainingYield;
            if (!inStatementContainingYield) {
                inStatementContainingYield = containsYield(node);
            }
            transformAndEmitStatementWorker(node);
            inStatementContainingYield = savedInStatementContainingYield;
        }
        function transformAndEmitStatementWorker(node) {
            switch (node.kind) {
                case 223 /* Block */:
                    return transformAndEmitBlock(node);
                case 226 /* ExpressionStatement */:
                    return transformAndEmitExpressionStatement(node);
                case 227 /* IfStatement */:
                    return transformAndEmitIfStatement(node);
                case 228 /* DoStatement */:
                    return transformAndEmitDoStatement(node);
                case 229 /* WhileStatement */:
                    return transformAndEmitWhileStatement(node);
                case 230 /* ForStatement */:
                    return transformAndEmitForStatement(node);
                case 231 /* ForInStatement */:
                    return transformAndEmitForInStatement(node);
                case 233 /* ContinueStatement */:
                    return transformAndEmitContinueStatement(node);
                case 234 /* BreakStatement */:
                    return transformAndEmitBreakStatement(node);
                case 235 /* ReturnStatement */:
                    return transformAndEmitReturnStatement(node);
                case 236 /* WithStatement */:
                    return transformAndEmitWithStatement(node);
                case 237 /* SwitchStatement */:
                    return transformAndEmitSwitchStatement(node);
                case 238 /* LabeledStatement */:
                    return transformAndEmitLabeledStatement(node);
                case 239 /* ThrowStatement */:
                    return transformAndEmitThrowStatement(node);
                case 240 /* TryStatement */:
                    return transformAndEmitTryStatement(node);
                default:
                    return emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitBlock(node) {
            if (containsYield(node)) {
                transformAndEmitStatements(node.statements);
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitExpressionStatement(node) {
            emitStatement(ts.visitNode(node, visitor, ts.isStatement));
        }
        function transformAndEmitVariableDeclarationList(node) {
            for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
                var variable = _a[_i];
                var name = ts.getSynthesizedClone(variable.name);
                ts.setCommentRange(name, variable.name);
                hoistVariableDeclaration(name);
            }
            var variables = ts.getInitializedVariables(node);
            var numVariables = variables.length;
            var variablesWritten = 0;
            var pendingExpressions = [];
            while (variablesWritten < numVariables) {
                for (var i = variablesWritten; i < numVariables; i++) {
                    var variable = variables[i];
                    if (containsYield(variable.initializer) && pendingExpressions.length > 0) {
                        break;
                    }
                    pendingExpressions.push(transformInitializedVariable(variable));
                }
                if (pendingExpressions.length) {
                    emitStatement(ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions)));
                    variablesWritten += pendingExpressions.length;
                    pendingExpressions = [];
                }
            }
            return undefined;
        }
        function transformInitializedVariable(node) {
            return ts.setSourceMapRange(ts.createAssignment(ts.setSourceMapRange(ts.getSynthesizedClone(node.name), node.name), ts.visitNode(node.initializer, visitor, ts.isExpression)), node);
        }
        function transformAndEmitIfStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      if (x)
                //          /*thenStatement*/
                //      else
                //          /*elseStatement*/
                //
                // [intermediate]
                //  .brfalse elseLabel, (x)
                //      /*thenStatement*/
                //  .br endLabel
                //  .mark elseLabel
                //      /*elseStatement*/
                //  .mark endLabel
                if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) {
                    var endLabel = defineLabel();
                    var elseLabel = node.elseStatement ? defineLabel() : undefined;
                    emitBreakWhenFalse(node.elseStatement ? elseLabel : endLabel, ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node.expression);
                    transformAndEmitEmbeddedStatement(node.thenStatement);
                    if (node.elseStatement) {
                        emitBreak(endLabel);
                        markLabel(elseLabel);
                        transformAndEmitEmbeddedStatement(node.elseStatement);
                    }
                    markLabel(endLabel);
                }
                else {
                    emitStatement(ts.visitNode(node, visitor, ts.isStatement));
                }
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitDoStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      do {
                //          /*body*/
                //      }
                //      while (i < 10);
                //
                // [intermediate]
                //  .loop conditionLabel, endLabel
                //  .mark loopLabel
                //      /*body*/
                //  .mark conditionLabel
                //  .brtrue loopLabel, (i < 10)
                //  .endloop
                //  .mark endLabel
                var conditionLabel = defineLabel();
                var loopLabel = defineLabel();
                beginLoopBlock(/*continueLabel*/ conditionLabel);
                markLabel(loopLabel);
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(conditionLabel);
                emitBreakWhenTrue(loopLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitDoStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
                node = ts.visitEachChild(node, visitor, context);
                endLoopBlock();
                return node;
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformAndEmitWhileStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      while (i < 10) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .loop loopLabel, endLabel
                //  .mark loopLabel
                //  .brfalse endLabel, (i < 10)
                //      /*body*/
                //  .br loopLabel
                //  .endloop
                //  .mark endLabel
                var loopLabel = defineLabel();
                var endLabel = beginLoopBlock(loopLabel);
                markLabel(loopLabel);
                emitBreakWhenFalse(endLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
                transformAndEmitEmbeddedStatement(node.statement);
                emitBreak(loopLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitWhileStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
                node = ts.visitEachChild(node, visitor, context);
                endLoopBlock();
                return node;
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformAndEmitForStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      for (var i = 0; i < 10; i++) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .local i
                //      i = 0;
                //  .loop incrementLabel, endLoopLabel
                //  .mark conditionLabel
                //  .brfalse endLoopLabel, (i < 10)
                //      /*body*/
                //  .mark incrementLabel
                //      i++;
                //  .br conditionLabel
                //  .endloop
                //  .mark endLoopLabel
                var conditionLabel = defineLabel();
                var incrementLabel = defineLabel();
                var endLabel = beginLoopBlock(incrementLabel);
                if (node.initializer) {
                    var initializer = node.initializer;
                    if (ts.isVariableDeclarationList(initializer)) {
                        transformAndEmitVariableDeclarationList(initializer);
                    }
                    else {
                        emitStatement(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(initializer, visitor, ts.isExpression)), initializer));
                    }
                }
                markLabel(conditionLabel);
                if (node.condition) {
                    emitBreakWhenFalse(endLabel, ts.visitNode(node.condition, visitor, ts.isExpression));
                }
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(incrementLabel);
                if (node.incrementor) {
                    emitStatement(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), node.incrementor));
                }
                emitBreak(conditionLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitForStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
            }
            var initializer = node.initializer;
            if (initializer && ts.isVariableDeclarationList(initializer)) {
                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                var variables = ts.getInitializedVariables(initializer);
                node = ts.updateFor(node, variables.length > 0
                    ? ts.inlineExpressions(ts.map(variables, transformInitializedVariable))
                    : undefined, ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            }
            else {
                node = ts.visitEachChild(node, visitor, context);
            }
            if (inStatementContainingYield) {
                endLoopBlock();
            }
            return node;
        }
        function transformAndEmitForInStatement(node) {
            // TODO(rbuckton): Source map locations
            if (containsYield(node)) {
                // [source]
                //      for (var p in o) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .local _a, _b, _i
                //      _a = [];
                //      for (_b in o) _a.push(_b);
                //      _i = 0;
                //  .loop incrementLabel, endLoopLabel
                //  .mark conditionLabel
                //  .brfalse endLoopLabel, (_i < _a.length)
                //      p = _a[_i];
                //      /*body*/
                //  .mark incrementLabel
                //      _b++;
                //  .br conditionLabel
                //  .endloop
                //  .mark endLoopLabel
                var keysArray = declareLocal(); // _a
                var key = declareLocal(); // _b
                var keysIndex = ts.createLoopVariable(); // _i
                var initializer = node.initializer;
                hoistVariableDeclaration(keysIndex);
                emitAssignment(keysArray, ts.createArrayLiteral());
                emitStatement(ts.createForIn(key, ts.visitNode(node.expression, visitor, ts.isExpression), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(keysArray, "push"), 
                /*typeArguments*/ undefined, [key]))));
                emitAssignment(keysIndex, ts.createLiteral(0));
                var conditionLabel = defineLabel();
                var incrementLabel = defineLabel();
                var endLabel = beginLoopBlock(incrementLabel);
                markLabel(conditionLabel);
                emitBreakWhenFalse(endLabel, ts.createLessThan(keysIndex, ts.createPropertyAccess(keysArray, "length")));
                var variable = void 0;
                if (ts.isVariableDeclarationList(initializer)) {
                    for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                        var variable_1 = _a[_i];
                        hoistVariableDeclaration(variable_1.name);
                    }
                    variable = ts.getSynthesizedClone(initializer.declarations[0].name);
                }
                else {
                    variable = ts.visitNode(initializer, visitor, ts.isExpression);
                    ts.Debug.assert(ts.isLeftHandSideExpression(variable));
                }
                emitAssignment(variable, ts.createElementAccess(keysArray, keysIndex));
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(incrementLabel);
                emitStatement(ts.createExpressionStatement(ts.createPostfixIncrement(keysIndex)));
                emitBreak(conditionLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitForInStatement(node) {
            // [source]
            //      for (var x in a) {
            //          /*body*/
            //      }
            //
            // [intermediate]
            //  .local x
            //  .loop
            //      for (x in a) {
            //          /*body*/
            //      }
            //  .endloop
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
            }
            var initializer = node.initializer;
            if (ts.isVariableDeclarationList(initializer)) {
                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                node = ts.updateForIn(node, initializer.declarations[0].name, ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            }
            else {
                node = ts.visitEachChild(node, visitor, context);
            }
            if (inStatementContainingYield) {
                endLoopBlock();
            }
            return node;
        }
        function transformAndEmitContinueStatement(node) {
            var label = findContinueTarget(node.label ? ts.idText(node.label) : undefined);
            if (label > 0) {
                emitBreak(label, /*location*/ node);
            }
            else {
                // invalid continue without a containing loop. Leave the node as is, per #17875.
                emitStatement(node);
            }
        }
        function visitContinueStatement(node) {
            if (inStatementContainingYield) {
                var label = findContinueTarget(node.label && ts.idText(node.label));
                if (label > 0) {
                    return createInlineBreak(label, /*location*/ node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitBreakStatement(node) {
            var label = findBreakTarget(node.label ? ts.idText(node.label) : undefined);
            if (label > 0) {
                emitBreak(label, /*location*/ node);
            }
            else {
                // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875.
                emitStatement(node);
            }
        }
        function visitBreakStatement(node) {
            if (inStatementContainingYield) {
                var label = findBreakTarget(node.label && ts.idText(node.label));
                if (label > 0) {
                    return createInlineBreak(label, /*location*/ node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitReturnStatement(node) {
            emitReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function visitReturnStatement(node) {
            return createInlineReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function transformAndEmitWithStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      with (x) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .with (x)
                //      /*body*/
                //  .endwith
                beginWithBlock(cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression)));
                transformAndEmitEmbeddedStatement(node.statement);
                endWithBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitSwitchStatement(node) {
            if (containsYield(node.caseBlock)) {
                // [source]
                //      switch (x) {
                //          case a:
                //              /*caseStatements*/
                //          case b:
                //              /*caseStatements*/
                //          default:
                //              /*defaultStatements*/
                //      }
                //
                // [intermediate]
                //  .local _a
                //  .switch endLabel
                //      _a = x;
                //      switch (_a) {
                //          case a:
                //  .br clauseLabels[0]
                //      }
                //      switch (_a) {
                //          case b:
                //  .br clauseLabels[1]
                //      }
                //  .br clauseLabels[2]
                //  .mark clauseLabels[0]
                //      /*caseStatements*/
                //  .mark clauseLabels[1]
                //      /*caseStatements*/
                //  .mark clauseLabels[2]
                //      /*caseStatements*/
                //  .endswitch
                //  .mark endLabel
                var caseBlock = node.caseBlock;
                var numClauses = caseBlock.clauses.length;
                var endLabel = beginSwitchBlock();
                var expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression));
                // Create labels for each clause and find the index of the first default clause.
                var clauseLabels = [];
                var defaultClauseIndex = -1;
                for (var i = 0; i < numClauses; i++) {
                    var clause = caseBlock.clauses[i];
                    clauseLabels.push(defineLabel());
                    if (clause.kind === 278 /* DefaultClause */ && defaultClauseIndex === -1) {
                        defaultClauseIndex = i;
                    }
                }
                // Emit switch statements for each run of case clauses either from the first case
                // clause or the next case clause with a `yield` in its expression, up to the next
                // case clause with a `yield` in its expression.
                var clausesWritten = 0;
                var pendingClauses = [];
                while (clausesWritten < numClauses) {
                    var defaultClausesSkipped = 0;
                    for (var i = clausesWritten; i < numClauses; i++) {
                        var clause = caseBlock.clauses[i];
                        if (clause.kind === 277 /* CaseClause */) {
                            if (containsYield(clause.expression) && pendingClauses.length > 0) {
                                break;
                            }
                            pendingClauses.push(ts.createCaseClause(ts.visitNode(clause.expression, visitor, ts.isExpression), [
                                createInlineBreak(clauseLabels[i], /*location*/ clause.expression)
                            ]));
                        }
                        else {
                            defaultClausesSkipped++;
                        }
                    }
                    if (pendingClauses.length) {
                        emitStatement(ts.createSwitch(expression, ts.createCaseBlock(pendingClauses)));
                        clausesWritten += pendingClauses.length;
                        pendingClauses = [];
                    }
                    if (defaultClausesSkipped > 0) {
                        clausesWritten += defaultClausesSkipped;
                        defaultClausesSkipped = 0;
                    }
                }
                if (defaultClauseIndex >= 0) {
                    emitBreak(clauseLabels[defaultClauseIndex]);
                }
                else {
                    emitBreak(endLabel);
                }
                for (var i = 0; i < numClauses; i++) {
                    markLabel(clauseLabels[i]);
                    transformAndEmitStatements(caseBlock.clauses[i].statements);
                }
                endSwitchBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitSwitchStatement(node) {
            if (inStatementContainingYield) {
                beginScriptSwitchBlock();
            }
            node = ts.visitEachChild(node, visitor, context);
            if (inStatementContainingYield) {
                endSwitchBlock();
            }
            return node;
        }
        function transformAndEmitLabeledStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      x: {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .labeled "x", endLabel
                //      /*body*/
                //  .endlabeled
                //  .mark endLabel
                beginLabeledBlock(ts.idText(node.label));
                transformAndEmitEmbeddedStatement(node.statement);
                endLabeledBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitLabeledStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLabeledBlock(ts.idText(node.label));
            }
            node = ts.visitEachChild(node, visitor, context);
            if (inStatementContainingYield) {
                endLabeledBlock();
            }
            return node;
        }
        function transformAndEmitThrowStatement(node) {
            emitThrow(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function transformAndEmitTryStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      try {
                //          /*tryBlock*/
                //      }
                //      catch (e) {
                //          /*catchBlock*/
                //      }
                //      finally {
                //          /*finallyBlock*/
                //      }
                //
                // [intermediate]
                //  .local _a
                //  .try tryLabel, catchLabel, finallyLabel, endLabel
                //  .mark tryLabel
                //  .nop
                //      /*tryBlock*/
                //  .br endLabel
                //  .catch
                //  .mark catchLabel
                //      _a = %error%;
                //      /*catchBlock*/
                //  .br endLabel
                //  .finally
                //  .mark finallyLabel
                //      /*finallyBlock*/
                //  .endfinally
                //  .endtry
                //  .mark endLabel
                beginExceptionBlock();
                transformAndEmitEmbeddedStatement(node.tryBlock);
                if (node.catchClause) {
                    beginCatchBlock(node.catchClause.variableDeclaration); // TODO: GH#18217
                    transformAndEmitEmbeddedStatement(node.catchClause.block);
                }
                if (node.finallyBlock) {
                    beginFinallyBlock();
                    transformAndEmitEmbeddedStatement(node.finallyBlock);
                }
                endExceptionBlock();
            }
            else {
                emitStatement(ts.visitEachChild(node, visitor, context));
            }
        }
        function containsYield(node) {
            return !!node && (node.transformFlags & 262144 /* ContainsYield */) !== 0;
        }
        function countInitialNodesWithoutYield(nodes) {
            var numNodes = nodes.length;
            for (var i = 0; i < numNodes; i++) {
                if (containsYield(nodes[i])) {
                    return i;
                }
            }
            return -1;
        }
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            if (ts.isIdentifier(node)) {
                return substituteExpressionIdentifier(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            if (!ts.isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(ts.idText(node))) {
                var original = ts.getOriginalNode(node);
                if (ts.isIdentifier(original) && original.parent) {
                    var declaration = resolver.getReferencedValueDeclaration(original);
                    if (declaration) {
                        var name = renamedCatchVariableDeclarations[ts.getOriginalNodeId(declaration)];
                        if (name) {
                            var clone_8 = ts.getMutableClone(name);
                            ts.setSourceMapRange(clone_8, node);
                            ts.setCommentRange(clone_8, node);
                            return clone_8;
                        }
                    }
                }
            }
            return node;
        }
        function cacheExpression(node) {
            if (ts.isGeneratedIdentifier(node) || ts.getEmitFlags(node) & 4096 /* HelperName */) {
                return node;
            }
            var temp = ts.createTempVariable(hoistVariableDeclaration);
            emitAssignment(temp, node, /*location*/ node);
            return temp;
        }
        function declareLocal(name) {
            var temp = name
                ? ts.createUniqueName(name)
                : ts.createTempVariable(/*recordTempVariable*/ undefined);
            hoistVariableDeclaration(temp);
            return temp;
        }
        /**
         * Defines a label, uses as the target of a Break operation.
         */
        function defineLabel() {
            if (!labelOffsets) {
                labelOffsets = [];
            }
            var label = nextLabelId;
            nextLabelId++;
            labelOffsets[label] = -1;
            return label;
        }
        /**
         * Marks the current operation with the specified label.
         */
        function markLabel(label) {
            ts.Debug.assert(labelOffsets !== undefined, "No labels were defined.");
            labelOffsets[label] = operations ? operations.length : 0;
        }
        /**
         * Begins a block operation (With, Break/Continue, Try/Catch/Finally)
         *
         * @param block Information about the block.
         */
        function beginBlock(block) {
            if (!blocks) {
                blocks = [];
                blockActions = [];
                blockOffsets = [];
                blockStack = [];
            }
            var index = blockActions.length;
            blockActions[index] = 0 /* Open */;
            blockOffsets[index] = operations ? operations.length : 0;
            blocks[index] = block;
            blockStack.push(block);
            return index;
        }
        /**
         * Ends the current block operation.
         */
        function endBlock() {
            var block = peekBlock();
            if (block === undefined)
                return ts.Debug.fail("beginBlock was never called.");
            var index = blockActions.length;
            blockActions[index] = 1 /* Close */;
            blockOffsets[index] = operations ? operations.length : 0;
            blocks[index] = block;
            blockStack.pop();
            return block;
        }
        /**
         * Gets the current open block.
         */
        function peekBlock() {
            return ts.lastOrUndefined(blockStack);
        }
        /**
         * Gets the kind of the current open block.
         */
        function peekBlockKind() {
            var block = peekBlock();
            return block && block.kind;
        }
        /**
         * Begins a code block for a generated `with` statement.
         *
         * @param expression An identifier representing expression for the `with` block.
         */
        function beginWithBlock(expression) {
            var startLabel = defineLabel();
            var endLabel = defineLabel();
            markLabel(startLabel);
            beginBlock({
                kind: 1 /* With */,
                expression: expression,
                startLabel: startLabel,
                endLabel: endLabel
            });
        }
        /**
         * Ends a code block for a generated `with` statement.
         */
        function endWithBlock() {
            ts.Debug.assert(peekBlockKind() === 1 /* With */);
            var block = endBlock();
            markLabel(block.endLabel);
        }
        /**
         * Begins a code block for a generated `try` statement.
         */
        function beginExceptionBlock() {
            var startLabel = defineLabel();
            var endLabel = defineLabel();
            markLabel(startLabel);
            beginBlock({
                kind: 0 /* Exception */,
                state: 0 /* Try */,
                startLabel: startLabel,
                endLabel: endLabel
            });
            emitNop();
            return endLabel;
        }
        /**
         * Enters the `catch` clause of a generated `try` statement.
         *
         * @param variable The catch variable.
         */
        function beginCatchBlock(variable) {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            // generated identifiers should already be unique within a file
            var name;
            if (ts.isGeneratedIdentifier(variable.name)) {
                name = variable.name;
                hoistVariableDeclaration(variable.name);
            }
            else {
                var text = ts.idText(variable.name);
                name = declareLocal(text);
                if (!renamedCatchVariables) {
                    renamedCatchVariables = ts.createMap();
                    renamedCatchVariableDeclarations = [];
                    context.enableSubstitution(75 /* Identifier */);
                }
                renamedCatchVariables.set(text, true);
                renamedCatchVariableDeclarations[ts.getOriginalNodeId(variable)] = name;
            }
            var exception = peekBlock();
            ts.Debug.assert(exception.state < 1 /* Catch */);
            var endLabel = exception.endLabel;
            emitBreak(endLabel);
            var catchLabel = defineLabel();
            markLabel(catchLabel);
            exception.state = 1 /* Catch */;
            exception.catchVariable = name;
            exception.catchLabel = catchLabel;
            emitAssignment(name, ts.createCall(ts.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, []));
            emitNop();
        }
        /**
         * Enters the `finally` block of a generated `try` statement.
         */
        function beginFinallyBlock() {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            var exception = peekBlock();
            ts.Debug.assert(exception.state < 2 /* Finally */);
            var endLabel = exception.endLabel;
            emitBreak(endLabel);
            var finallyLabel = defineLabel();
            markLabel(finallyLabel);
            exception.state = 2 /* Finally */;
            exception.finallyLabel = finallyLabel;
        }
        /**
         * Ends the code block for a generated `try` statement.
         */
        function endExceptionBlock() {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            var exception = endBlock();
            var state = exception.state;
            if (state < 2 /* Finally */) {
                emitBreak(exception.endLabel);
            }
            else {
                emitEndfinally();
            }
            markLabel(exception.endLabel);
            emitNop();
            exception.state = 3 /* Done */;
        }
        /**
         * Begins a code block that supports `break` or `continue` statements that are defined in
         * the source tree and not from generated code.
         *
         * @param labelText Names from containing labeled statements.
         */
        function beginScriptLoopBlock() {
            beginBlock({
                kind: 3 /* Loop */,
                isScript: true,
                breakLabel: -1,
                continueLabel: -1
            });
        }
        /**
         * Begins a code block that supports `break` or `continue` statements that are defined in
         * generated code. Returns a label used to mark the operation to which to jump when a
         * `break` statement targets this block.
         *
         * @param continueLabel A Label used to mark the operation to which to jump when a
         *                      `continue` statement targets this block.
         */
        function beginLoopBlock(continueLabel) {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 3 /* Loop */,
                isScript: false,
                breakLabel: breakLabel,
                continueLabel: continueLabel,
            });
            return breakLabel;
        }
        /**
         * Ends a code block that supports `break` or `continue` statements that are defined in
         * generated code or in the source tree.
         */
        function endLoopBlock() {
            ts.Debug.assert(peekBlockKind() === 3 /* Loop */);
            var block = endBlock();
            var breakLabel = block.breakLabel;
            if (!block.isScript) {
                markLabel(breakLabel);
            }
        }
        /**
         * Begins a code block that supports `break` statements that are defined in the source
         * tree and not from generated code.
         *
         */
        function beginScriptSwitchBlock() {
            beginBlock({
                kind: 2 /* Switch */,
                isScript: true,
                breakLabel: -1
            });
        }
        /**
         * Begins a code block that supports `break` statements that are defined in generated code.
         * Returns a label used to mark the operation to which to jump when a `break` statement
         * targets this block.
         */
        function beginSwitchBlock() {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 2 /* Switch */,
                isScript: false,
                breakLabel: breakLabel,
            });
            return breakLabel;
        }
        /**
         * Ends a code block that supports `break` statements that are defined in generated code.
         */
        function endSwitchBlock() {
            ts.Debug.assert(peekBlockKind() === 2 /* Switch */);
            var block = endBlock();
            var breakLabel = block.breakLabel;
            if (!block.isScript) {
                markLabel(breakLabel);
            }
        }
        function beginScriptLabeledBlock(labelText) {
            beginBlock({
                kind: 4 /* Labeled */,
                isScript: true,
                labelText: labelText,
                breakLabel: -1
            });
        }
        function beginLabeledBlock(labelText) {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 4 /* Labeled */,
                isScript: false,
                labelText: labelText,
                breakLabel: breakLabel
            });
        }
        function endLabeledBlock() {
            ts.Debug.assert(peekBlockKind() === 4 /* Labeled */);
            var block = endBlock();
            if (!block.isScript) {
                markLabel(block.breakLabel);
            }
        }
        /**
         * Indicates whether the provided block supports `break` statements.
         *
         * @param block A code block.
         */
        function supportsUnlabeledBreak(block) {
            return block.kind === 2 /* Switch */
                || block.kind === 3 /* Loop */;
        }
        /**
         * Indicates whether the provided block supports `break` statements with labels.
         *
         * @param block A code block.
         */
        function supportsLabeledBreakOrContinue(block) {
            return block.kind === 4 /* Labeled */;
        }
        /**
         * Indicates whether the provided block supports `continue` statements.
         *
         * @param block A code block.
         */
        function supportsUnlabeledContinue(block) {
            return block.kind === 3 /* Loop */;
        }
        function hasImmediateContainingLabeledBlock(labelText, start) {
            for (var j = start; j >= 0; j--) {
                var containingBlock = blockStack[j];
                if (supportsLabeledBreakOrContinue(containingBlock)) {
                    if (containingBlock.labelText === labelText) {
                        return true;
                    }
                }
                else {
                    break;
                }
            }
            return false;
        }
        /**
         * Finds the label that is the target for a `break` statement.
         *
         * @param labelText An optional name of a containing labeled statement.
         */
        function findBreakTarget(labelText) {
            if (blockStack) {
                if (labelText) {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
                            return block.breakLabel;
                        }
                        else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
                            return block.breakLabel;
                        }
                    }
                }
                else {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledBreak(block)) {
                            return block.breakLabel;
                        }
                    }
                }
            }
            return 0;
        }
        /**
         * Finds the label that is the target for a `continue` statement.
         *
         * @param labelText An optional name of a containing labeled statement.
         */
        function findContinueTarget(labelText) {
            if (blockStack) {
                if (labelText) {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
                            return block.continueLabel;
                        }
                    }
                }
                else {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledContinue(block)) {
                            return block.continueLabel;
                        }
                    }
                }
            }
            return 0;
        }
        /**
         * Creates an expression that can be used to indicate the value for a label.
         *
         * @param label A label.
         */
        function createLabel(label) {
            if (label !== undefined && label > 0) {
                if (labelExpressions === undefined) {
                    labelExpressions = [];
                }
                var expression = ts.createLiteral(-1);
                if (labelExpressions[label] === undefined) {
                    labelExpressions[label] = [expression];
                }
                else {
                    labelExpressions[label].push(expression);
                }
                return expression;
            }
            return ts.createOmittedExpression();
        }
        /**
         * Creates a numeric literal for the provided instruction.
         */
        function createInstruction(instruction) {
            var literal = ts.createLiteral(instruction);
            ts.addSyntheticTrailingComment(literal, 3 /* MultiLineCommentTrivia */, getInstructionName(instruction));
            return literal;
        }
        /**
         * Creates a statement that can be used indicate a Break operation to the provided label.
         *
         * @param label A label.
         * @param location An optional source map location for the statement.
         */
        function createInlineBreak(label, location) {
            ts.Debug.assertLessThan(0, label, "Invalid label");
            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), location);
        }
        /**
         * Creates a statement that can be used indicate a Return operation.
         *
         * @param expression The expression for the return statement.
         * @param location An optional source map location for the statement.
         */
        function createInlineReturn(expression, location) {
            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(2 /* Return */), expression]
                : [createInstruction(2 /* Return */)])), location);
        }
        /**
         * Creates an expression that can be used to resume from a Yield operation.
         */
        function createGeneratorResume(location) {
            return ts.setTextRange(ts.createCall(ts.createPropertyAccess(state, "sent"), 
            /*typeArguments*/ undefined, []), location);
        }
        /**
         * Emits an empty instruction.
         */
        function emitNop() {
            emitWorker(0 /* Nop */);
        }
        /**
         * Emits a Statement.
         *
         * @param node A statement.
         */
        function emitStatement(node) {
            if (node) {
                emitWorker(1 /* Statement */, [node]);
            }
            else {
                emitNop();
            }
        }
        /**
         * Emits an Assignment operation.
         *
         * @param left The left-hand side of the assignment.
         * @param right The right-hand side of the assignment.
         * @param location An optional source map location for the assignment.
         */
        function emitAssignment(left, right, location) {
            emitWorker(2 /* Assign */, [left, right], location);
        }
        /**
         * Emits a Break operation to the specified label.
         *
         * @param label A label.
         * @param location An optional source map location for the assignment.
         */
        function emitBreak(label, location) {
            emitWorker(3 /* Break */, [label], location);
        }
        /**
         * Emits a Break operation to the specified label when a condition evaluates to a truthy
         * value at runtime.
         *
         * @param label A label.
         * @param condition The condition.
         * @param location An optional source map location for the assignment.
         */
        function emitBreakWhenTrue(label, condition, location) {
            emitWorker(4 /* BreakWhenTrue */, [label, condition], location);
        }
        /**
         * Emits a Break to the specified label when a condition evaluates to a falsey value at
         * runtime.
         *
         * @param label A label.
         * @param condition The condition.
         * @param location An optional source map location for the assignment.
         */
        function emitBreakWhenFalse(label, condition, location) {
            emitWorker(5 /* BreakWhenFalse */, [label, condition], location);
        }
        /**
         * Emits a YieldStar operation for the provided expression.
         *
         * @param expression An optional value for the yield operation.
         * @param location An optional source map location for the assignment.
         */
        function emitYieldStar(expression, location) {
            emitWorker(7 /* YieldStar */, [expression], location);
        }
        /**
         * Emits a Yield operation for the provided expression.
         *
         * @param expression An optional value for the yield operation.
         * @param location An optional source map location for the assignment.
         */
        function emitYield(expression, location) {
            emitWorker(6 /* Yield */, [expression], location);
        }
        /**
         * Emits a Return operation for the provided expression.
         *
         * @param expression An optional value for the operation.
         * @param location An optional source map location for the assignment.
         */
        function emitReturn(expression, location) {
            emitWorker(8 /* Return */, [expression], location);
        }
        /**
         * Emits a Throw operation for the provided expression.
         *
         * @param expression A value for the operation.
         * @param location An optional source map location for the assignment.
         */
        function emitThrow(expression, location) {
            emitWorker(9 /* Throw */, [expression], location);
        }
        /**
         * Emits an Endfinally operation. This is used to handle `finally` block semantics.
         */
        function emitEndfinally() {
            emitWorker(10 /* Endfinally */);
        }
        /**
         * Emits an operation.
         *
         * @param code The OpCode for the operation.
         * @param args The optional arguments for the operation.
         */
        function emitWorker(code, args, location) {
            if (operations === undefined) {
                operations = [];
                operationArguments = [];
                operationLocations = [];
            }
            if (labelOffsets === undefined) {
                // mark entry point
                markLabel(defineLabel());
            }
            var operationIndex = operations.length;
            operations[operationIndex] = code;
            operationArguments[operationIndex] = args;
            operationLocations[operationIndex] = location;
        }
        /**
         * Builds the generator function body.
         */
        function build() {
            blockIndex = 0;
            labelNumber = 0;
            labelNumbers = undefined;
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            clauses = undefined;
            statements = undefined;
            exceptionBlockStack = undefined;
            currentExceptionBlock = undefined;
            withBlockStack = undefined;
            var buildResult = buildStatements();
            return createGeneratorHelper(context, ts.setEmitFlags(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)], 
            /*type*/ undefined, ts.createBlock(buildResult, 
            /*multiLine*/ buildResult.length > 0)), 524288 /* ReuseTempVariableScope */));
        }
        /**
         * Builds the statements for the generator function body.
         */
        function buildStatements() {
            if (operations) {
                for (var operationIndex = 0; operationIndex < operations.length; operationIndex++) {
                    writeOperation(operationIndex);
                }
                flushFinalLabel(operations.length);
            }
            else {
                flushFinalLabel(0);
            }
            if (clauses) {
                var labelExpression = ts.createPropertyAccess(state, "label");
                var switchStatement = ts.createSwitch(labelExpression, ts.createCaseBlock(clauses));
                return [ts.startOnNewLine(switchStatement)];
            }
            if (statements) {
                return statements;
            }
            return [];
        }
        /**
         * Flush the current label and advance to a new label.
         */
        function flushLabel() {
            if (!statements) {
                return;
            }
            appendLabel(/*markLabelEnd*/ !lastOperationWasAbrupt);
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            labelNumber++;
        }
        /**
         * Flush the final label of the generator function body.
         */
        function flushFinalLabel(operationIndex) {
            if (isFinalLabelReachable(operationIndex)) {
                tryEnterLabel(operationIndex);
                withBlockStack = undefined;
                writeReturn(/*expression*/ undefined, /*operationLocation*/ undefined);
            }
            if (statements && clauses) {
                appendLabel(/*markLabelEnd*/ false);
            }
            updateLabelExpressions();
        }
        /**
         * Tests whether the final label of the generator function body
         * is reachable by user code.
         */
        function isFinalLabelReachable(operationIndex) {
            // if the last operation was *not* a completion (return/throw) then
            // the final label is reachable.
            if (!lastOperationWasCompletion) {
                return true;
            }
            // if there are no labels defined or referenced, then the final label is
            // not reachable.
            if (!labelOffsets || !labelExpressions) {
                return false;
            }
            // if the label for this offset is referenced, then the final label
            // is reachable.
            for (var label = 0; label < labelOffsets.length; label++) {
                if (labelOffsets[label] === operationIndex && labelExpressions[label]) {
                    return true;
                }
            }
            return false;
        }
        /**
         * Appends a case clause for the last label and sets the new label.
         *
         * @param markLabelEnd Indicates that the transition between labels was a fall-through
         *                     from a previous case clause and the change in labels should be
         *                     reflected on the `state` object.
         */
        function appendLabel(markLabelEnd) {
            if (!clauses) {
                clauses = [];
            }
            if (statements) {
                if (withBlockStack) {
                    // The previous label was nested inside one or more `with` blocks, so we
                    // surround the statements in generated `with` blocks to create the same environment.
                    for (var i = withBlockStack.length - 1; i >= 0; i--) {
                        var withBlock = withBlockStack[i];
                        statements = [ts.createWith(withBlock.expression, ts.createBlock(statements))];
                    }
                }
                if (currentExceptionBlock) {
                    // The previous label was nested inside of an exception block, so we must
                    // indicate entry into a protected region by pushing the label numbers
                    // for each block in the protected region.
                    var startLabel = currentExceptionBlock.startLabel, catchLabel = currentExceptionBlock.catchLabel, finallyLabel = currentExceptionBlock.finallyLabel, endLabel = currentExceptionBlock.endLabel;
                    statements.unshift(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(state, "trys"), "push"), 
                    /*typeArguments*/ undefined, [
                        ts.createArrayLiteral([
                            createLabel(startLabel),
                            createLabel(catchLabel),
                            createLabel(finallyLabel),
                            createLabel(endLabel)
                        ])
                    ])));
                    currentExceptionBlock = undefined;
                }
                if (markLabelEnd) {
                    // The case clause for the last label falls through to this label, so we
                    // add an assignment statement to reflect the change in labels.
                    statements.push(ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(state, "label"), ts.createLiteral(labelNumber + 1))));
                }
            }
            clauses.push(ts.createCaseClause(ts.createLiteral(labelNumber), statements || []));
            statements = undefined;
        }
        /**
         * Tries to enter into a new label at the current operation index.
         */
        function tryEnterLabel(operationIndex) {
            if (!labelOffsets) {
                return;
            }
            for (var label = 0; label < labelOffsets.length; label++) {
                if (labelOffsets[label] === operationIndex) {
                    flushLabel();
                    if (labelNumbers === undefined) {
                        labelNumbers = [];
                    }
                    if (labelNumbers[labelNumber] === undefined) {
                        labelNumbers[labelNumber] = [label];
                    }
                    else {
                        labelNumbers[labelNumber].push(label);
                    }
                }
            }
        }
        /**
         * Updates literal expressions for labels with actual label numbers.
         */
        function updateLabelExpressions() {
            if (labelExpressions !== undefined && labelNumbers !== undefined) {
                for (var labelNumber_1 = 0; labelNumber_1 < labelNumbers.length; labelNumber_1++) {
                    var labels = labelNumbers[labelNumber_1];
                    if (labels !== undefined) {
                        for (var _i = 0, labels_1 = labels; _i < labels_1.length; _i++) {
                            var label = labels_1[_i];
                            var expressions = labelExpressions[label];
                            if (expressions !== undefined) {
                                for (var _a = 0, expressions_1 = expressions; _a < expressions_1.length; _a++) {
                                    var expression = expressions_1[_a];
                                    expression.text = String(labelNumber_1);
                                }
                            }
                        }
                    }
                }
            }
        }
        /**
         * Tries to enter or leave a code block.
         */
        function tryEnterOrLeaveBlock(operationIndex) {
            if (blocks) {
                for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) {
                    var block = blocks[blockIndex];
                    var blockAction = blockActions[blockIndex];
                    switch (block.kind) {
                        case 0 /* Exception */:
                            if (blockAction === 0 /* Open */) {
                                if (!exceptionBlockStack) {
                                    exceptionBlockStack = [];
                                }
                                if (!statements) {
                                    statements = [];
                                }
                                exceptionBlockStack.push(currentExceptionBlock);
                                currentExceptionBlock = block;
                            }
                            else if (blockAction === 1 /* Close */) {
                                currentExceptionBlock = exceptionBlockStack.pop();
                            }
                            break;
                        case 1 /* With */:
                            if (blockAction === 0 /* Open */) {
                                if (!withBlockStack) {
                                    withBlockStack = [];
                                }
                                withBlockStack.push(block);
                            }
                            else if (blockAction === 1 /* Close */) {
                                withBlockStack.pop();
                            }
                            break;
                        // default: do nothing
                    }
                }
            }
        }
        /**
         * Writes an operation as a statement to the current label's statement list.
         *
         * @param operation The OpCode of the operation
         */
        function writeOperation(operationIndex) {
            tryEnterLabel(operationIndex);
            tryEnterOrLeaveBlock(operationIndex);
            // early termination, nothing else to process in this label
            if (lastOperationWasAbrupt) {
                return;
            }
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            var opcode = operations[operationIndex];
            if (opcode === 0 /* Nop */) {
                return;
            }
            else if (opcode === 10 /* Endfinally */) {
                return writeEndfinally();
            }
            var args = operationArguments[operationIndex];
            if (opcode === 1 /* Statement */) {
                return writeStatement(args[0]);
            }
            var location = operationLocations[operationIndex];
            switch (opcode) {
                case 2 /* Assign */:
                    return writeAssign(args[0], args[1], location);
                case 3 /* Break */:
                    return writeBreak(args[0], location);
                case 4 /* BreakWhenTrue */:
                    return writeBreakWhenTrue(args[0], args[1], location);
                case 5 /* BreakWhenFalse */:
                    return writeBreakWhenFalse(args[0], args[1], location);
                case 6 /* Yield */:
                    return writeYield(args[0], location);
                case 7 /* YieldStar */:
                    return writeYieldStar(args[0], location);
                case 8 /* Return */:
                    return writeReturn(args[0], location);
                case 9 /* Throw */:
                    return writeThrow(args[0], location);
            }
        }
        /**
         * Writes a statement to the current label's statement list.
         *
         * @param statement A statement to write.
         */
        function writeStatement(statement) {
            if (statement) {
                if (!statements) {
                    statements = [statement];
                }
                else {
                    statements.push(statement);
                }
            }
        }
        /**
         * Writes an Assign operation to the current label's statement list.
         *
         * @param left The left-hand side of the assignment.
         * @param right The right-hand side of the assignment.
         * @param operationLocation The source map location for the operation.
         */
        function writeAssign(left, right, operationLocation) {
            writeStatement(ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(left, right)), operationLocation));
        }
        /**
         * Writes a Throw operation to the current label's statement list.
         *
         * @param expression The value to throw.
         * @param operationLocation The source map location for the operation.
         */
        function writeThrow(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            lastOperationWasCompletion = true;
            writeStatement(ts.setTextRange(ts.createThrow(expression), operationLocation));
        }
        /**
         * Writes a Return operation to the current label's statement list.
         *
         * @param expression The value to return.
         * @param operationLocation The source map location for the operation.
         */
        function writeReturn(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            lastOperationWasCompletion = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(2 /* Return */), expression]
                : [createInstruction(2 /* Return */)])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a Break operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreak(label, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a BreakWhenTrue operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param condition The condition for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreakWhenTrue(label, condition, operationLocation) {
            writeStatement(ts.setEmitFlags(ts.createIf(condition, ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
        }
        /**
         * Writes a BreakWhenFalse operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param condition The condition for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreakWhenFalse(label, condition, operationLocation) {
            writeStatement(ts.setEmitFlags(ts.createIf(ts.createLogicalNot(condition), ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
        }
        /**
         * Writes a Yield operation to the current label's statement list.
         *
         * @param expression The expression to yield.
         * @param operationLocation The source map location for the operation.
         */
        function writeYield(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(4 /* Yield */), expression]
                : [createInstruction(4 /* Yield */)])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a YieldStar instruction to the current label's statement list.
         *
         * @param expression The expression to yield.
         * @param operationLocation The source map location for the operation.
         */
        function writeYieldStar(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(5 /* YieldStar */),
                expression
            ])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes an Endfinally instruction to the current label's statement list.
         */
        function writeEndfinally() {
            lastOperationWasAbrupt = true;
            writeStatement(ts.createReturn(ts.createArrayLiteral([
                createInstruction(7 /* Endfinally */)
            ])));
        }
    }
    ts.transformGenerators = transformGenerators;
    function createGeneratorHelper(context, body) {
        context.requestEmitHelper(ts.generatorHelper);
        return ts.createCall(ts.getUnscopedHelperName("__generator"), 
        /*typeArguments*/ undefined, [ts.createThis(), body]);
    }
    // The __generator helper is used by down-level transformations to emulate the runtime
    // semantics of an ES2015 generator function. When called, this helper returns an
    // object that implements the Iterator protocol, in that it has `next`, `return`, and
    // `throw` methods that step through the generator when invoked.
    //
    // parameters:
    //  @param thisArg  The value to use as the `this` binding for the transformed generator body.
    //  @param body     A function that acts as the transformed generator body.
    //
    // variables:
    //  _       Persistent state for the generator that is shared between the helper and the
    //          generator body. The state object has the following members:
    //            sent() - A method that returns or throws the current completion value.
    //            label  - The next point at which to resume evaluation of the generator body.
    //            trys   - A stack of protected regions (try/catch/finally blocks).
    //            ops    - A stack of pending instructions when inside of a finally block.
    //  f       A value indicating whether the generator is executing.
    //  y       An iterator to delegate for a yield*.
    //  t       A temporary variable that holds one of the following values (note that these
    //          cases do not overlap):
    //          - The completion value when resuming from a `yield` or `yield*`.
    //          - The error value for a catch block.
    //          - The current protected region (array of try/catch/finally/end labels).
    //          - The verb (`next`, `throw`, or `return` method) to delegate to the expression
    //            of a `yield*`.
    //          - The result of evaluating the verb delegated to the expression of a `yield*`.
    //
    // functions:
    //  verb(n)     Creates a bound callback to the `step` function for opcode `n`.
    //  step(op)    Evaluates opcodes in a generator body until execution is suspended or
    //              completed.
    //
    // The __generator helper understands a limited set of instructions:
    //  0: next(value?)     - Start or resume the generator with the specified value.
    //  1: throw(error)     - Resume the generator with an exception. If the generator is
    //                        suspended inside of one or more protected regions, evaluates
    //                        any intervening finally blocks between the current label and
    //                        the nearest catch block or function boundary. If uncaught, the
    //                        exception is thrown to the caller.
    //  2: return(value?)   - Resume the generator as if with a return. If the generator is
    //                        suspended inside of one or more protected regions, evaluates any
    //                        intervening finally blocks.
    //  3: break(label)     - Jump to the specified label. If the label is outside of the
    //                        current protected region, evaluates any intervening finally
    //                        blocks.
    //  4: yield(value?)    - Yield execution to the caller with an optional value. When
    //                        resumed, the generator will continue at the next label.
    //  5: yield*(value)    - Delegates evaluation to the supplied iterator. When
    //                        delegation completes, the generator will continue at the next
    //                        label.
    //  6: catch(error)     - Handles an exception thrown from within the generator body. If
    //                        the current label is inside of one or more protected regions,
    //                        evaluates any intervening finally blocks between the current
    //                        label and the nearest catch block or function boundary. If
    //                        uncaught, the exception is thrown to the caller.
    //  7: endfinally       - Ends a finally block, resuming the last instruction prior to
    //                        entering a finally block.
    //
    // For examples of how these are used, see the comments in ./transformers/generators.ts
    ts.generatorHelper = {
        name: "typescript:generator",
        importName: "__generator",
        scoped: false,
        priority: 6,
        text: "\n            var __generator = (this && this.__generator) || function (thisArg, body) {\n                var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n                return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n                function verb(n) { return function (v) { return step([n, v]); }; }\n                function step(op) {\n                    if (f) throw new TypeError(\"Generator is already executing.\");\n                    while (_) try {\n                        if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n                        if (y = 0, t) op = [op[0] & 2, t.value];\n                        switch (op[0]) {\n                            case 0: case 1: t = op; break;\n                            case 4: _.label++; return { value: op[1], done: false };\n                            case 5: _.label++; y = op[1]; op = [0]; continue;\n                            case 7: op = _.ops.pop(); _.trys.pop(); continue;\n                            default:\n                                if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n                                if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n                                if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n                                if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n                                if (t[2]) _.ops.pop();\n                                _.trys.pop(); continue;\n                        }\n                        op = body.call(thisArg, _);\n                    } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n                    if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n                }\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformModule(context) {
        function getTransformModuleDelegate(moduleKind) {
            switch (moduleKind) {
                case ts.ModuleKind.AMD: return transformAMDModule;
                case ts.ModuleKind.UMD: return transformUMDModule;
                default: return transformCommonJSModule;
            }
        }
        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var host = context.getEmitHost();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.enableSubstitution(75 /* Identifier */); // Substitutes expression identifiers with imported/exported symbols.
        context.enableSubstitution(209 /* BinaryExpression */); // Substitutes assignments to exported symbols.
        context.enableSubstitution(207 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(208 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(282 /* ShorthandPropertyAssignment */); // Substitutes shorthand property assignments for imported/exported symbols.
        context.enableEmitNotification(290 /* SourceFile */); // Restore state when substituting nodes in a file.
        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
        var currentSourceFile; // The current file.
        var currentModuleInfo; // The ExternalModuleInfo for the current file.
        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
        var needUMDDynamicImportHelper;
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms the module aspects of a SourceFile.
         *
         * @param node The SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile ||
                !(ts.isEffectiveExternalModule(node, compilerOptions) ||
                    node.transformFlags & 2097152 /* ContainsDynamicImport */ ||
                    (ts.isJsonSourceFile(node) && ts.hasJsonModuleEmitEnabled(compilerOptions) && (compilerOptions.out || compilerOptions.outFile)))) {
                return node;
            }
            currentSourceFile = node;
            currentModuleInfo = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
            moduleInfoMap[ts.getOriginalNodeId(node)] = currentModuleInfo;
            // Perform the transformation.
            var transformModule = getTransformModuleDelegate(moduleKind);
            var updated = transformModule(node);
            currentSourceFile = undefined;
            currentModuleInfo = undefined;
            needUMDDynamicImportHelper = false;
            return ts.aggregateTransformFlags(updated);
        }
        function shouldEmitUnderscoreUnderscoreESModule() {
            if (!currentModuleInfo.exportEquals && ts.isExternalModule(currentSourceFile)) {
                return true;
            }
            return false;
        }
        /**
         * Transforms a SourceFile into a CommonJS module.
         *
         * @param node The SourceFile node.
         */
        function transformCommonJSModule(node) {
            startLexicalEnvironment();
            var statements = [];
            var ensureUseStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict && !ts.isJsonSourceFile(node), sourceElementVisitor);
            if (shouldEmitUnderscoreUnderscoreESModule()) {
                ts.append(statements, createUnderscoreUnderscoreESModule());
            }
            if (ts.length(currentModuleInfo.exportedNames)) {
                ts.append(statements, ts.createExpressionStatement(ts.reduceLeft(currentModuleInfo.exportedNames, function (prev, nextId) { return ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.createIdentifier(ts.idText(nextId))), prev); }, ts.createVoidZero())));
            }
            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Transforms a SourceFile into an AMD module.
         *
         * @param node The SourceFile node.
         */
        function transformAMDModule(node) {
            var define = ts.createIdentifier("define");
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var jsonSourceFile = ts.isJsonSourceFile(node) && node;
            // An AMD define function has the following shape:
            //
            //     define(id?, dependencies?, factory);
            //
            // This has the shape of the following:
            //
            //     define(name, ["module1", "module2"], function (module1Alias) { ... }
            //
            // The location of the alias in the parameter list in the factory function needs to
            // match the position of the module name in the dependency list.
            //
            // To ensure this is true in cases of modules with no aliases, e.g.:
            //
            //     import "module"
            //
            // or
            //
            //     /// <amd-dependency path= "a.css" />
            //
            // we need to add modules without alias names to the end of the dependencies list
            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ true), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
            // Create an updated SourceFile:
            //
            //     define(moduleName?, ["module1", "module2"], function ...
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(define, 
                /*typeArguments*/ undefined, __spreadArrays((moduleName ? [moduleName] : []), [
                    // Add the dependency array argument:
                    //
                    //     ["require", "exports", module1", "module2", ...]
                    ts.createArrayLiteral(jsonSourceFile ? ts.emptyArray : __spreadArrays([
                        ts.createLiteral("require"),
                        ts.createLiteral("exports")
                    ], aliasedModuleNames, unaliasedModuleNames)),
                    // Add the module body function argument:
                    //
                    //     function (require, exports, module1, module2) ...
                    jsonSourceFile ?
                        jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : ts.createObjectLiteral() :
                        ts.createFunctionExpression(
                        /*modifiers*/ undefined, 
                        /*asteriskToken*/ undefined, 
                        /*name*/ undefined, 
                        /*typeParameters*/ undefined, __spreadArrays([
                            ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
                            ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
                        ], importAliasNames), 
                        /*type*/ undefined, transformAsynchronousModuleBody(node))
                ])))
            ]), 
            /*location*/ node.statements));
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Transforms a SourceFile into a UMD module.
         *
         * @param node The SourceFile node.
         */
        function transformUMDModule(node) {
            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ false), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var umdHeader = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], 
            /*type*/ undefined, ts.setTextRange(ts.createBlock([
                ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("module"), "object"), ts.createTypeCheck(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), "object")), ts.createBlock([
                    ts.createVariableStatement(
                    /*modifiers*/ undefined, [
                        ts.createVariableDeclaration("v", 
                        /*type*/ undefined, ts.createCall(ts.createIdentifier("factory"), 
                        /*typeArguments*/ undefined, [
                            ts.createIdentifier("require"),
                            ts.createIdentifier("exports")
                        ]))
                    ]),
                    ts.setEmitFlags(ts.createIf(ts.createStrictInequality(ts.createIdentifier("v"), ts.createIdentifier("undefined")), ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), ts.createIdentifier("v")))), 1 /* SingleLine */)
                ]), ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("define"), "function"), ts.createPropertyAccess(ts.createIdentifier("define"), "amd")), ts.createBlock([
                    ts.createExpressionStatement(ts.createCall(ts.createIdentifier("define"), 
                    /*typeArguments*/ undefined, __spreadArrays((moduleName ? [moduleName] : []), [
                        ts.createArrayLiteral(__spreadArrays([
                            ts.createLiteral("require"),
                            ts.createLiteral("exports")
                        ], aliasedModuleNames, unaliasedModuleNames)),
                        ts.createIdentifier("factory")
                    ])))
                ])))
            ], 
            /*multiLine*/ true), 
            /*location*/ undefined));
            // Create an updated SourceFile:
            //
            //  (function (factory) {
            //      if (typeof module === "object" && typeof module.exports === "object") {
            //          var v = factory(require, exports);
            //          if (v !== undefined) module.exports = v;
            //      }
            //      else if (typeof define === 'function' && define.amd) {
            //          define(["require", "exports"], factory);
            //      }
            //  })(function ...)
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(umdHeader, 
                /*typeArguments*/ undefined, [
                    // Add the module body function argument:
                    //
                    //     function (require, exports) ...
                    ts.createFunctionExpression(
                    /*modifiers*/ undefined, 
                    /*asteriskToken*/ undefined, 
                    /*name*/ undefined, 
                    /*typeParameters*/ undefined, __spreadArrays([
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
                    ], importAliasNames), 
                    /*type*/ undefined, transformAsynchronousModuleBody(node))
                ]))
            ]), 
            /*location*/ node.statements));
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Collect the additional asynchronous dependencies for the module.
         *
         * @param node The source file.
         * @param includeNonAmdDependencies A value indicating whether to include non-AMD dependencies.
         */
        function collectAsynchronousDependencies(node, includeNonAmdDependencies) {
            // names of modules with corresponding parameter in the factory function
            var aliasedModuleNames = [];
            // names of modules with no corresponding parameters in factory function
            var unaliasedModuleNames = [];
            // names of the parameters in the factory function; these
            // parameters need to match the indexes of the corresponding
            // module names in aliasedModuleNames.
            var importAliasNames = [];
            // Fill in amd-dependency tags
            for (var _i = 0, _a = node.amdDependencies; _i < _a.length; _i++) {
                var amdDependency = _a[_i];
                if (amdDependency.name) {
                    aliasedModuleNames.push(ts.createLiteral(amdDependency.path));
                    importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, amdDependency.name));
                }
                else {
                    unaliasedModuleNames.push(ts.createLiteral(amdDependency.path));
                }
            }
            for (var _b = 0, _c = currentModuleInfo.externalImports; _b < _c.length; _b++) {
                var importNode = _c[_b];
                // Find the name of the external module
                var externalModuleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
                // Find the name of the module alias, if there is one
                var importAliasName = ts.getLocalNameForExternalImport(importNode, currentSourceFile);
                // It is possible that externalModuleName is undefined if it is not string literal.
                // This can happen in the invalid import syntax.
                // E.g : "import * from alias from 'someLib';"
                if (externalModuleName) {
                    if (includeNonAmdDependencies && importAliasName) {
                        // Set emitFlags on the name of the classDeclaration
                        // This is so that when printer will not substitute the identifier
                        ts.setEmitFlags(importAliasName, 4 /* NoSubstitution */);
                        aliasedModuleNames.push(externalModuleName);
                        importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName));
                    }
                    else {
                        unaliasedModuleNames.push(externalModuleName);
                    }
                }
            }
            return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
        }
        function getAMDImportExpressionForImport(node) {
            if (ts.isImportEqualsDeclaration(node) || ts.isExportDeclaration(node) || !ts.getExternalModuleNameLiteral(node, currentSourceFile, host, resolver, compilerOptions)) {
                return undefined;
            }
            var name = ts.getLocalNameForExternalImport(node, currentSourceFile); // TODO: GH#18217
            var expr = getHelperExpressionForImport(node, name);
            if (expr === name) {
                return undefined;
            }
            return ts.createExpressionStatement(ts.createAssignment(name, expr));
        }
        /**
         * Transforms a SourceFile into an AMD or UMD module body.
         *
         * @param node The SourceFile node.
         */
        function transformAsynchronousModuleBody(node) {
            startLexicalEnvironment();
            var statements = [];
            var statementOffset = ts.addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
            if (shouldEmitUnderscoreUnderscoreESModule()) {
                ts.append(statements, createUnderscoreUnderscoreESModule());
            }
            if (ts.length(currentModuleInfo.exportedNames)) {
                ts.append(statements, ts.createExpressionStatement(ts.reduceLeft(currentModuleInfo.exportedNames, function (prev, nextId) { return ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.createIdentifier(ts.idText(nextId))), prev); }, ts.createVoidZero())));
            }
            // Visit each statement of the module body.
            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
            if (moduleKind === ts.ModuleKind.AMD) {
                ts.addRange(statements, ts.mapDefined(currentModuleInfo.externalImports, getAMDImportExpressionForImport));
            }
            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
            // Append the 'export =' statement if provided.
            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
            // End the lexical environment for the module body
            // and merge any new lexical declarations.
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var body = ts.createBlock(statements, /*multiLine*/ true);
            if (needUMDDynamicImportHelper) {
                ts.addEmitHelper(body, dynamicImportUMDHelper);
            }
            return body;
        }
        /**
         * Adds the down-level representation of `export=` to the statement list if one exists
         * in the source file.
         *
         * @param statements The Statement list to modify.
         * @param emitAsReturn A value indicating whether to emit the `export=` statement as a
         * return statement.
         */
        function addExportEqualsIfNeeded(statements, emitAsReturn) {
            if (currentModuleInfo.exportEquals) {
                var expressionResult = ts.visitNode(currentModuleInfo.exportEquals.expression, moduleExpressionElementVisitor);
                if (expressionResult) {
                    if (emitAsReturn) {
                        var statement = ts.createReturn(expressionResult);
                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
                        ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */);
                        statements.push(statement);
                    }
                    else {
                        var statement = ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
                        ts.setEmitFlags(statement, 1536 /* NoComments */);
                        statements.push(statement);
                    }
                }
            }
        }
        //
        // Top-Level Source Element Visitors
        //
        /**
         * Visits a node at the top level of the source file.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 260 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                case 259 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 245 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 328 /* MergeDeclarationMarker */:
                    return visitMergeDeclarationMarker(node);
                case 329 /* EndOfDeclarationMarker */:
                    return visitEndOfDeclarationMarker(node);
                default:
                    return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
            }
        }
        function moduleExpressionElementVisitor(node) {
            // This visitor does not need to descend into the tree if there is no dynamic import or destructuring assignment,
            // as export/import statements are only transformed at the top level of a file.
            if (!(node.transformFlags & 2097152 /* ContainsDynamicImport */) && !(node.transformFlags & 1024 /* ContainsDestructuringAssignment */)) {
                return node;
            }
            if (ts.isImportCall(node)) {
                return visitImportCallExpression(node);
            }
            else if (ts.isDestructuringAssignment(node)) {
                return visitDestructuringAssignment(node);
            }
            else {
                return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
            }
        }
        function destructuringNeedsFlattening(node) {
            if (ts.isObjectLiteralExpression(node)) {
                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                    var elem = _a[_i];
                    switch (elem.kind) {
                        case 281 /* PropertyAssignment */:
                            if (destructuringNeedsFlattening(elem.initializer)) {
                                return true;
                            }
                            break;
                        case 282 /* ShorthandPropertyAssignment */:
                            if (destructuringNeedsFlattening(elem.name)) {
                                return true;
                            }
                            break;
                        case 283 /* SpreadAssignment */:
                            if (destructuringNeedsFlattening(elem.expression)) {
                                return true;
                            }
                            break;
                        case 161 /* MethodDeclaration */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                            return false;
                        default: ts.Debug.assertNever(elem, "Unhandled object member kind");
                    }
                }
            }
            else if (ts.isArrayLiteralExpression(node)) {
                for (var _b = 0, _c = node.elements; _b < _c.length; _b++) {
                    var elem = _c[_b];
                    if (ts.isSpreadElement(elem)) {
                        if (destructuringNeedsFlattening(elem.expression)) {
                            return true;
                        }
                    }
                    else if (destructuringNeedsFlattening(elem)) {
                        return true;
                    }
                }
            }
            else if (ts.isIdentifier(node)) {
                return ts.length(getExports(node)) > (ts.isExportName(node) ? 1 : 0);
            }
            return false;
        }
        function visitDestructuringAssignment(node) {
            if (destructuringNeedsFlattening(node.left)) {
                return ts.flattenDestructuringAssignment(node, moduleExpressionElementVisitor, context, 0 /* All */, /*needsValue*/ false, createAllExportExpressions);
            }
            return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
        }
        function visitImportCallExpression(node) {
            var argument = ts.visitNode(ts.firstOrUndefined(node.arguments), moduleExpressionElementVisitor);
            var containsLexicalThis = !!(node.transformFlags & 4096 /* ContainsLexicalThis */);
            switch (compilerOptions.module) {
                case ts.ModuleKind.AMD:
                    return createImportCallExpressionAMD(argument, containsLexicalThis);
                case ts.ModuleKind.UMD:
                    return createImportCallExpressionUMD(argument, containsLexicalThis);
                case ts.ModuleKind.CommonJS:
                default:
                    return createImportCallExpressionCommonJS(argument, containsLexicalThis);
            }
        }
        function createImportCallExpressionUMD(arg, containsLexicalThis) {
            // (function (factory) {
            //      ... (regular UMD)
            // }
            // })(function (require, exports, useSyncRequire) {
            //      "use strict";
            //      Object.defineProperty(exports, "__esModule", { value: true });
            //      var __syncRequire = typeof module === "object" && typeof module.exports === "object";
            //      var __resolved = new Promise(function (resolve) { resolve(); });
            //      .....
            //      __syncRequire
            //          ? __resolved.then(function () { return require(x); }) /*CommonJs Require*/
            //          : new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
            // });
            needUMDDynamicImportHelper = true;
            if (ts.isSimpleCopiableExpression(arg)) {
                var argClone = ts.isGeneratedIdentifier(arg) ? arg : ts.isStringLiteral(arg) ? ts.createLiteral(arg) : ts.setEmitFlags(ts.setTextRange(ts.getSynthesizedClone(arg), arg), 1536 /* NoComments */);
                return ts.createConditional(
                /*condition*/ ts.createIdentifier("__syncRequire"), 
                /*whenTrue*/ createImportCallExpressionCommonJS(arg, containsLexicalThis), 
                /*whenFalse*/ createImportCallExpressionAMD(argClone, containsLexicalThis));
            }
            else {
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                return ts.createComma(ts.createAssignment(temp, arg), ts.createConditional(
                /*condition*/ ts.createIdentifier("__syncRequire"), 
                /*whenTrue*/ createImportCallExpressionCommonJS(temp, containsLexicalThis), 
                /*whenFalse*/ createImportCallExpressionAMD(temp, containsLexicalThis)));
            }
        }
        function createImportCallExpressionAMD(arg, containsLexicalThis) {
            // improt("./blah")
            // emit as
            // define(["require", "exports", "blah"], function (require, exports) {
            //     ...
            //     new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
            // });
            var resolve = ts.createUniqueName("resolve");
            var reject = ts.createUniqueName("reject");
            var parameters = [
                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve),
                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject)
            ];
            var body = ts.createBlock([
                ts.createExpressionStatement(ts.createCall(ts.createIdentifier("require"), 
                /*typeArguments*/ undefined, [ts.createArrayLiteral([arg || ts.createOmittedExpression()]), resolve, reject]))
            ]);
            var func;
            if (languageVersion >= 2 /* ES2015 */) {
                func = ts.createArrowFunction(
                /*modifiers*/ undefined, 
                /*typeParameters*/ undefined, parameters, 
                /*type*/ undefined, 
                /*equalsGreaterThanToken*/ undefined, body);
            }
            else {
                func = ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, parameters, 
                /*type*/ undefined, body);
                // if there is a lexical 'this' in the import call arguments, ensure we indicate
                // that this new function expression indicates it captures 'this' so that the
                // es2015 transformer will properly substitute 'this' with '_this'.
                if (containsLexicalThis) {
                    ts.setEmitFlags(func, 8 /* CapturesThis */);
                }
            }
            var promise = ts.createNew(ts.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
            if (compilerOptions.esModuleInterop) {
                context.requestEmitHelper(ts.importStarHelper);
                return ts.createCall(ts.createPropertyAccess(promise, ts.createIdentifier("then")), /*typeArguments*/ undefined, [ts.getUnscopedHelperName("__importStar")]);
            }
            return promise;
        }
        function createImportCallExpressionCommonJS(arg, containsLexicalThis) {
            // import("./blah")
            // emit as
            // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/
            // We have to wrap require in then callback so that require is done in asynchronously
            // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately
            var promiseResolveCall = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []);
            var requireCall = ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
            if (compilerOptions.esModuleInterop) {
                context.requestEmitHelper(ts.importStarHelper);
                requireCall = ts.createCall(ts.getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]);
            }
            var func;
            if (languageVersion >= 2 /* ES2015 */) {
                func = ts.createArrowFunction(
                /*modifiers*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, 
                /*equalsGreaterThanToken*/ undefined, requireCall);
            }
            else {
                func = ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, ts.createBlock([ts.createReturn(requireCall)]));
                // if there is a lexical 'this' in the import call arguments, ensure we indicate
                // that this new function expression indicates it captures 'this' so that the
                // es2015 transformer will properly substitute 'this' with '_this'.
                if (containsLexicalThis) {
                    ts.setEmitFlags(func, 8 /* CapturesThis */);
                }
            }
            return ts.createCall(ts.createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
        }
        function getHelperExpressionForExport(node, innerExpr) {
            if (!compilerOptions.esModuleInterop || ts.getEmitFlags(node) & 67108864 /* NeverApplyImportHelper */) {
                return innerExpr;
            }
            if (ts.getExportNeedsImportStarHelper(node)) {
                context.requestEmitHelper(ts.importStarHelper);
                return ts.createCall(ts.getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
            }
            return innerExpr;
        }
        function getHelperExpressionForImport(node, innerExpr) {
            if (!compilerOptions.esModuleInterop || ts.getEmitFlags(node) & 67108864 /* NeverApplyImportHelper */) {
                return innerExpr;
            }
            if (ts.getImportNeedsImportStarHelper(node)) {
                context.requestEmitHelper(ts.importStarHelper);
                return ts.createCall(ts.getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
            }
            if (ts.getImportNeedsImportDefaultHelper(node)) {
                context.requestEmitHelper(ts.importDefaultHelper);
                return ts.createCall(ts.getUnscopedHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]);
            }
            return innerExpr;
        }
        /**
         * Visits an ImportDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportDeclaration(node) {
            var statements;
            var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
            if (moduleKind !== ts.ModuleKind.AMD) {
                if (!node.importClause) {
                    // import "mod";
                    return ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createRequireCall(node)), node), node);
                }
                else {
                    var variables = [];
                    if (namespaceDeclaration && !ts.isDefaultImport(node)) {
                        // import * as n from "mod";
                        variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                        /*type*/ undefined, getHelperExpressionForImport(node, createRequireCall(node))));
                    }
                    else {
                        // import d from "mod";
                        // import { x, y } from "mod";
                        // import d, { x, y } from "mod";
                        // import d, * as n from "mod";
                        variables.push(ts.createVariableDeclaration(ts.getGeneratedNameForNode(node), 
                        /*type*/ undefined, getHelperExpressionForImport(node, createRequireCall(node))));
                        if (namespaceDeclaration && ts.isDefaultImport(node)) {
                            variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                            /*type*/ undefined, ts.getGeneratedNameForNode(node)));
                        }
                    }
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList(variables, languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), 
                    /*location*/ node), 
                    /*original*/ node));
                }
            }
            else if (namespaceDeclaration && ts.isDefaultImport(node)) {
                // import d, * as n from "mod";
                statements = ts.append(statements, ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                    /*type*/ undefined, ts.getGeneratedNameForNode(node)), 
                    /*location*/ node), 
                    /*original*/ node)
                ], languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Creates a `require()` call to import an external module.
         *
         * @param importNode The declararation to import.
         */
        function createRequireCall(importNode) {
            var moduleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
            var args = [];
            if (moduleName) {
                args.push(moduleName);
            }
            return ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, args);
        }
        /**
         * Visits an ImportEqualsDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportEqualsDeclaration(node) {
            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
            var statements;
            if (moduleKind !== ts.ModuleKind.AMD) {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(node.name, createRequireCall(node))), node), node));
                }
                else {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(ts.getSynthesizedClone(node.name), 
                        /*type*/ undefined, createRequireCall(node))
                    ], 
                    /*flags*/ languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), node), node));
                }
            }
            else {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(ts.getExportName(node), ts.getLocalName(node))), node), node));
                }
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportEqualsDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ExportDeclaration node.
         *
         * @param The node to visit.
         */
        function visitExportDeclaration(node) {
            if (!node.moduleSpecifier) {
                // Elide export declarations with no module specifier as they are handled
                // elsewhere.
                return undefined;
            }
            var generatedName = ts.getGeneratedNameForNode(node);
            if (node.exportClause && ts.isNamedExports(node.exportClause)) {
                var statements = [];
                // export { x, y } from "mod";
                if (moduleKind !== ts.ModuleKind.AMD) {
                    statements.push(ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(generatedName, 
                        /*type*/ undefined, createRequireCall(node))
                    ])), 
                    /*location*/ node), 
                    /* original */ node));
                }
                for (var _i = 0, _a = node.exportClause.elements; _i < _a.length; _i++) {
                    var specifier = _a[_i];
                    if (languageVersion === 0 /* ES3 */) {
                        statements.push(ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createCreateBindingHelper(context, generatedName, ts.createLiteral(specifier.propertyName || specifier.name), specifier.propertyName ? ts.createLiteral(specifier.name) : undefined)), specifier), specifier));
                    }
                    else {
                        var exportedValue = ts.createPropertyAccess(generatedName, specifier.propertyName || specifier.name);
                        statements.push(ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(ts.getExportName(specifier), exportedValue, /* location */ undefined, /* liveBinding */ true)), specifier), specifier));
                    }
                }
                return ts.singleOrMany(statements);
            }
            else if (node.exportClause) {
                var statements = [];
                // export * as ns from "mod";
                statements.push(ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(ts.getSynthesizedClone(node.exportClause.name), moduleKind !== ts.ModuleKind.AMD ?
                    getHelperExpressionForExport(node, createRequireCall(node)) :
                    ts.createIdentifier(ts.idText(node.exportClause.name)))), node), node));
                return ts.singleOrMany(statements);
            }
            else {
                // export * from "mod";
                return ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportStarHelper(context, moduleKind !== ts.ModuleKind.AMD ? createRequireCall(node) : generatedName)), node), node);
            }
        }
        /**
         * Visits an ExportAssignment node.
         *
         * @param node The node to visit.
         */
        function visitExportAssignment(node) {
            if (node.isExportEquals) {
                return undefined;
            }
            var statements;
            var original = node.original;
            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), ts.visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true);
            }
            else {
                statements = appendExportStatement(statements, ts.createIdentifier("default"), ts.visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            var statements;
            if (ts.hasModifier(node, 1 /* Export */)) {
                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, moduleExpressionElementVisitor), 
                /*type*/ undefined, ts.visitEachChild(node.body, moduleExpressionElementVisitor, context)), 
                /*location*/ node), 
                /*original*/ node));
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a ClassDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitClassDeclaration(node) {
            var statements;
            if (ts.hasModifier(node, 1 /* Export */)) {
                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createClassDeclaration(
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, moduleExpressionElementVisitor), ts.visitNodes(node.members, moduleExpressionElementVisitor)), node), node));
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a VariableStatement node.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            var statements;
            var variables;
            var expressions;
            if (ts.hasModifier(node, 1 /* Export */)) {
                var modifiers = void 0;
                // If we're exporting these variables, then these just become assignments to 'exports.x'.
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    if (ts.isIdentifier(variable.name) && ts.isLocalName(variable.name)) {
                        if (!modifiers) {
                            modifiers = ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier);
                        }
                        variables = ts.append(variables, variable);
                    }
                    else if (variable.initializer) {
                        expressions = ts.append(expressions, transformInitializedVariable(variable));
                    }
                }
                if (variables) {
                    statements = ts.append(statements, ts.updateVariableStatement(node, modifiers, ts.updateVariableDeclarationList(node.declarationList, variables)));
                }
                if (expressions) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(expressions)), node), node));
                }
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfVariableStatement(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        function createAllExportExpressions(name, value, location) {
            var exportedNames = getExports(name);
            if (exportedNames) {
                // For each additional export of the declaration, apply an export assignment.
                var expression = ts.isExportName(name) ? value : ts.createAssignment(name, value);
                for (var _i = 0, exportedNames_1 = exportedNames; _i < exportedNames_1.length; _i++) {
                    var exportName = exportedNames_1[_i];
                    // Mark the node to prevent triggering substitution.
                    ts.setEmitFlags(expression, 4 /* NoSubstitution */);
                    expression = createExportExpression(exportName, expression, /*location*/ location);
                }
                return expression;
            }
            return ts.createAssignment(name, value);
        }
        /**
         * Transforms an exported variable with an initializer into an expression.
         *
         * @param node The node to transform.
         */
        function transformInitializedVariable(node) {
            if (ts.isBindingPattern(node.name)) {
                return ts.flattenDestructuringAssignment(ts.visitNode(node, moduleExpressionElementVisitor), 
                /*visitor*/ undefined, context, 0 /* All */, 
                /*needsValue*/ false, createAllExportExpressions);
            }
            else {
                return ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), node.name), 
                /*location*/ node.name), node.initializer ? ts.visitNode(node.initializer, moduleExpressionElementVisitor) : ts.createVoidZero());
            }
        }
        /**
         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
         * and transformed declaration.
         *
         * @param node The node to visit.
         */
        function visitMergeDeclarationMarker(node) {
            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
            // declaration we do not emit a leading variable declaration. To preserve the
            // begin/end semantics of the declararation and to properly handle exports
            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
            //
            // To balance the declaration, add the exports of the elided variable
            // statement.
            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 225 /* VariableStatement */) {
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original);
            }
            return node;
        }
        /**
         * Determines whether a node has an associated EndOfDeclarationMarker.
         *
         * @param node The node to test.
         */
        function hasAssociatedEndOfDeclarationMarker(node) {
            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
        }
        /**
         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
         * declaration.
         *
         * @param node The node to visit.
         */
        function visitEndOfDeclarationMarker(node) {
            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
            // end of the transformed declaration. We use this marker to emit any deferred exports
            // of the declaration.
            var id = ts.getOriginalNodeId(node);
            var statements = deferredExports[id];
            if (statements) {
                delete deferredExports[id];
                return ts.append(statements, node);
            }
            return node;
        }
        /**
         * Appends the exports of an ImportDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            var importClause = decl.importClause;
            if (!importClause) {
                return statements;
            }
            if (importClause.name) {
                statements = appendExportsOfDeclaration(statements, importClause);
            }
            var namedBindings = importClause.namedBindings;
            if (namedBindings) {
                switch (namedBindings.kind) {
                    case 256 /* NamespaceImport */:
                        statements = appendExportsOfDeclaration(statements, namedBindings);
                        break;
                    case 257 /* NamedImports */:
                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                            var importBinding = _a[_i];
                            statements = appendExportsOfDeclaration(statements, importBinding, /* liveBinding */ true);
                        }
                        break;
                }
            }
            return statements;
        }
        /**
         * Appends the exports of an ImportEqualsDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportEqualsDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            return appendExportsOfDeclaration(statements, decl);
        }
        /**
         * Appends the exports of a VariableStatement to a statement list, returning the statement
         * list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param node The VariableStatement whose exports are to be recorded.
         */
        function appendExportsOfVariableStatement(statements, node) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                statements = appendExportsOfBindingElement(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfBindingElement(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            if (ts.isBindingPattern(decl.name)) {
                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        statements = appendExportsOfBindingElement(statements, element);
                    }
                }
            }
            else if (!ts.isGeneratedIdentifier(decl.name)) {
                statements = appendExportsOfDeclaration(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfHoistedDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            if (ts.hasModifier(decl, 1 /* Export */)) {
                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : ts.getDeclarationName(decl);
                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), /*location*/ decl);
            }
            if (decl.name) {
                statements = appendExportsOfDeclaration(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a declaration to a statement list, returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration to export.
         */
        function appendExportsOfDeclaration(statements, decl, liveBinding) {
            var name = ts.getDeclarationName(decl);
            var exportSpecifiers = currentModuleInfo.exportSpecifiers.get(ts.idText(name));
            if (exportSpecifiers) {
                for (var _i = 0, exportSpecifiers_1 = exportSpecifiers; _i < exportSpecifiers_1.length; _i++) {
                    var exportSpecifier = exportSpecifiers_1[_i];
                    statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name, /* allowComments */ undefined, liveBinding);
                }
            }
            return statements;
        }
        /**
         * Appends the down-level representation of an export to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param exportName The name of the export.
         * @param expression The expression to export.
         * @param location The location to use for source maps and comments for the export.
         * @param allowComments Whether to allow comments on the export.
         */
        function appendExportStatement(statements, exportName, expression, location, allowComments, liveBinding) {
            statements = ts.append(statements, createExportStatement(exportName, expression, location, allowComments, liveBinding));
            return statements;
        }
        function createUnderscoreUnderscoreESModule() {
            var statement;
            if (languageVersion === 0 /* ES3 */) {
                statement = ts.createExpressionStatement(createExportExpression(ts.createIdentifier("__esModule"), ts.createLiteral(/*value*/ true)));
            }
            else {
                statement = ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
                /*typeArguments*/ undefined, [
                    ts.createIdentifier("exports"),
                    ts.createLiteral("__esModule"),
                    ts.createObjectLiteral([
                        ts.createPropertyAssignment("value", ts.createLiteral(/*value*/ true))
                    ])
                ]));
            }
            ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param location The location to use for source maps and comments for the export.
         * @param allowComments An optional value indicating whether to emit comments for the statement.
         */
        function createExportStatement(name, value, location, allowComments, liveBinding) {
            var statement = ts.setTextRange(ts.createExpressionStatement(createExportExpression(name, value, /* location */ undefined, liveBinding)), location);
            ts.startOnNewLine(statement);
            if (!allowComments) {
                ts.setEmitFlags(statement, 1536 /* NoComments */);
            }
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param location The location to use for source maps and comments for the export.
         */
        function createExportExpression(name, value, location, liveBinding) {
            return ts.setTextRange(liveBinding && languageVersion !== 0 /* ES3 */ ? ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                ts.createIdentifier("exports"),
                ts.createLiteral(name),
                ts.createObjectLiteral([
                    ts.createPropertyAssignment("enumerable", ts.createLiteral(/*value*/ true)),
                    ts.createPropertyAssignment("get", ts.createFunctionExpression(
                    /*modifiers*/ undefined, 
                    /*asteriskToken*/ undefined, 
                    /*name*/ undefined, 
                    /*typeParameters*/ undefined, 
                    /*parameters*/ [], 
                    /*type*/ undefined, ts.createBlock([ts.createReturn(value)])))
                ])
            ]) : ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(name)), value), location);
        }
        //
        // Modifier Visitors
        //
        /**
         * Visit nodes to elide module-specific modifiers.
         *
         * @param node The node to visit.
         */
        function modifierVisitor(node) {
            // Elide module-specific modifiers.
            switch (node.kind) {
                case 89 /* ExportKeyword */:
                case 84 /* DefaultKeyword */:
                    return undefined;
            }
            return node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit notifications.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (node.kind === 290 /* SourceFile */) {
                currentSourceFile = node;
                currentModuleInfo = moduleInfoMap[ts.getOriginalNodeId(currentSourceFile)];
                noSubstitution = [];
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
                currentModuleInfo = undefined;
                noSubstitution = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (node.id && noSubstitution[node.id]) {
                return node;
            }
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitution for a ShorthandPropertyAssignment whose declaration name is an imported
         * or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteShorthandPropertyAssignment(node) {
            var name = node.name;
            var exportedOrImportedName = substituteExpressionIdentifier(name);
            if (exportedOrImportedName !== name) {
                // A shorthand property with an assignment initializer is probably part of a
                // destructuring assignment
                if (node.objectAssignmentInitializer) {
                    var initializer = ts.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer);
                    return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
                }
                return ts.setTextRange(ts.createPropertyAssignment(name, exportedOrImportedName), node);
            }
            return node;
        }
        /**
         * Substitution for an Expression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 209 /* BinaryExpression */:
                    return substituteBinaryExpression(node);
                case 208 /* PostfixUnaryExpression */:
                case 207 /* PrefixUnaryExpression */:
                    return substituteUnaryExpression(node);
            }
            return node;
        }
        /**
         * Substitution for an Identifier expression that may contain an imported or exported
         * symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
                return node;
            }
            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                var exportContainer = resolver.getReferencedExportContainer(node, ts.isExportName(node));
                if (exportContainer && exportContainer.kind === 290 /* SourceFile */) {
                    return ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(node)), 
                    /*location*/ node);
                }
                var importDeclaration = resolver.getReferencedImportDeclaration(node);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        var name = importDeclaration.propertyName || importDeclaration.name;
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(name)), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteBinaryExpression(node) {
            // When we see an assignment expression whose left-hand side is an exported symbol,
            // we should ensure all exports of that symbol are updated with the correct value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if (ts.isAssignmentOperator(node.operatorToken.kind)
                && ts.isIdentifier(node.left)
                && !ts.isGeneratedIdentifier(node.left)
                && !ts.isLocalName(node.left)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
                var exportedNames = getExports(node.left);
                if (exportedNames) {
                    // For each additional export of the declaration, apply an export assignment.
                    var expression = node;
                    for (var _i = 0, exportedNames_2 = exportedNames; _i < exportedNames_2.length; _i++) {
                        var exportName = exportedNames_2[_i];
                        // Mark the node to prevent triggering this rule again.
                        noSubstitution[ts.getNodeId(expression)] = true;
                        expression = createExportExpression(exportName, expression, /*location*/ node);
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteUnaryExpression(node) {
            // When we see a prefix or postfix increment expression whose operand is an exported
            // symbol, we should ensure all exports of that symbol are updated with the correct
            // value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if ((node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */)
                && ts.isIdentifier(node.operand)
                && !ts.isGeneratedIdentifier(node.operand)
                && !ts.isLocalName(node.operand)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
                var exportedNames = getExports(node.operand);
                if (exportedNames) {
                    var expression = node.kind === 208 /* PostfixUnaryExpression */
                        ? ts.setTextRange(ts.createBinary(node.operand, ts.createToken(node.operator === 45 /* PlusPlusToken */ ? 63 /* PlusEqualsToken */ : 64 /* MinusEqualsToken */), ts.createLiteral(1)), 
                        /*location*/ node)
                        : node;
                    for (var _i = 0, exportedNames_3 = exportedNames; _i < exportedNames_3.length; _i++) {
                        var exportName = exportedNames_3[_i];
                        // Mark the node to prevent triggering this rule again.
                        noSubstitution[ts.getNodeId(expression)] = true;
                        expression = createExportExpression(exportName, expression);
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Gets the additional exports of a name.
         *
         * @param name The name.
         */
        function getExports(name) {
            if (!ts.isGeneratedIdentifier(name)) {
                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
                    || resolver.getReferencedValueDeclaration(name);
                if (valueDeclaration) {
                    return currentModuleInfo
                        && currentModuleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)];
                }
            }
        }
    }
    ts.transformModule = transformModule;
    ts.createBindingHelper = {
        name: "typescript:commonjscreatebinding",
        importName: "__createBinding",
        scoped: false,
        priority: 1,
        text: "\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));"
    };
    function createCreateBindingHelper(context, module, inputName, outputName) {
        context.requestEmitHelper(ts.createBindingHelper);
        return ts.createCall(ts.getUnscopedHelperName("__createBinding"), /*typeArguments*/ undefined, __spreadArrays([ts.createIdentifier("exports"), module, inputName], (outputName ? [outputName] : [])));
    }
    ts.setModuleDefaultHelper = {
        name: "typescript:commonjscreatevalue",
        importName: "__setModuleDefault",
        scoped: false,
        priority: 1,
        text: "\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});"
    };
    // emit output for the __export helper function
    var exportStarHelper = {
        name: "typescript:export-star",
        importName: "__exportStar",
        scoped: false,
        dependencies: [ts.createBindingHelper],
        priority: 2,
        text: "\n            var __exportStar = (this && this.__exportStar) || function(m, exports) {\n                for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);\n            };"
    };
    function createExportStarHelper(context, module) {
        context.requestEmitHelper(exportStarHelper);
        return ts.createCall(ts.getUnscopedHelperName("__exportStar"), /*typeArguments*/ undefined, [module, ts.createIdentifier("exports")]);
    }
    // emit helper for dynamic import
    var dynamicImportUMDHelper = {
        name: "typescript:dynamicimport-sync-require",
        scoped: true,
        text: "\n            var __syncRequire = typeof module === \"object\" && typeof module.exports === \"object\";"
    };
    // emit helper for `import * as Name from "foo"`
    ts.importStarHelper = {
        name: "typescript:commonjsimportstar",
        importName: "__importStar",
        scoped: false,
        dependencies: [ts.createBindingHelper, ts.setModuleDefaultHelper],
        priority: 2,
        text: "\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};"
    };
    // emit helper for `import Name from "foo"`
    ts.importDefaultHelper = {
        name: "typescript:commonjsimportdefault",
        importName: "__importDefault",
        scoped: false,
        text: "\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformSystemModule(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var host = context.getEmitHost();
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.enableSubstitution(75 /* Identifier */); // Substitutes expression identifiers for imported symbols.
        context.enableSubstitution(282 /* ShorthandPropertyAssignment */); // Substitutes expression identifiers for imported symbols
        context.enableSubstitution(209 /* BinaryExpression */); // Substitutes assignments to exported symbols.
        context.enableSubstitution(207 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(208 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(219 /* MetaProperty */); // Substitutes 'import.meta'
        context.enableEmitNotification(290 /* SourceFile */); // Restore state when substituting nodes in a file.
        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
        var exportFunctionsMap = []; // The export function associated with a source file.
        var noSubstitutionMap = []; // Set of nodes for which substitution rules should be ignored for each file.
        var contextObjectMap = []; // The context object associated with a source file.
        var currentSourceFile; // The current file.
        var moduleInfo; // ExternalModuleInfo for the current file.
        var exportFunction; // The export function for the current file.
        var contextObject; // The context object for the current file.
        var hoistedStatements;
        var enclosingBlockScopedContainer;
        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms the module aspects of a SourceFile.
         *
         * @param node The SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile || !(ts.isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 2097152 /* ContainsDynamicImport */)) {
                return node;
            }
            var id = ts.getOriginalNodeId(node);
            currentSourceFile = node;
            enclosingBlockScopedContainer = node;
            // System modules have the following shape:
            //
            //     System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
            //
            // The parameter 'exports' here is a callback '<T>(name: string, value: T) => T' that
            // is used to publish exported values. 'exports' returns its 'value' argument so in
            // most cases expressions that mutate exported values can be rewritten as:
            //
            //     expr -> exports('name', expr)
            //
            // The only exception in this rule is postfix unary operators,
            // see comment to 'substitutePostfixUnaryExpression' for more details
            // Collect information about the external module and dependency groups.
            moduleInfo = moduleInfoMap[id] = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
            // Make sure that the name of the 'exports' function does not conflict with
            // existing identifiers.
            exportFunction = ts.createUniqueName("exports");
            exportFunctionsMap[id] = exportFunction;
            contextObject = contextObjectMap[id] = ts.createUniqueName("context");
            // Add the body of the module.
            var dependencyGroups = collectDependencyGroups(moduleInfo.externalImports);
            var moduleBodyBlock = createSystemModuleBody(node, dependencyGroups);
            var moduleBodyFunction = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [
                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, exportFunction),
                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject)
            ], 
            /*type*/ undefined, moduleBodyBlock);
            // Write the call to `System.register`
            // Clear the emit-helpers flag for later passes since we'll have already used it in the module body
            // So the helper will be emit at the correct position instead of at the top of the source-file
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var dependencies = ts.createArrayLiteral(ts.map(dependencyGroups, function (dependencyGroup) { return dependencyGroup.name; }));
            var updated = ts.setEmitFlags(ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("System"), "register"), 
                /*typeArguments*/ undefined, moduleName
                    ? [moduleName, dependencies, moduleBodyFunction]
                    : [dependencies, moduleBodyFunction]))
            ]), node.statements)), 1024 /* NoTrailingComments */);
            if (!(compilerOptions.outFile || compilerOptions.out)) {
                ts.moveEmitHelpers(updated, moduleBodyBlock, function (helper) { return !helper.scoped; });
            }
            if (noSubstitution) {
                noSubstitutionMap[id] = noSubstitution;
                noSubstitution = undefined;
            }
            currentSourceFile = undefined;
            moduleInfo = undefined;
            exportFunction = undefined;
            contextObject = undefined;
            hoistedStatements = undefined;
            enclosingBlockScopedContainer = undefined;
            return ts.aggregateTransformFlags(updated);
        }
        /**
         * Collects the dependency groups for this files imports.
         *
         * @param externalImports The imports for the file.
         */
        function collectDependencyGroups(externalImports) {
            var groupIndices = ts.createMap();
            var dependencyGroups = [];
            for (var _i = 0, externalImports_1 = externalImports; _i < externalImports_1.length; _i++) {
                var externalImport = externalImports_1[_i];
                var externalModuleName = ts.getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
                if (externalModuleName) {
                    var text = externalModuleName.text;
                    var groupIndex = groupIndices.get(text);
                    if (groupIndex !== undefined) {
                        // deduplicate/group entries in dependency list by the dependency name
                        dependencyGroups[groupIndex].externalImports.push(externalImport);
                    }
                    else {
                        groupIndices.set(text, dependencyGroups.length);
                        dependencyGroups.push({
                            name: externalModuleName,
                            externalImports: [externalImport]
                        });
                    }
                }
            }
            return dependencyGroups;
        }
        /**
         * Adds the statements for the module body function for the source file.
         *
         * @param node The source file for the module.
         * @param dependencyGroups The grouped dependencies of the module.
         */
        function createSystemModuleBody(node, dependencyGroups) {
            // Shape of the body in system modules:
            //
            //  function (exports) {
            //      <list of local aliases for imports>
            //      <hoisted variable declarations>
            //      <hoisted function declarations>
            //      return {
            //          setters: [
            //              <list of setter function for imports>
            //          ],
            //          execute: function() {
            //              <module statements>
            //          }
            //      }
            //      <temp declarations>
            //  }
            //
            // i.e:
            //
            //   import {x} from 'file1'
            //   var y = 1;
            //   export function foo() { return y + x(); }
            //   console.log(y);
            //
            // Will be transformed to:
            //
            //  function(exports) {
            //      function foo() { return y + file_1.x(); }
            //      exports("foo", foo);
            //      var file_1, y;
            //      return {
            //          setters: [
            //              function(v) { file_1 = v }
            //          ],
            //          execute(): function() {
            //              y = 1;
            //              console.log(y);
            //          }
            //      };
            //  }
            var statements = [];
            // We start a new lexical environment in this function body, but *not* in the
            // body of the execute function. This allows us to emit temporary declarations
            // only in the outer module body and not in the inner one.
            startLexicalEnvironment();
            // Add any prologue directives.
            var ensureUseStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
            // var __moduleName = context_1 && context_1.id;
            statements.push(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration("__moduleName", 
                /*type*/ undefined, ts.createLogicalAnd(contextObject, ts.createPropertyAccess(contextObject, "id")))
            ])));
            // Visit the synthetic external helpers import declaration if present
            ts.visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement);
            // Visit the statements of the source file, emitting any transformations into
            // the `executeStatements` array. We do this *before* we fill the `setters` array
            // as we both emit transformations as well as aggregate some data used when creating
            // setters. This allows us to reduce the number of times we need to loop through the
            // statements of the source file.
            var executeStatements = ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset);
            // Emit early exports for function declarations.
            ts.addRange(statements, hoistedStatements);
            // We emit hoisted variables early to align roughly with our previous emit output.
            // Two key differences in this approach are:
            // - Temporary variables will appear at the top rather than at the bottom of the file
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var exportStarFunction = addExportStarIfNeeded(statements); // TODO: GH#18217
            var modifiers = node.transformFlags & 524288 /* ContainsAwait */ ?
                ts.createModifiersFromModifierFlags(256 /* Async */) :
                undefined;
            var moduleObject = ts.createObjectLiteral([
                ts.createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups)),
                ts.createPropertyAssignment("execute", ts.createFunctionExpression(modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, ts.createBlock(executeStatements, /*multiLine*/ true)))
            ]);
            moduleObject.multiLine = true;
            statements.push(ts.createReturn(moduleObject));
            return ts.createBlock(statements, /*multiLine*/ true);
        }
        /**
         * Adds an exportStar function to a statement list if it is needed for the file.
         *
         * @param statements A statement list.
         */
        function addExportStarIfNeeded(statements) {
            if (!moduleInfo.hasExportStarsToExportValues) {
                return;
            }
            // when resolving exports local exported entries/indirect exported entries in the module
            // should always win over entries with similar names that were added via star exports
            // to support this we store names of local/indirect exported entries in a set.
            // this set is used to filter names brought by star expors.
            // local names set should only be added if we have anything exported
            if (!moduleInfo.exportedNames && moduleInfo.exportSpecifiers.size === 0) {
                // no exported declarations (export var ...) or export specifiers (export {x})
                // check if we have any non star export declarations.
                var hasExportDeclarationWithExportClause = false;
                for (var _i = 0, _a = moduleInfo.externalImports; _i < _a.length; _i++) {
                    var externalImport = _a[_i];
                    if (externalImport.kind === 260 /* ExportDeclaration */ && externalImport.exportClause) {
                        hasExportDeclarationWithExportClause = true;
                        break;
                    }
                }
                if (!hasExportDeclarationWithExportClause) {
                    // we still need to emit exportStar helper
                    var exportStarFunction_1 = createExportStarFunction(/*localNames*/ undefined);
                    statements.push(exportStarFunction_1);
                    return exportStarFunction_1.name;
                }
            }
            var exportedNames = [];
            if (moduleInfo.exportedNames) {
                for (var _b = 0, _c = moduleInfo.exportedNames; _b < _c.length; _b++) {
                    var exportedLocalName = _c[_b];
                    if (exportedLocalName.escapedText === "default") {
                        continue;
                    }
                    // write name of exported declaration, i.e 'export var x...'
                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(exportedLocalName), ts.createTrue()));
                }
            }
            for (var _d = 0, _e = moduleInfo.externalImports; _d < _e.length; _d++) {
                var externalImport = _e[_d];
                if (externalImport.kind !== 260 /* ExportDeclaration */) {
                    continue;
                }
                if (!externalImport.exportClause) {
                    // export * from ...
                    continue;
                }
                if (ts.isNamedExports(externalImport.exportClause)) {
                    for (var _f = 0, _g = externalImport.exportClause.elements; _f < _g.length; _f++) {
                        var element = _g[_f];
                        // write name of indirectly exported entry, i.e. 'export {x} from ...'
                        exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(element.name || element.propertyName)), ts.createTrue()));
                    }
                }
                else {
                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(externalImport.exportClause.name)), ts.createTrue()));
                }
            }
            var exportedNamesStorageRef = ts.createUniqueName("exportedNames");
            statements.push(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(exportedNamesStorageRef, 
                /*type*/ undefined, ts.createObjectLiteral(exportedNames, /*multiline*/ true))
            ])));
            var exportStarFunction = createExportStarFunction(exportedNamesStorageRef);
            statements.push(exportStarFunction);
            return exportStarFunction.name;
        }
        /**
         * Creates an exportStar function for the file, with an optional set of excluded local
         * names.
         *
         * @param localNames An optional reference to an object containing a set of excluded local
         * names.
         */
        function createExportStarFunction(localNames) {
            var exportStarFunction = ts.createUniqueName("exportStar");
            var m = ts.createIdentifier("m");
            var n = ts.createIdentifier("n");
            var exports = ts.createIdentifier("exports");
            var condition = ts.createStrictInequality(n, ts.createLiteral("default"));
            if (localNames) {
                condition = ts.createLogicalAnd(condition, ts.createLogicalNot(ts.createCall(ts.createPropertyAccess(localNames, "hasOwnProperty"), 
                /*typeArguments*/ undefined, [n])));
            }
            return ts.createFunctionDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, exportStarFunction, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, m)], 
            /*type*/ undefined, ts.createBlock([
                ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(exports, 
                    /*type*/ undefined, ts.createObjectLiteral([]))
                ])),
                ts.createForIn(ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(n, /*type*/ undefined)
                ]), m, ts.createBlock([
                    ts.setEmitFlags(ts.createIf(condition, ts.createExpressionStatement(ts.createAssignment(ts.createElementAccess(exports, n), ts.createElementAccess(m, n)))), 1 /* SingleLine */)
                ])),
                ts.createExpressionStatement(ts.createCall(exportFunction, 
                /*typeArguments*/ undefined, [exports]))
            ], /*multiline*/ true));
        }
        /**
         * Creates an array setter callbacks for each dependency group.
         *
         * @param exportStarFunction A reference to an exportStarFunction for the file.
         * @param dependencyGroups An array of grouped dependencies.
         */
        function createSettersArray(exportStarFunction, dependencyGroups) {
            var setters = [];
            for (var _i = 0, dependencyGroups_1 = dependencyGroups; _i < dependencyGroups_1.length; _i++) {
                var group_2 = dependencyGroups_1[_i];
                // derive a unique name for parameter from the first named entry in the group
                var localName = ts.forEach(group_2.externalImports, function (i) { return ts.getLocalNameForExternalImport(i, currentSourceFile); });
                var parameterName = localName ? ts.getGeneratedNameForNode(localName) : ts.createUniqueName("");
                var statements = [];
                for (var _a = 0, _b = group_2.externalImports; _a < _b.length; _a++) {
                    var entry = _b[_a];
                    var importVariableName = ts.getLocalNameForExternalImport(entry, currentSourceFile); // TODO: GH#18217
                    switch (entry.kind) {
                        case 254 /* ImportDeclaration */:
                            if (!entry.importClause) {
                                // 'import "..."' case
                                // module is imported only for side-effects, no emit required
                                break;
                            }
                        // falls through
                        case 253 /* ImportEqualsDeclaration */:
                            ts.Debug.assert(importVariableName !== undefined);
                            // save import into the local
                            statements.push(ts.createExpressionStatement(ts.createAssignment(importVariableName, parameterName)));
                            break;
                        case 260 /* ExportDeclaration */:
                            ts.Debug.assert(importVariableName !== undefined);
                            if (entry.exportClause) {
                                if (ts.isNamedExports(entry.exportClause)) {
                                    //  export {a, b as c} from 'foo'
                                    //
                                    // emit as:
                                    //
                                    //  exports_({
                                    //     "a": _["a"],
                                    //     "c": _["b"]
                                    //  });
                                    var properties = [];
                                    for (var _c = 0, _d = entry.exportClause.elements; _c < _d.length; _c++) {
                                        var e = _d[_c];
                                        properties.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(e.name)), ts.createElementAccess(parameterName, ts.createLiteral(ts.idText(e.propertyName || e.name)))));
                                    }
                                    statements.push(ts.createExpressionStatement(ts.createCall(exportFunction, 
                                    /*typeArguments*/ undefined, [ts.createObjectLiteral(properties, /*multiline*/ true)])));
                                }
                                else {
                                    statements.push(ts.createExpressionStatement(ts.createCall(exportFunction, 
                                    /*typeArguments*/ undefined, [
                                        ts.createLiteral(ts.idText(entry.exportClause.name)),
                                        parameterName
                                    ])));
                                }
                            }
                            else {
                                //  export * from 'foo'
                                //
                                // emit as:
                                //
                                //  exportStar(foo_1_1);
                                statements.push(ts.createExpressionStatement(ts.createCall(exportStarFunction, 
                                /*typeArguments*/ undefined, [parameterName])));
                            }
                            break;
                    }
                }
                setters.push(ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
                /*type*/ undefined, ts.createBlock(statements, /*multiLine*/ true)));
            }
            return ts.createArrayLiteral(setters, /*multiLine*/ true);
        }
        //
        // Top-level Source Element Visitors
        //
        /**
         * Visit source elements at the top-level of a module.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 260 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                case 259 /* ExportAssignment */:
                    return visitExportAssignment(node);
                default:
                    return nestedElementVisitor(node);
            }
        }
        /**
         * Visits an ImportDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportDeclaration(node) {
            var statements;
            if (node.importClause) {
                hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile)); // TODO: GH#18217
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        function visitExportDeclaration(node) {
            ts.Debug.assertIsDefined(node);
            return undefined;
        }
        /**
         * Visits an ImportEqualsDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportEqualsDeclaration(node) {
            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
            var statements;
            hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile)); // TODO: GH#18217
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportEqualsDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ExportAssignment node.
         *
         * @param node The node to visit.
         */
        function visitExportAssignment(node) {
            if (node.isExportEquals) {
                // Elide `export=` as it is illegal in a SystemJS module.
                return undefined;
            }
            var expression = ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression);
            var original = node.original;
            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), expression, /*allowComments*/ true);
            }
            else {
                return createExportStatement(ts.createIdentifier("default"), expression, /*allowComments*/ true);
            }
        }
        /**
         * Visits a FunctionDeclaration, hoisting it to the outer module body function.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            if (ts.hasModifier(node, 1 /* Export */)) {
                hoistedStatements = ts.append(hoistedStatements, ts.updateFunctionDeclaration(node, node.decorators, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, destructuringAndImportCallVisitor, ts.isParameterDeclaration), 
                /*type*/ undefined, ts.visitNode(node.body, destructuringAndImportCallVisitor, ts.isBlock)));
            }
            else {
                hoistedStatements = ts.append(hoistedStatements, ts.visitEachChild(node, destructuringAndImportCallVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node);
            }
            return undefined;
        }
        /**
         * Visits a ClassDeclaration, hoisting its name to the outer module body function.
         *
         * @param node The node to visit.
         */
        function visitClassDeclaration(node) {
            var statements;
            // Hoist the name of the class declaration to the outer module body function.
            var name = ts.getLocalName(node);
            hoistVariableDeclaration(name);
            // Rewrite the class declaration into an assignment of a class expression.
            statements = ts.append(statements, ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(name, ts.setTextRange(ts.createClassExpression(
            /*modifiers*/ undefined, node.name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, destructuringAndImportCallVisitor, ts.isHeritageClause), ts.visitNodes(node.members, destructuringAndImportCallVisitor, ts.isClassElement)), node))), node));
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a variable statement, hoisting declared names to the top-level module body.
         * Each declaration is rewritten into an assignment expression.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            if (!shouldHoistVariableDeclarationList(node.declarationList)) {
                return ts.visitNode(node, destructuringAndImportCallVisitor, ts.isStatement);
            }
            var expressions;
            var isExportedDeclaration = ts.hasModifier(node, 1 /* Export */);
            var isMarkedDeclaration = hasAssociatedEndOfDeclarationMarker(node);
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var variable = _a[_i];
                if (variable.initializer) {
                    expressions = ts.append(expressions, transformInitializedVariable(variable, isExportedDeclaration && !isMarkedDeclaration));
                }
                else {
                    hoistBindingElement(variable);
                }
            }
            var statements;
            if (expressions) {
                statements = ts.append(statements, ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(expressions)), node));
            }
            if (isMarkedDeclaration) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node, isExportedDeclaration);
            }
            else {
                statements = appendExportsOfVariableStatement(statements, node, /*exportSelf*/ false);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Hoists the declared names of a VariableDeclaration or BindingElement.
         *
         * @param node The declaration to hoist.
         */
        function hoistBindingElement(node) {
            if (ts.isBindingPattern(node.name)) {
                for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        hoistBindingElement(element);
                    }
                }
            }
            else {
                hoistVariableDeclaration(ts.getSynthesizedClone(node.name));
            }
        }
        /**
         * Determines whether a VariableDeclarationList should be hoisted.
         *
         * @param node The node to test.
         */
        function shouldHoistVariableDeclarationList(node) {
            // hoist only non-block scoped declarations or block scoped declarations parented by source file
            return (ts.getEmitFlags(node) & 2097152 /* NoHoisting */) === 0
                && (enclosingBlockScopedContainer.kind === 290 /* SourceFile */
                    || (ts.getOriginalNode(node).flags & 3 /* BlockScoped */) === 0);
        }
        /**
         * Transform an initialized variable declaration into an expression.
         *
         * @param node The node to transform.
         * @param isExportedDeclaration A value indicating whether the variable is exported.
         */
        function transformInitializedVariable(node, isExportedDeclaration) {
            var createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
            return ts.isBindingPattern(node.name)
                ? ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
                /*needsValue*/ false, createAssignment)
                : node.initializer ? createAssignment(node.name, ts.visitNode(node.initializer, destructuringAndImportCallVisitor, ts.isExpression)) : node.name;
        }
        /**
         * Creates an assignment expression for an exported variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         */
        function createExportedVariableAssignment(name, value, location) {
            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ true);
        }
        /**
         * Creates an assignment expression for a non-exported variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         */
        function createNonExportedVariableAssignment(name, value, location) {
            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ false);
        }
        /**
         * Creates an assignment expression for a variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         * @param isExportedDeclaration A value indicating whether the variable is exported.
         */
        function createVariableAssignment(name, value, location, isExportedDeclaration) {
            hoistVariableDeclaration(ts.getSynthesizedClone(name));
            return isExportedDeclaration
                ? createExportExpression(name, preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location)))
                : preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location));
        }
        /**
         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
         * and transformed declaration.
         *
         * @param node The node to visit.
         */
        function visitMergeDeclarationMarker(node) {
            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
            // declaration we do not emit a leading variable declaration. To preserve the
            // begin/end semantics of the declararation and to properly handle exports
            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
            //
            // To balance the declaration, we defer the exports of the elided variable
            // statement until we visit this declaration's `EndOfDeclarationMarker`.
            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 225 /* VariableStatement */) {
                var id = ts.getOriginalNodeId(node);
                var isExportedDeclaration = ts.hasModifier(node.original, 1 /* Export */);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original, isExportedDeclaration);
            }
            return node;
        }
        /**
         * Determines whether a node has an associated EndOfDeclarationMarker.
         *
         * @param node The node to test.
         */
        function hasAssociatedEndOfDeclarationMarker(node) {
            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
        }
        /**
         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
         * declaration.
         *
         * @param node The node to visit.
         */
        function visitEndOfDeclarationMarker(node) {
            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
            // end of the transformed declaration. We use this marker to emit any deferred exports
            // of the declaration.
            var id = ts.getOriginalNodeId(node);
            var statements = deferredExports[id];
            if (statements) {
                delete deferredExports[id];
                return ts.append(statements, node);
            }
            else {
                var original = ts.getOriginalNode(node);
                if (ts.isModuleOrEnumDeclaration(original)) {
                    return ts.append(appendExportsOfDeclaration(statements, original), node);
                }
            }
            return node;
        }
        /**
         * Appends the exports of an ImportDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var importClause = decl.importClause;
            if (!importClause) {
                return statements;
            }
            if (importClause.name) {
                statements = appendExportsOfDeclaration(statements, importClause);
            }
            var namedBindings = importClause.namedBindings;
            if (namedBindings) {
                switch (namedBindings.kind) {
                    case 256 /* NamespaceImport */:
                        statements = appendExportsOfDeclaration(statements, namedBindings);
                        break;
                    case 257 /* NamedImports */:
                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                            var importBinding = _a[_i];
                            statements = appendExportsOfDeclaration(statements, importBinding);
                        }
                        break;
                }
            }
            return statements;
        }
        /**
         * Appends the export of an ImportEqualsDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportEqualsDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            return appendExportsOfDeclaration(statements, decl);
        }
        /**
         * Appends the exports of a VariableStatement to a statement list, returning the statement
         * list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param node The VariableStatement whose exports are to be recorded.
         * @param exportSelf A value indicating whether to also export each VariableDeclaration of
         * `nodes` declaration list.
         */
        function appendExportsOfVariableStatement(statements, node, exportSelf) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (decl.initializer || exportSelf) {
                    statements = appendExportsOfBindingElement(statements, decl, exportSelf);
                }
            }
            return statements;
        }
        /**
         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         * @param exportSelf A value indicating whether to also export the declaration itself.
         */
        function appendExportsOfBindingElement(statements, decl, exportSelf) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            if (ts.isBindingPattern(decl.name)) {
                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        statements = appendExportsOfBindingElement(statements, element, exportSelf);
                    }
                }
            }
            else if (!ts.isGeneratedIdentifier(decl.name)) {
                var excludeName = void 0;
                if (exportSelf) {
                    statements = appendExportStatement(statements, decl.name, ts.getLocalName(decl));
                    excludeName = ts.idText(decl.name);
                }
                statements = appendExportsOfDeclaration(statements, decl, excludeName);
            }
            return statements;
        }
        /**
         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfHoistedDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var excludeName;
            if (ts.hasModifier(decl, 1 /* Export */)) {
                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createLiteral("default") : decl.name;
                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl));
                excludeName = ts.getTextOfIdentifierOrLiteral(exportName);
            }
            if (decl.name) {
                statements = appendExportsOfDeclaration(statements, decl, excludeName);
            }
            return statements;
        }
        /**
         * Appends the exports of a declaration to a statement list, returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration to export.
         * @param excludeName An optional name to exclude from exports.
         */
        function appendExportsOfDeclaration(statements, decl, excludeName) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var name = ts.getDeclarationName(decl);
            var exportSpecifiers = moduleInfo.exportSpecifiers.get(ts.idText(name));
            if (exportSpecifiers) {
                for (var _i = 0, exportSpecifiers_2 = exportSpecifiers; _i < exportSpecifiers_2.length; _i++) {
                    var exportSpecifier = exportSpecifiers_2[_i];
                    if (exportSpecifier.name.escapedText !== excludeName) {
                        statements = appendExportStatement(statements, exportSpecifier.name, name);
                    }
                }
            }
            return statements;
        }
        /**
         * Appends the down-level representation of an export to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param exportName The name of the export.
         * @param expression The expression to export.
         * @param allowComments Whether to allow comments on the export.
         */
        function appendExportStatement(statements, exportName, expression, allowComments) {
            statements = ts.append(statements, createExportStatement(exportName, expression, allowComments));
            return statements;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param allowComments An optional value indicating whether to emit comments for the statement.
         */
        function createExportStatement(name, value, allowComments) {
            var statement = ts.createExpressionStatement(createExportExpression(name, value));
            ts.startOnNewLine(statement);
            if (!allowComments) {
                ts.setEmitFlags(statement, 1536 /* NoComments */);
            }
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         */
        function createExportExpression(name, value) {
            var exportName = ts.isIdentifier(name) ? ts.createLiteral(name) : name;
            ts.setEmitFlags(value, ts.getEmitFlags(value) | 1536 /* NoComments */);
            return ts.setCommentRange(ts.createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value);
        }
        //
        // Top-Level or Nested Source Element Visitors
        //
        /**
         * Visit nested elements at the top-level of a module.
         *
         * @param node The node to visit.
         */
        function nestedElementVisitor(node) {
            switch (node.kind) {
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 245 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 230 /* ForStatement */:
                    return visitForStatement(node);
                case 231 /* ForInStatement */:
                    return visitForInStatement(node);
                case 232 /* ForOfStatement */:
                    return visitForOfStatement(node);
                case 228 /* DoStatement */:
                    return visitDoStatement(node);
                case 229 /* WhileStatement */:
                    return visitWhileStatement(node);
                case 238 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 236 /* WithStatement */:
                    return visitWithStatement(node);
                case 237 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 251 /* CaseBlock */:
                    return visitCaseBlock(node);
                case 277 /* CaseClause */:
                    return visitCaseClause(node);
                case 278 /* DefaultClause */:
                    return visitDefaultClause(node);
                case 240 /* TryStatement */:
                    return visitTryStatement(node);
                case 280 /* CatchClause */:
                    return visitCatchClause(node);
                case 223 /* Block */:
                    return visitBlock(node);
                case 328 /* MergeDeclarationMarker */:
                    return visitMergeDeclarationMarker(node);
                case 329 /* EndOfDeclarationMarker */:
                    return visitEndOfDeclarationMarker(node);
                default:
                    return destructuringAndImportCallVisitor(node);
            }
        }
        /**
         * Visits the body of a ForStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateFor(node, node.initializer && visitForInitializer(node.initializer), ts.visitNode(node.condition, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.incrementor, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a ForInStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForInStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateForIn(node, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a ForOfStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForOfStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateForOf(node, node.awaitModifier, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Determines whether to hoist the initializer of a ForStatement, ForInStatement, or
         * ForOfStatement.
         *
         * @param node The node to test.
         */
        function shouldHoistForInitializer(node) {
            return ts.isVariableDeclarationList(node)
                && shouldHoistVariableDeclarationList(node);
        }
        /**
         * Visits the initializer of a ForStatement, ForInStatement, or ForOfStatement
         *
         * @param node The node to visit.
         */
        function visitForInitializer(node) {
            if (shouldHoistForInitializer(node)) {
                var expressions = void 0;
                for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    expressions = ts.append(expressions, transformInitializedVariable(variable, /*isExportedDeclaration*/ false));
                    if (!variable.initializer) {
                        hoistBindingElement(variable);
                    }
                }
                return expressions ? ts.inlineExpressions(expressions) : ts.createOmittedExpression();
            }
            else {
                return ts.visitEachChild(node, nestedElementVisitor, context);
            }
        }
        /**
         * Visits the body of a DoStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitDoStatement(node) {
            return ts.updateDo(node, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression));
        }
        /**
         * Visits the body of a WhileStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitWhileStatement(node) {
            return ts.updateWhile(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a LabeledStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitLabeledStatement(node) {
            return ts.updateLabel(node, node.label, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a WithStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitWithStatement(node) {
            return ts.updateWith(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a SwitchStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitSwitchStatement(node) {
            return ts.updateSwitch(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.caseBlock, nestedElementVisitor, ts.isCaseBlock));
        }
        /**
         * Visits the body of a CaseBlock to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCaseBlock(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateCaseBlock(node, ts.visitNodes(node.clauses, nestedElementVisitor, ts.isCaseOrDefaultClause));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a CaseClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCaseClause(node) {
            return ts.updateCaseClause(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNodes(node.statements, nestedElementVisitor, ts.isStatement));
        }
        /**
         * Visits the body of a DefaultClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitDefaultClause(node) {
            return ts.visitEachChild(node, nestedElementVisitor, context);
        }
        /**
         * Visits the body of a TryStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitTryStatement(node) {
            return ts.visitEachChild(node, nestedElementVisitor, context);
        }
        /**
         * Visits the body of a CatchClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCatchClause(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateCatchClause(node, node.variableDeclaration, ts.visitNode(node.block, nestedElementVisitor, ts.isBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a Block to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitBlock(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.visitEachChild(node, nestedElementVisitor, context);
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        //
        // Destructuring Assignment Visitors
        //
        /**
         * Visit nodes to flatten destructuring assignments to exported symbols.
         *
         * @param node The node to visit.
         */
        function destructuringAndImportCallVisitor(node) {
            if (ts.isDestructuringAssignment(node)) {
                return visitDestructuringAssignment(node);
            }
            else if (ts.isImportCall(node)) {
                return visitImportCallExpression(node);
            }
            else if ((node.transformFlags & 1024 /* ContainsDestructuringAssignment */) || (node.transformFlags & 2097152 /* ContainsDynamicImport */)) {
                return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
            }
            else {
                return node;
            }
        }
        function visitImportCallExpression(node) {
            // import("./blah")
            // emit as
            // System.register([], function (_export, _context) {
            //     return {
            //         setters: [],
            //         execute: () => {
            //             _context.import('./blah');
            //         }
            //     };
            // });
            return ts.createCall(ts.createPropertyAccess(contextObject, ts.createIdentifier("import")), 
            /*typeArguments*/ undefined, ts.some(node.arguments) ? [ts.visitNode(node.arguments[0], destructuringAndImportCallVisitor)] : []);
        }
        /**
         * Visits a DestructuringAssignment to flatten destructuring to exported symbols.
         *
         * @param node The node to visit.
         */
        function visitDestructuringAssignment(node) {
            if (hasExportedReferenceInDestructuringTarget(node.left)) {
                return ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
                /*needsValue*/ true);
            }
            return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
        }
        /**
         * Determines whether the target of a destructuring assigment refers to an exported symbol.
         *
         * @param node The destructuring target.
         */
        function hasExportedReferenceInDestructuringTarget(node) {
            if (ts.isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
                return hasExportedReferenceInDestructuringTarget(node.left);
            }
            else if (ts.isSpreadElement(node)) {
                return hasExportedReferenceInDestructuringTarget(node.expression);
            }
            else if (ts.isObjectLiteralExpression(node)) {
                return ts.some(node.properties, hasExportedReferenceInDestructuringTarget);
            }
            else if (ts.isArrayLiteralExpression(node)) {
                return ts.some(node.elements, hasExportedReferenceInDestructuringTarget);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return hasExportedReferenceInDestructuringTarget(node.name);
            }
            else if (ts.isPropertyAssignment(node)) {
                return hasExportedReferenceInDestructuringTarget(node.initializer);
            }
            else if (ts.isIdentifier(node)) {
                var container = resolver.getReferencedExportContainer(node);
                return container !== undefined && container.kind === 290 /* SourceFile */;
            }
            else {
                return false;
            }
        }
        //
        // Modifier Visitors
        //
        /**
         * Visit nodes to elide module-specific modifiers.
         *
         * @param node The node to visit.
         */
        function modifierVisitor(node) {
            switch (node.kind) {
                case 89 /* ExportKeyword */:
                case 84 /* DefaultKeyword */:
                    return undefined;
            }
            return node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit notifications.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (node.kind === 290 /* SourceFile */) {
                var id = ts.getOriginalNodeId(node);
                currentSourceFile = node;
                moduleInfo = moduleInfoMap[id];
                exportFunction = exportFunctionsMap[id];
                noSubstitution = noSubstitutionMap[id];
                contextObject = contextObjectMap[id];
                if (noSubstitution) {
                    delete noSubstitutionMap[id];
                }
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
                moduleInfo = undefined;
                exportFunction = undefined;
                contextObject = undefined;
                noSubstitution = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (isSubstitutionPrevented(node)) {
                return node;
            }
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (hint === 4 /* Unspecified */) {
                return substituteUnspecified(node);
            }
            return node;
        }
        /**
         * Substitute the node, if necessary.
         *
         * @param node The node to substitute.
         */
        function substituteUnspecified(node) {
            switch (node.kind) {
                case 282 /* ShorthandPropertyAssignment */:
                    return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteShorthandPropertyAssignment(node) {
            var name = node.name;
            if (!ts.isGeneratedIdentifier(name) && !ts.isLocalName(name)) {
                var importDeclaration = resolver.getReferencedImportDeclaration(name);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAssignment(ts.getSynthesizedClone(name), ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default"))), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAssignment(ts.getSynthesizedClone(name), ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name))), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitute the expression, if necessary.
         *
         * @param node The node to substitute.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 209 /* BinaryExpression */:
                    return substituteBinaryExpression(node);
                case 207 /* PrefixUnaryExpression */:
                case 208 /* PostfixUnaryExpression */:
                    return substituteUnaryExpression(node);
                case 219 /* MetaProperty */:
                    return substituteMetaProperty(node);
            }
            return node;
        }
        /**
         * Substitution for an Identifier expression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
                return node;
            }
            // When we see an identifier in an expression position that
            // points to an imported symbol, we should substitute a qualified
            // reference to the imported symbol if one is needed.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                var importDeclaration = resolver.getReferencedImportDeclaration(node);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteBinaryExpression(node) {
            // When we see an assignment expression whose left-hand side is an exported symbol,
            // we should ensure all exports of that symbol are updated with the correct value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if (ts.isAssignmentOperator(node.operatorToken.kind)
                && ts.isIdentifier(node.left)
                && !ts.isGeneratedIdentifier(node.left)
                && !ts.isLocalName(node.left)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
                var exportedNames = getExports(node.left);
                if (exportedNames) {
                    // For each additional export of the declaration, apply an export assignment.
                    var expression = node;
                    for (var _i = 0, exportedNames_4 = exportedNames; _i < exportedNames_4.length; _i++) {
                        var exportName = exportedNames_4[_i];
                        expression = createExportExpression(exportName, preventSubstitution(expression));
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteUnaryExpression(node) {
            // When we see a prefix or postfix increment expression whose operand is an exported
            // symbol, we should ensure all exports of that symbol are updated with the correct
            // value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if ((node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */)
                && ts.isIdentifier(node.operand)
                && !ts.isGeneratedIdentifier(node.operand)
                && !ts.isLocalName(node.operand)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
                var exportedNames = getExports(node.operand);
                if (exportedNames) {
                    var expression = node.kind === 208 /* PostfixUnaryExpression */
                        ? ts.setTextRange(ts.createPrefix(node.operator, node.operand), node)
                        : node;
                    for (var _i = 0, exportedNames_5 = exportedNames; _i < exportedNames_5.length; _i++) {
                        var exportName = exportedNames_5[_i];
                        expression = createExportExpression(exportName, preventSubstitution(expression));
                    }
                    if (node.kind === 208 /* PostfixUnaryExpression */) {
                        expression = node.operator === 45 /* PlusPlusToken */
                            ? ts.createSubtract(preventSubstitution(expression), ts.createLiteral(1))
                            : ts.createAdd(preventSubstitution(expression), ts.createLiteral(1));
                    }
                    return expression;
                }
            }
            return node;
        }
        function substituteMetaProperty(node) {
            if (ts.isImportMeta(node)) {
                return ts.createPropertyAccess(contextObject, ts.createIdentifier("meta"));
            }
            return node;
        }
        /**
         * Gets the exports of a name.
         *
         * @param name The name.
         */
        function getExports(name) {
            var exportedNames;
            if (!ts.isGeneratedIdentifier(name)) {
                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
                    || resolver.getReferencedValueDeclaration(name);
                if (valueDeclaration) {
                    var exportContainer = resolver.getReferencedExportContainer(name, /*prefixLocals*/ false);
                    if (exportContainer && exportContainer.kind === 290 /* SourceFile */) {
                        exportedNames = ts.append(exportedNames, ts.getDeclarationName(valueDeclaration));
                    }
                    exportedNames = ts.addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)]);
                }
            }
            return exportedNames;
        }
        /**
         * Prevent substitution of a node for this transformer.
         *
         * @param node The node which should not be substituted.
         */
        function preventSubstitution(node) {
            if (noSubstitution === undefined)
                noSubstitution = [];
            noSubstitution[ts.getNodeId(node)] = true;
            return node;
        }
        /**
         * Determines whether a node should not be substituted.
         *
         * @param node The node to test.
         */
        function isSubstitutionPrevented(node) {
            return noSubstitution && node.id && noSubstitution[node.id];
        }
    }
    ts.transformSystemModule = transformSystemModule;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformECMAScriptModule(context) {
        var compilerOptions = context.getCompilerOptions();
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.enableEmitNotification(290 /* SourceFile */);
        context.enableSubstitution(75 /* Identifier */);
        var helperNameSubstitutions;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
                var externalHelpersImportDeclaration = ts.createExternalHelpersImportDeclarationIfNeeded(node, compilerOptions);
                if (externalHelpersImportDeclaration) {
                    var statements = [];
                    var statementOffset = ts.addPrologue(statements, node.statements);
                    ts.append(statements, externalHelpersImportDeclaration);
                    ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
                    return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
                }
                else {
                    return ts.visitEachChild(node, visitor, context);
                }
            }
            return node;
        }
        function visitor(node) {
            switch (node.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    // Elide `import=` as it is not legal with --module ES6
                    return undefined;
                case 259 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 260 /* ExportDeclaration */:
                    var exportDecl = node;
                    return visitExportDeclaration(exportDecl);
            }
            return node;
        }
        function visitExportAssignment(node) {
            // Elide `export=` as it is not legal with --module ES6
            return node.isExportEquals ? undefined : node;
        }
        function visitExportDeclaration(node) {
            // `export * as ns` only needs to be transformed in ES2015
            if (compilerOptions.module !== undefined && compilerOptions.module > ts.ModuleKind.ES2015) {
                return node;
            }
            // Either ill-formed or don't need to be tranformed.
            if (!node.exportClause || !ts.isNamespaceExport(node.exportClause) || !node.moduleSpecifier) {
                return node;
            }
            var oldIdentifier = node.exportClause.name;
            var synthName = ts.getGeneratedNameForNode(oldIdentifier);
            var importDecl = ts.createImportDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(synthName)), node.moduleSpecifier);
            ts.setOriginalNode(importDecl, node.exportClause);
            var exportDecl = ts.createExportDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, ts.createNamedExports([ts.createExportSpecifier(synthName, oldIdentifier)]));
            ts.setOriginalNode(exportDecl, node);
            return [importDecl, exportDecl];
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (ts.isSourceFile(node)) {
                if ((ts.isExternalModule(node) || compilerOptions.isolatedModules) && compilerOptions.importHelpers) {
                    helperNameSubstitutions = ts.createMap();
                }
                previousOnEmitNode(hint, node, emitCallback);
                helperNameSubstitutions = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (helperNameSubstitutions && ts.isIdentifier(node) && ts.getEmitFlags(node) & 4096 /* HelperName */) {
                return substituteHelperName(node);
            }
            return node;
        }
        function substituteHelperName(node) {
            var name = ts.idText(node);
            var substitution = helperNameSubstitutions.get(name);
            if (!substitution) {
                helperNameSubstitutions.set(name, substitution = ts.createFileLevelUniqueName(name));
            }
            return substitution;
        }
    }
    ts.transformECMAScriptModule = transformECMAScriptModule;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function canProduceDiagnostics(node) {
        return ts.isVariableDeclaration(node) ||
            ts.isPropertyDeclaration(node) ||
            ts.isPropertySignature(node) ||
            ts.isBindingElement(node) ||
            ts.isSetAccessor(node) ||
            ts.isGetAccessor(node) ||
            ts.isConstructSignatureDeclaration(node) ||
            ts.isCallSignatureDeclaration(node) ||
            ts.isMethodDeclaration(node) ||
            ts.isMethodSignature(node) ||
            ts.isFunctionDeclaration(node) ||
            ts.isParameter(node) ||
            ts.isTypeParameterDeclaration(node) ||
            ts.isExpressionWithTypeArguments(node) ||
            ts.isImportEqualsDeclaration(node) ||
            ts.isTypeAliasDeclaration(node) ||
            ts.isConstructorDeclaration(node) ||
            ts.isIndexSignatureDeclaration(node) ||
            ts.isPropertyAccessExpression(node);
    }
    ts.canProduceDiagnostics = canProduceDiagnostics;
    function createGetSymbolAccessibilityDiagnosticForNodeName(node) {
        if (ts.isSetAccessor(node) || ts.isGetAccessor(node)) {
            return getAccessorNameVisibilityError;
        }
        else if (ts.isMethodSignature(node) || ts.isMethodDeclaration(node)) {
            return getMethodNameVisibilityError;
        }
        else {
            return createGetSymbolAccessibilityDiagnosticForNode(node);
        }
        function getAccessorNameVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (ts.hasModifier(node, 32 /* Static */)) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else if (node.parent.kind === 245 /* ClassDeclaration */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else {
                return symbolAccessibilityResult.errorModuleName ?
                    ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
            }
        }
        function getMethodNameVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (ts.hasModifier(node, 32 /* Static */)) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else if (node.parent.kind === 245 /* ClassDeclaration */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else {
                return symbolAccessibilityResult.errorModuleName ?
                    ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_private_name_1;
            }
        }
    }
    ts.createGetSymbolAccessibilityDiagnosticForNodeName = createGetSymbolAccessibilityDiagnosticForNodeName;
    function createGetSymbolAccessibilityDiagnosticForNode(node) {
        if (ts.isVariableDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isPropertyAccessExpression(node) || ts.isBindingElement(node) || ts.isConstructorDeclaration(node)) {
            return getVariableDeclarationTypeVisibilityError;
        }
        else if (ts.isSetAccessor(node) || ts.isGetAccessor(node)) {
            return getAccessorDeclarationTypeVisibilityError;
        }
        else if (ts.isConstructSignatureDeclaration(node) || ts.isCallSignatureDeclaration(node) || ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isFunctionDeclaration(node) || ts.isIndexSignatureDeclaration(node)) {
            return getReturnTypeVisibilityError;
        }
        else if (ts.isParameter(node)) {
            if (ts.isParameterPropertyDeclaration(node, node.parent) && ts.hasModifier(node.parent, 8 /* Private */)) {
                return getVariableDeclarationTypeVisibilityError;
            }
            return getParameterDeclarationTypeVisibilityError;
        }
        else if (ts.isTypeParameterDeclaration(node)) {
            return getTypeParameterConstraintVisibilityError;
        }
        else if (ts.isExpressionWithTypeArguments(node)) {
            return getHeritageClauseVisibilityError;
        }
        else if (ts.isImportEqualsDeclaration(node)) {
            return getImportEntityNameVisibilityError;
        }
        else if (ts.isTypeAliasDeclaration(node)) {
            return getTypeAliasDeclarationVisibilityError;
        }
        else {
            return ts.Debug.assertNever(node, "Attempted to set a declaration diagnostic context for unhandled node kind: " + ts.SyntaxKind[node.kind]);
        }
        function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (node.kind === 242 /* VariableDeclaration */ || node.kind === 191 /* BindingElement */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
            }
            // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit
            // The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all.
            else if (node.kind === 159 /* PropertyDeclaration */ || node.kind === 194 /* PropertyAccessExpression */ || node.kind === 158 /* PropertySignature */ ||
                (node.kind === 156 /* Parameter */ && ts.hasModifier(node.parent, 8 /* Private */))) {
                // TODO(jfreeman): Deal with computed properties in error reporting.
                if (ts.hasModifier(node, 32 /* Static */)) {
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
                }
                else if (node.parent.kind === 245 /* ClassDeclaration */ || node.kind === 156 /* Parameter */) {
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    // Interfaces cannot have types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
                }
            }
        }
        function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage;
            if (node.kind === 164 /* SetAccessor */) {
                // Getters can infer the return type from the returned expression, but setters cannot, so the
                // "_from_external_module_1_but_cannot_be_named" case cannot occur.
                if (ts.hasModifier(node, 32 /* Static */)) {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1;
                }
            }
            else {
                if (ts.hasModifier(node, 32 /* Static */)) {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1;
                }
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node.name,
                typeName: node.name
            };
        }
        function getReturnTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage;
            switch (node.kind) {
                case 166 /* ConstructSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 165 /* CallSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 167 /* IndexSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    if (ts.hasModifier(node, 32 /* Static */)) {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0;
                    }
                    else if (node.parent.kind === 245 /* ClassDeclaration */) {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0;
                    }
                    else {
                        // Interfaces cannot have return types that cannot be named
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0;
                    }
                    break;
                case 244 /* FunctionDeclaration */:
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0;
                    break;
                default:
                    return ts.Debug.fail("This is unknown kind for signature: " + node.kind);
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node.name || node
            };
        }
        function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            switch (node.parent.kind) {
                case 162 /* Constructor */:
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
                case 166 /* ConstructSignature */:
                case 171 /* ConstructorType */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 165 /* CallSignature */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 167 /* IndexSignature */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    if (ts.hasModifier(node.parent, 32 /* Static */)) {
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else if (node.parent.parent.kind === 245 /* ClassDeclaration */) {
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else {
                        // Interfaces cannot have parameter types that cannot be named
                        return symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                    }
                case 244 /* FunctionDeclaration */:
                case 170 /* FunctionType */:
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
                case 164 /* SetAccessor */:
                case 163 /* GetAccessor */:
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_private_name_1;
                default:
                    return ts.Debug.fail("Unknown parent for parameter: " + ts.SyntaxKind[node.parent.kind]);
            }
        }
        function getTypeParameterConstraintVisibilityError() {
            // Type parameter constraints are named by user so we should always be able to name it
            var diagnosticMessage;
            switch (node.parent.kind) {
                case 245 /* ClassDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
                    break;
                case 246 /* InterfaceDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 186 /* MappedType */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1;
                    break;
                case 171 /* ConstructorType */:
                case 166 /* ConstructSignature */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 165 /* CallSignature */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    if (ts.hasModifier(node.parent, 32 /* Static */)) {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else if (node.parent.parent.kind === 245 /* ClassDeclaration */) {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                    }
                    break;
                case 170 /* FunctionType */:
                case 244 /* FunctionDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
                    break;
                case 247 /* TypeAliasDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1;
                    break;
                default:
                    return ts.Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            };
        }
        function getHeritageClauseVisibilityError() {
            var diagnosticMessage;
            // Heritage clause is written by user so it can always be named
            if (node.parent.parent.kind === 245 /* ClassDeclaration */) {
                // Class or Interface implemented/extended is inaccessible
                diagnosticMessage = ts.isHeritageClause(node.parent) && node.parent.token === 113 /* ImplementsKeyword */ ?
                    ts.Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
                    ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
            }
            else {
                // interface is inaccessible
                diagnosticMessage = ts.Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: ts.getNameOfDeclaration(node.parent.parent)
            };
        }
        function getImportEntityNameVisibilityError() {
            return {
                diagnosticMessage: ts.Diagnostics.Import_declaration_0_is_using_private_name_1,
                errorNode: node,
                typeName: node.name
            };
        }
        function getTypeAliasDeclarationVisibilityError() {
            return {
                diagnosticMessage: ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
                errorNode: node.type,
                typeName: node.name
            };
        }
    }
    ts.createGetSymbolAccessibilityDiagnosticForNode = createGetSymbolAccessibilityDiagnosticForNode;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function getDeclarationDiagnostics(host, resolver, file) {
        if (file && ts.isJsonSourceFile(file)) {
            return []; // No declaration diagnostics for json for now
        }
        var compilerOptions = host.getCompilerOptions();
        var result = ts.transformNodes(resolver, host, compilerOptions, file ? [file] : ts.filter(host.getSourceFiles(), ts.isSourceFileNotJson), [transformDeclarations], /*allowDtsFiles*/ false);
        return result.diagnostics;
    }
    ts.getDeclarationDiagnostics = getDeclarationDiagnostics;
    function hasInternalAnnotation(range, currentSourceFile) {
        var comment = currentSourceFile.text.substring(range.pos, range.end);
        return ts.stringContains(comment, "@internal");
    }
    function isInternalDeclaration(node, currentSourceFile) {
        var parseTreeNode = ts.getParseTreeNode(node);
        if (parseTreeNode && parseTreeNode.kind === 156 /* Parameter */) {
            var paramIdx = parseTreeNode.parent.parameters.indexOf(parseTreeNode);
            var previousSibling = paramIdx > 0 ? parseTreeNode.parent.parameters[paramIdx - 1] : undefined;
            var text = currentSourceFile.text;
            var commentRanges = previousSibling
                ? ts.concatenate(
                // to handle
                // ... parameters, /* @internal */
                // public param: string
                ts.getTrailingCommentRanges(text, ts.skipTrivia(text, previousSibling.end + 1, /* stopAfterLineBreak */ false, /* stopAtComments */ true)), ts.getLeadingCommentRanges(text, node.pos))
                : ts.getTrailingCommentRanges(text, ts.skipTrivia(text, node.pos, /* stopAfterLineBreak */ false, /* stopAtComments */ true));
            return commentRanges && commentRanges.length && hasInternalAnnotation(ts.last(commentRanges), currentSourceFile);
        }
        var leadingCommentRanges = parseTreeNode && ts.getLeadingCommentRangesOfNode(parseTreeNode, currentSourceFile);
        return !!ts.forEach(leadingCommentRanges, function (range) {
            return hasInternalAnnotation(range, currentSourceFile);
        });
    }
    ts.isInternalDeclaration = isInternalDeclaration;
    var declarationEmitNodeBuilderFlags = 1024 /* MultilineObjectLiterals */ |
        2048 /* WriteClassExpressionAsTypeLiteral */ |
        4096 /* UseTypeOfFunction */ |
        8 /* UseStructuralFallback */ |
        524288 /* AllowEmptyTuple */ |
        4 /* GenerateNamesForShadowedTypeParams */ |
        1 /* NoTruncation */;
    /**
     * Transforms a ts file into a .d.ts file
     * This process requires type information, which is retrieved through the emit resolver. Because of this,
     * in many places this transformer assumes it will be operating on parse tree nodes directly.
     * This means that _no transforms should be allowed to occur before this one_.
     */
    function transformDeclarations(context) {
        var throwDiagnostic = function () { return ts.Debug.fail("Diagnostic emitted without context"); };
        var getSymbolAccessibilityDiagnostic = throwDiagnostic;
        var needsDeclare = true;
        var isBundledEmit = false;
        var resultHasExternalModuleIndicator = false;
        var needsScopeFixMarker = false;
        var resultHasScopeMarker = false;
        var enclosingDeclaration;
        var necessaryTypeReferences;
        var lateMarkedStatements;
        var lateStatementReplacementMap;
        var suppressNewDiagnosticContexts;
        var exportedModulesFromDeclarationEmit;
        var host = context.getEmitHost();
        var symbolTracker = {
            trackSymbol: trackSymbol,
            reportInaccessibleThisError: reportInaccessibleThisError,
            reportInaccessibleUniqueSymbolError: reportInaccessibleUniqueSymbolError,
            reportCyclicStructureError: reportCyclicStructureError,
            reportPrivateInBaseOfClassExpression: reportPrivateInBaseOfClassExpression,
            reportLikelyUnsafeImportRequiredError: reportLikelyUnsafeImportRequiredError,
            moduleResolverHost: host,
            trackReferencedAmbientModule: trackReferencedAmbientModule,
            trackExternalModuleSymbolOfImportTypeNode: trackExternalModuleSymbolOfImportTypeNode,
            reportNonlocalAugmentation: reportNonlocalAugmentation
        };
        var errorNameNode;
        var currentSourceFile;
        var refs;
        var libs;
        var emittedImports; // must be declared in container so it can be `undefined` while transformer's first pass
        var resolver = context.getEmitResolver();
        var options = context.getCompilerOptions();
        var noResolve = options.noResolve, stripInternal = options.stripInternal;
        return transformRoot;
        function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives) {
            if (!typeReferenceDirectives) {
                return;
            }
            necessaryTypeReferences = necessaryTypeReferences || ts.createMap();
            for (var _i = 0, typeReferenceDirectives_2 = typeReferenceDirectives; _i < typeReferenceDirectives_2.length; _i++) {
                var ref = typeReferenceDirectives_2[_i];
                necessaryTypeReferences.set(ref, true);
            }
        }
        function trackReferencedAmbientModule(node, symbol) {
            // If it is visible via `// <reference types="..."/>`, then we should just use that
            var directives = resolver.getTypeReferenceDirectivesForSymbol(symbol, 67108863 /* All */);
            if (ts.length(directives)) {
                return recordTypeReferenceDirectivesIfNecessary(directives);
            }
            // Otherwise we should emit a path-based reference
            var container = ts.getSourceFileOfNode(node);
            refs.set("" + ts.getOriginalNodeId(container), container);
        }
        function handleSymbolAccessibilityError(symbolAccessibilityResult) {
            if (symbolAccessibilityResult.accessibility === 0 /* Accessible */) {
                // Add aliases back onto the possible imports list if they're not there so we can try them again with updated visibility info
                if (symbolAccessibilityResult && symbolAccessibilityResult.aliasesToMakeVisible) {
                    if (!lateMarkedStatements) {
                        lateMarkedStatements = symbolAccessibilityResult.aliasesToMakeVisible;
                    }
                    else {
                        for (var _i = 0, _a = symbolAccessibilityResult.aliasesToMakeVisible; _i < _a.length; _i++) {
                            var ref = _a[_i];
                            ts.pushIfUnique(lateMarkedStatements, ref);
                        }
                    }
                }
                // TODO: Do all these accessibility checks inside/after the first pass in the checker when declarations are enabled, if possible
            }
            else {
                // Report error
                var errorInfo = getSymbolAccessibilityDiagnostic(symbolAccessibilityResult);
                if (errorInfo) {
                    if (errorInfo.typeName) {
                        context.addDiagnostic(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNode(errorInfo.typeName), symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
                    }
                    else {
                        context.addDiagnostic(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
                    }
                }
            }
        }
        function trackExternalModuleSymbolOfImportTypeNode(symbol) {
            if (!isBundledEmit) {
                (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
            }
        }
        function trackSymbol(symbol, enclosingDeclaration, meaning) {
            if (symbol.flags & 262144 /* TypeParameter */)
                return;
            handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
        }
        function reportPrivateInBaseOfClassExpression(propertyName) {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName));
            }
        }
        function reportInaccessibleUniqueSymbolError() {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), "unique symbol"));
            }
        }
        function reportCyclicStructureError() {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode)));
            }
        }
        function reportInaccessibleThisError() {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), "this"));
            }
        }
        function reportLikelyUnsafeImportRequiredError(specifier) {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), specifier));
            }
        }
        function reportNonlocalAugmentation(containingFile, parentSymbol, symbol) {
            var primaryDeclaration = ts.find(parentSymbol.declarations, function (d) { return ts.getSourceFileOfNode(d) === containingFile; });
            var augmentingDeclarations = ts.filter(symbol.declarations, function (d) { return ts.getSourceFileOfNode(d) !== containingFile; });
            for (var _i = 0, augmentingDeclarations_1 = augmentingDeclarations; _i < augmentingDeclarations_1.length; _i++) {
                var augmentations = augmentingDeclarations_1[_i];
                context.addDiagnostic(ts.addRelatedInfo(ts.createDiagnosticForNode(augmentations, ts.Diagnostics.Declaration_augments_declaration_in_another_file_This_cannot_be_serialized), ts.createDiagnosticForNode(primaryDeclaration, ts.Diagnostics.This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file)));
            }
        }
        function transformDeclarationsForJS(sourceFile, bundled) {
            var oldDiag = getSymbolAccessibilityDiagnostic;
            getSymbolAccessibilityDiagnostic = function (s) { return ({
                diagnosticMessage: s.errorModuleName
                    ? ts.Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit
                    : ts.Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit,
                errorNode: s.errorNode || sourceFile
            }); };
            var result = resolver.getDeclarationStatementsForSourceFile(sourceFile, declarationEmitNodeBuilderFlags, symbolTracker, bundled);
            getSymbolAccessibilityDiagnostic = oldDiag;
            return result;
        }
        function transformRoot(node) {
            if (node.kind === 290 /* SourceFile */ && node.isDeclarationFile) {
                return node;
            }
            if (node.kind === 291 /* Bundle */) {
                isBundledEmit = true;
                refs = ts.createMap();
                libs = ts.createMap();
                var hasNoDefaultLib_1 = false;
                var bundle = ts.createBundle(ts.map(node.sourceFiles, function (sourceFile) {
                    if (sourceFile.isDeclarationFile)
                        return undefined; // Omit declaration files from bundle results, too // TODO: GH#18217
                    hasNoDefaultLib_1 = hasNoDefaultLib_1 || sourceFile.hasNoDefaultLib;
                    currentSourceFile = sourceFile;
                    enclosingDeclaration = sourceFile;
                    lateMarkedStatements = undefined;
                    suppressNewDiagnosticContexts = false;
                    lateStatementReplacementMap = ts.createMap();
                    getSymbolAccessibilityDiagnostic = throwDiagnostic;
                    needsScopeFixMarker = false;
                    resultHasScopeMarker = false;
                    collectReferences(sourceFile, refs);
                    collectLibs(sourceFile, libs);
                    if (ts.isExternalOrCommonJsModule(sourceFile) || ts.isJsonSourceFile(sourceFile)) {
                        resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules)
                        needsDeclare = false;
                        var statements = ts.isSourceFileJS(sourceFile) ? ts.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : ts.visitNodes(sourceFile.statements, visitDeclarationStatements);
                        var newFile = ts.updateSourceFileNode(sourceFile, [ts.createModuleDeclaration([], [ts.createModifier(130 /* DeclareKeyword */)], ts.createLiteral(ts.getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), ts.createModuleBlock(ts.setTextRange(ts.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements)))], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
                        return newFile;
                    }
                    needsDeclare = true;
                    var updated = ts.isSourceFileJS(sourceFile) ? ts.createNodeArray(transformDeclarationsForJS(sourceFile)) : ts.visitNodes(sourceFile.statements, visitDeclarationStatements);
                    return ts.updateSourceFileNode(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
                }), ts.mapDefined(node.prepends, function (prepend) {
                    if (prepend.kind === 293 /* InputFiles */) {
                        var sourceFile = ts.createUnparsedSourceFile(prepend, "dts", stripInternal);
                        hasNoDefaultLib_1 = hasNoDefaultLib_1 || !!sourceFile.hasNoDefaultLib;
                        collectReferences(sourceFile, refs);
                        recordTypeReferenceDirectivesIfNecessary(sourceFile.typeReferenceDirectives);
                        collectLibs(sourceFile, libs);
                        return sourceFile;
                    }
                    return prepend;
                }));
                bundle.syntheticFileReferences = [];
                bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
                bundle.syntheticLibReferences = getLibReferences();
                bundle.hasNoDefaultLib = hasNoDefaultLib_1;
                var outputFilePath_1 = ts.getDirectoryPath(ts.normalizeSlashes(ts.getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
                var referenceVisitor_1 = mapReferencesIntoArray(bundle.syntheticFileReferences, outputFilePath_1);
                refs.forEach(referenceVisitor_1);
                return bundle;
            }
            // Single source file
            needsDeclare = true;
            needsScopeFixMarker = false;
            resultHasScopeMarker = false;
            enclosingDeclaration = node;
            currentSourceFile = node;
            getSymbolAccessibilityDiagnostic = throwDiagnostic;
            isBundledEmit = false;
            resultHasExternalModuleIndicator = false;
            suppressNewDiagnosticContexts = false;
            lateMarkedStatements = undefined;
            lateStatementReplacementMap = ts.createMap();
            necessaryTypeReferences = undefined;
            refs = collectReferences(currentSourceFile, ts.createMap());
            libs = collectLibs(currentSourceFile, ts.createMap());
            var references = [];
            var outputFilePath = ts.getDirectoryPath(ts.normalizeSlashes(ts.getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
            var referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
            var combinedStatements;
            if (ts.isSourceFileJS(currentSourceFile)) {
                combinedStatements = ts.createNodeArray(transformDeclarationsForJS(node));
                refs.forEach(referenceVisitor);
                emittedImports = ts.filter(combinedStatements, ts.isAnyImportSyntax);
            }
            else {
                var statements = ts.visitNodes(node.statements, visitDeclarationStatements);
                combinedStatements = ts.setTextRange(ts.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements);
                refs.forEach(referenceVisitor);
                emittedImports = ts.filter(combinedStatements, ts.isAnyImportSyntax);
                if (ts.isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) {
                    combinedStatements = ts.setTextRange(ts.createNodeArray(__spreadArrays(combinedStatements, [ts.createEmptyExports()])), combinedStatements);
                }
            }
            var updated = ts.updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
            updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
            return updated;
            function getLibReferences() {
                return ts.map(ts.arrayFrom(libs.keys()), function (lib) { return ({ fileName: lib, pos: -1, end: -1 }); });
            }
            function getFileReferencesForUsedTypeReferences() {
                return necessaryTypeReferences ? ts.mapDefined(ts.arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForTypeName) : [];
            }
            function getFileReferenceForTypeName(typeName) {
                // Elide type references for which we have imports
                if (emittedImports) {
                    for (var _i = 0, emittedImports_1 = emittedImports; _i < emittedImports_1.length; _i++) {
                        var importStatement = emittedImports_1[_i];
                        if (ts.isImportEqualsDeclaration(importStatement) && ts.isExternalModuleReference(importStatement.moduleReference)) {
                            var expr = importStatement.moduleReference.expression;
                            if (ts.isStringLiteralLike(expr) && expr.text === typeName) {
                                return undefined;
                            }
                        }
                        else if (ts.isImportDeclaration(importStatement) && ts.isStringLiteral(importStatement.moduleSpecifier) && importStatement.moduleSpecifier.text === typeName) {
                            return undefined;
                        }
                    }
                }
                return { fileName: typeName, pos: -1, end: -1 };
            }
            function mapReferencesIntoArray(references, outputFilePath) {
                return function (file) {
                    var declFileName;
                    if (file.isDeclarationFile) { // Neither decl files or js should have their refs changed
                        declFileName = file.fileName;
                    }
                    else {
                        if (isBundledEmit && ts.contains(node.sourceFiles, file))
                            return; // Omit references to files which are being merged
                        var paths = ts.getOutputPathsFor(file, host, /*forceDtsPaths*/ true);
                        declFileName = paths.declarationFilePath || paths.jsFilePath || file.fileName;
                    }
                    if (declFileName) {
                        var specifier = ts.moduleSpecifiers.getModuleSpecifier(__assign(__assign({}, options), { baseUrl: options.baseUrl && ts.toPath(options.baseUrl, host.getCurrentDirectory(), host.getCanonicalFileName) }), currentSourceFile, ts.toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName), ts.toPath(declFileName, host.getCurrentDirectory(), host.getCanonicalFileName), host, 
                        /*preferences*/ undefined);
                        if (!ts.pathIsRelative(specifier)) {
                            // If some compiler option/symlink/whatever allows access to the file containing the ambient module declaration
                            // via a non-relative name, emit a type reference directive to that non-relative name, rather than
                            // a relative path to the declaration file
                            recordTypeReferenceDirectivesIfNecessary([specifier]);
                            return;
                        }
                        var fileName = ts.getRelativePathToDirectoryOrUrl(outputFilePath, declFileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
                        /*isAbsolutePathAnUrl*/ false);
                        if (ts.startsWith(fileName, "./") && ts.hasExtension(fileName)) {
                            fileName = fileName.substring(2);
                        }
                        // omit references to files from node_modules (npm may disambiguate module
                        // references when installing this package, making the path is unreliable).
                        if (ts.startsWith(fileName, "node_modules/") || ts.pathContainsNodeModules(fileName)) {
                            return;
                        }
                        references.push({ pos: -1, end: -1, fileName: fileName });
                    }
                };
            }
        }
        function collectReferences(sourceFile, ret) {
            if (noResolve || (!ts.isUnparsedSource(sourceFile) && ts.isSourceFileJS(sourceFile)))
                return ret;
            ts.forEach(sourceFile.referencedFiles, function (f) {
                var elem = host.getSourceFileFromReference(sourceFile, f);
                if (elem) {
                    ret.set("" + ts.getOriginalNodeId(elem), elem);
                }
            });
            return ret;
        }
        function collectLibs(sourceFile, ret) {
            ts.forEach(sourceFile.libReferenceDirectives, function (ref) {
                var lib = host.getLibFileFromReference(ref);
                if (lib) {
                    ret.set(ts.toFileNameLowerCase(ref.fileName), true);
                }
            });
            return ret;
        }
        function filterBindingPatternInitializers(name) {
            if (name.kind === 75 /* Identifier */) {
                return name;
            }
            else {
                if (name.kind === 190 /* ArrayBindingPattern */) {
                    return ts.updateArrayBindingPattern(name, ts.visitNodes(name.elements, visitBindingElement));
                }
                else {
                    return ts.updateObjectBindingPattern(name, ts.visitNodes(name.elements, visitBindingElement));
                }
            }
            function visitBindingElement(elem) {
                if (elem.kind === 215 /* OmittedExpression */) {
                    return elem;
                }
                return ts.updateBindingElement(elem, elem.dotDotDotToken, elem.propertyName, filterBindingPatternInitializers(elem.name), shouldPrintWithInitializer(elem) ? elem.initializer : undefined);
            }
        }
        function ensureParameter(p, modifierMask, type) {
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(p);
            }
            var newParam = ts.updateParameter(p, 
            /*decorators*/ undefined, maskModifiers(p, modifierMask), p.dotDotDotToken, filterBindingPatternInitializers(p.name), resolver.isOptionalParameter(p) ? (p.questionToken || ts.createToken(57 /* QuestionToken */)) : undefined, ensureType(p, type || p.type, /*ignorePrivate*/ true), // Ignore private param props, since this type is going straight back into a param
            ensureNoInitializer(p));
            if (!suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = oldDiag;
            }
            return newParam;
        }
        function shouldPrintWithInitializer(node) {
            return canHaveLiteralInitializer(node) && resolver.isLiteralConstDeclaration(ts.getParseTreeNode(node)); // TODO: Make safe
        }
        function ensureNoInitializer(node) {
            if (shouldPrintWithInitializer(node)) {
                return resolver.createLiteralConstValue(ts.getParseTreeNode(node), symbolTracker); // TODO: Make safe
            }
            return undefined;
        }
        function ensureType(node, type, ignorePrivate) {
            if (!ignorePrivate && ts.hasModifier(node, 8 /* Private */)) {
                // Private nodes emit no types (except private parameter properties, whose parameter types are actually visible)
                return;
            }
            if (shouldPrintWithInitializer(node)) {
                // Literal const declarations will have an initializer ensured rather than a type
                return;
            }
            var shouldUseResolverType = node.kind === 156 /* Parameter */ &&
                (resolver.isRequiredInitializedParameter(node) ||
                    resolver.isOptionalUninitializedParameterProperty(node));
            if (type && !shouldUseResolverType) {
                return ts.visitNode(type, visitDeclarationSubtree);
            }
            if (!ts.getParseTreeNode(node)) {
                return type ? ts.visitNode(type, visitDeclarationSubtree) : ts.createKeywordTypeNode(125 /* AnyKeyword */);
            }
            if (node.kind === 164 /* SetAccessor */) {
                // Set accessors with no associated type node (from it's param or get accessor return) are `any` since they are never contextually typed right now
                // (The inferred type here will be void, but the old declaration emitter printed `any`, so this replicates that)
                return ts.createKeywordTypeNode(125 /* AnyKeyword */);
            }
            errorNameNode = node.name;
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(node);
            }
            if (node.kind === 242 /* VariableDeclaration */ || node.kind === 191 /* BindingElement */) {
                return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            }
            if (node.kind === 156 /* Parameter */
                || node.kind === 159 /* PropertyDeclaration */
                || node.kind === 158 /* PropertySignature */) {
                if (!node.initializer)
                    return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType));
                return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType) || resolver.createTypeOfExpression(node.initializer, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            }
            return cleanup(resolver.createReturnTypeOfSignatureDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            function cleanup(returnValue) {
                errorNameNode = undefined;
                if (!suppressNewDiagnosticContexts) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                return returnValue || ts.createKeywordTypeNode(125 /* AnyKeyword */);
            }
        }
        function isDeclarationAndNotVisible(node) {
            node = ts.getParseTreeNode(node);
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 245 /* ClassDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 248 /* EnumDeclaration */:
                    return !resolver.isDeclarationVisible(node);
                // The following should be doing their own visibility checks based on filtering their members
                case 242 /* VariableDeclaration */:
                    return !getBindingNameVisible(node);
                case 253 /* ImportEqualsDeclaration */:
                case 254 /* ImportDeclaration */:
                case 260 /* ExportDeclaration */:
                case 259 /* ExportAssignment */:
                    return false;
            }
            return false;
        }
        function getBindingNameVisible(elem) {
            if (ts.isOmittedExpression(elem)) {
                return false;
            }
            if (ts.isBindingPattern(elem.name)) {
                // If any child binding pattern element has been marked visible (usually by collect linked aliases), then this is visible
                return ts.some(elem.name.elements, getBindingNameVisible);
            }
            else {
                return resolver.isDeclarationVisible(elem);
            }
        }
        function updateParamsList(node, params, modifierMask) {
            if (ts.hasModifier(node, 8 /* Private */)) {
                return undefined; // TODO: GH#18217
            }
            var newParams = ts.map(params, function (p) { return ensureParameter(p, modifierMask); });
            if (!newParams) {
                return undefined; // TODO: GH#18217
            }
            return ts.createNodeArray(newParams, params.hasTrailingComma);
        }
        function updateAccessorParamsList(input, isPrivate) {
            var newParams;
            if (!isPrivate) {
                var thisParameter = ts.getThisParameter(input);
                if (thisParameter) {
                    newParams = [ensureParameter(thisParameter)];
                }
            }
            if (ts.isSetAccessorDeclaration(input)) {
                var newValueParameter = void 0;
                if (!isPrivate) {
                    var valueParameter = ts.getSetAccessorValueParameter(input);
                    if (valueParameter) {
                        var accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
                        newValueParameter = ensureParameter(valueParameter, /*modifierMask*/ undefined, accessorType);
                    }
                }
                if (!newValueParameter) {
                    newValueParameter = ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, "value");
                }
                newParams = ts.append(newParams, newValueParameter);
            }
            return ts.createNodeArray(newParams || ts.emptyArray);
        }
        function ensureTypeParams(node, params) {
            return ts.hasModifier(node, 8 /* Private */) ? undefined : ts.visitNodes(params, visitDeclarationSubtree);
        }
        function isEnclosingDeclaration(node) {
            return ts.isSourceFile(node)
                || ts.isTypeAliasDeclaration(node)
                || ts.isModuleDeclaration(node)
                || ts.isClassDeclaration(node)
                || ts.isInterfaceDeclaration(node)
                || ts.isFunctionLike(node)
                || ts.isIndexSignatureDeclaration(node)
                || ts.isMappedTypeNode(node);
        }
        function checkEntityNameVisibility(entityName, enclosingDeclaration) {
            var visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration);
            handleSymbolAccessibilityError(visibilityResult);
            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
        }
        function preserveJsDoc(updated, original) {
            if (ts.hasJSDocNodes(updated) && ts.hasJSDocNodes(original)) {
                updated.jsDoc = original.jsDoc;
            }
            return ts.setCommentRange(updated, ts.getCommentRange(original));
        }
        function rewriteModuleSpecifier(parent, input) {
            if (!input)
                return undefined; // TODO: GH#18217
            resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== 249 /* ModuleDeclaration */ && parent.kind !== 188 /* ImportType */);
            if (ts.isStringLiteralLike(input)) {
                if (isBundledEmit) {
                    var newName = ts.getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
                    if (newName) {
                        return ts.createLiteral(newName);
                    }
                }
                else {
                    var symbol = resolver.getSymbolOfExternalModuleSpecifier(input);
                    if (symbol) {
                        (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
                    }
                }
            }
            return input;
        }
        function transformImportEqualsDeclaration(decl) {
            if (!resolver.isDeclarationVisible(decl))
                return;
            if (decl.moduleReference.kind === 265 /* ExternalModuleReference */) {
                // Rewrite external module names if necessary
                var specifier = ts.getExternalModuleImportEqualsDeclarationExpression(decl);
                return ts.updateImportEqualsDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, decl.name, ts.updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier)));
            }
            else {
                var oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(decl);
                checkEntityNameVisibility(decl.moduleReference, enclosingDeclaration);
                getSymbolAccessibilityDiagnostic = oldDiag;
                return decl;
            }
        }
        function transformImportDeclaration(decl) {
            if (!decl.importClause) {
                // import "mod" - possibly needed for side effects? (global interface patches, module augmentations, etc)
                return ts.updateImportDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, decl.importClause, rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            // The `importClause` visibility corresponds to the default's visibility.
            var visibleDefaultBinding = decl.importClause && decl.importClause.name && resolver.isDeclarationVisible(decl.importClause) ? decl.importClause.name : undefined;
            if (!decl.importClause.namedBindings) {
                // No named bindings (either namespace or list), meaning the import is just default or should be elided
                return visibleDefaultBinding && ts.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, 
                /*namedBindings*/ undefined, decl.importClause.isTypeOnly), rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            if (decl.importClause.namedBindings.kind === 256 /* NamespaceImport */) {
                // Namespace import (optionally with visible default)
                var namedBindings = resolver.isDeclarationVisible(decl.importClause.namedBindings) ? decl.importClause.namedBindings : /*namedBindings*/ undefined;
                return visibleDefaultBinding || namedBindings ? ts.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, namedBindings, decl.importClause.isTypeOnly), rewriteModuleSpecifier(decl, decl.moduleSpecifier)) : undefined;
            }
            // Named imports (optionally with visible default)
            var bindingList = ts.mapDefined(decl.importClause.namedBindings.elements, function (b) { return resolver.isDeclarationVisible(b) ? b : undefined; });
            if ((bindingList && bindingList.length) || visibleDefaultBinding) {
                return ts.updateImportDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, bindingList && bindingList.length ? ts.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, decl.importClause.isTypeOnly), rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            // Augmentation of export depends on import
            if (resolver.isImportRequiredByAugmentation(decl)) {
                return ts.updateImportDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, 
                /*importClause*/ undefined, rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            // Nothing visible
        }
        function transformAndReplaceLatePaintedStatements(statements) {
            // This is a `while` loop because `handleSymbolAccessibilityError` can see additional import aliases marked as visible during
            // error handling which must now be included in the output and themselves checked for errors.
            // For example:
            // ```
            // module A {
            //   export module Q {}
            //   import B = Q;
            //   import C = B;
            //   export import D = C;
            // }
            // ```
            // In such a scenario, only Q and D are initially visible, but we don't consider imports as private names - instead we say they if they are referenced they must
            // be recorded. So while checking D's visibility we mark C as visible, then we must check C which in turn marks B, completing the chain of
            // dependent imports and allowing a valid declaration file output. Today, this dependent alias marking only happens for internal import aliases.
            while (ts.length(lateMarkedStatements)) {
                var i = lateMarkedStatements.shift();
                if (!ts.isLateVisibilityPaintedStatement(i)) {
                    return ts.Debug.fail("Late replaced statement was found which is not handled by the declaration transformer!: " + (ts.SyntaxKind ? ts.SyntaxKind[i.kind] : i.kind));
                }
                var priorNeedsDeclare = needsDeclare;
                needsDeclare = i.parent && ts.isSourceFile(i.parent) && !(ts.isExternalModule(i.parent) && isBundledEmit);
                var result = transformTopLevelDeclaration(i);
                needsDeclare = priorNeedsDeclare;
                lateStatementReplacementMap.set("" + ts.getOriginalNodeId(i), result);
            }
            // And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list
            // (and remove them from the set to examine for outter declarations)
            return ts.visitNodes(statements, visitLateVisibilityMarkedStatements);
            function visitLateVisibilityMarkedStatements(statement) {
                if (ts.isLateVisibilityPaintedStatement(statement)) {
                    var key = "" + ts.getOriginalNodeId(statement);
                    if (lateStatementReplacementMap.has(key)) {
                        var result = lateStatementReplacementMap.get(key);
                        lateStatementReplacementMap.delete(key);
                        if (result) {
                            if (ts.isArray(result) ? ts.some(result, ts.needsScopeMarker) : ts.needsScopeMarker(result)) {
                                // Top-level declarations in .d.ts files are always considered exported even without a modifier unless there's an export assignment or specifier
                                needsScopeFixMarker = true;
                            }
                            if (ts.isSourceFile(statement.parent) && (ts.isArray(result) ? ts.some(result, ts.isExternalModuleIndicator) : ts.isExternalModuleIndicator(result))) {
                                resultHasExternalModuleIndicator = true;
                            }
                        }
                        return result;
                    }
                }
                return statement;
            }
        }
        function visitDeclarationSubtree(input) {
            if (shouldStripInternal(input))
                return;
            if (ts.isDeclaration(input)) {
                if (isDeclarationAndNotVisible(input))
                    return;
                if (ts.hasDynamicName(input) && !resolver.isLateBound(ts.getParseTreeNode(input))) {
                    return;
                }
            }
            // Elide implementation signatures from overload sets
            if (ts.isFunctionLike(input) && resolver.isImplementationOfOverload(input))
                return;
            // Elide semicolon class statements
            if (ts.isSemicolonClassElement(input))
                return;
            var previousEnclosingDeclaration;
            if (isEnclosingDeclaration(input)) {
                previousEnclosingDeclaration = enclosingDeclaration;
                enclosingDeclaration = input;
            }
            var oldDiag = getSymbolAccessibilityDiagnostic;
            // Setup diagnostic-related flags before first potential `cleanup` call, otherwise
            // We'd see a TDZ violation at runtime
            var canProduceDiagnostic = ts.canProduceDiagnostics(input);
            var oldWithinObjectLiteralType = suppressNewDiagnosticContexts;
            var shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === 173 /* TypeLiteral */ || input.kind === 186 /* MappedType */) && input.parent.kind !== 247 /* TypeAliasDeclaration */);
            // Emit methods which are private as properties with no type information
            if (ts.isMethodDeclaration(input) || ts.isMethodSignature(input)) {
                if (ts.hasModifier(input, 8 /* Private */)) {
                    if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input)
                        return; // Elide all but the first overload
                    return cleanup(ts.createProperty(/*decorators*/ undefined, ensureModifiers(input), input.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined));
                }
            }
            if (canProduceDiagnostic && !suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(input);
            }
            if (ts.isTypeQueryNode(input)) {
                checkEntityNameVisibility(input.exprName, enclosingDeclaration);
            }
            if (shouldEnterSuppressNewDiagnosticsContextContext) {
                // We stop making new diagnostic contexts within object literal types. Unless it's an object type on the RHS of a type alias declaration. Then we do.
                suppressNewDiagnosticContexts = true;
            }
            if (isProcessedComponent(input)) {
                switch (input.kind) {
                    case 216 /* ExpressionWithTypeArguments */: {
                        if ((ts.isEntityName(input.expression) || ts.isEntityNameExpression(input.expression))) {
                            checkEntityNameVisibility(input.expression, enclosingDeclaration);
                        }
                        var node = ts.visitEachChild(input, visitDeclarationSubtree, context);
                        return cleanup(ts.updateExpressionWithTypeArguments(node, ts.parenthesizeTypeParameters(node.typeArguments), node.expression));
                    }
                    case 169 /* TypeReference */: {
                        checkEntityNameVisibility(input.typeName, enclosingDeclaration);
                        var node = ts.visitEachChild(input, visitDeclarationSubtree, context);
                        return cleanup(ts.updateTypeReferenceNode(node, node.typeName, ts.parenthesizeTypeParameters(node.typeArguments)));
                    }
                    case 166 /* ConstructSignature */:
                        return cleanup(ts.updateConstructSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type)));
                    case 162 /* Constructor */: {
                        // A constructor declaration may not have a type annotation
                        var ctor = ts.createSignatureDeclaration(162 /* Constructor */, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters, 0 /* None */), 
                        /*type*/ undefined);
                        ctor.modifiers = ts.createNodeArray(ensureModifiers(input));
                        return cleanup(ctor);
                    }
                    case 161 /* MethodDeclaration */: {
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        var sig = ts.createSignatureDeclaration(160 /* MethodSignature */, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type));
                        sig.name = input.name;
                        sig.modifiers = ts.createNodeArray(ensureModifiers(input));
                        sig.questionToken = input.questionToken;
                        return cleanup(sig);
                    }
                    case 163 /* GetAccessor */: {
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        var accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
                        return cleanup(ts.updateGetAccessor(input, 
                        /*decorators*/ undefined, ensureModifiers(input), input.name, updateAccessorParamsList(input, ts.hasModifier(input, 8 /* Private */)), ensureType(input, accessorType), 
                        /*body*/ undefined));
                    }
                    case 164 /* SetAccessor */: {
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        return cleanup(ts.updateSetAccessor(input, 
                        /*decorators*/ undefined, ensureModifiers(input), input.name, updateAccessorParamsList(input, ts.hasModifier(input, 8 /* Private */)), 
                        /*body*/ undefined));
                    }
                    case 159 /* PropertyDeclaration */:
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        return cleanup(ts.updateProperty(input, 
                        /*decorators*/ undefined, ensureModifiers(input), input.name, input.questionToken, ensureType(input, input.type), ensureNoInitializer(input)));
                    case 158 /* PropertySignature */:
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        return cleanup(ts.updatePropertySignature(input, ensureModifiers(input), input.name, input.questionToken, ensureType(input, input.type), ensureNoInitializer(input)));
                    case 160 /* MethodSignature */: {
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        return cleanup(ts.updateMethodSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type), input.name, input.questionToken));
                    }
                    case 165 /* CallSignature */: {
                        return cleanup(ts.updateCallSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type)));
                    }
                    case 167 /* IndexSignature */: {
                        return cleanup(ts.updateIndexSignature(input, 
                        /*decorators*/ undefined, ensureModifiers(input), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree) || ts.createKeywordTypeNode(125 /* AnyKeyword */)));
                    }
                    case 242 /* VariableDeclaration */: {
                        if (ts.isBindingPattern(input.name)) {
                            return recreateBindingPattern(input.name);
                        }
                        shouldEnterSuppressNewDiagnosticsContextContext = true;
                        suppressNewDiagnosticContexts = true; // Variable declaration types also suppress new diagnostic contexts, provided the contexts wouldn't be made for binding pattern types
                        return cleanup(ts.updateTypeScriptVariableDeclaration(input, input.name, /*exclaimationToken*/ undefined, ensureType(input, input.type), ensureNoInitializer(input)));
                    }
                    case 155 /* TypeParameter */: {
                        if (isPrivateMethodTypeParameter(input) && (input.default || input.constraint)) {
                            return cleanup(ts.updateTypeParameterDeclaration(input, input.name, /*constraint*/ undefined, /*defaultType*/ undefined));
                        }
                        return cleanup(ts.visitEachChild(input, visitDeclarationSubtree, context));
                    }
                    case 180 /* ConditionalType */: {
                        // We have to process conditional types in a special way because for visibility purposes we need to push a new enclosingDeclaration
                        // just for the `infer` types in the true branch. It's an implicit declaration scope that only applies to _part_ of the type.
                        var checkType = ts.visitNode(input.checkType, visitDeclarationSubtree);
                        var extendsType = ts.visitNode(input.extendsType, visitDeclarationSubtree);
                        var oldEnclosingDecl = enclosingDeclaration;
                        enclosingDeclaration = input.trueType;
                        var trueType = ts.visitNode(input.trueType, visitDeclarationSubtree);
                        enclosingDeclaration = oldEnclosingDecl;
                        var falseType = ts.visitNode(input.falseType, visitDeclarationSubtree);
                        return cleanup(ts.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType));
                    }
                    case 170 /* FunctionType */: {
                        return cleanup(ts.updateFunctionTypeNode(input, ts.visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree)));
                    }
                    case 171 /* ConstructorType */: {
                        return cleanup(ts.updateConstructorTypeNode(input, ts.visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree)));
                    }
                    case 188 /* ImportType */: {
                        if (!ts.isLiteralImportTypeNode(input))
                            return cleanup(input);
                        return cleanup(ts.updateImportTypeNode(input, ts.updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)), input.qualifier, ts.visitNodes(input.typeArguments, visitDeclarationSubtree, ts.isTypeNode), input.isTypeOf));
                    }
                    default: ts.Debug.assertNever(input, "Attempted to process unhandled node kind: " + ts.SyntaxKind[input.kind]);
                }
            }
            return cleanup(ts.visitEachChild(input, visitDeclarationSubtree, context));
            function cleanup(returnValue) {
                if (returnValue && canProduceDiagnostic && ts.hasDynamicName(input)) {
                    checkName(input);
                }
                if (isEnclosingDeclaration(input)) {
                    enclosingDeclaration = previousEnclosingDeclaration;
                }
                if (canProduceDiagnostic && !suppressNewDiagnosticContexts) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                if (shouldEnterSuppressNewDiagnosticsContextContext) {
                    suppressNewDiagnosticContexts = oldWithinObjectLiteralType;
                }
                if (returnValue === input) {
                    return returnValue;
                }
                return returnValue && ts.setOriginalNode(preserveJsDoc(returnValue, input), input);
            }
        }
        function isPrivateMethodTypeParameter(node) {
            return node.parent.kind === 161 /* MethodDeclaration */ && ts.hasModifier(node.parent, 8 /* Private */);
        }
        function visitDeclarationStatements(input) {
            if (!isPreservedDeclarationStatement(input)) {
                // return undefined for unmatched kinds to omit them from the tree
                return;
            }
            if (shouldStripInternal(input))
                return;
            switch (input.kind) {
                case 260 /* ExportDeclaration */: {
                    if (ts.isSourceFile(input.parent)) {
                        resultHasExternalModuleIndicator = true;
                    }
                    resultHasScopeMarker = true;
                    // Always visible if the parent node isn't dropped for being not visible
                    // Rewrite external module names if necessary
                    return ts.updateExportDeclaration(input, 
                    /*decorators*/ undefined, input.modifiers, input.exportClause, rewriteModuleSpecifier(input, input.moduleSpecifier), input.isTypeOnly);
                }
                case 259 /* ExportAssignment */: {
                    // Always visible if the parent node isn't dropped for being not visible
                    if (ts.isSourceFile(input.parent)) {
                        resultHasExternalModuleIndicator = true;
                    }
                    resultHasScopeMarker = true;
                    if (input.expression.kind === 75 /* Identifier */) {
                        return input;
                    }
                    else {
                        var newId = ts.createOptimisticUniqueName("_default");
                        getSymbolAccessibilityDiagnostic = function () { return ({
                            diagnosticMessage: ts.Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
                            errorNode: input
                        }); };
                        var varDecl = ts.createVariableDeclaration(newId, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
                        var statement = ts.createVariableStatement(needsDeclare ? [ts.createModifier(130 /* DeclareKeyword */)] : [], ts.createVariableDeclarationList([varDecl], 2 /* Const */));
                        return [statement, ts.updateExportAssignment(input, input.decorators, input.modifiers, newId)];
                    }
                }
            }
            var result = transformTopLevelDeclaration(input);
            // Don't actually transform yet; just leave as original node - will be elided/swapped by late pass
            lateStatementReplacementMap.set("" + ts.getOriginalNodeId(input), result);
            return input;
        }
        function stripExportModifiers(statement) {
            if (ts.isImportEqualsDeclaration(statement) || ts.hasModifier(statement, 512 /* Default */)) {
                // `export import` statements should remain as-is, as imports are _not_ implicitly exported in an ambient namespace
                // Likewise, `export default` classes and the like and just be `default`, so we preserve their `export` modifiers, too
                return statement;
            }
            var clone = ts.getMutableClone(statement);
            var modifiers = ts.createModifiersFromModifierFlags(ts.getModifierFlags(statement) & (3071 /* All */ ^ 1 /* Export */));
            clone.modifiers = modifiers.length ? ts.createNodeArray(modifiers) : undefined;
            return clone;
        }
        function transformTopLevelDeclaration(input) {
            if (shouldStripInternal(input))
                return;
            switch (input.kind) {
                case 253 /* ImportEqualsDeclaration */: {
                    return transformImportEqualsDeclaration(input);
                }
                case 254 /* ImportDeclaration */: {
                    return transformImportDeclaration(input);
                }
            }
            if (ts.isDeclaration(input) && isDeclarationAndNotVisible(input))
                return;
            // Elide implementation signatures from overload sets
            if (ts.isFunctionLike(input) && resolver.isImplementationOfOverload(input))
                return;
            var previousEnclosingDeclaration;
            if (isEnclosingDeclaration(input)) {
                previousEnclosingDeclaration = enclosingDeclaration;
                enclosingDeclaration = input;
            }
            var canProdiceDiagnostic = ts.canProduceDiagnostics(input);
            var oldDiag = getSymbolAccessibilityDiagnostic;
            if (canProdiceDiagnostic) {
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(input);
            }
            var previousNeedsDeclare = needsDeclare;
            switch (input.kind) {
                case 247 /* TypeAliasDeclaration */: // Type aliases get `declare`d if need be (for legacy support), but that's all
                    return cleanup(ts.updateTypeAliasDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input), input.name, ts.visitNodes(input.typeParameters, visitDeclarationSubtree, ts.isTypeParameterDeclaration), ts.visitNode(input.type, visitDeclarationSubtree, ts.isTypeNode)));
                case 246 /* InterfaceDeclaration */: {
                    return cleanup(ts.updateInterfaceDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input), input.name, ensureTypeParams(input, input.typeParameters), transformHeritageClauses(input.heritageClauses), ts.visitNodes(input.members, visitDeclarationSubtree)));
                }
                case 244 /* FunctionDeclaration */: {
                    // Generators lose their generator-ness, excepting their return type
                    var clean = cleanup(ts.updateFunctionDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input), 
                    /*asteriskToken*/ undefined, input.name, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type), 
                    /*body*/ undefined));
                    if (clean && resolver.isExpandoFunctionDeclaration(input)) {
                        var props = resolver.getPropertiesOfContainerFunction(input);
                        var fakespace_1 = ts.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || ts.createIdentifier("_default"), ts.createModuleBlock([]), 16 /* Namespace */);
                        fakespace_1.flags ^= 8 /* Synthesized */; // unset synthesized so it is usable as an enclosing declaration
                        fakespace_1.parent = enclosingDeclaration;
                        fakespace_1.locals = ts.createSymbolTable(props);
                        fakespace_1.symbol = props[0].parent;
                        var declarations = ts.mapDefined(props, function (p) {
                            if (!ts.isPropertyAccessExpression(p.valueDeclaration)) {
                                return undefined; // TODO GH#33569: Handle element access expressions that created late bound names (rather than silently omitting them)
                            }
                            getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
                            var type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace_1, declarationEmitNodeBuilderFlags, symbolTracker);
                            getSymbolAccessibilityDiagnostic = oldDiag;
                            var varDecl = ts.createVariableDeclaration(ts.unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
                            return ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([varDecl]));
                        });
                        var namespaceDecl = ts.createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name, ts.createModuleBlock(declarations), 16 /* Namespace */);
                        if (!ts.hasModifier(clean, 512 /* Default */)) {
                            return [clean, namespaceDecl];
                        }
                        var modifiers = ts.createModifiersFromModifierFlags((ts.getModifierFlags(clean) & ~513 /* ExportDefault */) | 2 /* Ambient */);
                        var cleanDeclaration = ts.updateFunctionDeclaration(clean, 
                        /*decorators*/ undefined, modifiers, 
                        /*asteriskToken*/ undefined, clean.name, clean.typeParameters, clean.parameters, clean.type, 
                        /*body*/ undefined);
                        var namespaceDeclaration = ts.updateModuleDeclaration(namespaceDecl, 
                        /*decorators*/ undefined, modifiers, namespaceDecl.name, namespaceDecl.body);
                        var exportDefaultDeclaration = ts.createExportAssignment(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, 
                        /*isExportEquals*/ false, namespaceDecl.name);
                        if (ts.isSourceFile(input.parent)) {
                            resultHasExternalModuleIndicator = true;
                        }
                        resultHasScopeMarker = true;
                        return [cleanDeclaration, namespaceDeclaration, exportDefaultDeclaration];
                    }
                    else {
                        return clean;
                    }
                }
                case 249 /* ModuleDeclaration */: {
                    needsDeclare = false;
                    var inner = input.body;
                    if (inner && inner.kind === 250 /* ModuleBlock */) {
                        var oldNeedsScopeFix = needsScopeFixMarker;
                        var oldHasScopeFix = resultHasScopeMarker;
                        resultHasScopeMarker = false;
                        needsScopeFixMarker = false;
                        var statements = ts.visitNodes(inner.statements, visitDeclarationStatements);
                        var lateStatements = transformAndReplaceLatePaintedStatements(statements);
                        if (input.flags & 8388608 /* Ambient */) {
                            needsScopeFixMarker = false; // If it was `declare`'d everything is implicitly exported already, ignore late printed "privates"
                        }
                        // With the final list of statements, there are 3 possibilities:
                        // 1. There's an export assignment or export declaration in the namespace - do nothing
                        // 2. Everything is exported and there are no export assignments or export declarations - strip all export modifiers
                        // 3. Some things are exported, some are not, and there's no marker - add an empty marker
                        if (!ts.isGlobalScopeAugmentation(input) && !hasScopeMarker(lateStatements) && !resultHasScopeMarker) {
                            if (needsScopeFixMarker) {
                                lateStatements = ts.createNodeArray(__spreadArrays(lateStatements, [ts.createEmptyExports()]));
                            }
                            else {
                                lateStatements = ts.visitNodes(lateStatements, stripExportModifiers);
                            }
                        }
                        var body = ts.updateModuleBlock(inner, lateStatements);
                        needsDeclare = previousNeedsDeclare;
                        needsScopeFixMarker = oldNeedsScopeFix;
                        resultHasScopeMarker = oldHasScopeFix;
                        var mods = ensureModifiers(input);
                        return cleanup(ts.updateModuleDeclaration(input, 
                        /*decorators*/ undefined, mods, ts.isExternalModuleAugmentation(input) ? rewriteModuleSpecifier(input, input.name) : input.name, body));
                    }
                    else {
                        needsDeclare = previousNeedsDeclare;
                        var mods = ensureModifiers(input);
                        needsDeclare = false;
                        ts.visitNode(inner, visitDeclarationStatements);
                        // eagerly transform nested namespaces (the nesting doesn't need any elision or painting done)
                        var id = "" + ts.getOriginalNodeId(inner); // TODO: GH#18217
                        var body = lateStatementReplacementMap.get(id);
                        lateStatementReplacementMap.delete(id);
                        return cleanup(ts.updateModuleDeclaration(input, 
                        /*decorators*/ undefined, mods, input.name, body));
                    }
                }
                case 245 /* ClassDeclaration */: {
                    var modifiers = ts.createNodeArray(ensureModifiers(input));
                    var typeParameters = ensureTypeParams(input, input.typeParameters);
                    var ctor = ts.getFirstConstructorWithBody(input);
                    var parameterProperties = void 0;
                    if (ctor) {
                        var oldDiag_1 = getSymbolAccessibilityDiagnostic;
                        parameterProperties = ts.compact(ts.flatMap(ctor.parameters, function (param) {
                            if (!ts.hasModifier(param, 92 /* ParameterPropertyModifier */) || shouldStripInternal(param))
                                return;
                            getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(param);
                            if (param.name.kind === 75 /* Identifier */) {
                                return preserveJsDoc(ts.createProperty(
                                /*decorators*/ undefined, ensureModifiers(param), param.name, param.questionToken, ensureType(param, param.type), ensureNoInitializer(param)), param);
                            }
                            else {
                                // Pattern - this is currently an error, but we emit declarations for it somewhat correctly
                                return walkBindingPattern(param.name);
                            }
                            function walkBindingPattern(pattern) {
                                var elems;
                                for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                                    var elem = _a[_i];
                                    if (ts.isOmittedExpression(elem))
                                        continue;
                                    if (ts.isBindingPattern(elem.name)) {
                                        elems = ts.concatenate(elems, walkBindingPattern(elem.name));
                                    }
                                    elems = elems || [];
                                    elems.push(ts.createProperty(
                                    /*decorators*/ undefined, ensureModifiers(param), elem.name, 
                                    /*questionToken*/ undefined, ensureType(elem, /*type*/ undefined), 
                                    /*initializer*/ undefined));
                                }
                                return elems;
                            }
                        }));
                        getSymbolAccessibilityDiagnostic = oldDiag_1;
                    }
                    var hasPrivateIdentifier = ts.some(input.members, function (member) { return !!member.name && ts.isPrivateIdentifier(member.name); });
                    var privateIdentifier = hasPrivateIdentifier ? [
                        ts.createProperty(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, ts.createPrivateIdentifier("#private"), 
                        /*questionToken*/ undefined, 
                        /*type*/ undefined, 
                        /*initializer*/ undefined)
                    ] : undefined;
                    var memberNodes = ts.concatenate(ts.concatenate(privateIdentifier, parameterProperties), ts.visitNodes(input.members, visitDeclarationSubtree));
                    var members = ts.createNodeArray(memberNodes);
                    var extendsClause_1 = ts.getEffectiveBaseTypeNode(input);
                    if (extendsClause_1 && !ts.isEntityNameExpression(extendsClause_1.expression) && extendsClause_1.expression.kind !== 100 /* NullKeyword */) {
                        // We must add a temporary declaration for the extends clause expression
                        var oldId = input.name ? ts.unescapeLeadingUnderscores(input.name.escapedText) : "default";
                        var newId_1 = ts.createOptimisticUniqueName(oldId + "_base");
                        getSymbolAccessibilityDiagnostic = function () { return ({
                            diagnosticMessage: ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
                            errorNode: extendsClause_1,
                            typeName: input.name
                        }); };
                        var varDecl = ts.createVariableDeclaration(newId_1, resolver.createTypeOfExpression(extendsClause_1.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
                        var statement = ts.createVariableStatement(needsDeclare ? [ts.createModifier(130 /* DeclareKeyword */)] : [], ts.createVariableDeclarationList([varDecl], 2 /* Const */));
                        var heritageClauses = ts.createNodeArray(ts.map(input.heritageClauses, function (clause) {
                            if (clause.token === 90 /* ExtendsKeyword */) {
                                var oldDiag_2 = getSymbolAccessibilityDiagnostic;
                                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]);
                                var newClause = ts.updateHeritageClause(clause, ts.map(clause.types, function (t) { return ts.updateExpressionWithTypeArguments(t, ts.visitNodes(t.typeArguments, visitDeclarationSubtree), newId_1); }));
                                getSymbolAccessibilityDiagnostic = oldDiag_2;
                                return newClause;
                            }
                            return ts.updateHeritageClause(clause, ts.visitNodes(ts.createNodeArray(ts.filter(clause.types, function (t) { return ts.isEntityNameExpression(t.expression) || t.expression.kind === 100 /* NullKeyword */; })), visitDeclarationSubtree));
                        }));
                        return [statement, cleanup(ts.updateClassDeclaration(input, 
                            /*decorators*/ undefined, modifiers, input.name, typeParameters, heritageClauses, members))]; // TODO: GH#18217
                    }
                    else {
                        var heritageClauses = transformHeritageClauses(input.heritageClauses);
                        return cleanup(ts.updateClassDeclaration(input, 
                        /*decorators*/ undefined, modifiers, input.name, typeParameters, heritageClauses, members));
                    }
                }
                case 225 /* VariableStatement */: {
                    return cleanup(transformVariableStatement(input));
                }
                case 248 /* EnumDeclaration */: {
                    return cleanup(ts.updateEnumDeclaration(input, /*decorators*/ undefined, ts.createNodeArray(ensureModifiers(input)), input.name, ts.createNodeArray(ts.mapDefined(input.members, function (m) {
                        if (shouldStripInternal(m))
                            return;
                        // Rewrite enum values to their constants, if available
                        var constValue = resolver.getConstantValue(m);
                        return preserveJsDoc(ts.updateEnumMember(m, m.name, constValue !== undefined ? ts.createLiteral(constValue) : undefined), m);
                    }))));
                }
            }
            // Anything left unhandled is an error, so this should be unreachable
            return ts.Debug.assertNever(input, "Unhandled top-level node in declaration emit: " + ts.SyntaxKind[input.kind]);
            function cleanup(node) {
                if (isEnclosingDeclaration(input)) {
                    enclosingDeclaration = previousEnclosingDeclaration;
                }
                if (canProdiceDiagnostic) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                if (input.kind === 249 /* ModuleDeclaration */) {
                    needsDeclare = previousNeedsDeclare;
                }
                if (node === input) {
                    return node;
                }
                return node && ts.setOriginalNode(preserveJsDoc(node, input), input);
            }
        }
        function transformVariableStatement(input) {
            if (!ts.forEach(input.declarationList.declarations, getBindingNameVisible))
                return;
            var nodes = ts.visitNodes(input.declarationList.declarations, visitDeclarationSubtree);
            if (!ts.length(nodes))
                return;
            return ts.updateVariableStatement(input, ts.createNodeArray(ensureModifiers(input)), ts.updateVariableDeclarationList(input.declarationList, nodes));
        }
        function recreateBindingPattern(d) {
            return ts.flatten(ts.mapDefined(d.elements, function (e) { return recreateBindingElement(e); }));
        }
        function recreateBindingElement(e) {
            if (e.kind === 215 /* OmittedExpression */) {
                return;
            }
            if (e.name) {
                if (!getBindingNameVisible(e))
                    return;
                if (ts.isBindingPattern(e.name)) {
                    return recreateBindingPattern(e.name);
                }
                else {
                    return ts.createVariableDeclaration(e.name, ensureType(e, /*type*/ undefined), /*initializer*/ undefined);
                }
            }
        }
        function checkName(node) {
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNodeName(node);
            }
            errorNameNode = node.name;
            ts.Debug.assert(resolver.isLateBound(ts.getParseTreeNode(node))); // Should only be called with dynamic names
            var decl = node;
            var entityName = decl.name.expression;
            checkEntityNameVisibility(entityName, enclosingDeclaration);
            if (!suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = oldDiag;
            }
            errorNameNode = undefined;
        }
        function shouldStripInternal(node) {
            return !!stripInternal && !!node && isInternalDeclaration(node, currentSourceFile);
        }
        function isScopeMarker(node) {
            return ts.isExportAssignment(node) || ts.isExportDeclaration(node);
        }
        function hasScopeMarker(statements) {
            return ts.some(statements, isScopeMarker);
        }
        function ensureModifiers(node) {
            var currentFlags = ts.getModifierFlags(node);
            var newFlags = ensureModifierFlags(node);
            if (currentFlags === newFlags) {
                return node.modifiers;
            }
            return ts.createModifiersFromModifierFlags(newFlags);
        }
        function ensureModifierFlags(node) {
            var mask = 3071 /* All */ ^ (4 /* Public */ | 256 /* Async */); // No async modifiers in declaration files
            var additions = (needsDeclare && !isAlwaysType(node)) ? 2 /* Ambient */ : 0 /* None */;
            var parentIsFile = node.parent.kind === 290 /* SourceFile */;
            if (!parentIsFile || (isBundledEmit && parentIsFile && ts.isExternalModule(node.parent))) {
                mask ^= 2 /* Ambient */;
                additions = 0 /* None */;
            }
            return maskModifierFlags(node, mask, additions);
        }
        function getTypeAnnotationFromAllAccessorDeclarations(node, accessors) {
            var accessorType = getTypeAnnotationFromAccessor(node);
            if (!accessorType && node !== accessors.firstAccessor) {
                accessorType = getTypeAnnotationFromAccessor(accessors.firstAccessor);
                // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(accessors.firstAccessor);
            }
            if (!accessorType && accessors.secondAccessor && node !== accessors.secondAccessor) {
                accessorType = getTypeAnnotationFromAccessor(accessors.secondAccessor);
                // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(accessors.secondAccessor);
            }
            return accessorType;
        }
        function transformHeritageClauses(nodes) {
            return ts.createNodeArray(ts.filter(ts.map(nodes, function (clause) { return ts.updateHeritageClause(clause, ts.visitNodes(ts.createNodeArray(ts.filter(clause.types, function (t) {
                return ts.isEntityNameExpression(t.expression) || (clause.token === 90 /* ExtendsKeyword */ && t.expression.kind === 100 /* NullKeyword */);
            })), visitDeclarationSubtree)); }), function (clause) { return clause.types && !!clause.types.length; }));
        }
    }
    ts.transformDeclarations = transformDeclarations;
    function isAlwaysType(node) {
        if (node.kind === 246 /* InterfaceDeclaration */) {
            return true;
        }
        return false;
    }
    // Elide "public" modifier, as it is the default
    function maskModifiers(node, modifierMask, modifierAdditions) {
        return ts.createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions));
    }
    function maskModifierFlags(node, modifierMask, modifierAdditions) {
        if (modifierMask === void 0) { modifierMask = 3071 /* All */ ^ 4 /* Public */; }
        if (modifierAdditions === void 0) { modifierAdditions = 0 /* None */; }
        var flags = (ts.getModifierFlags(node) & modifierMask) | modifierAdditions;
        if (flags & 512 /* Default */ && !(flags & 1 /* Export */)) {
            // A non-exported default is a nonsequitor - we usually try to remove all export modifiers
            // from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid
            flags ^= 1 /* Export */;
        }
        if (flags & 512 /* Default */ && flags & 2 /* Ambient */) {
            flags ^= 2 /* Ambient */; // `declare` is never required alongside `default` (and would be an error if printed)
        }
        return flags;
    }
    function getTypeAnnotationFromAccessor(accessor) {
        if (accessor) {
            return accessor.kind === 163 /* GetAccessor */
                ? accessor.type // Getter - return type
                : accessor.parameters.length > 0
                    ? accessor.parameters[0].type // Setter parameter type
                    : undefined;
        }
    }
    function canHaveLiteralInitializer(node) {
        switch (node.kind) {
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
                return !ts.hasModifier(node, 8 /* Private */);
            case 156 /* Parameter */:
            case 242 /* VariableDeclaration */:
                return true;
        }
        return false;
    }
    function isPreservedDeclarationStatement(node) {
        switch (node.kind) {
            case 244 /* FunctionDeclaration */:
            case 249 /* ModuleDeclaration */:
            case 253 /* ImportEqualsDeclaration */:
            case 246 /* InterfaceDeclaration */:
            case 245 /* ClassDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 248 /* EnumDeclaration */:
            case 225 /* VariableStatement */:
            case 254 /* ImportDeclaration */:
            case 260 /* ExportDeclaration */:
            case 259 /* ExportAssignment */:
                return true;
        }
        return false;
    }
    function isProcessedComponent(node) {
        switch (node.kind) {
            case 166 /* ConstructSignature */:
            case 162 /* Constructor */:
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 160 /* MethodSignature */:
            case 165 /* CallSignature */:
            case 167 /* IndexSignature */:
            case 242 /* VariableDeclaration */:
            case 155 /* TypeParameter */:
            case 216 /* ExpressionWithTypeArguments */:
            case 169 /* TypeReference */:
            case 180 /* ConditionalType */:
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
            case 188 /* ImportType */:
                return true;
        }
        return false;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getModuleTransformer(moduleKind) {
        switch (moduleKind) {
            case ts.ModuleKind.ESNext:
            case ts.ModuleKind.ES2020:
            case ts.ModuleKind.ES2015:
                return ts.transformECMAScriptModule;
            case ts.ModuleKind.System:
                return ts.transformSystemModule;
            default:
                return ts.transformModule;
        }
    }
    var TransformationState;
    (function (TransformationState) {
        TransformationState[TransformationState["Uninitialized"] = 0] = "Uninitialized";
        TransformationState[TransformationState["Initialized"] = 1] = "Initialized";
        TransformationState[TransformationState["Completed"] = 2] = "Completed";
        TransformationState[TransformationState["Disposed"] = 3] = "Disposed";
    })(TransformationState || (TransformationState = {}));
    var SyntaxKindFeatureFlags;
    (function (SyntaxKindFeatureFlags) {
        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["Substitution"] = 1] = "Substitution";
        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["EmitNotifications"] = 2] = "EmitNotifications";
    })(SyntaxKindFeatureFlags || (SyntaxKindFeatureFlags = {}));
    ts.noTransformers = { scriptTransformers: ts.emptyArray, declarationTransformers: ts.emptyArray };
    function getTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles) {
        return {
            scriptTransformers: getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles),
            declarationTransformers: getDeclarationTransformers(customTransformers),
        };
    }
    ts.getTransformers = getTransformers;
    function getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles) {
        if (emitOnlyDtsFiles)
            return ts.emptyArray;
        var jsx = compilerOptions.jsx;
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var transformers = [];
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.before, wrapScriptTransformerFactory));
        transformers.push(ts.transformTypeScript);
        transformers.push(ts.transformClassFields);
        if (jsx === 2 /* React */) {
            transformers.push(ts.transformJsx);
        }
        if (languageVersion < 99 /* ESNext */) {
            transformers.push(ts.transformESNext);
        }
        if (languageVersion < 7 /* ES2020 */) {
            transformers.push(ts.transformES2020);
        }
        if (languageVersion < 6 /* ES2019 */) {
            transformers.push(ts.transformES2019);
        }
        if (languageVersion < 5 /* ES2018 */) {
            transformers.push(ts.transformES2018);
        }
        if (languageVersion < 4 /* ES2017 */) {
            transformers.push(ts.transformES2017);
        }
        if (languageVersion < 3 /* ES2016 */) {
            transformers.push(ts.transformES2016);
        }
        if (languageVersion < 2 /* ES2015 */) {
            transformers.push(ts.transformES2015);
            transformers.push(ts.transformGenerators);
        }
        transformers.push(getModuleTransformer(moduleKind));
        // The ES5 transformer is last so that it can substitute expressions like `exports.default`
        // for ES3.
        if (languageVersion < 1 /* ES5 */) {
            transformers.push(ts.transformES5);
        }
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.after, wrapScriptTransformerFactory));
        return transformers;
    }
    function getDeclarationTransformers(customTransformers) {
        var transformers = [];
        transformers.push(ts.transformDeclarations);
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.afterDeclarations, wrapDeclarationTransformerFactory));
        return transformers;
    }
    /**
     * Wrap a custom script or declaration transformer object in a `Transformer` callback with fallback support for transforming bundles.
     */
    function wrapCustomTransformer(transformer) {
        return function (node) { return ts.isBundle(node) ? transformer.transformBundle(node) : transformer.transformSourceFile(node); };
    }
    /**
     * Wrap a transformer factory that may return a custom script or declaration transformer object.
     */
    function wrapCustomTransformerFactory(transformer, handleDefault) {
        return function (context) {
            var customTransformer = transformer(context);
            return typeof customTransformer === "function"
                ? handleDefault(customTransformer)
                : wrapCustomTransformer(customTransformer);
        };
    }
    function wrapScriptTransformerFactory(transformer) {
        return wrapCustomTransformerFactory(transformer, ts.chainBundle);
    }
    function wrapDeclarationTransformerFactory(transformer) {
        return wrapCustomTransformerFactory(transformer, ts.identity);
    }
    function noEmitSubstitution(_hint, node) {
        return node;
    }
    ts.noEmitSubstitution = noEmitSubstitution;
    function noEmitNotification(hint, node, callback) {
        callback(hint, node);
    }
    ts.noEmitNotification = noEmitNotification;
    /**
     * Transforms an array of SourceFiles by passing them through each transformer.
     *
     * @param resolver The emit resolver provided by the checker.
     * @param host The emit host object used to interact with the file system.
     * @param options Compiler options to surface in the `TransformationContext`.
     * @param nodes An array of nodes to transform.
     * @param transforms An array of `TransformerFactory` callbacks.
     * @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
     */
    function transformNodes(resolver, host, options, nodes, transformers, allowDtsFiles) {
        var enabledSyntaxKindFeatures = new Array(331 /* Count */);
        var lexicalEnvironmentVariableDeclarations;
        var lexicalEnvironmentFunctionDeclarations;
        var lexicalEnvironmentStatements;
        var lexicalEnvironmentFlags = 0 /* None */;
        var lexicalEnvironmentVariableDeclarationsStack = [];
        var lexicalEnvironmentFunctionDeclarationsStack = [];
        var lexicalEnvironmentStatementsStack = [];
        var lexicalEnvironmentFlagsStack = [];
        var lexicalEnvironmentStackOffset = 0;
        var lexicalEnvironmentSuspended = false;
        var emitHelpers;
        var onSubstituteNode = noEmitSubstitution;
        var onEmitNode = noEmitNotification;
        var state = 0 /* Uninitialized */;
        var diagnostics = [];
        // The transformation context is provided to each transformer as part of transformer
        // initialization.
        var context = {
            getCompilerOptions: function () { return options; },
            getEmitResolver: function () { return resolver; },
            getEmitHost: function () { return host; },
            startLexicalEnvironment: startLexicalEnvironment,
            suspendLexicalEnvironment: suspendLexicalEnvironment,
            resumeLexicalEnvironment: resumeLexicalEnvironment,
            endLexicalEnvironment: endLexicalEnvironment,
            setLexicalEnvironmentFlags: setLexicalEnvironmentFlags,
            getLexicalEnvironmentFlags: getLexicalEnvironmentFlags,
            hoistVariableDeclaration: hoistVariableDeclaration,
            hoistFunctionDeclaration: hoistFunctionDeclaration,
            addInitializationStatement: addInitializationStatement,
            requestEmitHelper: requestEmitHelper,
            readEmitHelpers: readEmitHelpers,
            enableSubstitution: enableSubstitution,
            enableEmitNotification: enableEmitNotification,
            isSubstitutionEnabled: isSubstitutionEnabled,
            isEmitNotificationEnabled: isEmitNotificationEnabled,
            get onSubstituteNode() { return onSubstituteNode; },
            set onSubstituteNode(value) {
                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
                onSubstituteNode = value;
            },
            get onEmitNode() { return onEmitNode; },
            set onEmitNode(value) {
                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
                onEmitNode = value;
            },
            addDiagnostic: function (diag) {
                diagnostics.push(diag);
            }
        };
        // Ensure the parse tree is clean before applying transformations
        for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) {
            var node = nodes_4[_i];
            ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
        }
        ts.performance.mark("beforeTransform");
        // Chain together and initialize each transformer.
        var transformersWithContext = transformers.map(function (t) { return t(context); });
        var transformation = function (node) {
            for (var _i = 0, transformersWithContext_1 = transformersWithContext; _i < transformersWithContext_1.length; _i++) {
                var transform = transformersWithContext_1[_i];
                node = transform(node);
            }
            return node;
        };
        // prevent modification of transformation hooks.
        state = 1 /* Initialized */;
        // Transform each node.
        var transformed = ts.map(nodes, allowDtsFiles ? transformation : transformRoot);
        // prevent modification of the lexical environment.
        state = 2 /* Completed */;
        ts.performance.mark("afterTransform");
        ts.performance.measure("transformTime", "beforeTransform", "afterTransform");
        return {
            transformed: transformed,
            substituteNode: substituteNode,
            emitNodeWithNotification: emitNodeWithNotification,
            isEmitNotificationEnabled: isEmitNotificationEnabled,
            dispose: dispose,
            diagnostics: diagnostics
        };
        function transformRoot(node) {
            return node && (!ts.isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node;
        }
        /**
         * Enables expression substitutions in the pretty printer for the provided SyntaxKind.
         */
        function enableSubstitution(kind) {
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            enabledSyntaxKindFeatures[kind] |= 1 /* Substitution */;
        }
        /**
         * Determines whether expression substitutions are enabled for the provided node.
         */
        function isSubstitutionEnabled(node) {
            return (enabledSyntaxKindFeatures[node.kind] & 1 /* Substitution */) !== 0
                && (ts.getEmitFlags(node) & 4 /* NoSubstitution */) === 0;
        }
        /**
         * Emits a node with possible substitution.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node or its substitute.
         */
        function substituteNode(hint, node) {
            ts.Debug.assert(state < 3 /* Disposed */, "Cannot substitute a node after the result is disposed.");
            return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
        }
        /**
         * Enables before/after emit notifications in the pretty printer for the provided SyntaxKind.
         */
        function enableEmitNotification(kind) {
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            enabledSyntaxKindFeatures[kind] |= 2 /* EmitNotifications */;
        }
        /**
         * Determines whether before/after emit notifications should be raised in the pretty
         * printer when it emits a node.
         */
        function isEmitNotificationEnabled(node) {
            return (enabledSyntaxKindFeatures[node.kind] & 2 /* EmitNotifications */) !== 0
                || (ts.getEmitFlags(node) & 2 /* AdviseOnEmitNode */) !== 0;
        }
        /**
         * Emits a node with possible emit notification.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node.
         */
        function emitNodeWithNotification(hint, node, emitCallback) {
            ts.Debug.assert(state < 3 /* Disposed */, "Cannot invoke TransformationResult callbacks after the result is disposed.");
            if (node) {
                // TODO: Remove check and unconditionally use onEmitNode when API is breakingly changed
                // (see https://github.com/microsoft/TypeScript/pull/36248/files/5062623f39120171b98870c71344b3242eb03d23#r369766739)
                if (isEmitNotificationEnabled(node)) {
                    onEmitNode(hint, node, emitCallback);
                }
                else {
                    emitCallback(hint, node);
                }
            }
        }
        /**
         * Records a hoisted variable declaration for the provided name within a lexical environment.
         */
        function hoistVariableDeclaration(name) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            var decl = ts.setEmitFlags(ts.createVariableDeclaration(name), 64 /* NoNestedSourceMaps */);
            if (!lexicalEnvironmentVariableDeclarations) {
                lexicalEnvironmentVariableDeclarations = [decl];
            }
            else {
                lexicalEnvironmentVariableDeclarations.push(decl);
            }
            if (lexicalEnvironmentFlags & 1 /* InParameters */) {
                lexicalEnvironmentFlags |= 2 /* VariablesHoistedInParameters */;
            }
        }
        /**
         * Records a hoisted function declaration within a lexical environment.
         */
        function hoistFunctionDeclaration(func) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.setEmitFlags(func, 1048576 /* CustomPrologue */);
            if (!lexicalEnvironmentFunctionDeclarations) {
                lexicalEnvironmentFunctionDeclarations = [func];
            }
            else {
                lexicalEnvironmentFunctionDeclarations.push(func);
            }
        }
        /**
         * Adds an initialization statement to the top of the lexical environment.
         */
        function addInitializationStatement(node) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.setEmitFlags(node, 1048576 /* CustomPrologue */);
            if (!lexicalEnvironmentStatements) {
                lexicalEnvironmentStatements = [node];
            }
            else {
                lexicalEnvironmentStatements.push(node);
            }
        }
        /**
         * Starts a new lexical environment. Any existing hoisted variable or function declarations
         * are pushed onto a stack, and the related storage variables are reset.
         */
        function startLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
            // Save the current lexical environment. Rather than resizing the array we adjust the
            // stack size variable. This allows us to reuse existing array slots we've
            // already allocated between transformations to avoid allocation and GC overhead during
            // transformation.
            lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations;
            lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations;
            lexicalEnvironmentStatementsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentStatements;
            lexicalEnvironmentFlagsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFlags;
            lexicalEnvironmentStackOffset++;
            lexicalEnvironmentVariableDeclarations = undefined;
            lexicalEnvironmentFunctionDeclarations = undefined;
            lexicalEnvironmentStatements = undefined;
            lexicalEnvironmentFlags = 0 /* None */;
        }
        /** Suspends the current lexical environment, usually after visiting a parameter list. */
        function suspendLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
            lexicalEnvironmentSuspended = true;
        }
        /** Resumes a suspended lexical environment, usually before visiting a function body. */
        function resumeLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
            lexicalEnvironmentSuspended = false;
        }
        /**
         * Ends a lexical environment. The previous set of hoisted declarations are restored and
         * any hoisted declarations added in this environment are returned.
         */
        function endLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
            var statements;
            if (lexicalEnvironmentVariableDeclarations ||
                lexicalEnvironmentFunctionDeclarations ||
                lexicalEnvironmentStatements) {
                if (lexicalEnvironmentFunctionDeclarations) {
                    statements = __spreadArrays(lexicalEnvironmentFunctionDeclarations);
                }
                if (lexicalEnvironmentVariableDeclarations) {
                    var statement = ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations));
                    ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
                    if (!statements) {
                        statements = [statement];
                    }
                    else {
                        statements.push(statement);
                    }
                }
                if (lexicalEnvironmentStatements) {
                    if (!statements) {
                        statements = __spreadArrays(lexicalEnvironmentStatements);
                    }
                    else {
                        statements = __spreadArrays(statements, lexicalEnvironmentStatements);
                    }
                }
            }
            // Restore the previous lexical environment.
            lexicalEnvironmentStackOffset--;
            lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
            lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
            lexicalEnvironmentStatements = lexicalEnvironmentStatementsStack[lexicalEnvironmentStackOffset];
            lexicalEnvironmentFlags = lexicalEnvironmentFlagsStack[lexicalEnvironmentStackOffset];
            if (lexicalEnvironmentStackOffset === 0) {
                lexicalEnvironmentVariableDeclarationsStack = [];
                lexicalEnvironmentFunctionDeclarationsStack = [];
                lexicalEnvironmentStatementsStack = [];
                lexicalEnvironmentFlagsStack = [];
            }
            return statements;
        }
        function setLexicalEnvironmentFlags(flags, value) {
            lexicalEnvironmentFlags = value ?
                lexicalEnvironmentFlags | flags :
                lexicalEnvironmentFlags & ~flags;
        }
        function getLexicalEnvironmentFlags() {
            return lexicalEnvironmentFlags;
        }
        function requestEmitHelper(helper) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            ts.Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
            if (helper.dependencies) {
                for (var _i = 0, _a = helper.dependencies; _i < _a.length; _i++) {
                    var h = _a[_i];
                    requestEmitHelper(h);
                }
            }
            emitHelpers = ts.append(emitHelpers, helper);
        }
        function readEmitHelpers() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            var helpers = emitHelpers;
            emitHelpers = undefined;
            return helpers;
        }
        function dispose() {
            if (state < 3 /* Disposed */) {
                // Clean up emit nodes on parse tree
                for (var _i = 0, nodes_5 = nodes; _i < nodes_5.length; _i++) {
                    var node = nodes_5[_i];
                    ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
                }
                // Release references to external entries for GC purposes.
                lexicalEnvironmentVariableDeclarations = undefined;
                lexicalEnvironmentVariableDeclarationsStack = undefined;
                lexicalEnvironmentFunctionDeclarations = undefined;
                lexicalEnvironmentFunctionDeclarationsStack = undefined;
                onSubstituteNode = undefined;
                onEmitNode = undefined;
                emitHelpers = undefined;
                // Prevent further use of the transformation result.
                state = 3 /* Disposed */;
            }
        }
    }
    ts.transformNodes = transformNodes;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var brackets = createBracketsMap();
    var syntheticParent = { pos: -1, end: -1 };
    /*@internal*/
    function isBuildInfoFile(file) {
        return ts.fileExtensionIs(file, ".tsbuildinfo" /* TsBuildInfo */);
    }
    ts.isBuildInfoFile = isBuildInfoFile;
    /*@internal*/
    /**
     * Iterates over the source files that are expected to have an emit output.
     *
     * @param host An EmitHost.
     * @param action The action to execute.
     * @param sourceFilesOrTargetSourceFile
     *   If an array, the full list of source files to emit.
     *   Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
     */
    function forEachEmittedFile(host, action, sourceFilesOrTargetSourceFile, forceDtsEmit, onlyBuildInfo, includeBuildInfo) {
        if (forceDtsEmit === void 0) { forceDtsEmit = false; }
        var sourceFiles = ts.isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : ts.getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile, forceDtsEmit);
        var options = host.getCompilerOptions();
        if (options.outFile || options.out) {
            var prepends = host.getPrependNodes();
            if (sourceFiles.length || prepends.length) {
                var bundle = ts.createBundle(sourceFiles, prepends);
                var result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle);
                if (result) {
                    return result;
                }
            }
        }
        else {
            if (!onlyBuildInfo) {
                for (var _a = 0, sourceFiles_1 = sourceFiles; _a < sourceFiles_1.length; _a++) {
                    var sourceFile = sourceFiles_1[_a];
                    var result = action(getOutputPathsFor(sourceFile, host, forceDtsEmit), sourceFile);
                    if (result) {
                        return result;
                    }
                }
            }
            if (includeBuildInfo) {
                var buildInfoPath = getTsBuildInfoEmitOutputFilePath(host.getCompilerOptions());
                if (buildInfoPath)
                    return action({ buildInfoPath: buildInfoPath }, /*sourceFileOrBundle*/ undefined);
            }
        }
    }
    ts.forEachEmittedFile = forEachEmittedFile;
    function getTsBuildInfoEmitOutputFilePath(options) {
        var configFile = options.configFilePath;
        if (!ts.isIncrementalCompilation(options))
            return undefined;
        if (options.tsBuildInfoFile)
            return options.tsBuildInfoFile;
        var outPath = options.outFile || options.out;
        var buildInfoExtensionLess;
        if (outPath) {
            buildInfoExtensionLess = ts.removeFileExtension(outPath);
        }
        else {
            if (!configFile)
                return undefined;
            var configFileExtensionLess = ts.removeFileExtension(configFile);
            buildInfoExtensionLess = options.outDir ?
                options.rootDir ?
                    ts.resolvePath(options.outDir, ts.getRelativePathFromDirectory(options.rootDir, configFileExtensionLess, /*ignoreCase*/ true)) :
                    ts.combinePaths(options.outDir, ts.getBaseFileName(configFileExtensionLess)) :
                configFileExtensionLess;
        }
        return buildInfoExtensionLess + ".tsbuildinfo" /* TsBuildInfo */;
    }
    ts.getTsBuildInfoEmitOutputFilePath = getTsBuildInfoEmitOutputFilePath;
    /*@internal*/
    function getOutputPathsForBundle(options, forceDtsPaths) {
        var outPath = options.outFile || options.out;
        var jsFilePath = options.emitDeclarationOnly ? undefined : outPath;
        var sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options);
        var declarationFilePath = (forceDtsPaths || ts.getEmitDeclarations(options)) ? ts.removeFileExtension(outPath) + ".d.ts" /* Dts */ : undefined;
        var declarationMapPath = declarationFilePath && ts.getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
        var buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
        return { jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath, declarationMapPath: declarationMapPath, buildInfoPath: buildInfoPath };
    }
    ts.getOutputPathsForBundle = getOutputPathsForBundle;
    /*@internal*/
    function getOutputPathsFor(sourceFile, host, forceDtsPaths) {
        var options = host.getCompilerOptions();
        if (sourceFile.kind === 291 /* Bundle */) {
            return getOutputPathsForBundle(options, forceDtsPaths);
        }
        else {
            var ownOutputFilePath = ts.getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile, options));
            var isJsonFile = ts.isJsonSourceFile(sourceFile);
            // If json file emits to the same location skip writing it, if emitDeclarationOnly skip writing it
            var isJsonEmittedToSameLocation = isJsonFile &&
                ts.comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
            var jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? undefined : ownOutputFilePath;
            var sourceMapFilePath = !jsFilePath || ts.isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
            var declarationFilePath = (forceDtsPaths || (ts.getEmitDeclarations(options) && !isJsonFile)) ? ts.getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined;
            var declarationMapPath = declarationFilePath && ts.getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
            return { jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath, declarationMapPath: declarationMapPath, buildInfoPath: undefined };
        }
    }
    ts.getOutputPathsFor = getOutputPathsFor;
    function getSourceMapFilePath(jsFilePath, options) {
        return (options.sourceMap && !options.inlineSourceMap) ? jsFilePath + ".map" : undefined;
    }
    // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
    // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
    // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
    /* @internal */
    function getOutputExtension(sourceFile, options) {
        if (ts.isJsonSourceFile(sourceFile)) {
            return ".json" /* Json */;
        }
        if (options.jsx === 1 /* Preserve */) {
            if (ts.isSourceFileJS(sourceFile)) {
                if (ts.fileExtensionIs(sourceFile.fileName, ".jsx" /* Jsx */)) {
                    return ".jsx" /* Jsx */;
                }
            }
            else if (sourceFile.languageVariant === 1 /* JSX */) {
                // TypeScript source file preserving JSX syntax
                return ".jsx" /* Jsx */;
            }
        }
        return ".js" /* Js */;
    }
    ts.getOutputExtension = getOutputExtension;
    function rootDirOfOptions(configFile) {
        return configFile.options.rootDir || ts.getDirectoryPath(ts.Debug.checkDefined(configFile.options.configFilePath));
    }
    function getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, outputDir) {
        return outputDir ?
            ts.resolvePath(outputDir, ts.getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase)) :
            inputFileName;
    }
    /* @internal */
    function getOutputDeclarationFileName(inputFileName, configFile, ignoreCase) {
        ts.Debug.assert(!ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */) && !ts.fileExtensionIs(inputFileName, ".json" /* Json */));
        return ts.changeExtension(getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir), ".d.ts" /* Dts */);
    }
    ts.getOutputDeclarationFileName = getOutputDeclarationFileName;
    function getOutputJSFileName(inputFileName, configFile, ignoreCase) {
        if (configFile.options.emitDeclarationOnly)
            return undefined;
        var isJsonFile = ts.fileExtensionIs(inputFileName, ".json" /* Json */);
        var outputFileName = ts.changeExtension(getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir), isJsonFile ?
            ".json" /* Json */ :
            ts.fileExtensionIs(inputFileName, ".tsx" /* Tsx */) && configFile.options.jsx === 1 /* Preserve */ ?
                ".jsx" /* Jsx */ :
                ".js" /* Js */);
        return !isJsonFile || ts.comparePaths(inputFileName, outputFileName, ts.Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== 0 /* EqualTo */ ?
            outputFileName :
            undefined;
    }
    function createAddOutput() {
        var outputs;
        return { addOutput: addOutput, getOutputs: getOutputs };
        function addOutput(path) {
            if (path) {
                (outputs || (outputs = [])).push(path);
            }
        }
        function getOutputs() {
            return outputs || ts.emptyArray;
        }
    }
    function getSingleOutputFileNames(configFile, addOutput) {
        var _a = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false), jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
        addOutput(jsFilePath);
        addOutput(sourceMapFilePath);
        addOutput(declarationFilePath);
        addOutput(declarationMapPath);
        addOutput(buildInfoPath);
    }
    function getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput) {
        if (ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */))
            return;
        var js = getOutputJSFileName(inputFileName, configFile, ignoreCase);
        addOutput(js);
        if (ts.fileExtensionIs(inputFileName, ".json" /* Json */))
            return;
        if (js && configFile.options.sourceMap) {
            addOutput(js + ".map");
        }
        if (ts.getEmitDeclarations(configFile.options)) {
            var dts = getOutputDeclarationFileName(inputFileName, configFile, ignoreCase);
            addOutput(dts);
            if (configFile.options.declarationMap) {
                addOutput(dts + ".map");
            }
        }
    }
    /*@internal*/
    function getAllProjectOutputs(configFile, ignoreCase) {
        var _a = createAddOutput(), addOutput = _a.addOutput, getOutputs = _a.getOutputs;
        if (configFile.options.outFile || configFile.options.out) {
            getSingleOutputFileNames(configFile, addOutput);
        }
        else {
            for (var _b = 0, _c = configFile.fileNames; _b < _c.length; _b++) {
                var inputFileName = _c[_b];
                getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput);
            }
            addOutput(getTsBuildInfoEmitOutputFilePath(configFile.options));
        }
        return getOutputs();
    }
    ts.getAllProjectOutputs = getAllProjectOutputs;
    function getOutputFileNames(commandLine, inputFileName, ignoreCase) {
        inputFileName = ts.normalizePath(inputFileName);
        ts.Debug.assert(ts.contains(commandLine.fileNames, inputFileName), "Expected fileName to be present in command line");
        var _a = createAddOutput(), addOutput = _a.addOutput, getOutputs = _a.getOutputs;
        if (commandLine.options.outFile || commandLine.options.out) {
            getSingleOutputFileNames(commandLine, addOutput);
        }
        else {
            getOwnOutputFileNames(commandLine, inputFileName, ignoreCase, addOutput);
        }
        return getOutputs();
    }
    ts.getOutputFileNames = getOutputFileNames;
    /*@internal*/
    function getFirstProjectOutput(configFile, ignoreCase) {
        if (configFile.options.outFile || configFile.options.out) {
            var jsFilePath = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false).jsFilePath;
            return ts.Debug.checkDefined(jsFilePath, "project " + configFile.options.configFilePath + " expected to have at least one output");
        }
        for (var _a = 0, _b = configFile.fileNames; _a < _b.length; _a++) {
            var inputFileName = _b[_a];
            if (ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */))
                continue;
            var jsFilePath = getOutputJSFileName(inputFileName, configFile, ignoreCase);
            if (jsFilePath)
                return jsFilePath;
            if (ts.fileExtensionIs(inputFileName, ".json" /* Json */))
                continue;
            if (ts.getEmitDeclarations(configFile.options)) {
                return getOutputDeclarationFileName(inputFileName, configFile, ignoreCase);
            }
        }
        var buildInfoPath = getTsBuildInfoEmitOutputFilePath(configFile.options);
        if (buildInfoPath)
            return buildInfoPath;
        return ts.Debug.fail("project " + configFile.options.configFilePath + " expected to have at least one output");
    }
    ts.getFirstProjectOutput = getFirstProjectOutput;
    /*@internal*/
    // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
    function emitFiles(resolver, host, targetSourceFile, _a, emitOnlyDtsFiles, onlyBuildInfo, forceDtsEmit) {
        var scriptTransformers = _a.scriptTransformers, declarationTransformers = _a.declarationTransformers;
        var compilerOptions = host.getCompilerOptions();
        var sourceMapDataList = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || ts.getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
        var emittedFilesList = compilerOptions.listEmittedFiles ? [] : undefined;
        var emitterDiagnostics = ts.createDiagnosticCollection();
        var newLine = ts.getNewLineCharacter(compilerOptions, function () { return host.getNewLine(); });
        var writer = ts.createTextWriter(newLine);
        var _b = ts.performance.createTimer("printTime", "beforePrint", "afterPrint"), enter = _b.enter, exit = _b.exit;
        var bundleBuildInfo;
        var emitSkipped = false;
        var exportedModulesFromDeclarationEmit;
        // Emit each output file
        enter();
        forEachEmittedFile(host, emitSourceFileOrBundle, ts.getSourceFilesToEmit(host, targetSourceFile, forceDtsEmit), forceDtsEmit, onlyBuildInfo, !targetSourceFile);
        exit();
        return {
            emitSkipped: emitSkipped,
            diagnostics: emitterDiagnostics.getDiagnostics(),
            emittedFiles: emittedFilesList,
            sourceMaps: sourceMapDataList,
            exportedModulesFromDeclarationEmit: exportedModulesFromDeclarationEmit
        };
        function emitSourceFileOrBundle(_a, sourceFileOrBundle) {
            var jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
            var buildInfoDirectory;
            if (buildInfoPath && sourceFileOrBundle && ts.isBundle(sourceFileOrBundle)) {
                buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
                bundleBuildInfo = {
                    commonSourceDirectory: relativeToBuildInfo(host.getCommonSourceDirectory()),
                    sourceFiles: sourceFileOrBundle.sourceFiles.map(function (file) { return relativeToBuildInfo(ts.getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory())); })
                };
            }
            emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath, relativeToBuildInfo);
            emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath, relativeToBuildInfo);
            emitBuildInfo(bundleBuildInfo, buildInfoPath);
            if (!emitSkipped && emittedFilesList) {
                if (!emitOnlyDtsFiles) {
                    if (jsFilePath) {
                        emittedFilesList.push(jsFilePath);
                    }
                    if (sourceMapFilePath) {
                        emittedFilesList.push(sourceMapFilePath);
                    }
                    if (buildInfoPath) {
                        emittedFilesList.push(buildInfoPath);
                    }
                }
                if (declarationFilePath) {
                    emittedFilesList.push(declarationFilePath);
                }
                if (declarationMapPath) {
                    emittedFilesList.push(declarationMapPath);
                }
            }
            function relativeToBuildInfo(path) {
                return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(buildInfoDirectory, path, host.getCanonicalFileName));
            }
        }
        function emitBuildInfo(bundle, buildInfoPath) {
            // Write build information if applicable
            if (!buildInfoPath || targetSourceFile || emitSkipped)
                return;
            var program = host.getProgramBuildInfo();
            if (host.isEmitBlocked(buildInfoPath) || compilerOptions.noEmit) {
                emitSkipped = true;
                return;
            }
            var version = ts.version; // Extracted into a const so the form is stable between namespace and module
            ts.writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText({ bundle: bundle, program: program, version: version }), /*writeByteOrderMark*/ false);
        }
        function emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath, relativeToBuildInfo) {
            if (!sourceFileOrBundle || emitOnlyDtsFiles || !jsFilePath) {
                return;
            }
            // Make sure not to write js file and source map file if any of them cannot be written
            if ((jsFilePath && host.isEmitBlocked(jsFilePath)) || compilerOptions.noEmit) {
                emitSkipped = true;
                return;
            }
            // Transform the source files
            var transform = ts.transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
            var printerOptions = {
                removeComments: compilerOptions.removeComments,
                newLine: compilerOptions.newLine,
                noEmitHelpers: compilerOptions.noEmitHelpers,
                module: compilerOptions.module,
                target: compilerOptions.target,
                sourceMap: compilerOptions.sourceMap,
                inlineSourceMap: compilerOptions.inlineSourceMap,
                inlineSources: compilerOptions.inlineSources,
                extendedDiagnostics: compilerOptions.extendedDiagnostics,
                writeBundleFileInfo: !!bundleBuildInfo,
                relativeToBuildInfo: relativeToBuildInfo
            };
            // Create a printer to print the nodes
            var printer = createPrinter(printerOptions, {
                // resolver hooks
                hasGlobalName: resolver.hasGlobalName,
                // transform hooks
                onEmitNode: transform.emitNodeWithNotification,
                isEmitNotificationEnabled: transform.isEmitNotificationEnabled,
                substituteNode: transform.substituteNode,
            });
            ts.Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform");
            printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform.transformed[0], printer, compilerOptions);
            // Clean up emit nodes on parse tree
            transform.dispose();
            if (bundleBuildInfo)
                bundleBuildInfo.js = printer.bundleFileInfo;
        }
        function emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath, relativeToBuildInfo) {
            if (!sourceFileOrBundle)
                return;
            if (!declarationFilePath) {
                if (emitOnlyDtsFiles || compilerOptions.emitDeclarationOnly)
                    emitSkipped = true;
                return;
            }
            var sourceFiles = ts.isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
            var filesForEmit = forceDtsEmit ? sourceFiles : ts.filter(sourceFiles, ts.isSourceFileNotJson);
            // Setup and perform the transformation to retrieve declarations from the input files
            var inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [ts.createBundle(filesForEmit, !ts.isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : filesForEmit;
            if (emitOnlyDtsFiles && !ts.getEmitDeclarations(compilerOptions)) {
                // Checker wont collect the linked aliases since thats only done when declaration is enabled.
                // Do that here when emitting only dts files
                filesForEmit.forEach(collectLinkedAliases);
            }
            var declarationTransform = ts.transformNodes(resolver, host, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
            if (ts.length(declarationTransform.diagnostics)) {
                for (var _a = 0, _b = declarationTransform.diagnostics; _a < _b.length; _a++) {
                    var diagnostic = _b[_a];
                    emitterDiagnostics.add(diagnostic);
                }
            }
            var printerOptions = {
                removeComments: compilerOptions.removeComments,
                newLine: compilerOptions.newLine,
                noEmitHelpers: true,
                module: compilerOptions.module,
                target: compilerOptions.target,
                sourceMap: compilerOptions.sourceMap,
                inlineSourceMap: compilerOptions.inlineSourceMap,
                extendedDiagnostics: compilerOptions.extendedDiagnostics,
                onlyPrintJsDocStyle: true,
                writeBundleFileInfo: !!bundleBuildInfo,
                recordInternalSection: !!bundleBuildInfo,
                relativeToBuildInfo: relativeToBuildInfo
            };
            var declarationPrinter = createPrinter(printerOptions, {
                // resolver hooks
                hasGlobalName: resolver.hasGlobalName,
                // transform hooks
                onEmitNode: declarationTransform.emitNodeWithNotification,
                isEmitNotificationEnabled: declarationTransform.isEmitNotificationEnabled,
                substituteNode: declarationTransform.substituteNode,
            });
            var declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit;
            emitSkipped = emitSkipped || declBlocked;
            if (!declBlocked || forceDtsEmit) {
                ts.Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform");
                printSourceFileOrBundle(declarationFilePath, declarationMapPath, declarationTransform.transformed[0], declarationPrinter, {
                    sourceMap: compilerOptions.declarationMap,
                    sourceRoot: compilerOptions.sourceRoot,
                    mapRoot: compilerOptions.mapRoot,
                    extendedDiagnostics: compilerOptions.extendedDiagnostics,
                });
                if (forceDtsEmit && declarationTransform.transformed[0].kind === 290 /* SourceFile */) {
                    var sourceFile = declarationTransform.transformed[0];
                    exportedModulesFromDeclarationEmit = sourceFile.exportedModulesFromDeclarationEmit;
                }
            }
            declarationTransform.dispose();
            if (bundleBuildInfo)
                bundleBuildInfo.dts = declarationPrinter.bundleFileInfo;
        }
        function collectLinkedAliases(node) {
            if (ts.isExportAssignment(node)) {
                if (node.expression.kind === 75 /* Identifier */) {
                    resolver.collectLinkedAliases(node.expression, /*setVisibility*/ true);
                }
                return;
            }
            else if (ts.isExportSpecifier(node)) {
                resolver.collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true);
                return;
            }
            ts.forEachChild(node, collectLinkedAliases);
        }
        function printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle, printer, mapOptions) {
            var bundle = sourceFileOrBundle.kind === 291 /* Bundle */ ? sourceFileOrBundle : undefined;
            var sourceFile = sourceFileOrBundle.kind === 290 /* SourceFile */ ? sourceFileOrBundle : undefined;
            var sourceFiles = bundle ? bundle.sourceFiles : [sourceFile];
            var sourceMapGenerator;
            if (shouldEmitSourceMaps(mapOptions, sourceFileOrBundle)) {
                sourceMapGenerator = ts.createSourceMapGenerator(host, ts.getBaseFileName(ts.normalizeSlashes(jsFilePath)), getSourceRoot(mapOptions), getSourceMapDirectory(mapOptions, jsFilePath, sourceFile), mapOptions);
            }
            if (bundle) {
                printer.writeBundle(bundle, writer, sourceMapGenerator);
            }
            else {
                printer.writeFile(sourceFile, writer, sourceMapGenerator);
            }
            if (sourceMapGenerator) {
                if (sourceMapDataList) {
                    sourceMapDataList.push({
                        inputSourceFileNames: sourceMapGenerator.getSources(),
                        sourceMap: sourceMapGenerator.toJSON()
                    });
                }
                var sourceMappingURL = getSourceMappingURL(mapOptions, sourceMapGenerator, jsFilePath, sourceMapFilePath, sourceFile);
                if (sourceMappingURL) {
                    if (!writer.isAtStartOfLine())
                        writer.rawWrite(newLine);
                    writer.writeComment("//# " + "sourceMappingURL" + "=" + sourceMappingURL); // Tools can sometimes see this line as a source mapping url comment
                }
                // Write the source map
                if (sourceMapFilePath) {
                    var sourceMap = sourceMapGenerator.toString();
                    ts.writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap, /*writeByteOrderMark*/ false, sourceFiles);
                }
            }
            else {
                writer.writeLine();
            }
            // Write the output file
            ts.writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), !!compilerOptions.emitBOM, sourceFiles);
            // Reset state
            writer.clear();
        }
        function shouldEmitSourceMaps(mapOptions, sourceFileOrBundle) {
            return (mapOptions.sourceMap || mapOptions.inlineSourceMap)
                && (sourceFileOrBundle.kind !== 290 /* SourceFile */ || !ts.fileExtensionIs(sourceFileOrBundle.fileName, ".json" /* Json */));
        }
        function getSourceRoot(mapOptions) {
            // Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the
            // relative paths of the sources list in the sourcemap
            var sourceRoot = ts.normalizeSlashes(mapOptions.sourceRoot || "");
            return sourceRoot ? ts.ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot;
        }
        function getSourceMapDirectory(mapOptions, filePath, sourceFile) {
            if (mapOptions.sourceRoot)
                return host.getCommonSourceDirectory();
            if (mapOptions.mapRoot) {
                var sourceMapDir = ts.normalizeSlashes(mapOptions.mapRoot);
                if (sourceFile) {
                    // For modules or multiple emit files the mapRoot will have directory structure like the sources
                    // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
                    sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
                }
                if (ts.getRootLength(sourceMapDir) === 0) {
                    // The relative paths are relative to the common directory
                    sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
                }
                return sourceMapDir;
            }
            return ts.getDirectoryPath(ts.normalizePath(filePath));
        }
        function getSourceMappingURL(mapOptions, sourceMapGenerator, filePath, sourceMapFilePath, sourceFile) {
            if (mapOptions.inlineSourceMap) {
                // Encode the sourceMap into the sourceMap url
                var sourceMapText = sourceMapGenerator.toString();
                var base64SourceMapText = ts.base64encode(ts.sys, sourceMapText);
                return "data:application/json;base64," + base64SourceMapText;
            }
            var sourceMapFile = ts.getBaseFileName(ts.normalizeSlashes(ts.Debug.checkDefined(sourceMapFilePath)));
            if (mapOptions.mapRoot) {
                var sourceMapDir = ts.normalizeSlashes(mapOptions.mapRoot);
                if (sourceFile) {
                    // For modules or multiple emit files the mapRoot will have directory structure like the sources
                    // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
                    sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
                }
                if (ts.getRootLength(sourceMapDir) === 0) {
                    // The relative paths are relative to the common directory
                    sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
                    return ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
                    ts.combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
                    host.getCurrentDirectory(), host.getCanonicalFileName, 
                    /*isAbsolutePathAnUrl*/ true);
                }
                else {
                    return ts.combinePaths(sourceMapDir, sourceMapFile);
                }
            }
            return sourceMapFile;
        }
    }
    ts.emitFiles = emitFiles;
    /*@internal*/
    function getBuildInfoText(buildInfo) {
        return JSON.stringify(buildInfo, undefined, 2);
    }
    ts.getBuildInfoText = getBuildInfoText;
    /*@internal*/
    function getBuildInfo(buildInfoText) {
        return JSON.parse(buildInfoText);
    }
    ts.getBuildInfo = getBuildInfo;
    /*@internal*/
    ts.notImplementedResolver = {
        hasGlobalName: ts.notImplemented,
        getReferencedExportContainer: ts.notImplemented,
        getReferencedImportDeclaration: ts.notImplemented,
        getReferencedDeclarationWithCollidingName: ts.notImplemented,
        isDeclarationWithCollidingName: ts.notImplemented,
        isValueAliasDeclaration: ts.notImplemented,
        isReferencedAliasDeclaration: ts.notImplemented,
        isTopLevelValueImportEqualsWithEntityName: ts.notImplemented,
        getNodeCheckFlags: ts.notImplemented,
        isDeclarationVisible: ts.notImplemented,
        isLateBound: function (_node) { return false; },
        collectLinkedAliases: ts.notImplemented,
        isImplementationOfOverload: ts.notImplemented,
        isRequiredInitializedParameter: ts.notImplemented,
        isOptionalUninitializedParameterProperty: ts.notImplemented,
        isExpandoFunctionDeclaration: ts.notImplemented,
        getPropertiesOfContainerFunction: ts.notImplemented,
        createTypeOfDeclaration: ts.notImplemented,
        createReturnTypeOfSignatureDeclaration: ts.notImplemented,
        createTypeOfExpression: ts.notImplemented,
        createLiteralConstValue: ts.notImplemented,
        isSymbolAccessible: ts.notImplemented,
        isEntityNameVisible: ts.notImplemented,
        // Returns the constant value this property access resolves to: notImplemented, or 'undefined' for a non-constant
        getConstantValue: ts.notImplemented,
        getReferencedValueDeclaration: ts.notImplemented,
        getTypeReferenceSerializationKind: ts.notImplemented,
        isOptionalParameter: ts.notImplemented,
        moduleExportsSomeValue: ts.notImplemented,
        isArgumentsLocalBinding: ts.notImplemented,
        getExternalModuleFileFromDeclaration: ts.notImplemented,
        getTypeReferenceDirectivesForEntityName: ts.notImplemented,
        getTypeReferenceDirectivesForSymbol: ts.notImplemented,
        isLiteralConstDeclaration: ts.notImplemented,
        getJsxFactoryEntity: ts.notImplemented,
        getAllAccessorDeclarations: ts.notImplemented,
        getSymbolOfExternalModuleSpecifier: ts.notImplemented,
        isBindingCapturedByNode: ts.notImplemented,
        getDeclarationStatementsForSourceFile: ts.notImplemented,
        isImportRequiredByAugmentation: ts.notImplemented,
    };
    function createSourceFilesFromBundleBuildInfo(bundle, buildInfoDirectory, host) {
        var sourceFiles = bundle.sourceFiles.map(function (fileName) {
            var sourceFile = ts.createNode(290 /* SourceFile */, 0, 0);
            sourceFile.fileName = ts.getRelativePathFromDirectory(host.getCurrentDirectory(), ts.getNormalizedAbsolutePath(fileName, buildInfoDirectory), !host.useCaseSensitiveFileNames());
            sourceFile.text = "";
            sourceFile.statements = ts.createNodeArray();
            return sourceFile;
        });
        var jsBundle = ts.Debug.checkDefined(bundle.js);
        ts.forEach(jsBundle.sources && jsBundle.sources.prologues, function (prologueInfo) {
            var sourceFile = sourceFiles[prologueInfo.file];
            sourceFile.text = prologueInfo.text;
            sourceFile.end = prologueInfo.text.length;
            sourceFile.statements = ts.createNodeArray(prologueInfo.directives.map(function (directive) {
                var statement = ts.createNode(226 /* ExpressionStatement */, directive.pos, directive.end);
                statement.expression = ts.createNode(10 /* StringLiteral */, directive.expression.pos, directive.expression.end);
                statement.expression.text = directive.expression.text;
                return statement;
            }));
        });
        return sourceFiles;
    }
    /*@internal*/
    function emitUsingBuildInfo(config, host, getCommandLine, customTransformers) {
        var _a = getOutputPathsForBundle(config.options, /*forceDtsPaths*/ false), buildInfoPath = _a.buildInfoPath, jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath;
        var buildInfoText = host.readFile(ts.Debug.checkDefined(buildInfoPath));
        if (!buildInfoText)
            return buildInfoPath;
        var jsFileText = host.readFile(ts.Debug.checkDefined(jsFilePath));
        if (!jsFileText)
            return jsFilePath;
        var sourceMapText = sourceMapFilePath && host.readFile(sourceMapFilePath);
        // error if no source map or for now if inline sourcemap
        if ((sourceMapFilePath && !sourceMapText) || config.options.inlineSourceMap)
            return sourceMapFilePath || "inline sourcemap decoding";
        // read declaration text
        var declarationText = declarationFilePath && host.readFile(declarationFilePath);
        if (declarationFilePath && !declarationText)
            return declarationFilePath;
        var declarationMapText = declarationMapPath && host.readFile(declarationMapPath);
        // error if no source map or for now if inline sourcemap
        if ((declarationMapPath && !declarationMapText) || config.options.inlineSourceMap)
            return declarationMapPath || "inline sourcemap decoding";
        var buildInfo = getBuildInfo(buildInfoText);
        if (!buildInfo.bundle || !buildInfo.bundle.js || (declarationText && !buildInfo.bundle.dts))
            return buildInfoPath;
        var buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
        var ownPrependInput = ts.createInputFiles(jsFileText, declarationText, sourceMapFilePath, sourceMapText, declarationMapPath, declarationMapText, jsFilePath, declarationFilePath, buildInfoPath, buildInfo, 
        /*onlyOwnText*/ true);
        var outputFiles = [];
        var prependNodes = ts.createPrependNodes(config.projectReferences, getCommandLine, function (f) { return host.readFile(f); });
        var sourceFilesForJsEmit = createSourceFilesFromBundleBuildInfo(buildInfo.bundle, buildInfoDirectory, host);
        var emitHost = {
            getPrependNodes: ts.memoize(function () { return __spreadArrays(prependNodes, [ownPrependInput]); }),
            getCanonicalFileName: host.getCanonicalFileName,
            getCommonSourceDirectory: function () { return ts.getNormalizedAbsolutePath(buildInfo.bundle.commonSourceDirectory, buildInfoDirectory); },
            getCompilerOptions: function () { return config.options; },
            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
            getNewLine: function () { return host.getNewLine(); },
            getSourceFile: ts.returnUndefined,
            getSourceFileByPath: ts.returnUndefined,
            getSourceFiles: function () { return sourceFilesForJsEmit; },
            getLibFileFromReference: ts.notImplemented,
            isSourceFileFromExternalLibrary: ts.returnFalse,
            getResolvedProjectReferenceToRedirect: ts.returnUndefined,
            getProjectReferenceRedirect: ts.returnUndefined,
            isSourceOfProjectReferenceRedirect: ts.returnFalse,
            writeFile: function (name, text, writeByteOrderMark) {
                switch (name) {
                    case jsFilePath:
                        if (jsFileText === text)
                            return;
                        break;
                    case sourceMapFilePath:
                        if (sourceMapText === text)
                            return;
                        break;
                    case buildInfoPath:
                        var newBuildInfo = getBuildInfo(text);
                        newBuildInfo.program = buildInfo.program;
                        // Update sourceFileInfo
                        var _a = buildInfo.bundle, js = _a.js, dts = _a.dts, sourceFiles = _a.sourceFiles;
                        newBuildInfo.bundle.js.sources = js.sources;
                        if (dts) {
                            newBuildInfo.bundle.dts.sources = dts.sources;
                        }
                        newBuildInfo.bundle.sourceFiles = sourceFiles;
                        outputFiles.push({ name: name, text: getBuildInfoText(newBuildInfo), writeByteOrderMark: writeByteOrderMark });
                        return;
                    case declarationFilePath:
                        if (declarationText === text)
                            return;
                        break;
                    case declarationMapPath:
                        if (declarationMapText === text)
                            return;
                        break;
                    default:
                        ts.Debug.fail("Unexpected path: " + name);
                }
                outputFiles.push({ name: name, text: text, writeByteOrderMark: writeByteOrderMark });
            },
            isEmitBlocked: ts.returnFalse,
            readFile: function (f) { return host.readFile(f); },
            fileExists: function (f) { return host.fileExists(f); },
            useCaseSensitiveFileNames: function () { return host.useCaseSensitiveFileNames(); },
            getProgramBuildInfo: ts.returnUndefined,
            getSourceFileFromReference: ts.returnUndefined,
            redirectTargetsMap: ts.createMultiMap()
        };
        emitFiles(ts.notImplementedResolver, emitHost, 
        /*targetSourceFile*/ undefined, ts.getTransformers(config.options, customTransformers));
        return outputFiles;
    }
    ts.emitUsingBuildInfo = emitUsingBuildInfo;
    var PipelinePhase;
    (function (PipelinePhase) {
        PipelinePhase[PipelinePhase["Notification"] = 0] = "Notification";
        PipelinePhase[PipelinePhase["Substitution"] = 1] = "Substitution";
        PipelinePhase[PipelinePhase["Comments"] = 2] = "Comments";
        PipelinePhase[PipelinePhase["SourceMaps"] = 3] = "SourceMaps";
        PipelinePhase[PipelinePhase["Emit"] = 4] = "Emit";
    })(PipelinePhase || (PipelinePhase = {}));
    function createPrinter(printerOptions, handlers) {
        if (printerOptions === void 0) { printerOptions = {}; }
        if (handlers === void 0) { handlers = {}; }
        var hasGlobalName = handlers.hasGlobalName, _a = handlers.onEmitNode, onEmitNode = _a === void 0 ? ts.noEmitNotification : _a, isEmitNotificationEnabled = handlers.isEmitNotificationEnabled, _b = handlers.substituteNode, substituteNode = _b === void 0 ? ts.noEmitSubstitution : _b, onBeforeEmitNodeArray = handlers.onBeforeEmitNodeArray, onAfterEmitNodeArray = handlers.onAfterEmitNodeArray, onBeforeEmitToken = handlers.onBeforeEmitToken, onAfterEmitToken = handlers.onAfterEmitToken;
        var extendedDiagnostics = !!printerOptions.extendedDiagnostics;
        var newLine = ts.getNewLineCharacter(printerOptions);
        var moduleKind = ts.getEmitModuleKind(printerOptions);
        var bundledHelpers = ts.createMap();
        var currentSourceFile;
        var nodeIdToGeneratedName; // Map of generated names for specific nodes.
        var autoGeneratedIdToGeneratedName; // Map of generated names for temp and loop variables.
        var generatedNames; // Set of names generated by the NameGenerator.
        var tempFlagsStack; // Stack of enclosing name generation scopes.
        var tempFlags; // TempFlags for the current name generation scope.
        var reservedNamesStack; // Stack of TempFlags reserved in enclosing name generation scopes.
        var reservedNames; // TempFlags to reserve in nested name generation scopes.
        var preserveSourceNewlines = printerOptions.preserveSourceNewlines; // Can be overridden inside nodes with the `IgnoreSourceNewlines` emit flag.
        var writer;
        var ownWriter; // Reusable `EmitTextWriter` for basic printing.
        var write = writeBase;
        var isOwnFileEmit;
        var bundleFileInfo = printerOptions.writeBundleFileInfo ? { sections: [] } : undefined;
        var relativeToBuildInfo = bundleFileInfo ? ts.Debug.checkDefined(printerOptions.relativeToBuildInfo) : undefined;
        var recordInternalSection = printerOptions.recordInternalSection;
        var sourceFileTextPos = 0;
        var sourceFileTextKind = "text" /* Text */;
        // Source Maps
        var sourceMapsDisabled = true;
        var sourceMapGenerator;
        var sourceMapSource;
        var sourceMapSourceIndex = -1;
        // Comments
        var containerPos = -1;
        var containerEnd = -1;
        var declarationListContainerEnd = -1;
        var currentLineMap;
        var detachedCommentsInfo;
        var hasWrittenComment = false;
        var commentsDisabled = !!printerOptions.removeComments;
        var lastNode;
        var lastSubstitution;
        var _c = ts.performance.createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment"), enterComment = _c.enter, exitComment = _c.exit;
        reset();
        return {
            // public API
            printNode: printNode,
            printList: printList,
            printFile: printFile,
            printBundle: printBundle,
            // internal API
            writeNode: writeNode,
            writeList: writeList,
            writeFile: writeFile,
            writeBundle: writeBundle,
            bundleFileInfo: bundleFileInfo
        };
        function printNode(hint, node, sourceFile) {
            switch (hint) {
                case 0 /* SourceFile */:
                    ts.Debug.assert(ts.isSourceFile(node), "Expected a SourceFile node.");
                    break;
                case 2 /* IdentifierName */:
                    ts.Debug.assert(ts.isIdentifier(node), "Expected an Identifier node.");
                    break;
                case 1 /* Expression */:
                    ts.Debug.assert(ts.isExpression(node), "Expected an Expression node.");
                    break;
            }
            switch (node.kind) {
                case 290 /* SourceFile */: return printFile(node);
                case 291 /* Bundle */: return printBundle(node);
                case 292 /* UnparsedSource */: return printUnparsedSource(node);
            }
            writeNode(hint, node, sourceFile, beginPrint());
            return endPrint();
        }
        function printList(format, nodes, sourceFile) {
            writeList(format, nodes, sourceFile, beginPrint());
            return endPrint();
        }
        function printBundle(bundle) {
            writeBundle(bundle, beginPrint(), /*sourceMapEmitter*/ undefined);
            return endPrint();
        }
        function printFile(sourceFile) {
            writeFile(sourceFile, beginPrint(), /*sourceMapEmitter*/ undefined);
            return endPrint();
        }
        function printUnparsedSource(unparsed) {
            writeUnparsedSource(unparsed, beginPrint());
            return endPrint();
        }
        function writeNode(hint, node, sourceFile, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            print(hint, node, sourceFile);
            reset();
            writer = previousWriter;
        }
        function writeList(format, nodes, sourceFile, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            if (sourceFile) {
                setSourceFile(sourceFile);
            }
            emitList(syntheticParent, nodes, format);
            reset();
            writer = previousWriter;
        }
        function getTextPosWithWriteLine() {
            return writer.getTextPosWithWriteLine ? writer.getTextPosWithWriteLine() : writer.getTextPos();
        }
        function updateOrPushBundleFileTextLike(pos, end, kind) {
            var last = ts.lastOrUndefined(bundleFileInfo.sections);
            if (last && last.kind === kind) {
                last.end = end;
            }
            else {
                bundleFileInfo.sections.push({ pos: pos, end: end, kind: kind });
            }
        }
        function recordBundleFileInternalSectionStart(node) {
            if (recordInternalSection &&
                bundleFileInfo &&
                currentSourceFile &&
                (ts.isDeclaration(node) || ts.isVariableStatement(node)) &&
                ts.isInternalDeclaration(node, currentSourceFile) &&
                sourceFileTextKind !== "internal" /* Internal */) {
                var prevSourceFileTextKind = sourceFileTextKind;
                recordBundleFileTextLikeSection(writer.getTextPos());
                sourceFileTextPos = getTextPosWithWriteLine();
                sourceFileTextKind = "internal" /* Internal */;
                return prevSourceFileTextKind;
            }
            return undefined;
        }
        function recordBundleFileInternalSectionEnd(prevSourceFileTextKind) {
            if (prevSourceFileTextKind) {
                recordBundleFileTextLikeSection(writer.getTextPos());
                sourceFileTextPos = getTextPosWithWriteLine();
                sourceFileTextKind = prevSourceFileTextKind;
            }
        }
        function recordBundleFileTextLikeSection(end) {
            if (sourceFileTextPos < end) {
                updateOrPushBundleFileTextLike(sourceFileTextPos, end, sourceFileTextKind);
                return true;
            }
            return false;
        }
        function writeBundle(bundle, output, sourceMapGenerator) {
            var _a;
            isOwnFileEmit = false;
            var previousWriter = writer;
            setWriter(output, sourceMapGenerator);
            emitShebangIfNeeded(bundle);
            emitPrologueDirectivesIfNeeded(bundle);
            emitHelpers(bundle);
            emitSyntheticTripleSlashReferencesIfNeeded(bundle);
            for (var _b = 0, _c = bundle.prepends; _b < _c.length; _b++) {
                var prepend = _c[_b];
                writeLine();
                var pos = writer.getTextPos();
                var savedSections = bundleFileInfo && bundleFileInfo.sections;
                if (savedSections)
                    bundleFileInfo.sections = [];
                print(4 /* Unspecified */, prepend, /*sourceFile*/ undefined);
                if (bundleFileInfo) {
                    var newSections = bundleFileInfo.sections;
                    bundleFileInfo.sections = savedSections;
                    if (prepend.oldFileOfCurrentEmit)
                        (_a = bundleFileInfo.sections).push.apply(_a, newSections);
                    else {
                        newSections.forEach(function (section) { return ts.Debug.assert(ts.isBundleFileTextLike(section)); });
                        bundleFileInfo.sections.push({
                            pos: pos,
                            end: writer.getTextPos(),
                            kind: "prepend" /* Prepend */,
                            data: relativeToBuildInfo(prepend.fileName),
                            texts: newSections
                        });
                    }
                }
            }
            sourceFileTextPos = getTextPosWithWriteLine();
            for (var _d = 0, _e = bundle.sourceFiles; _d < _e.length; _d++) {
                var sourceFile = _e[_d];
                print(0 /* SourceFile */, sourceFile, sourceFile);
            }
            if (bundleFileInfo && bundle.sourceFiles.length) {
                var end = writer.getTextPos();
                if (recordBundleFileTextLikeSection(end)) {
                    // Store prologues
                    var prologues = getPrologueDirectivesFromBundledSourceFiles(bundle);
                    if (prologues) {
                        if (!bundleFileInfo.sources)
                            bundleFileInfo.sources = {};
                        bundleFileInfo.sources.prologues = prologues;
                    }
                    // Store helpes
                    var helpers = getHelpersFromBundledSourceFiles(bundle);
                    if (helpers) {
                        if (!bundleFileInfo.sources)
                            bundleFileInfo.sources = {};
                        bundleFileInfo.sources.helpers = helpers;
                    }
                }
            }
            reset();
            writer = previousWriter;
        }
        function writeUnparsedSource(unparsed, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            print(4 /* Unspecified */, unparsed, /*sourceFile*/ undefined);
            reset();
            writer = previousWriter;
        }
        function writeFile(sourceFile, output, sourceMapGenerator) {
            isOwnFileEmit = true;
            var previousWriter = writer;
            setWriter(output, sourceMapGenerator);
            emitShebangIfNeeded(sourceFile);
            emitPrologueDirectivesIfNeeded(sourceFile);
            print(0 /* SourceFile */, sourceFile, sourceFile);
            reset();
            writer = previousWriter;
        }
        function beginPrint() {
            return ownWriter || (ownWriter = ts.createTextWriter(newLine));
        }
        function endPrint() {
            var text = ownWriter.getText();
            ownWriter.clear();
            return text;
        }
        function print(hint, node, sourceFile) {
            if (sourceFile) {
                setSourceFile(sourceFile);
            }
            pipelineEmit(hint, node);
        }
        function setSourceFile(sourceFile) {
            currentSourceFile = sourceFile;
            currentLineMap = undefined;
            detachedCommentsInfo = undefined;
            if (sourceFile) {
                setSourceMapSource(sourceFile);
            }
        }
        function setWriter(_writer, _sourceMapGenerator) {
            if (_writer && printerOptions.omitTrailingSemicolon) {
                _writer = ts.getTrailingSemicolonDeferringWriter(_writer);
            }
            writer = _writer; // TODO: GH#18217
            sourceMapGenerator = _sourceMapGenerator;
            sourceMapsDisabled = !writer || !sourceMapGenerator;
        }
        function reset() {
            nodeIdToGeneratedName = [];
            autoGeneratedIdToGeneratedName = [];
            generatedNames = ts.createMap();
            tempFlagsStack = [];
            tempFlags = 0 /* Auto */;
            reservedNamesStack = [];
            currentSourceFile = undefined;
            currentLineMap = undefined;
            detachedCommentsInfo = undefined;
            lastNode = undefined;
            lastSubstitution = undefined;
            setWriter(/*output*/ undefined, /*_sourceMapGenerator*/ undefined);
        }
        function getCurrentLineMap() {
            return currentLineMap || (currentLineMap = ts.getLineStarts(currentSourceFile));
        }
        function emit(node) {
            if (node === undefined)
                return;
            var prevSourceFileTextKind = recordBundleFileInternalSectionStart(node);
            var substitute = pipelineEmit(4 /* Unspecified */, node);
            recordBundleFileInternalSectionEnd(prevSourceFileTextKind);
            return substitute;
        }
        function emitIdentifierName(node) {
            if (node === undefined)
                return;
            return pipelineEmit(2 /* IdentifierName */, node);
        }
        function emitExpression(node) {
            if (node === undefined)
                return;
            return pipelineEmit(1 /* Expression */, node);
        }
        function emitJsxAttributeValue(node) {
            return pipelineEmit(ts.isStringLiteral(node) ? 6 /* JsxAttributeValue */ : 4 /* Unspecified */, node);
        }
        function pipelineEmit(emitHint, node) {
            var savedLastNode = lastNode;
            var savedLastSubstitution = lastSubstitution;
            var savedPreserveSourceNewlines = preserveSourceNewlines;
            lastNode = node;
            lastSubstitution = undefined;
            if (preserveSourceNewlines && !!(ts.getEmitFlags(node) & 134217728 /* IgnoreSourceNewlines */)) {
                preserveSourceNewlines = false;
            }
            var pipelinePhase = getPipelinePhase(0 /* Notification */, emitHint, node);
            pipelinePhase(emitHint, node);
            ts.Debug.assert(lastNode === node);
            var substitute = lastSubstitution;
            lastNode = savedLastNode;
            lastSubstitution = savedLastSubstitution;
            preserveSourceNewlines = savedPreserveSourceNewlines;
            return substitute || node;
        }
        function getPipelinePhase(phase, emitHint, node) {
            switch (phase) {
                case 0 /* Notification */:
                    if (onEmitNode !== ts.noEmitNotification && (!isEmitNotificationEnabled || isEmitNotificationEnabled(node))) {
                        return pipelineEmitWithNotification;
                    }
                // falls through
                case 1 /* Substitution */:
                    if (substituteNode !== ts.noEmitSubstitution && (lastSubstitution = substituteNode(emitHint, node)) !== node) {
                        return pipelineEmitWithSubstitution;
                    }
                // falls through
                case 2 /* Comments */:
                    if (!commentsDisabled && node.kind !== 290 /* SourceFile */) {
                        return pipelineEmitWithComments;
                    }
                // falls through
                case 3 /* SourceMaps */:
                    if (!sourceMapsDisabled && node.kind !== 290 /* SourceFile */ && !ts.isInJsonFile(node)) {
                        return pipelineEmitWithSourceMap;
                    }
                // falls through
                case 4 /* Emit */:
                    return pipelineEmitWithHint;
                default:
                    return ts.Debug.assertNever(phase);
            }
        }
        function getNextPipelinePhase(currentPhase, emitHint, node) {
            return getPipelinePhase(currentPhase + 1, emitHint, node);
        }
        function pipelineEmitWithNotification(hint, node) {
            ts.Debug.assert(lastNode === node);
            var pipelinePhase = getNextPipelinePhase(0 /* Notification */, hint, node);
            onEmitNode(hint, node, pipelinePhase);
            ts.Debug.assert(lastNode === node);
        }
        function pipelineEmitWithHint(hint, node) {
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
            if (hint === 0 /* SourceFile */)
                return emitSourceFile(ts.cast(node, ts.isSourceFile));
            if (hint === 2 /* IdentifierName */)
                return emitIdentifier(ts.cast(node, ts.isIdentifier));
            if (hint === 6 /* JsxAttributeValue */)
                return emitLiteral(ts.cast(node, ts.isStringLiteral), /*jsxAttributeEscape*/ true);
            if (hint === 3 /* MappedTypeParameter */)
                return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration));
            if (hint === 5 /* EmbeddedStatement */) {
                ts.Debug.assertNode(node, ts.isEmptyStatement);
                return emitEmptyStatement(/*isEmbeddedStatement*/ true);
            }
            if (hint === 4 /* Unspecified */) {
                if (ts.isKeyword(node.kind))
                    return writeTokenNode(node, writeKeyword);
                switch (node.kind) {
                    // Pseudo-literals
                    case 15 /* TemplateHead */:
                    case 16 /* TemplateMiddle */:
                    case 17 /* TemplateTail */:
                        return emitLiteral(node, /*jsxAttributeEscape*/ false);
                    case 292 /* UnparsedSource */:
                    case 286 /* UnparsedPrepend */:
                        return emitUnparsedSourceOrPrepend(node);
                    case 285 /* UnparsedPrologue */:
                        return writeUnparsedNode(node);
                    case 287 /* UnparsedText */:
                    case 288 /* UnparsedInternalText */:
                        return emitUnparsedTextLike(node);
                    case 289 /* UnparsedSyntheticReference */:
                        return emitUnparsedSyntheticReference(node);
                    // Identifiers
                    case 75 /* Identifier */:
                        return emitIdentifier(node);
                    // PrivateIdentifiers
                    case 76 /* PrivateIdentifier */:
                        return emitPrivateIdentifier(node);
                    // Parse tree nodes
                    // Names
                    case 153 /* QualifiedName */:
                        return emitQualifiedName(node);
                    case 154 /* ComputedPropertyName */:
                        return emitComputedPropertyName(node);
                    // Signature elements
                    case 155 /* TypeParameter */:
                        return emitTypeParameter(node);
                    case 156 /* Parameter */:
                        return emitParameter(node);
                    case 157 /* Decorator */:
                        return emitDecorator(node);
                    // Type members
                    case 158 /* PropertySignature */:
                        return emitPropertySignature(node);
                    case 159 /* PropertyDeclaration */:
                        return emitPropertyDeclaration(node);
                    case 160 /* MethodSignature */:
                        return emitMethodSignature(node);
                    case 161 /* MethodDeclaration */:
                        return emitMethodDeclaration(node);
                    case 162 /* Constructor */:
                        return emitConstructor(node);
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        return emitAccessorDeclaration(node);
                    case 165 /* CallSignature */:
                        return emitCallSignature(node);
                    case 166 /* ConstructSignature */:
                        return emitConstructSignature(node);
                    case 167 /* IndexSignature */:
                        return emitIndexSignature(node);
                    // Types
                    case 168 /* TypePredicate */:
                        return emitTypePredicate(node);
                    case 169 /* TypeReference */:
                        return emitTypeReference(node);
                    case 170 /* FunctionType */:
                        return emitFunctionType(node);
                    case 300 /* JSDocFunctionType */:
                        return emitJSDocFunctionType(node);
                    case 171 /* ConstructorType */:
                        return emitConstructorType(node);
                    case 172 /* TypeQuery */:
                        return emitTypeQuery(node);
                    case 173 /* TypeLiteral */:
                        return emitTypeLiteral(node);
                    case 174 /* ArrayType */:
                        return emitArrayType(node);
                    case 175 /* TupleType */:
                        return emitTupleType(node);
                    case 176 /* OptionalType */:
                        return emitOptionalType(node);
                    case 178 /* UnionType */:
                        return emitUnionType(node);
                    case 179 /* IntersectionType */:
                        return emitIntersectionType(node);
                    case 180 /* ConditionalType */:
                        return emitConditionalType(node);
                    case 181 /* InferType */:
                        return emitInferType(node);
                    case 182 /* ParenthesizedType */:
                        return emitParenthesizedType(node);
                    case 216 /* ExpressionWithTypeArguments */:
                        return emitExpressionWithTypeArguments(node);
                    case 183 /* ThisType */:
                        return emitThisType();
                    case 184 /* TypeOperator */:
                        return emitTypeOperator(node);
                    case 185 /* IndexedAccessType */:
                        return emitIndexedAccessType(node);
                    case 186 /* MappedType */:
                        return emitMappedType(node);
                    case 187 /* LiteralType */:
                        return emitLiteralType(node);
                    case 188 /* ImportType */:
                        return emitImportTypeNode(node);
                    case 295 /* JSDocAllType */:
                        writePunctuation("*");
                        return;
                    case 296 /* JSDocUnknownType */:
                        writePunctuation("?");
                        return;
                    case 297 /* JSDocNullableType */:
                        return emitJSDocNullableType(node);
                    case 298 /* JSDocNonNullableType */:
                        return emitJSDocNonNullableType(node);
                    case 299 /* JSDocOptionalType */:
                        return emitJSDocOptionalType(node);
                    case 177 /* RestType */:
                    case 301 /* JSDocVariadicType */:
                        return emitRestOrJSDocVariadicType(node);
                    // Binding patterns
                    case 189 /* ObjectBindingPattern */:
                        return emitObjectBindingPattern(node);
                    case 190 /* ArrayBindingPattern */:
                        return emitArrayBindingPattern(node);
                    case 191 /* BindingElement */:
                        return emitBindingElement(node);
                    // Misc
                    case 221 /* TemplateSpan */:
                        return emitTemplateSpan(node);
                    case 222 /* SemicolonClassElement */:
                        return emitSemicolonClassElement();
                    // Statements
                    case 223 /* Block */:
                        return emitBlock(node);
                    case 225 /* VariableStatement */:
                        return emitVariableStatement(node);
                    case 224 /* EmptyStatement */:
                        return emitEmptyStatement(/*isEmbeddedStatement*/ false);
                    case 226 /* ExpressionStatement */:
                        return emitExpressionStatement(node);
                    case 227 /* IfStatement */:
                        return emitIfStatement(node);
                    case 228 /* DoStatement */:
                        return emitDoStatement(node);
                    case 229 /* WhileStatement */:
                        return emitWhileStatement(node);
                    case 230 /* ForStatement */:
                        return emitForStatement(node);
                    case 231 /* ForInStatement */:
                        return emitForInStatement(node);
                    case 232 /* ForOfStatement */:
                        return emitForOfStatement(node);
                    case 233 /* ContinueStatement */:
                        return emitContinueStatement(node);
                    case 234 /* BreakStatement */:
                        return emitBreakStatement(node);
                    case 235 /* ReturnStatement */:
                        return emitReturnStatement(node);
                    case 236 /* WithStatement */:
                        return emitWithStatement(node);
                    case 237 /* SwitchStatement */:
                        return emitSwitchStatement(node);
                    case 238 /* LabeledStatement */:
                        return emitLabeledStatement(node);
                    case 239 /* ThrowStatement */:
                        return emitThrowStatement(node);
                    case 240 /* TryStatement */:
                        return emitTryStatement(node);
                    case 241 /* DebuggerStatement */:
                        return emitDebuggerStatement(node);
                    // Declarations
                    case 242 /* VariableDeclaration */:
                        return emitVariableDeclaration(node);
                    case 243 /* VariableDeclarationList */:
                        return emitVariableDeclarationList(node);
                    case 244 /* FunctionDeclaration */:
                        return emitFunctionDeclaration(node);
                    case 245 /* ClassDeclaration */:
                        return emitClassDeclaration(node);
                    case 246 /* InterfaceDeclaration */:
                        return emitInterfaceDeclaration(node);
                    case 247 /* TypeAliasDeclaration */:
                        return emitTypeAliasDeclaration(node);
                    case 248 /* EnumDeclaration */:
                        return emitEnumDeclaration(node);
                    case 249 /* ModuleDeclaration */:
                        return emitModuleDeclaration(node);
                    case 250 /* ModuleBlock */:
                        return emitModuleBlock(node);
                    case 251 /* CaseBlock */:
                        return emitCaseBlock(node);
                    case 252 /* NamespaceExportDeclaration */:
                        return emitNamespaceExportDeclaration(node);
                    case 253 /* ImportEqualsDeclaration */:
                        return emitImportEqualsDeclaration(node);
                    case 254 /* ImportDeclaration */:
                        return emitImportDeclaration(node);
                    case 255 /* ImportClause */:
                        return emitImportClause(node);
                    case 256 /* NamespaceImport */:
                        return emitNamespaceImport(node);
                    case 262 /* NamespaceExport */:
                        return emitNamespaceExport(node);
                    case 257 /* NamedImports */:
                        return emitNamedImports(node);
                    case 258 /* ImportSpecifier */:
                        return emitImportSpecifier(node);
                    case 259 /* ExportAssignment */:
                        return emitExportAssignment(node);
                    case 260 /* ExportDeclaration */:
                        return emitExportDeclaration(node);
                    case 261 /* NamedExports */:
                        return emitNamedExports(node);
                    case 263 /* ExportSpecifier */:
                        return emitExportSpecifier(node);
                    case 264 /* MissingDeclaration */:
                        return;
                    // Module references
                    case 265 /* ExternalModuleReference */:
                        return emitExternalModuleReference(node);
                    // JSX (non-expression)
                    case 11 /* JsxText */:
                        return emitJsxText(node);
                    case 268 /* JsxOpeningElement */:
                    case 271 /* JsxOpeningFragment */:
                        return emitJsxOpeningElementOrFragment(node);
                    case 269 /* JsxClosingElement */:
                    case 272 /* JsxClosingFragment */:
                        return emitJsxClosingElementOrFragment(node);
                    case 273 /* JsxAttribute */:
                        return emitJsxAttribute(node);
                    case 274 /* JsxAttributes */:
                        return emitJsxAttributes(node);
                    case 275 /* JsxSpreadAttribute */:
                        return emitJsxSpreadAttribute(node);
                    case 276 /* JsxExpression */:
                        return emitJsxExpression(node);
                    // Clauses
                    case 277 /* CaseClause */:
                        return emitCaseClause(node);
                    case 278 /* DefaultClause */:
                        return emitDefaultClause(node);
                    case 279 /* HeritageClause */:
                        return emitHeritageClause(node);
                    case 280 /* CatchClause */:
                        return emitCatchClause(node);
                    // Property assignments
                    case 281 /* PropertyAssignment */:
                        return emitPropertyAssignment(node);
                    case 282 /* ShorthandPropertyAssignment */:
                        return emitShorthandPropertyAssignment(node);
                    case 283 /* SpreadAssignment */:
                        return emitSpreadAssignment(node);
                    // Enum
                    case 284 /* EnumMember */:
                        return emitEnumMember(node);
                    // JSDoc nodes (only used in codefixes currently)
                    case 317 /* JSDocParameterTag */:
                    case 323 /* JSDocPropertyTag */:
                        return emitJSDocPropertyLikeTag(node);
                    case 318 /* JSDocReturnTag */:
                    case 320 /* JSDocTypeTag */:
                    case 319 /* JSDocThisTag */:
                    case 316 /* JSDocEnumTag */:
                        return emitJSDocSimpleTypedTag(node);
                    case 308 /* JSDocImplementsTag */:
                    case 307 /* JSDocAugmentsTag */:
                        return emitJSDocHeritageTag(node);
                    case 321 /* JSDocTemplateTag */:
                        return emitJSDocTemplateTag(node);
                    case 322 /* JSDocTypedefTag */:
                        return emitJSDocTypedefTag(node);
                    case 315 /* JSDocCallbackTag */:
                        return emitJSDocCallbackTag(node);
                    case 305 /* JSDocSignature */:
                        return emitJSDocSignature(node);
                    case 304 /* JSDocTypeLiteral */:
                        return emitJSDocTypeLiteral(node);
                    case 310 /* JSDocClassTag */:
                    case 306 /* JSDocTag */:
                        return emitJSDocSimpleTag(node);
                    case 303 /* JSDocComment */:
                        return emitJSDoc(node);
                    // Transformation nodes (ignored)
                }
                if (ts.isExpression(node)) {
                    hint = 1 /* Expression */;
                    if (substituteNode !== ts.noEmitSubstitution) {
                        lastSubstitution = node = substituteNode(hint, node);
                    }
                }
                else if (ts.isToken(node)) {
                    return writeTokenNode(node, writePunctuation);
                }
            }
            if (hint === 1 /* Expression */) {
                switch (node.kind) {
                    // Literals
                    case 8 /* NumericLiteral */:
                    case 9 /* BigIntLiteral */:
                        return emitNumericOrBigIntLiteral(node);
                    case 10 /* StringLiteral */:
                    case 13 /* RegularExpressionLiteral */:
                    case 14 /* NoSubstitutionTemplateLiteral */:
                        return emitLiteral(node, /*jsxAttributeEscape*/ false);
                    // Identifiers
                    case 75 /* Identifier */:
                        return emitIdentifier(node);
                    // Reserved words
                    case 91 /* FalseKeyword */:
                    case 100 /* NullKeyword */:
                    case 102 /* SuperKeyword */:
                    case 106 /* TrueKeyword */:
                    case 104 /* ThisKeyword */:
                    case 96 /* ImportKeyword */:
                        writeTokenNode(node, writeKeyword);
                        return;
                    // Expressions
                    case 192 /* ArrayLiteralExpression */:
                        return emitArrayLiteralExpression(node);
                    case 193 /* ObjectLiteralExpression */:
                        return emitObjectLiteralExpression(node);
                    case 194 /* PropertyAccessExpression */:
                        return emitPropertyAccessExpression(node);
                    case 195 /* ElementAccessExpression */:
                        return emitElementAccessExpression(node);
                    case 196 /* CallExpression */:
                        return emitCallExpression(node);
                    case 197 /* NewExpression */:
                        return emitNewExpression(node);
                    case 198 /* TaggedTemplateExpression */:
                        return emitTaggedTemplateExpression(node);
                    case 199 /* TypeAssertionExpression */:
                        return emitTypeAssertionExpression(node);
                    case 200 /* ParenthesizedExpression */:
                        return emitParenthesizedExpression(node);
                    case 201 /* FunctionExpression */:
                        return emitFunctionExpression(node);
                    case 202 /* ArrowFunction */:
                        return emitArrowFunction(node);
                    case 203 /* DeleteExpression */:
                        return emitDeleteExpression(node);
                    case 204 /* TypeOfExpression */:
                        return emitTypeOfExpression(node);
                    case 205 /* VoidExpression */:
                        return emitVoidExpression(node);
                    case 206 /* AwaitExpression */:
                        return emitAwaitExpression(node);
                    case 207 /* PrefixUnaryExpression */:
                        return emitPrefixUnaryExpression(node);
                    case 208 /* PostfixUnaryExpression */:
                        return emitPostfixUnaryExpression(node);
                    case 209 /* BinaryExpression */:
                        return emitBinaryExpression(node);
                    case 210 /* ConditionalExpression */:
                        return emitConditionalExpression(node);
                    case 211 /* TemplateExpression */:
                        return emitTemplateExpression(node);
                    case 212 /* YieldExpression */:
                        return emitYieldExpression(node);
                    case 213 /* SpreadElement */:
                        return emitSpreadExpression(node);
                    case 214 /* ClassExpression */:
                        return emitClassExpression(node);
                    case 215 /* OmittedExpression */:
                        return;
                    case 217 /* AsExpression */:
                        return emitAsExpression(node);
                    case 218 /* NonNullExpression */:
                        return emitNonNullExpression(node);
                    case 219 /* MetaProperty */:
                        return emitMetaProperty(node);
                    // JSX
                    case 266 /* JsxElement */:
                        return emitJsxElement(node);
                    case 267 /* JsxSelfClosingElement */:
                        return emitJsxSelfClosingElement(node);
                    case 270 /* JsxFragment */:
                        return emitJsxFragment(node);
                    // Transformation nodes
                    case 326 /* PartiallyEmittedExpression */:
                        return emitPartiallyEmittedExpression(node);
                    case 327 /* CommaListExpression */:
                        return emitCommaList(node);
                }
            }
        }
        function emitMappedTypeParameter(node) {
            emit(node.name);
            writeSpace();
            writeKeyword("in");
            writeSpace();
            emit(node.constraint);
        }
        function pipelineEmitWithSubstitution(hint, node) {
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
            var pipelinePhase = getNextPipelinePhase(1 /* Substitution */, hint, node);
            pipelinePhase(hint, lastSubstitution);
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
        }
        function getHelpersFromBundledSourceFiles(bundle) {
            var result;
            if (moduleKind === ts.ModuleKind.None || printerOptions.noEmitHelpers) {
                return undefined;
            }
            var bundledHelpers = ts.createMap();
            for (var _a = 0, _b = bundle.sourceFiles; _a < _b.length; _a++) {
                var sourceFile = _b[_a];
                var shouldSkip = ts.getExternalHelpersModuleName(sourceFile) !== undefined;
                var helpers = getSortedEmitHelpers(sourceFile);
                if (!helpers)
                    continue;
                for (var _c = 0, helpers_4 = helpers; _c < helpers_4.length; _c++) {
                    var helper = helpers_4[_c];
                    if (!helper.scoped && !shouldSkip && !bundledHelpers.get(helper.name)) {
                        bundledHelpers.set(helper.name, true);
                        (result || (result = [])).push(helper.name);
                    }
                }
            }
            return result;
        }
        function emitHelpers(node) {
            var helpersEmitted = false;
            var bundle = node.kind === 291 /* Bundle */ ? node : undefined;
            if (bundle && moduleKind === ts.ModuleKind.None) {
                return;
            }
            var numPrepends = bundle ? bundle.prepends.length : 0;
            var numNodes = bundle ? bundle.sourceFiles.length + numPrepends : 1;
            for (var i = 0; i < numNodes; i++) {
                var currentNode = bundle ? i < numPrepends ? bundle.prepends[i] : bundle.sourceFiles[i - numPrepends] : node;
                var sourceFile = ts.isSourceFile(currentNode) ? currentNode : ts.isUnparsedSource(currentNode) ? undefined : currentSourceFile;
                var shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && ts.hasRecordedExternalHelpers(sourceFile));
                var shouldBundle = (ts.isSourceFile(currentNode) || ts.isUnparsedSource(currentNode)) && !isOwnFileEmit;
                var helpers = ts.isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode);
                if (helpers) {
                    for (var _a = 0, helpers_5 = helpers; _a < helpers_5.length; _a++) {
                        var helper = helpers_5[_a];
                        if (!helper.scoped) {
                            // Skip the helper if it can be skipped and the noEmitHelpers compiler
                            // option is set, or if it can be imported and the importHelpers compiler
                            // option is set.
                            if (shouldSkip)
                                continue;
                            // Skip the helper if it can be bundled but hasn't already been emitted and we
                            // are emitting a bundled module.
                            if (shouldBundle) {
                                if (bundledHelpers.get(helper.name)) {
                                    continue;
                                }
                                bundledHelpers.set(helper.name, true);
                            }
                        }
                        else if (bundle) {
                            // Skip the helper if it is scoped and we are emitting bundled helpers
                            continue;
                        }
                        var pos = getTextPosWithWriteLine();
                        if (typeof helper.text === "string") {
                            writeLines(helper.text);
                        }
                        else {
                            writeLines(helper.text(makeFileLevelOptimisticUniqueName));
                        }
                        if (bundleFileInfo)
                            bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "emitHelpers" /* EmitHelpers */, data: helper.name });
                        helpersEmitted = true;
                    }
                }
            }
            return helpersEmitted;
        }
        function getSortedEmitHelpers(node) {
            var helpers = ts.getEmitHelpers(node);
            return helpers && ts.stableSort(helpers, ts.compareEmitHelpers);
        }
        //
        // Literals/Pseudo-literals
        //
        // SyntaxKind.NumericLiteral
        // SyntaxKind.BigIntLiteral
        function emitNumericOrBigIntLiteral(node) {
            emitLiteral(node, /*jsxAttributeEscape*/ false);
        }
        // SyntaxKind.StringLiteral
        // SyntaxKind.RegularExpressionLiteral
        // SyntaxKind.NoSubstitutionTemplateLiteral
        // SyntaxKind.TemplateHead
        // SyntaxKind.TemplateMiddle
        // SyntaxKind.TemplateTail
        function emitLiteral(node, jsxAttributeEscape) {
            var text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape, jsxAttributeEscape);
            if ((printerOptions.sourceMap || printerOptions.inlineSourceMap)
                && (node.kind === 10 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) {
                writeLiteral(text);
            }
            else {
                // Quick info expects all literals to be called with writeStringLiteral, as there's no specific type for numberLiterals
                writeStringLiteral(text);
            }
        }
        // SyntaxKind.UnparsedSource
        // SyntaxKind.UnparsedPrepend
        function emitUnparsedSourceOrPrepend(unparsed) {
            for (var _a = 0, _b = unparsed.texts; _a < _b.length; _a++) {
                var text = _b[_a];
                writeLine();
                emit(text);
            }
        }
        // SyntaxKind.UnparsedPrologue
        // SyntaxKind.UnparsedText
        // SyntaxKind.UnparsedInternal
        // SyntaxKind.UnparsedSyntheticReference
        function writeUnparsedNode(unparsed) {
            writer.rawWrite(unparsed.parent.text.substring(unparsed.pos, unparsed.end));
        }
        // SyntaxKind.UnparsedText
        // SyntaxKind.UnparsedInternal
        function emitUnparsedTextLike(unparsed) {
            var pos = getTextPosWithWriteLine();
            writeUnparsedNode(unparsed);
            if (bundleFileInfo) {
                updateOrPushBundleFileTextLike(pos, writer.getTextPos(), unparsed.kind === 287 /* UnparsedText */ ?
                    "text" /* Text */ :
                    "internal" /* Internal */);
            }
        }
        // SyntaxKind.UnparsedSyntheticReference
        function emitUnparsedSyntheticReference(unparsed) {
            var pos = getTextPosWithWriteLine();
            writeUnparsedNode(unparsed);
            if (bundleFileInfo) {
                var section = ts.clone(unparsed.section);
                section.pos = pos;
                section.end = writer.getTextPos();
                bundleFileInfo.sections.push(section);
            }
        }
        //
        // Identifiers
        //
        function emitIdentifier(node) {
            var writeText = node.symbol ? writeSymbol : write;
            writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol);
            emitList(node, node.typeArguments, 53776 /* TypeParameters */); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments
        }
        //
        // Names
        //
        function emitPrivateIdentifier(node) {
            var writeText = node.symbol ? writeSymbol : write;
            writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol);
        }
        function emitQualifiedName(node) {
            emitEntityName(node.left);
            writePunctuation(".");
            emit(node.right);
        }
        function emitEntityName(node) {
            if (node.kind === 75 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        function emitComputedPropertyName(node) {
            writePunctuation("[");
            emitExpression(node.expression);
            writePunctuation("]");
        }
        //
        // Signature elements
        //
        function emitTypeParameter(node) {
            emit(node.name);
            if (node.constraint) {
                writeSpace();
                writeKeyword("extends");
                writeSpace();
                emit(node.constraint);
            }
            if (node.default) {
                writeSpace();
                writeOperator("=");
                writeSpace();
                emit(node.default);
            }
        }
        function emitParameter(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.dotDotDotToken);
            emitNodeWithWriter(node.name, writeParameter);
            emit(node.questionToken);
            if (node.parent && node.parent.kind === 300 /* JSDocFunctionType */ && !node.name) {
                emit(node.type);
            }
            else {
                emitTypeAnnotation(node.type);
            }
            // The comment position has to fallback to any present node within the parameterdeclaration because as it turns out, the parser can make parameter declarations with _just_ an initializer.
            emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name ? node.name.end : node.modifiers ? node.modifiers.end : node.decorators ? node.decorators.end : node.pos, node);
        }
        function emitDecorator(decorator) {
            writePunctuation("@");
            emitExpression(decorator.expression);
        }
        //
        // Type members
        //
        function emitPropertySignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitNodeWithWriter(node.name, writeProperty);
            emit(node.questionToken);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
        }
        function emitPropertyDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emit(node.questionToken);
            emit(node.exclamationToken);
            emitTypeAnnotation(node.type);
            emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name.end, node);
            writeTrailingSemicolon();
        }
        function emitMethodSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emit(node.questionToken);
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitMethodDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.asteriskToken);
            emit(node.name);
            emit(node.questionToken);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitConstructor(node) {
            emitModifiers(node, node.modifiers);
            writeKeyword("constructor");
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitAccessorDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword(node.kind === 163 /* GetAccessor */ ? "get" : "set");
            writeSpace();
            emit(node.name);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitCallSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitConstructSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("new");
            writeSpace();
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitIndexSignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitParametersForIndexSignature(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
        }
        function emitSemicolonClassElement() {
            writeTrailingSemicolon();
        }
        //
        // Types
        //
        function emitTypePredicate(node) {
            if (node.assertsModifier) {
                emit(node.assertsModifier);
                writeSpace();
            }
            emit(node.parameterName);
            if (node.type) {
                writeSpace();
                writeKeyword("is");
                writeSpace();
                emit(node.type);
            }
        }
        function emitTypeReference(node) {
            emit(node.typeName);
            emitTypeArguments(node, node.typeArguments);
        }
        function emitFunctionType(node) {
            pushNameGenerationScope(node);
            emitTypeParameters(node, node.typeParameters);
            emitParametersForArrow(node, node.parameters);
            writeSpace();
            writePunctuation("=>");
            writeSpace();
            emit(node.type);
            popNameGenerationScope(node);
        }
        function emitJSDocFunctionType(node) {
            writeKeyword("function");
            emitParameters(node, node.parameters);
            writePunctuation(":");
            emit(node.type);
        }
        function emitJSDocNullableType(node) {
            writePunctuation("?");
            emit(node.type);
        }
        function emitJSDocNonNullableType(node) {
            writePunctuation("!");
            emit(node.type);
        }
        function emitJSDocOptionalType(node) {
            emit(node.type);
            writePunctuation("=");
        }
        function emitConstructorType(node) {
            pushNameGenerationScope(node);
            writeKeyword("new");
            writeSpace();
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            writeSpace();
            writePunctuation("=>");
            writeSpace();
            emit(node.type);
            popNameGenerationScope(node);
        }
        function emitTypeQuery(node) {
            writeKeyword("typeof");
            writeSpace();
            emit(node.exprName);
        }
        function emitTypeLiteral(node) {
            writePunctuation("{");
            var flags = ts.getEmitFlags(node) & 1 /* SingleLine */ ? 768 /* SingleLineTypeLiteralMembers */ : 32897 /* MultiLineTypeLiteralMembers */;
            emitList(node, node.members, flags | 524288 /* NoSpaceIfEmpty */);
            writePunctuation("}");
        }
        function emitArrayType(node) {
            emit(node.elementType);
            writePunctuation("[");
            writePunctuation("]");
        }
        function emitRestOrJSDocVariadicType(node) {
            writePunctuation("...");
            emit(node.type);
        }
        function emitTupleType(node) {
            writePunctuation("[");
            emitList(node, node.elementTypes, 528 /* TupleTypeElements */);
            writePunctuation("]");
        }
        function emitOptionalType(node) {
            emit(node.type);
            writePunctuation("?");
        }
        function emitUnionType(node) {
            emitList(node, node.types, 516 /* UnionTypeConstituents */);
        }
        function emitIntersectionType(node) {
            emitList(node, node.types, 520 /* IntersectionTypeConstituents */);
        }
        function emitConditionalType(node) {
            emit(node.checkType);
            writeSpace();
            writeKeyword("extends");
            writeSpace();
            emit(node.extendsType);
            writeSpace();
            writePunctuation("?");
            writeSpace();
            emit(node.trueType);
            writeSpace();
            writePunctuation(":");
            writeSpace();
            emit(node.falseType);
        }
        function emitInferType(node) {
            writeKeyword("infer");
            writeSpace();
            emit(node.typeParameter);
        }
        function emitParenthesizedType(node) {
            writePunctuation("(");
            emit(node.type);
            writePunctuation(")");
        }
        function emitThisType() {
            writeKeyword("this");
        }
        function emitTypeOperator(node) {
            writeTokenText(node.operator, writeKeyword);
            writeSpace();
            emit(node.type);
        }
        function emitIndexedAccessType(node) {
            emit(node.objectType);
            writePunctuation("[");
            emit(node.indexType);
            writePunctuation("]");
        }
        function emitMappedType(node) {
            var emitFlags = ts.getEmitFlags(node);
            writePunctuation("{");
            if (emitFlags & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
                increaseIndent();
            }
            if (node.readonlyToken) {
                emit(node.readonlyToken);
                if (node.readonlyToken.kind !== 138 /* ReadonlyKeyword */) {
                    writeKeyword("readonly");
                }
                writeSpace();
            }
            writePunctuation("[");
            pipelineEmit(3 /* MappedTypeParameter */, node.typeParameter);
            writePunctuation("]");
            if (node.questionToken) {
                emit(node.questionToken);
                if (node.questionToken.kind !== 57 /* QuestionToken */) {
                    writePunctuation("?");
                }
            }
            writePunctuation(":");
            writeSpace();
            emit(node.type);
            writeTrailingSemicolon();
            if (emitFlags & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
                decreaseIndent();
            }
            writePunctuation("}");
        }
        function emitLiteralType(node) {
            emitExpression(node.literal);
        }
        function emitImportTypeNode(node) {
            if (node.isTypeOf) {
                writeKeyword("typeof");
                writeSpace();
            }
            writeKeyword("import");
            writePunctuation("(");
            emit(node.argument);
            writePunctuation(")");
            if (node.qualifier) {
                writePunctuation(".");
                emit(node.qualifier);
            }
            emitTypeArguments(node, node.typeArguments);
        }
        //
        // Binding patterns
        //
        function emitObjectBindingPattern(node) {
            writePunctuation("{");
            emitList(node, node.elements, 525136 /* ObjectBindingPatternElements */);
            writePunctuation("}");
        }
        function emitArrayBindingPattern(node) {
            writePunctuation("[");
            emitList(node, node.elements, 524880 /* ArrayBindingPatternElements */);
            writePunctuation("]");
        }
        function emitBindingElement(node) {
            emit(node.dotDotDotToken);
            if (node.propertyName) {
                emit(node.propertyName);
                writePunctuation(":");
                writeSpace();
            }
            emit(node.name);
            emitInitializer(node.initializer, node.name.end, node);
        }
        //
        // Expressions
        //
        function emitArrayLiteralExpression(node) {
            var elements = node.elements;
            var preferNewLine = node.multiLine ? 65536 /* PreferNewLine */ : 0 /* None */;
            emitExpressionList(node, elements, 8914 /* ArrayLiteralExpressionElements */ | preferNewLine);
        }
        function emitObjectLiteralExpression(node) {
            ts.forEach(node.properties, generateMemberNames);
            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
            if (indentedFlag) {
                increaseIndent();
            }
            var preferNewLine = node.multiLine ? 65536 /* PreferNewLine */ : 0 /* None */;
            var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ && !ts.isJsonSourceFile(currentSourceFile) ? 64 /* AllowTrailingComma */ : 0 /* None */;
            emitList(node, node.properties, 526226 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine);
            if (indentedFlag) {
                decreaseIndent();
            }
        }
        function emitPropertyAccessExpression(node) {
            var expression = ts.cast(emitExpression(node.expression), ts.isExpression);
            var token = node.questionDotToken || ts.createNode(24 /* DotToken */, node.expression.end, node.name.pos);
            var linesBeforeDot = getLinesBetweenNodes(node, node.expression, token);
            var linesAfterDot = getLinesBetweenNodes(node, token, node.name);
            writeLinesAndIndent(linesBeforeDot, /*writeSpaceIfNotIndenting*/ false);
            var shouldEmitDotDot = token.kind !== 28 /* QuestionDotToken */ &&
                mayNeedDotDotForPropertyAccess(expression) &&
                !writer.hasTrailingComment() &&
                !writer.hasTrailingWhitespace();
            if (shouldEmitDotDot) {
                writePunctuation(".");
            }
            if (node.questionDotToken) {
                emit(token);
            }
            else {
                emitTokenWithComment(token.kind, node.expression.end, writePunctuation, node);
            }
            writeLinesAndIndent(linesAfterDot, /*writeSpaceIfNotIndenting*/ false);
            emit(node.name);
            decreaseIndentIf(linesBeforeDot, linesAfterDot);
        }
        // 1..toString is a valid property access, emit a dot after the literal
        // Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
        function mayNeedDotDotForPropertyAccess(expression) {
            expression = ts.skipPartiallyEmittedExpressions(expression);
            if (ts.isNumericLiteral(expression)) {
                // check if numeric literal is a decimal literal that was originally written with a dot
                var text = getLiteralTextOfNode(expression, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false);
                // If he number will be printed verbatim and it doesn't already contain a dot, add one
                // if the expression doesn't have any comments that will be emitted.
                return !expression.numericLiteralFlags && !ts.stringContains(text, ts.tokenToString(24 /* DotToken */));
            }
            else if (ts.isAccessExpression(expression)) {
                // check if constant enum value is integer
                var constantValue = ts.getConstantValue(expression);
                // isFinite handles cases when constantValue is undefined
                return typeof constantValue === "number" && isFinite(constantValue)
                    && Math.floor(constantValue) === constantValue;
            }
        }
        function emitElementAccessExpression(node) {
            emitExpression(node.expression);
            emit(node.questionDotToken);
            emitTokenWithComment(22 /* OpenBracketToken */, node.expression.end, writePunctuation, node);
            emitExpression(node.argumentExpression);
            emitTokenWithComment(23 /* CloseBracketToken */, node.argumentExpression.end, writePunctuation, node);
        }
        function emitCallExpression(node) {
            emitExpression(node.expression);
            emit(node.questionDotToken);
            emitTypeArguments(node, node.typeArguments);
            emitExpressionList(node, node.arguments, 2576 /* CallExpressionArguments */);
        }
        function emitNewExpression(node) {
            emitTokenWithComment(99 /* NewKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
            emitExpressionList(node, node.arguments, 18960 /* NewExpressionArguments */);
        }
        function emitTaggedTemplateExpression(node) {
            emitExpression(node.tag);
            emitTypeArguments(node, node.typeArguments);
            writeSpace();
            emitExpression(node.template);
        }
        function emitTypeAssertionExpression(node) {
            writePunctuation("<");
            emit(node.type);
            writePunctuation(">");
            emitExpression(node.expression);
        }
        function emitParenthesizedExpression(node) {
            var openParenPos = emitTokenWithComment(20 /* OpenParenToken */, node.pos, writePunctuation, node);
            var indented = writeLineSeparatorsAndIndentBefore(node.expression, node);
            emitExpression(node.expression);
            writeLineSeparatorsAfter(node.expression, node);
            decreaseIndentIf(indented);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression ? node.expression.end : openParenPos, writePunctuation, node);
        }
        function emitFunctionExpression(node) {
            generateNameIfNeeded(node.name);
            emitFunctionDeclarationOrExpression(node);
        }
        function emitArrowFunction(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitSignatureAndBody(node, emitArrowFunctionHead);
        }
        function emitArrowFunctionHead(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParametersForArrow(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeSpace();
            emit(node.equalsGreaterThanToken);
        }
        function emitDeleteExpression(node) {
            emitTokenWithComment(85 /* DeleteKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitTypeOfExpression(node) {
            emitTokenWithComment(108 /* TypeOfKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitVoidExpression(node) {
            emitTokenWithComment(110 /* VoidKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitAwaitExpression(node) {
            emitTokenWithComment(127 /* AwaitKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitPrefixUnaryExpression(node) {
            writeTokenText(node.operator, writeOperator);
            if (shouldEmitWhitespaceBeforeOperand(node)) {
                writeSpace();
            }
            emitExpression(node.operand);
        }
        function shouldEmitWhitespaceBeforeOperand(node) {
            // In some cases, we need to emit a space between the operator and the operand. One obvious case
            // is when the operator is an identifier, like delete or typeof. We also need to do this for plus
            // and minus expressions in certain cases. Specifically, consider the following two cases (parens
            // are just for clarity of exposition, and not part of the source code):
            //
            //  (+(+1))
            //  (+(++1))
            //
            // We need to emit a space in both cases. In the first case, the absence of a space will make
            // the resulting expression a prefix increment operation. And in the second, it will make the resulting
            // expression a prefix increment whose operand is a plus expression - (++(+x))
            // The same is true of minus of course.
            var operand = node.operand;
            return operand.kind === 207 /* PrefixUnaryExpression */
                && ((node.operator === 39 /* PlusToken */ && (operand.operator === 39 /* PlusToken */ || operand.operator === 45 /* PlusPlusToken */))
                    || (node.operator === 40 /* MinusToken */ && (operand.operator === 40 /* MinusToken */ || operand.operator === 46 /* MinusMinusToken */)));
        }
        function emitPostfixUnaryExpression(node) {
            emitExpression(node.operand);
            writeTokenText(node.operator, writeOperator);
        }
        var EmitBinaryExpressionState;
        (function (EmitBinaryExpressionState) {
            EmitBinaryExpressionState[EmitBinaryExpressionState["EmitLeft"] = 0] = "EmitLeft";
            EmitBinaryExpressionState[EmitBinaryExpressionState["EmitRight"] = 1] = "EmitRight";
            EmitBinaryExpressionState[EmitBinaryExpressionState["FinishEmit"] = 2] = "FinishEmit";
        })(EmitBinaryExpressionState || (EmitBinaryExpressionState = {}));
        /**
         * emitBinaryExpression includes an embedded work stack to attempt to handle as many nested binary expressions
         * as possible without creating any additional stack frames. This can only be done when the emit pipeline does
         * not require notification/substitution/comment/sourcemap decorations.
         */
        function emitBinaryExpression(node) {
            var nodeStack = [node];
            var stateStack = [0 /* EmitLeft */];
            var stackIndex = 0;
            while (stackIndex >= 0) {
                node = nodeStack[stackIndex];
                switch (stateStack[stackIndex]) {
                    case 0 /* EmitLeft */: {
                        maybePipelineEmitExpression(node.left);
                        break;
                    }
                    case 1 /* EmitRight */: {
                        var isCommaOperator = node.operatorToken.kind !== 27 /* CommaToken */;
                        var linesBeforeOperator = getLinesBetweenNodes(node, node.left, node.operatorToken);
                        var linesAfterOperator = getLinesBetweenNodes(node, node.operatorToken, node.right);
                        writeLinesAndIndent(linesBeforeOperator, isCommaOperator);
                        emitLeadingCommentsOfPosition(node.operatorToken.pos);
                        writeTokenNode(node.operatorToken, node.operatorToken.kind === 97 /* InKeyword */ ? writeKeyword : writeOperator);
                        emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts
                        writeLinesAndIndent(linesAfterOperator, /*writeSpaceIfNotIndenting*/ true);
                        maybePipelineEmitExpression(node.right);
                        break;
                    }
                    case 2 /* FinishEmit */: {
                        var linesBeforeOperator = getLinesBetweenNodes(node, node.left, node.operatorToken);
                        var linesAfterOperator = getLinesBetweenNodes(node, node.operatorToken, node.right);
                        decreaseIndentIf(linesBeforeOperator, linesAfterOperator);
                        stackIndex--;
                        break;
                    }
                    default: return ts.Debug.fail("Invalid state " + stateStack[stackIndex] + " for emitBinaryExpressionWorker");
                }
            }
            function maybePipelineEmitExpression(next) {
                // Advance the state of this unit of work,
                stateStack[stackIndex]++;
                // Then actually do the work of emitting the node `next` returned by the prior state
                // The following section should be identical to `pipelineEmit` save it assumes EmitHint.Expression and offloads
                // binary expression handling, where possible, to the contained work queue
                // #region trampolinePipelineEmit
                var savedLastNode = lastNode;
                var savedLastSubstitution = lastSubstitution;
                lastNode = next;
                lastSubstitution = undefined;
                var pipelinePhase = getPipelinePhase(0 /* Notification */, 1 /* Expression */, next);
                if (pipelinePhase === pipelineEmitWithHint && ts.isBinaryExpression(next)) {
                    // If the target pipeline phase is emit directly, and the next node's also a binary expression,
                    // skip all the intermediate indirection and push the expression directly onto the work stack
                    stackIndex++;
                    stateStack[stackIndex] = 0 /* EmitLeft */;
                    nodeStack[stackIndex] = next;
                }
                else {
                    pipelinePhase(1 /* Expression */, next);
                }
                ts.Debug.assert(lastNode === next);
                lastNode = savedLastNode;
                lastSubstitution = savedLastSubstitution;
                // #endregion trampolinePipelineEmit
            }
        }
        function emitConditionalExpression(node) {
            var linesBeforeQuestion = getLinesBetweenNodes(node, node.condition, node.questionToken);
            var linesAfterQuestion = getLinesBetweenNodes(node, node.questionToken, node.whenTrue);
            var linesBeforeColon = getLinesBetweenNodes(node, node.whenTrue, node.colonToken);
            var linesAfterColon = getLinesBetweenNodes(node, node.colonToken, node.whenFalse);
            emitExpression(node.condition);
            writeLinesAndIndent(linesBeforeQuestion, /*writeSpaceIfNotIndenting*/ true);
            emit(node.questionToken);
            writeLinesAndIndent(linesAfterQuestion, /*writeSpaceIfNotIndenting*/ true);
            emitExpression(node.whenTrue);
            decreaseIndentIf(linesBeforeQuestion, linesAfterQuestion);
            writeLinesAndIndent(linesBeforeColon, /*writeSpaceIfNotIndenting*/ true);
            emit(node.colonToken);
            writeLinesAndIndent(linesAfterColon, /*writeSpaceIfNotIndenting*/ true);
            emitExpression(node.whenFalse);
            decreaseIndentIf(linesBeforeColon, linesAfterColon);
        }
        function emitTemplateExpression(node) {
            emit(node.head);
            emitList(node, node.templateSpans, 262144 /* TemplateExpressionSpans */);
        }
        function emitYieldExpression(node) {
            emitTokenWithComment(121 /* YieldKeyword */, node.pos, writeKeyword, node);
            emit(node.asteriskToken);
            emitExpressionWithLeadingSpace(node.expression);
        }
        function emitSpreadExpression(node) {
            emitTokenWithComment(25 /* DotDotDotToken */, node.pos, writePunctuation, node);
            emitExpression(node.expression);
        }
        function emitClassExpression(node) {
            generateNameIfNeeded(node.name);
            emitClassDeclarationOrExpression(node);
        }
        function emitExpressionWithTypeArguments(node) {
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
        }
        function emitAsExpression(node) {
            emitExpression(node.expression);
            if (node.type) {
                writeSpace();
                writeKeyword("as");
                writeSpace();
                emit(node.type);
            }
        }
        function emitNonNullExpression(node) {
            emitExpression(node.expression);
            writeOperator("!");
        }
        function emitMetaProperty(node) {
            writeToken(node.keywordToken, node.pos, writePunctuation);
            writePunctuation(".");
            emit(node.name);
        }
        //
        // Misc
        //
        function emitTemplateSpan(node) {
            emitExpression(node.expression);
            emit(node.literal);
        }
        //
        // Statements
        //
        function emitBlock(node) {
            emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node));
        }
        function emitBlockStatements(node, forceSingleLine) {
            emitTokenWithComment(18 /* OpenBraceToken */, node.pos, writePunctuation, /*contextNode*/ node);
            var format = forceSingleLine || ts.getEmitFlags(node) & 1 /* SingleLine */ ? 768 /* SingleLineBlockStatements */ : 129 /* MultiLineBlockStatements */;
            emitList(node, node.statements, format);
            emitTokenWithComment(19 /* CloseBraceToken */, node.statements.end, writePunctuation, /*contextNode*/ node, /*indentLeading*/ !!(format & 1 /* MultiLine */));
        }
        function emitVariableStatement(node) {
            emitModifiers(node, node.modifiers);
            emit(node.declarationList);
            writeTrailingSemicolon();
        }
        function emitEmptyStatement(isEmbeddedStatement) {
            // While most trailing semicolons are possibly insignificant, an embedded "empty"
            // statement is significant and cannot be elided by a trailing-semicolon-omitting writer.
            if (isEmbeddedStatement) {
                writePunctuation(";");
            }
            else {
                writeTrailingSemicolon();
            }
        }
        function emitExpressionStatement(node) {
            emitExpression(node.expression);
            // Emit semicolon in non json files
            // or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation)
            if (!ts.isJsonSourceFile(currentSourceFile) || ts.nodeIsSynthesized(node.expression)) {
                writeTrailingSemicolon();
            }
        }
        function emitIfStatement(node) {
            var openParenPos = emitTokenWithComment(95 /* IfKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.thenStatement);
            if (node.elseStatement) {
                writeLineOrSpace(node);
                emitTokenWithComment(87 /* ElseKeyword */, node.thenStatement.end, writeKeyword, node);
                if (node.elseStatement.kind === 227 /* IfStatement */) {
                    writeSpace();
                    emit(node.elseStatement);
                }
                else {
                    emitEmbeddedStatement(node, node.elseStatement);
                }
            }
        }
        function emitWhileClause(node, startPos) {
            var openParenPos = emitTokenWithComment(111 /* WhileKeyword */, startPos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
        }
        function emitDoStatement(node) {
            emitTokenWithComment(86 /* DoKeyword */, node.pos, writeKeyword, node);
            emitEmbeddedStatement(node, node.statement);
            if (ts.isBlock(node.statement)) {
                writeSpace();
            }
            else {
                writeLineOrSpace(node);
            }
            emitWhileClause(node, node.statement.end);
            writeTrailingSemicolon();
        }
        function emitWhileStatement(node) {
            emitWhileClause(node, node.pos);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForStatement(node) {
            var openParenPos = emitTokenWithComment(93 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            var pos = emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, /*contextNode*/ node);
            emitForBinding(node.initializer);
            pos = emitTokenWithComment(26 /* SemicolonToken */, node.initializer ? node.initializer.end : pos, writePunctuation, node);
            emitExpressionWithLeadingSpace(node.condition);
            pos = emitTokenWithComment(26 /* SemicolonToken */, node.condition ? node.condition.end : pos, writePunctuation, node);
            emitExpressionWithLeadingSpace(node.incrementor);
            emitTokenWithComment(21 /* CloseParenToken */, node.incrementor ? node.incrementor.end : pos, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForInStatement(node) {
            var openParenPos = emitTokenWithComment(93 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitForBinding(node.initializer);
            writeSpace();
            emitTokenWithComment(97 /* InKeyword */, node.initializer.end, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForOfStatement(node) {
            var openParenPos = emitTokenWithComment(93 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitWithTrailingSpace(node.awaitModifier);
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitForBinding(node.initializer);
            writeSpace();
            emitTokenWithComment(152 /* OfKeyword */, node.initializer.end, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForBinding(node) {
            if (node !== undefined) {
                if (node.kind === 243 /* VariableDeclarationList */) {
                    emit(node);
                }
                else {
                    emitExpression(node);
                }
            }
        }
        function emitContinueStatement(node) {
            emitTokenWithComment(82 /* ContinueKeyword */, node.pos, writeKeyword, node);
            emitWithLeadingSpace(node.label);
            writeTrailingSemicolon();
        }
        function emitBreakStatement(node) {
            emitTokenWithComment(77 /* BreakKeyword */, node.pos, writeKeyword, node);
            emitWithLeadingSpace(node.label);
            writeTrailingSemicolon();
        }
        function emitTokenWithComment(token, pos, writer, contextNode, indentLeading) {
            var node = ts.getParseTreeNode(contextNode);
            var isSimilarNode = node && node.kind === contextNode.kind;
            var startPos = pos;
            if (isSimilarNode && currentSourceFile) {
                pos = ts.skipTrivia(currentSourceFile.text, pos);
            }
            if (emitLeadingCommentsOfPosition && isSimilarNode && contextNode.pos !== startPos) {
                var needsIndent = indentLeading && currentSourceFile && !ts.positionsAreOnSameLine(startPos, pos, currentSourceFile);
                if (needsIndent) {
                    increaseIndent();
                }
                emitLeadingCommentsOfPosition(startPos);
                if (needsIndent) {
                    decreaseIndent();
                }
            }
            pos = writeTokenText(token, writer, pos);
            if (emitTrailingCommentsOfPosition && isSimilarNode && contextNode.end !== pos) {
                emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true);
            }
            return pos;
        }
        function emitReturnStatement(node) {
            emitTokenWithComment(101 /* ReturnKeyword */, node.pos, writeKeyword, /*contextNode*/ node);
            emitExpressionWithLeadingSpace(node.expression);
            writeTrailingSemicolon();
        }
        function emitWithStatement(node) {
            var openParenPos = emitTokenWithComment(112 /* WithKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitSwitchStatement(node) {
            var openParenPos = emitTokenWithComment(103 /* SwitchKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            writeSpace();
            emit(node.caseBlock);
        }
        function emitLabeledStatement(node) {
            emit(node.label);
            emitTokenWithComment(58 /* ColonToken */, node.label.end, writePunctuation, node);
            writeSpace();
            emit(node.statement);
        }
        function emitThrowStatement(node) {
            emitTokenWithComment(105 /* ThrowKeyword */, node.pos, writeKeyword, node);
            emitExpressionWithLeadingSpace(node.expression);
            writeTrailingSemicolon();
        }
        function emitTryStatement(node) {
            emitTokenWithComment(107 /* TryKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emit(node.tryBlock);
            if (node.catchClause) {
                writeLineOrSpace(node);
                emit(node.catchClause);
            }
            if (node.finallyBlock) {
                writeLineOrSpace(node);
                emitTokenWithComment(92 /* FinallyKeyword */, (node.catchClause || node.tryBlock).end, writeKeyword, node);
                writeSpace();
                emit(node.finallyBlock);
            }
        }
        function emitDebuggerStatement(node) {
            writeToken(83 /* DebuggerKeyword */, node.pos, writeKeyword);
            writeTrailingSemicolon();
        }
        //
        // Declarations
        //
        function emitVariableDeclaration(node) {
            emit(node.name);
            emit(node.exclamationToken);
            emitTypeAnnotation(node.type);
            emitInitializer(node.initializer, node.type ? node.type.end : node.name.end, node);
        }
        function emitVariableDeclarationList(node) {
            writeKeyword(ts.isLet(node) ? "let" : ts.isVarConst(node) ? "const" : "var");
            writeSpace();
            emitList(node, node.declarations, 528 /* VariableDeclarationList */);
        }
        function emitFunctionDeclaration(node) {
            emitFunctionDeclarationOrExpression(node);
        }
        function emitFunctionDeclarationOrExpression(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("function");
            emit(node.asteriskToken);
            writeSpace();
            emitIdentifierName(node.name);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitBlockCallback(_hint, body) {
            emitBlockFunctionBody(body);
        }
        function emitSignatureAndBody(node, emitSignatureHead) {
            var body = node.body;
            if (body) {
                if (ts.isBlock(body)) {
                    var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
                    if (indentedFlag) {
                        increaseIndent();
                    }
                    pushNameGenerationScope(node);
                    ts.forEach(node.parameters, generateNames);
                    generateNames(node.body);
                    emitSignatureHead(node);
                    if (onEmitNode) {
                        onEmitNode(4 /* Unspecified */, body, emitBlockCallback);
                    }
                    else {
                        emitBlockFunctionBody(body);
                    }
                    popNameGenerationScope(node);
                    if (indentedFlag) {
                        decreaseIndent();
                    }
                }
                else {
                    emitSignatureHead(node);
                    writeSpace();
                    emitExpression(body);
                }
            }
            else {
                emitSignatureHead(node);
                writeTrailingSemicolon();
            }
        }
        function emitSignatureHead(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
        }
        function shouldEmitBlockFunctionBodyOnSingleLine(body) {
            // We must emit a function body as a single-line body in the following case:
            // * The body has NodeEmitFlags.SingleLine specified.
            // We must emit a function body as a multi-line body in the following cases:
            // * The body is explicitly marked as multi-line.
            // * A non-synthesized body's start and end position are on different lines.
            // * Any statement in the body starts on a new line.
            if (ts.getEmitFlags(body) & 1 /* SingleLine */) {
                return true;
            }
            if (body.multiLine) {
                return false;
            }
            if (!ts.nodeIsSynthesized(body) && !ts.rangeIsOnSingleLine(body, currentSourceFile)) {
                return false;
            }
            if (getLeadingLineTerminatorCount(body, body.statements, 2 /* PreserveLines */)
                || getClosingLineTerminatorCount(body, body.statements, 2 /* PreserveLines */)) {
                return false;
            }
            var previousStatement;
            for (var _a = 0, _b = body.statements; _a < _b.length; _a++) {
                var statement = _b[_a];
                if (getSeparatingLineTerminatorCount(previousStatement, statement, 2 /* PreserveLines */) > 0) {
                    return false;
                }
                previousStatement = statement;
            }
            return true;
        }
        function emitBlockFunctionBody(body) {
            writeSpace();
            writePunctuation("{");
            increaseIndent();
            var emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body)
                ? emitBlockFunctionBodyOnSingleLine
                : emitBlockFunctionBodyWorker;
            if (emitBodyWithDetachedComments) {
                emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
            }
            else {
                emitBlockFunctionBody(body);
            }
            decreaseIndent();
            writeToken(19 /* CloseBraceToken */, body.statements.end, writePunctuation, body);
        }
        function emitBlockFunctionBodyOnSingleLine(body) {
            emitBlockFunctionBodyWorker(body, /*emitBlockFunctionBodyOnSingleLine*/ true);
        }
        function emitBlockFunctionBodyWorker(body, emitBlockFunctionBodyOnSingleLine) {
            // Emit all the prologue directives (like "use strict").
            var statementOffset = emitPrologueDirectives(body.statements);
            var pos = writer.getTextPos();
            emitHelpers(body);
            if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) {
                decreaseIndent();
                emitList(body, body.statements, 768 /* SingleLineFunctionBodyStatements */);
                increaseIndent();
            }
            else {
                emitList(body, body.statements, 1 /* MultiLineFunctionBodyStatements */, statementOffset);
            }
        }
        function emitClassDeclaration(node) {
            emitClassDeclarationOrExpression(node);
        }
        function emitClassDeclarationOrExpression(node) {
            ts.forEach(node.members, generateMemberNames);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("class");
            if (node.name) {
                writeSpace();
                emitIdentifierName(node.name);
            }
            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
            if (indentedFlag) {
                increaseIndent();
            }
            emitTypeParameters(node, node.typeParameters);
            emitList(node, node.heritageClauses, 0 /* ClassHeritageClauses */);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 129 /* ClassMembers */);
            writePunctuation("}");
            if (indentedFlag) {
                decreaseIndent();
            }
        }
        function emitInterfaceDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("interface");
            writeSpace();
            emit(node.name);
            emitTypeParameters(node, node.typeParameters);
            emitList(node, node.heritageClauses, 512 /* HeritageClauses */);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 129 /* InterfaceMembers */);
            writePunctuation("}");
        }
        function emitTypeAliasDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("type");
            writeSpace();
            emit(node.name);
            emitTypeParameters(node, node.typeParameters);
            writeSpace();
            writePunctuation("=");
            writeSpace();
            emit(node.type);
            writeTrailingSemicolon();
        }
        function emitEnumDeclaration(node) {
            emitModifiers(node, node.modifiers);
            writeKeyword("enum");
            writeSpace();
            emit(node.name);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 145 /* EnumMembers */);
            writePunctuation("}");
        }
        function emitModuleDeclaration(node) {
            emitModifiers(node, node.modifiers);
            if (~node.flags & 1024 /* GlobalAugmentation */) {
                writeKeyword(node.flags & 16 /* Namespace */ ? "namespace" : "module");
                writeSpace();
            }
            emit(node.name);
            var body = node.body;
            if (!body)
                return writeTrailingSemicolon();
            while (body.kind === 249 /* ModuleDeclaration */) {
                writePunctuation(".");
                emit(body.name);
                body = body.body;
            }
            writeSpace();
            emit(body);
        }
        function emitModuleBlock(node) {
            pushNameGenerationScope(node);
            ts.forEach(node.statements, generateNames);
            emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node));
            popNameGenerationScope(node);
        }
        function emitCaseBlock(node) {
            emitTokenWithComment(18 /* OpenBraceToken */, node.pos, writePunctuation, node);
            emitList(node, node.clauses, 129 /* CaseBlockClauses */);
            emitTokenWithComment(19 /* CloseBraceToken */, node.clauses.end, writePunctuation, node, /*indentLeading*/ true);
        }
        function emitImportEqualsDeclaration(node) {
            emitModifiers(node, node.modifiers);
            emitTokenWithComment(96 /* ImportKeyword */, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
            writeSpace();
            emit(node.name);
            writeSpace();
            emitTokenWithComment(62 /* EqualsToken */, node.name.end, writePunctuation, node);
            writeSpace();
            emitModuleReference(node.moduleReference);
            writeTrailingSemicolon();
        }
        function emitModuleReference(node) {
            if (node.kind === 75 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        function emitImportDeclaration(node) {
            emitModifiers(node, node.modifiers);
            emitTokenWithComment(96 /* ImportKeyword */, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
            writeSpace();
            if (node.importClause) {
                emit(node.importClause);
                writeSpace();
                emitTokenWithComment(149 /* FromKeyword */, node.importClause.end, writeKeyword, node);
                writeSpace();
            }
            emitExpression(node.moduleSpecifier);
            writeTrailingSemicolon();
        }
        function emitImportClause(node) {
            if (node.isTypeOnly) {
                emitTokenWithComment(145 /* TypeKeyword */, node.pos, writeKeyword, node);
                writeSpace();
            }
            emit(node.name);
            if (node.name && node.namedBindings) {
                emitTokenWithComment(27 /* CommaToken */, node.name.end, writePunctuation, node);
                writeSpace();
            }
            emit(node.namedBindings);
        }
        function emitNamespaceImport(node) {
            var asPos = emitTokenWithComment(41 /* AsteriskToken */, node.pos, writePunctuation, node);
            writeSpace();
            emitTokenWithComment(123 /* AsKeyword */, asPos, writeKeyword, node);
            writeSpace();
            emit(node.name);
        }
        function emitNamedImports(node) {
            emitNamedImportsOrExports(node);
        }
        function emitImportSpecifier(node) {
            emitImportOrExportSpecifier(node);
        }
        function emitExportAssignment(node) {
            var nextPos = emitTokenWithComment(89 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.isExportEquals) {
                emitTokenWithComment(62 /* EqualsToken */, nextPos, writeOperator, node);
            }
            else {
                emitTokenWithComment(84 /* DefaultKeyword */, nextPos, writeKeyword, node);
            }
            writeSpace();
            emitExpression(node.expression);
            writeTrailingSemicolon();
        }
        function emitExportDeclaration(node) {
            var nextPos = emitTokenWithComment(89 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.isTypeOnly) {
                nextPos = emitTokenWithComment(145 /* TypeKeyword */, nextPos, writeKeyword, node);
                writeSpace();
            }
            if (node.exportClause) {
                emit(node.exportClause);
            }
            else {
                nextPos = emitTokenWithComment(41 /* AsteriskToken */, nextPos, writePunctuation, node);
            }
            if (node.moduleSpecifier) {
                writeSpace();
                var fromPos = node.exportClause ? node.exportClause.end : nextPos;
                emitTokenWithComment(149 /* FromKeyword */, fromPos, writeKeyword, node);
                writeSpace();
                emitExpression(node.moduleSpecifier);
            }
            writeTrailingSemicolon();
        }
        function emitNamespaceExportDeclaration(node) {
            var nextPos = emitTokenWithComment(89 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            nextPos = emitTokenWithComment(123 /* AsKeyword */, nextPos, writeKeyword, node);
            writeSpace();
            nextPos = emitTokenWithComment(136 /* NamespaceKeyword */, nextPos, writeKeyword, node);
            writeSpace();
            emit(node.name);
            writeTrailingSemicolon();
        }
        function emitNamespaceExport(node) {
            var asPos = emitTokenWithComment(41 /* AsteriskToken */, node.pos, writePunctuation, node);
            writeSpace();
            emitTokenWithComment(123 /* AsKeyword */, asPos, writeKeyword, node);
            writeSpace();
            emit(node.name);
        }
        function emitNamedExports(node) {
            emitNamedImportsOrExports(node);
        }
        function emitExportSpecifier(node) {
            emitImportOrExportSpecifier(node);
        }
        function emitNamedImportsOrExports(node) {
            writePunctuation("{");
            emitList(node, node.elements, 525136 /* NamedImportsOrExportsElements */);
            writePunctuation("}");
        }
        function emitImportOrExportSpecifier(node) {
            if (node.propertyName) {
                emit(node.propertyName);
                writeSpace();
                emitTokenWithComment(123 /* AsKeyword */, node.propertyName.end, writeKeyword, node);
                writeSpace();
            }
            emit(node.name);
        }
        //
        // Module references
        //
        function emitExternalModuleReference(node) {
            writeKeyword("require");
            writePunctuation("(");
            emitExpression(node.expression);
            writePunctuation(")");
        }
        //
        // JSX
        //
        function emitJsxElement(node) {
            emit(node.openingElement);
            emitList(node, node.children, 262144 /* JsxElementOrFragmentChildren */);
            emit(node.closingElement);
        }
        function emitJsxSelfClosingElement(node) {
            writePunctuation("<");
            emitJsxTagName(node.tagName);
            emitTypeArguments(node, node.typeArguments);
            writeSpace();
            emit(node.attributes);
            writePunctuation("/>");
        }
        function emitJsxFragment(node) {
            emit(node.openingFragment);
            emitList(node, node.children, 262144 /* JsxElementOrFragmentChildren */);
            emit(node.closingFragment);
        }
        function emitJsxOpeningElementOrFragment(node) {
            writePunctuation("<");
            if (ts.isJsxOpeningElement(node)) {
                var indented = writeLineSeparatorsAndIndentBefore(node.tagName, node);
                emitJsxTagName(node.tagName);
                emitTypeArguments(node, node.typeArguments);
                if (node.attributes.properties && node.attributes.properties.length > 0) {
                    writeSpace();
                }
                emit(node.attributes);
                writeLineSeparatorsAfter(node.attributes, node);
                decreaseIndentIf(indented);
            }
            writePunctuation(">");
        }
        function emitJsxText(node) {
            writer.writeLiteral(node.text);
        }
        function emitJsxClosingElementOrFragment(node) {
            writePunctuation("</");
            if (ts.isJsxClosingElement(node)) {
                emitJsxTagName(node.tagName);
            }
            writePunctuation(">");
        }
        function emitJsxAttributes(node) {
            emitList(node, node.properties, 262656 /* JsxElementAttributes */);
        }
        function emitJsxAttribute(node) {
            emit(node.name);
            emitNodeWithPrefix("=", writePunctuation, node.initializer, emitJsxAttributeValue);
        }
        function emitJsxSpreadAttribute(node) {
            writePunctuation("{...");
            emitExpression(node.expression);
            writePunctuation("}");
        }
        function emitJsxExpression(node) {
            if (node.expression) {
                writePunctuation("{");
                emit(node.dotDotDotToken);
                emitExpression(node.expression);
                writePunctuation("}");
            }
        }
        function emitJsxTagName(node) {
            if (node.kind === 75 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        //
        // Clauses
        //
        function emitCaseClause(node) {
            emitTokenWithComment(78 /* CaseKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitCaseOrDefaultClauseRest(node, node.statements, node.expression.end);
        }
        function emitDefaultClause(node) {
            var pos = emitTokenWithComment(84 /* DefaultKeyword */, node.pos, writeKeyword, node);
            emitCaseOrDefaultClauseRest(node, node.statements, pos);
        }
        function emitCaseOrDefaultClauseRest(parentNode, statements, colonPos) {
            var emitAsSingleStatement = statements.length === 1 &&
                (
                // treat synthesized nodes as located on the same line for emit purposes
                ts.nodeIsSynthesized(parentNode) ||
                    ts.nodeIsSynthesized(statements[0]) ||
                    ts.rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile));
            var format = 163969 /* CaseOrDefaultClauseStatements */;
            if (emitAsSingleStatement) {
                writeToken(58 /* ColonToken */, colonPos, writePunctuation, parentNode);
                writeSpace();
                format &= ~(1 /* MultiLine */ | 128 /* Indented */);
            }
            else {
                emitTokenWithComment(58 /* ColonToken */, colonPos, writePunctuation, parentNode);
            }
            emitList(parentNode, statements, format);
        }
        function emitHeritageClause(node) {
            writeSpace();
            writeTokenText(node.token, writeKeyword);
            writeSpace();
            emitList(node, node.types, 528 /* HeritageClauseTypes */);
        }
        function emitCatchClause(node) {
            var openParenPos = emitTokenWithComment(79 /* CatchKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.variableDeclaration) {
                emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
                emit(node.variableDeclaration);
                emitTokenWithComment(21 /* CloseParenToken */, node.variableDeclaration.end, writePunctuation, node);
                writeSpace();
            }
            emit(node.block);
        }
        //
        // Property assignments
        //
        function emitPropertyAssignment(node) {
            emit(node.name);
            writePunctuation(":");
            writeSpace();
            // This is to ensure that we emit comment in the following case:
            //      For example:
            //          obj = {
            //              id: /*comment1*/ ()=>void
            //          }
            // "comment1" is not considered to be leading comment for node.initializer
            // but rather a trailing comment on the previous node.
            var initializer = node.initializer;
            if (emitTrailingCommentsOfPosition && (ts.getEmitFlags(initializer) & 512 /* NoLeadingComments */) === 0) {
                var commentRange = ts.getCommentRange(initializer);
                emitTrailingCommentsOfPosition(commentRange.pos);
            }
            emitExpression(initializer);
        }
        function emitShorthandPropertyAssignment(node) {
            emit(node.name);
            if (node.objectAssignmentInitializer) {
                writeSpace();
                writePunctuation("=");
                writeSpace();
                emitExpression(node.objectAssignmentInitializer);
            }
        }
        function emitSpreadAssignment(node) {
            if (node.expression) {
                emitTokenWithComment(25 /* DotDotDotToken */, node.pos, writePunctuation, node);
                emitExpression(node.expression);
            }
        }
        //
        // Enum
        //
        function emitEnumMember(node) {
            emit(node.name);
            emitInitializer(node.initializer, node.name.end, node);
        }
        //
        // JSDoc
        //
        function emitJSDoc(node) {
            write("/**");
            if (node.comment) {
                var lines = node.comment.split(/\r\n?|\n/g);
                for (var _a = 0, lines_2 = lines; _a < lines_2.length; _a++) {
                    var line = lines_2[_a];
                    writeLine();
                    writeSpace();
                    writePunctuation("*");
                    writeSpace();
                    write(line);
                }
            }
            if (node.tags) {
                if (node.tags.length === 1 && node.tags[0].kind === 320 /* JSDocTypeTag */ && !node.comment) {
                    writeSpace();
                    emit(node.tags[0]);
                }
                else {
                    emitList(node, node.tags, 33 /* JSDocComment */);
                }
            }
            writeSpace();
            write("*/");
        }
        function emitJSDocSimpleTypedTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocTypeExpression(tag.typeExpression);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocHeritageTag(tag) {
            emitJSDocTagName(tag.tagName);
            writeSpace();
            writePunctuation("{");
            emit(tag.class);
            writePunctuation("}");
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTemplateTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocTypeExpression(tag.constraint);
            writeSpace();
            emitList(tag, tag.typeParameters, 528 /* CommaListElements */);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTypedefTag(tag) {
            emitJSDocTagName(tag.tagName);
            if (tag.typeExpression) {
                if (tag.typeExpression.kind === 294 /* JSDocTypeExpression */) {
                    emitJSDocTypeExpression(tag.typeExpression);
                }
                else {
                    writeSpace();
                    writePunctuation("{");
                    write("Object");
                    if (tag.typeExpression.isArrayType) {
                        writePunctuation("[");
                        writePunctuation("]");
                    }
                    writePunctuation("}");
                }
            }
            if (tag.fullName) {
                writeSpace();
                emit(tag.fullName);
            }
            emitJSDocComment(tag.comment);
            if (tag.typeExpression && tag.typeExpression.kind === 304 /* JSDocTypeLiteral */) {
                emitJSDocTypeLiteral(tag.typeExpression);
            }
        }
        function emitJSDocCallbackTag(tag) {
            emitJSDocTagName(tag.tagName);
            if (tag.name) {
                writeSpace();
                emit(tag.name);
            }
            emitJSDocComment(tag.comment);
            emitJSDocSignature(tag.typeExpression);
        }
        function emitJSDocSimpleTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTypeLiteral(lit) {
            emitList(lit, ts.createNodeArray(lit.jsDocPropertyTags), 33 /* JSDocComment */);
        }
        function emitJSDocSignature(sig) {
            if (sig.typeParameters) {
                emitList(sig, ts.createNodeArray(sig.typeParameters), 33 /* JSDocComment */);
            }
            if (sig.parameters) {
                emitList(sig, ts.createNodeArray(sig.parameters), 33 /* JSDocComment */);
            }
            if (sig.type) {
                writeLine();
                writeSpace();
                writePunctuation("*");
                writeSpace();
                emit(sig.type);
            }
        }
        function emitJSDocPropertyLikeTag(param) {
            emitJSDocTagName(param.tagName);
            emitJSDocTypeExpression(param.typeExpression);
            writeSpace();
            if (param.isBracketed) {
                writePunctuation("[");
            }
            emit(param.name);
            if (param.isBracketed) {
                writePunctuation("]");
            }
            emitJSDocComment(param.comment);
        }
        function emitJSDocTagName(tagName) {
            writePunctuation("@");
            emit(tagName);
        }
        function emitJSDocComment(comment) {
            if (comment) {
                writeSpace();
                write(comment);
            }
        }
        function emitJSDocTypeExpression(typeExpression) {
            if (typeExpression) {
                writeSpace();
                writePunctuation("{");
                emit(typeExpression.type);
                writePunctuation("}");
            }
        }
        //
        // Top-level nodes
        //
        function emitSourceFile(node) {
            writeLine();
            var statements = node.statements;
            if (emitBodyWithDetachedComments) {
                // Emit detached comment if there are no prologue directives or if the first node is synthesized.
                // The synthesized node will have no leading comment so some comments may be missed.
                var shouldEmitDetachedComment = statements.length === 0 ||
                    !ts.isPrologueDirective(statements[0]) ||
                    ts.nodeIsSynthesized(statements[0]);
                if (shouldEmitDetachedComment) {
                    emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
                    return;
                }
            }
            emitSourceFileWorker(node);
        }
        function emitSyntheticTripleSlashReferencesIfNeeded(node) {
            emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || [], node.syntheticLibReferences || []);
            for (var _a = 0, _b = node.prepends; _a < _b.length; _a++) {
                var prepend = _b[_a];
                if (ts.isUnparsedSource(prepend) && prepend.syntheticReferences) {
                    for (var _c = 0, _d = prepend.syntheticReferences; _c < _d.length; _c++) {
                        var ref = _d[_c];
                        emit(ref);
                        writeLine();
                    }
                }
            }
        }
        function emitTripleSlashDirectivesIfNeeded(node) {
            if (node.isDeclarationFile)
                emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives);
        }
        function emitTripleSlashDirectives(hasNoDefaultLib, files, types, libs) {
            if (hasNoDefaultLib) {
                var pos = writer.getTextPos();
                writeComment("/// <reference no-default-lib=\"true\"/>");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "no-default-lib" /* NoDefaultLib */ });
                writeLine();
            }
            if (currentSourceFile && currentSourceFile.moduleName) {
                writeComment("/// <amd-module name=\"" + currentSourceFile.moduleName + "\" />");
                writeLine();
            }
            if (currentSourceFile && currentSourceFile.amdDependencies) {
                for (var _a = 0, _b = currentSourceFile.amdDependencies; _a < _b.length; _a++) {
                    var dep = _b[_a];
                    if (dep.name) {
                        writeComment("/// <amd-dependency name=\"" + dep.name + "\" path=\"" + dep.path + "\" />");
                    }
                    else {
                        writeComment("/// <amd-dependency path=\"" + dep.path + "\" />");
                    }
                    writeLine();
                }
            }
            for (var _c = 0, files_1 = files; _c < files_1.length; _c++) {
                var directive = files_1[_c];
                var pos = writer.getTextPos();
                writeComment("/// <reference path=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "reference" /* Reference */, data: directive.fileName });
                writeLine();
            }
            for (var _d = 0, types_22 = types; _d < types_22.length; _d++) {
                var directive = types_22[_d];
                var pos = writer.getTextPos();
                writeComment("/// <reference types=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "type" /* Type */, data: directive.fileName });
                writeLine();
            }
            for (var _e = 0, libs_1 = libs; _e < libs_1.length; _e++) {
                var directive = libs_1[_e];
                var pos = writer.getTextPos();
                writeComment("/// <reference lib=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "lib" /* Lib */, data: directive.fileName });
                writeLine();
            }
        }
        function emitSourceFileWorker(node) {
            var statements = node.statements;
            pushNameGenerationScope(node);
            ts.forEach(node.statements, generateNames);
            emitHelpers(node);
            var index = ts.findIndex(statements, function (statement) { return !ts.isPrologueDirective(statement); });
            emitTripleSlashDirectivesIfNeeded(node);
            emitList(node, statements, 1 /* MultiLine */, index === -1 ? statements.length : index);
            popNameGenerationScope(node);
        }
        // Transformation nodes
        function emitPartiallyEmittedExpression(node) {
            emitExpression(node.expression);
        }
        function emitCommaList(node) {
            emitExpressionList(node, node.elements, 528 /* CommaListElements */);
        }
        /**
         * Emits any prologue directives at the start of a Statement list, returning the
         * number of prologue directives written to the output.
         */
        function emitPrologueDirectives(statements, sourceFile, seenPrologueDirectives, recordBundleFileSection) {
            var needsToSetSourceFile = !!sourceFile;
            for (var i = 0; i < statements.length; i++) {
                var statement = statements[i];
                if (ts.isPrologueDirective(statement)) {
                    var shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
                    if (shouldEmitPrologueDirective) {
                        if (needsToSetSourceFile) {
                            needsToSetSourceFile = false;
                            setSourceFile(sourceFile);
                        }
                        writeLine();
                        var pos = writer.getTextPos();
                        emit(statement);
                        if (recordBundleFileSection && bundleFileInfo)
                            bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "prologue" /* Prologue */, data: statement.expression.text });
                        if (seenPrologueDirectives) {
                            seenPrologueDirectives.set(statement.expression.text, true);
                        }
                    }
                }
                else {
                    // return index of the first non prologue directive
                    return i;
                }
            }
            return statements.length;
        }
        function emitUnparsedPrologues(prologues, seenPrologueDirectives) {
            for (var _a = 0, prologues_1 = prologues; _a < prologues_1.length; _a++) {
                var prologue = prologues_1[_a];
                if (!seenPrologueDirectives.has(prologue.data)) {
                    writeLine();
                    var pos = writer.getTextPos();
                    emit(prologue);
                    if (bundleFileInfo)
                        bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "prologue" /* Prologue */, data: prologue.data });
                    if (seenPrologueDirectives) {
                        seenPrologueDirectives.set(prologue.data, true);
                    }
                }
            }
        }
        function emitPrologueDirectivesIfNeeded(sourceFileOrBundle) {
            if (ts.isSourceFile(sourceFileOrBundle)) {
                emitPrologueDirectives(sourceFileOrBundle.statements, sourceFileOrBundle);
            }
            else {
                var seenPrologueDirectives = ts.createMap();
                for (var _a = 0, _b = sourceFileOrBundle.prepends; _a < _b.length; _a++) {
                    var prepend = _b[_a];
                    emitUnparsedPrologues(prepend.prologues, seenPrologueDirectives);
                }
                for (var _c = 0, _d = sourceFileOrBundle.sourceFiles; _c < _d.length; _c++) {
                    var sourceFile = _d[_c];
                    emitPrologueDirectives(sourceFile.statements, sourceFile, seenPrologueDirectives, /*recordBundleFileSection*/ true);
                }
                setSourceFile(undefined);
            }
        }
        function getPrologueDirectivesFromBundledSourceFiles(bundle) {
            var seenPrologueDirectives = ts.createMap();
            var prologues;
            for (var index = 0; index < bundle.sourceFiles.length; index++) {
                var sourceFile = bundle.sourceFiles[index];
                var directives = void 0;
                var end = 0;
                for (var _a = 0, _b = sourceFile.statements; _a < _b.length; _a++) {
                    var statement = _b[_a];
                    if (!ts.isPrologueDirective(statement))
                        break;
                    if (seenPrologueDirectives.has(statement.expression.text))
                        continue;
                    seenPrologueDirectives.set(statement.expression.text, true);
                    (directives || (directives = [])).push({
                        pos: statement.pos,
                        end: statement.end,
                        expression: {
                            pos: statement.expression.pos,
                            end: statement.expression.end,
                            text: statement.expression.text
                        }
                    });
                    end = end < statement.end ? statement.end : end;
                }
                if (directives)
                    (prologues || (prologues = [])).push({ file: index, text: sourceFile.text.substring(0, end), directives: directives });
            }
            return prologues;
        }
        function emitShebangIfNeeded(sourceFileOrBundle) {
            if (ts.isSourceFile(sourceFileOrBundle) || ts.isUnparsedSource(sourceFileOrBundle)) {
                var shebang = ts.getShebang(sourceFileOrBundle.text);
                if (shebang) {
                    writeComment(shebang);
                    writeLine();
                    return true;
                }
            }
            else {
                for (var _a = 0, _b = sourceFileOrBundle.prepends; _a < _b.length; _a++) {
                    var prepend = _b[_a];
                    ts.Debug.assertNode(prepend, ts.isUnparsedSource);
                    if (emitShebangIfNeeded(prepend)) {
                        return true;
                    }
                }
                for (var _c = 0, _d = sourceFileOrBundle.sourceFiles; _c < _d.length; _c++) {
                    var sourceFile = _d[_c];
                    // Emit only the first encountered shebang
                    if (emitShebangIfNeeded(sourceFile)) {
                        return true;
                    }
                }
            }
        }
        //
        // Helpers
        //
        function emitNodeWithWriter(node, writer) {
            if (!node)
                return;
            var savedWrite = write;
            write = writer;
            emit(node);
            write = savedWrite;
        }
        function emitModifiers(node, modifiers) {
            if (modifiers && modifiers.length) {
                emitList(node, modifiers, 262656 /* Modifiers */);
                writeSpace();
            }
        }
        function emitTypeAnnotation(node) {
            if (node) {
                writePunctuation(":");
                writeSpace();
                emit(node);
            }
        }
        function emitInitializer(node, equalCommentStartPos, container) {
            if (node) {
                writeSpace();
                emitTokenWithComment(62 /* EqualsToken */, equalCommentStartPos, writeOperator, container);
                writeSpace();
                emitExpression(node);
            }
        }
        function emitNodeWithPrefix(prefix, prefixWriter, node, emit) {
            if (node) {
                prefixWriter(prefix);
                emit(node);
            }
        }
        function emitWithLeadingSpace(node) {
            if (node) {
                writeSpace();
                emit(node);
            }
        }
        function emitExpressionWithLeadingSpace(node) {
            if (node) {
                writeSpace();
                emitExpression(node);
            }
        }
        function emitWithTrailingSpace(node) {
            if (node) {
                emit(node);
                writeSpace();
            }
        }
        function emitEmbeddedStatement(parent, node) {
            if (ts.isBlock(node) || ts.getEmitFlags(parent) & 1 /* SingleLine */) {
                writeSpace();
                emit(node);
            }
            else {
                writeLine();
                increaseIndent();
                if (ts.isEmptyStatement(node)) {
                    pipelineEmit(5 /* EmbeddedStatement */, node);
                }
                else {
                    emit(node);
                }
                decreaseIndent();
            }
        }
        function emitDecorators(parentNode, decorators) {
            emitList(parentNode, decorators, 2146305 /* Decorators */);
        }
        function emitTypeArguments(parentNode, typeArguments) {
            emitList(parentNode, typeArguments, 53776 /* TypeArguments */);
        }
        function emitTypeParameters(parentNode, typeParameters) {
            if (ts.isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures
                return emitTypeArguments(parentNode, parentNode.typeArguments);
            }
            emitList(parentNode, typeParameters, 53776 /* TypeParameters */);
        }
        function emitParameters(parentNode, parameters) {
            emitList(parentNode, parameters, 2576 /* Parameters */);
        }
        function canEmitSimpleArrowHead(parentNode, parameters) {
            var parameter = ts.singleOrUndefined(parameters);
            return parameter
                && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
                && ts.isArrowFunction(parentNode) // only arrow functions may have simple arrow head
                && !parentNode.type // arrow function may not have return type annotation
                && !ts.some(parentNode.decorators) // parent may not have decorators
                && !ts.some(parentNode.modifiers) // parent may not have modifiers
                && !ts.some(parentNode.typeParameters) // parent may not have type parameters
                && !ts.some(parameter.decorators) // parameter may not have decorators
                && !ts.some(parameter.modifiers) // parameter may not have modifiers
                && !parameter.dotDotDotToken // parameter may not be rest
                && !parameter.questionToken // parameter may not be optional
                && !parameter.type // parameter may not have a type annotation
                && !parameter.initializer // parameter may not have an initializer
                && ts.isIdentifier(parameter.name); // parameter name must be identifier
        }
        function emitParametersForArrow(parentNode, parameters) {
            if (canEmitSimpleArrowHead(parentNode, parameters)) {
                emitList(parentNode, parameters, 2576 /* Parameters */ & ~2048 /* Parenthesis */);
            }
            else {
                emitParameters(parentNode, parameters);
            }
        }
        function emitParametersForIndexSignature(parentNode, parameters) {
            emitList(parentNode, parameters, 8848 /* IndexSignatureParameters */);
        }
        function emitList(parentNode, children, format, start, count) {
            emitNodeList(emit, parentNode, children, format, start, count);
        }
        function emitExpressionList(parentNode, children, format, start, count) {
            emitNodeList(emitExpression, parentNode, children, format, start, count); // TODO: GH#18217
        }
        function writeDelimiter(format) {
            switch (format & 60 /* DelimitersMask */) {
                case 0 /* None */:
                    break;
                case 16 /* CommaDelimited */:
                    writePunctuation(",");
                    break;
                case 4 /* BarDelimited */:
                    writeSpace();
                    writePunctuation("|");
                    break;
                case 32 /* AsteriskDelimited */:
                    writeSpace();
                    writePunctuation("*");
                    writeSpace();
                    break;
                case 8 /* AmpersandDelimited */:
                    writeSpace();
                    writePunctuation("&");
                    break;
            }
        }
        function emitNodeList(emit, parentNode, children, format, start, count) {
            if (start === void 0) { start = 0; }
            if (count === void 0) { count = children ? children.length - start : 0; }
            var isUndefined = children === undefined;
            if (isUndefined && format & 16384 /* OptionalIfUndefined */) {
                return;
            }
            var isEmpty = children === undefined || start >= children.length || count === 0;
            if (isEmpty && format & 32768 /* OptionalIfEmpty */) {
                if (onBeforeEmitNodeArray) {
                    onBeforeEmitNodeArray(children);
                }
                if (onAfterEmitNodeArray) {
                    onAfterEmitNodeArray(children);
                }
                return;
            }
            if (format & 15360 /* BracketsMask */) {
                writePunctuation(getOpeningBracket(format));
                if (isEmpty && !isUndefined) {
                    // TODO: GH#18217
                    emitTrailingCommentsOfPosition(children.pos, /*prefixSpace*/ true); // Emit comments within empty bracketed lists
                }
            }
            if (onBeforeEmitNodeArray) {
                onBeforeEmitNodeArray(children);
            }
            if (isEmpty) {
                // Write a line terminator if the parent node was multi-line
                if (format & 1 /* MultiLine */ && !(preserveSourceNewlines && ts.rangeIsOnSingleLine(parentNode, currentSourceFile))) {
                    writeLine();
                }
                else if (format & 256 /* SpaceBetweenBraces */ && !(format & 524288 /* NoSpaceIfEmpty */)) {
                    writeSpace();
                }
            }
            else {
                // Write the opening line terminator or leading whitespace.
                var mayEmitInterveningComments = (format & 262144 /* NoInterveningComments */) === 0;
                var shouldEmitInterveningComments = mayEmitInterveningComments;
                var leadingLineTerminatorCount = getLeadingLineTerminatorCount(parentNode, children, format); // TODO: GH#18217
                if (leadingLineTerminatorCount) {
                    writeLine(leadingLineTerminatorCount);
                    shouldEmitInterveningComments = false;
                }
                else if (format & 256 /* SpaceBetweenBraces */) {
                    writeSpace();
                }
                // Increase the indent, if requested.
                if (format & 128 /* Indented */) {
                    increaseIndent();
                }
                // Emit each child.
                var previousSibling = void 0;
                var previousSourceFileTextKind = void 0;
                var shouldDecreaseIndentAfterEmit = false;
                for (var i = 0; i < count; i++) {
                    var child = children[start + i];
                    // Write the delimiter if this is not the first node.
                    if (format & 32 /* AsteriskDelimited */) {
                        // always write JSDoc in the format "\n *"
                        writeLine();
                        writeDelimiter(format);
                    }
                    else if (previousSibling) {
                        // i.e
                        //      function commentedParameters(
                        //          /* Parameter a */
                        //          a
                        //          /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline
                        //          ,
                        if (format & 60 /* DelimitersMask */ && previousSibling.end !== parentNode.end) {
                            emitLeadingCommentsOfPosition(previousSibling.end);
                        }
                        writeDelimiter(format);
                        recordBundleFileInternalSectionEnd(previousSourceFileTextKind);
                        // Write either a line terminator or whitespace to separate the elements.
                        var separatingLineTerminatorCount = getSeparatingLineTerminatorCount(previousSibling, child, format);
                        if (separatingLineTerminatorCount > 0) {
                            // If a synthesized node in a single-line list starts on a new
                            // line, we should increase the indent.
                            if ((format & (3 /* LinesMask */ | 128 /* Indented */)) === 0 /* SingleLine */) {
                                increaseIndent();
                                shouldDecreaseIndentAfterEmit = true;
                            }
                            writeLine(separatingLineTerminatorCount);
                            shouldEmitInterveningComments = false;
                        }
                        else if (previousSibling && format & 512 /* SpaceBetweenSiblings */) {
                            writeSpace();
                        }
                    }
                    // Emit this child.
                    previousSourceFileTextKind = recordBundleFileInternalSectionStart(child);
                    if (shouldEmitInterveningComments) {
                        if (emitTrailingCommentsOfPosition) {
                            var commentRange = ts.getCommentRange(child);
                            emitTrailingCommentsOfPosition(commentRange.pos);
                        }
                    }
                    else {
                        shouldEmitInterveningComments = mayEmitInterveningComments;
                    }
                    emit(child);
                    if (shouldDecreaseIndentAfterEmit) {
                        decreaseIndent();
                        shouldDecreaseIndentAfterEmit = false;
                    }
                    previousSibling = child;
                }
                // Write a trailing comma, if requested.
                var hasTrailingComma = (format & 64 /* AllowTrailingComma */) && children.hasTrailingComma;
                if (format & 16 /* CommaDelimited */ && hasTrailingComma) {
                    writePunctuation(",");
                }
                // Emit any trailing comment of the last element in the list
                // i.e
                //       var array = [...
                //          2
                //          /* end of element 2 */
                //       ];
                if (previousSibling && format & 60 /* DelimitersMask */ && previousSibling.end !== parentNode.end && !(ts.getEmitFlags(previousSibling) & 1024 /* NoTrailingComments */)) {
                    emitLeadingCommentsOfPosition(previousSibling.end);
                }
                // Decrease the indent, if requested.
                if (format & 128 /* Indented */) {
                    decreaseIndent();
                }
                recordBundleFileInternalSectionEnd(previousSourceFileTextKind);
                // Write the closing line terminator or closing whitespace.
                var closingLineTerminatorCount = getClosingLineTerminatorCount(parentNode, children, format);
                if (closingLineTerminatorCount) {
                    writeLine(closingLineTerminatorCount);
                }
                else if (format & (2097152 /* SpaceAfterList */ | 256 /* SpaceBetweenBraces */)) {
                    writeSpace();
                }
            }
            if (onAfterEmitNodeArray) {
                onAfterEmitNodeArray(children);
            }
            if (format & 15360 /* BracketsMask */) {
                if (isEmpty && !isUndefined) {
                    // TODO: GH#18217
                    emitLeadingCommentsOfPosition(children.end); // Emit leading comments within empty lists
                }
                writePunctuation(getClosingBracket(format));
            }
        }
        // Writers
        function writeLiteral(s) {
            writer.writeLiteral(s);
        }
        function writeStringLiteral(s) {
            writer.writeStringLiteral(s);
        }
        function writeBase(s) {
            writer.write(s);
        }
        function writeSymbol(s, sym) {
            writer.writeSymbol(s, sym);
        }
        function writePunctuation(s) {
            writer.writePunctuation(s);
        }
        function writeTrailingSemicolon() {
            writer.writeTrailingSemicolon(";");
        }
        function writeKeyword(s) {
            writer.writeKeyword(s);
        }
        function writeOperator(s) {
            writer.writeOperator(s);
        }
        function writeParameter(s) {
            writer.writeParameter(s);
        }
        function writeComment(s) {
            writer.writeComment(s);
        }
        function writeSpace() {
            writer.writeSpace(" ");
        }
        function writeProperty(s) {
            writer.writeProperty(s);
        }
        function writeLine(count) {
            if (count === void 0) { count = 1; }
            for (var i = 0; i < count; i++) {
                writer.writeLine(i > 0);
            }
        }
        function increaseIndent() {
            writer.increaseIndent();
        }
        function decreaseIndent() {
            writer.decreaseIndent();
        }
        function writeToken(token, pos, writer, contextNode) {
            return !sourceMapsDisabled
                ? emitTokenWithSourceMap(contextNode, token, writer, pos, writeTokenText)
                : writeTokenText(token, writer, pos);
        }
        function writeTokenNode(node, writer) {
            if (onBeforeEmitToken) {
                onBeforeEmitToken(node);
            }
            writer(ts.tokenToString(node.kind));
            if (onAfterEmitToken) {
                onAfterEmitToken(node);
            }
        }
        function writeTokenText(token, writer, pos) {
            var tokenString = ts.tokenToString(token);
            writer(tokenString);
            return pos < 0 ? pos : pos + tokenString.length;
        }
        function writeLineOrSpace(node) {
            if (ts.getEmitFlags(node) & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
            }
        }
        function writeLines(text) {
            var lines = text.split(/\r\n?|\n/g);
            var indentation = ts.guessIndentation(lines);
            for (var _a = 0, lines_3 = lines; _a < lines_3.length; _a++) {
                var lineText = lines_3[_a];
                var line = indentation ? lineText.slice(indentation) : lineText;
                if (line.length) {
                    writeLine();
                    write(line);
                }
            }
        }
        function writeLinesAndIndent(lineCount, writeSpaceIfNotIndenting) {
            if (lineCount) {
                increaseIndent();
                writeLine(lineCount);
            }
            else if (writeSpaceIfNotIndenting) {
                writeSpace();
            }
        }
        // Helper function to decrease the indent if we previously indented.  Allows multiple
        // previous indent values to be considered at a time.  This also allows caller to just
        // call this once, passing in all their appropriate indent values, instead of needing
        // to call this helper function multiple times.
        function decreaseIndentIf(value1, value2) {
            if (value1) {
                decreaseIndent();
            }
            if (value2) {
                decreaseIndent();
            }
        }
        function getLeadingLineTerminatorCount(parentNode, children, format) {
            if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
                if (format & 65536 /* PreferNewLine */) {
                    return 1;
                }
                var firstChild_1 = children[0];
                if (firstChild_1 === undefined) {
                    return ts.rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
                }
                if (firstChild_1.kind === 11 /* JsxText */) {
                    // JsxText will be written with its leading whitespace, so don't add more manually.
                    return 0;
                }
                if (!ts.positionIsSynthesized(parentNode.pos) && !ts.nodeIsSynthesized(firstChild_1) && (!firstChild_1.parent || firstChild_1.parent === parentNode)) {
                    if (preserveSourceNewlines) {
                        return getEffectiveLines(function (includeComments) { return ts.getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(firstChild_1.pos, parentNode.pos, currentSourceFile, includeComments); });
                    }
                    return ts.rangeStartPositionsAreOnSameLine(parentNode, firstChild_1, currentSourceFile) ? 0 : 1;
                }
                if (synthesizedNodeStartsOnNewLine(firstChild_1, format)) {
                    return 1;
                }
            }
            return format & 1 /* MultiLine */ ? 1 : 0;
        }
        function getSeparatingLineTerminatorCount(previousNode, nextNode, format) {
            if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
                if (previousNode === undefined || nextNode === undefined) {
                    return 0;
                }
                if (nextNode.kind === 11 /* JsxText */) {
                    // JsxText will be written with its leading whitespace, so don't add more manually.
                    return 0;
                }
                else if (!ts.nodeIsSynthesized(previousNode) && !ts.nodeIsSynthesized(nextNode) && previousNode.parent === nextNode.parent) {
                    if (preserveSourceNewlines) {
                        return getEffectiveLines(function (includeComments) { return ts.getLinesBetweenRangeEndAndRangeStart(previousNode, nextNode, currentSourceFile, includeComments); });
                    }
                    return ts.rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile) ? 0 : 1;
                }
                else if (synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format)) {
                    return 1;
                }
            }
            else if (ts.getStartsOnNewLine(nextNode)) {
                return 1;
            }
            return format & 1 /* MultiLine */ ? 1 : 0;
        }
        function getClosingLineTerminatorCount(parentNode, children, format) {
            if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
                if (format & 65536 /* PreferNewLine */) {
                    return 1;
                }
                var lastChild_1 = ts.lastOrUndefined(children);
                if (lastChild_1 === undefined) {
                    return ts.rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
                }
                if (!ts.positionIsSynthesized(parentNode.pos) && !ts.nodeIsSynthesized(lastChild_1) && (!lastChild_1.parent || lastChild_1.parent === parentNode)) {
                    if (preserveSourceNewlines) {
                        return getEffectiveLines(function (includeComments) { return ts.getLinesBetweenPositionAndNextNonWhitespaceCharacter(lastChild_1.end, parentNode.end, currentSourceFile, includeComments); });
                    }
                    return ts.rangeEndPositionsAreOnSameLine(parentNode, lastChild_1, currentSourceFile) ? 0 : 1;
                }
                if (synthesizedNodeStartsOnNewLine(lastChild_1, format)) {
                    return 1;
                }
            }
            if (format & 1 /* MultiLine */ && !(format & 131072 /* NoTrailingNewLine */)) {
                return 1;
            }
            return 0;
        }
        function getEffectiveLines(getLineDifference) {
            // If 'preserveSourceNewlines' is disabled, we should never call this function
            // because it could be more expensive than alternative approximations.
            ts.Debug.assert(!!preserveSourceNewlines);
            // We start by measuring the line difference from a position to its adjacent comments,
            // so that this is counted as a one-line difference, not two:
            //
            //   node1;
            //   // NODE2 COMMENT
            //   node2;
            var lines = getLineDifference(/*includeComments*/ true);
            if (lines === 0) {
                // However, if the line difference considering comments was 0, we might have this:
                //
                //   node1; // NODE2 COMMENT
                //   node2;
                //
                // in which case we should be ignoring node2's comment, so this too is counted as
                // a one-line difference, not zero.
                return getLineDifference(/*includeComments*/ false);
            }
            return lines;
        }
        function writeLineSeparatorsAndIndentBefore(node, parent) {
            var leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(parent, [node], 0 /* None */);
            if (leadingNewlines) {
                writeLinesAndIndent(leadingNewlines, /*writeLinesIfNotIndenting*/ false);
            }
            return !!leadingNewlines;
        }
        function writeLineSeparatorsAfter(node, parent) {
            var trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(parent, [node], 0 /* None */);
            if (trailingNewlines) {
                writeLine(trailingNewlines);
            }
        }
        function synthesizedNodeStartsOnNewLine(node, format) {
            if (ts.nodeIsSynthesized(node)) {
                var startsOnNewLine = ts.getStartsOnNewLine(node);
                if (startsOnNewLine === undefined) {
                    return (format & 65536 /* PreferNewLine */) !== 0;
                }
                return startsOnNewLine;
            }
            return (format & 65536 /* PreferNewLine */) !== 0;
        }
        function getLinesBetweenNodes(parent, node1, node2) {
            if (ts.getEmitFlags(parent) & 131072 /* NoIndentation */) {
                return 0;
            }
            parent = skipSynthesizedParentheses(parent);
            node1 = skipSynthesizedParentheses(node1);
            node2 = skipSynthesizedParentheses(node2);
            // Always use a newline for synthesized code if the synthesizer desires it.
            if (ts.getStartsOnNewLine(node2)) {
                return 1;
            }
            if (!ts.nodeIsSynthesized(parent) && !ts.nodeIsSynthesized(node1) && !ts.nodeIsSynthesized(node2)) {
                if (preserveSourceNewlines) {
                    return getEffectiveLines(function (includeComments) { return ts.getLinesBetweenRangeEndAndRangeStart(node1, node2, currentSourceFile, includeComments); });
                }
                return ts.rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile) ? 0 : 1;
            }
            return 0;
        }
        function isEmptyBlock(block) {
            return block.statements.length === 0
                && ts.rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
        }
        function skipSynthesizedParentheses(node) {
            while (node.kind === 200 /* ParenthesizedExpression */ && ts.nodeIsSynthesized(node)) {
                node = node.expression;
            }
            return node;
        }
        function getTextOfNode(node, includeTrivia) {
            if (ts.isGeneratedIdentifier(node)) {
                return generateName(node);
            }
            else if ((ts.isIdentifier(node) || ts.isPrivateIdentifier(node)) && (ts.nodeIsSynthesized(node) || !node.parent || !currentSourceFile || (node.parent && currentSourceFile && ts.getSourceFileOfNode(node) !== ts.getOriginalNode(currentSourceFile)))) {
                return ts.idText(node);
            }
            else if (node.kind === 10 /* StringLiteral */ && node.textSourceNode) {
                return getTextOfNode(node.textSourceNode, includeTrivia);
            }
            else if (ts.isLiteralExpression(node) && (ts.nodeIsSynthesized(node) || !node.parent)) {
                return node.text;
            }
            return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
        }
        function getLiteralTextOfNode(node, neverAsciiEscape, jsxAttributeEscape) {
            if (node.kind === 10 /* StringLiteral */ && node.textSourceNode) {
                var textSourceNode = node.textSourceNode;
                if (ts.isIdentifier(textSourceNode)) {
                    return jsxAttributeEscape ? "\"" + ts.escapeJsxAttributeString(getTextOfNode(textSourceNode)) + "\"" :
                        neverAsciiEscape || (ts.getEmitFlags(node) & 16777216 /* NoAsciiEscaping */) ? "\"" + ts.escapeString(getTextOfNode(textSourceNode)) + "\"" :
                            "\"" + ts.escapeNonAsciiString(getTextOfNode(textSourceNode)) + "\"";
                }
                else {
                    return getLiteralTextOfNode(textSourceNode, neverAsciiEscape, jsxAttributeEscape);
                }
            }
            return ts.getLiteralText(node, currentSourceFile, neverAsciiEscape, jsxAttributeEscape);
        }
        /**
         * Push a new name generation scope.
         */
        function pushNameGenerationScope(node) {
            if (node && ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                return;
            }
            tempFlagsStack.push(tempFlags);
            tempFlags = 0;
            reservedNamesStack.push(reservedNames);
        }
        /**
         * Pop the current name generation scope.
         */
        function popNameGenerationScope(node) {
            if (node && ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                return;
            }
            tempFlags = tempFlagsStack.pop();
            reservedNames = reservedNamesStack.pop();
        }
        function reserveNameInNestedScopes(name) {
            if (!reservedNames || reservedNames === ts.lastOrUndefined(reservedNamesStack)) {
                reservedNames = ts.createMap();
            }
            reservedNames.set(name, true);
        }
        function generateNames(node) {
            if (!node)
                return;
            switch (node.kind) {
                case 223 /* Block */:
                    ts.forEach(node.statements, generateNames);
                    break;
                case 238 /* LabeledStatement */:
                case 236 /* WithStatement */:
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                    generateNames(node.statement);
                    break;
                case 227 /* IfStatement */:
                    generateNames(node.thenStatement);
                    generateNames(node.elseStatement);
                    break;
                case 230 /* ForStatement */:
                case 232 /* ForOfStatement */:
                case 231 /* ForInStatement */:
                    generateNames(node.initializer);
                    generateNames(node.statement);
                    break;
                case 237 /* SwitchStatement */:
                    generateNames(node.caseBlock);
                    break;
                case 251 /* CaseBlock */:
                    ts.forEach(node.clauses, generateNames);
                    break;
                case 277 /* CaseClause */:
                case 278 /* DefaultClause */:
                    ts.forEach(node.statements, generateNames);
                    break;
                case 240 /* TryStatement */:
                    generateNames(node.tryBlock);
                    generateNames(node.catchClause);
                    generateNames(node.finallyBlock);
                    break;
                case 280 /* CatchClause */:
                    generateNames(node.variableDeclaration);
                    generateNames(node.block);
                    break;
                case 225 /* VariableStatement */:
                    generateNames(node.declarationList);
                    break;
                case 243 /* VariableDeclarationList */:
                    ts.forEach(node.declarations, generateNames);
                    break;
                case 242 /* VariableDeclaration */:
                case 156 /* Parameter */:
                case 191 /* BindingElement */:
                case 245 /* ClassDeclaration */:
                    generateNameIfNeeded(node.name);
                    break;
                case 244 /* FunctionDeclaration */:
                    generateNameIfNeeded(node.name);
                    if (ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                        ts.forEach(node.parameters, generateNames);
                        generateNames(node.body);
                    }
                    break;
                case 189 /* ObjectBindingPattern */:
                case 190 /* ArrayBindingPattern */:
                    ts.forEach(node.elements, generateNames);
                    break;
                case 254 /* ImportDeclaration */:
                    generateNames(node.importClause);
                    break;
                case 255 /* ImportClause */:
                    generateNameIfNeeded(node.name);
                    generateNames(node.namedBindings);
                    break;
                case 256 /* NamespaceImport */:
                    generateNameIfNeeded(node.name);
                    break;
                case 262 /* NamespaceExport */:
                    generateNameIfNeeded(node.name);
                    break;
                case 257 /* NamedImports */:
                    ts.forEach(node.elements, generateNames);
                    break;
                case 258 /* ImportSpecifier */:
                    generateNameIfNeeded(node.propertyName || node.name);
                    break;
            }
        }
        function generateMemberNames(node) {
            if (!node)
                return;
            switch (node.kind) {
                case 281 /* PropertyAssignment */:
                case 282 /* ShorthandPropertyAssignment */:
                case 159 /* PropertyDeclaration */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    generateNameIfNeeded(node.name);
                    break;
            }
        }
        function generateNameIfNeeded(name) {
            if (name) {
                if (ts.isGeneratedIdentifier(name)) {
                    generateName(name);
                }
                else if (ts.isBindingPattern(name)) {
                    generateNames(name);
                }
            }
        }
        /**
         * Generate the text for a generated identifier.
         */
        function generateName(name) {
            if ((name.autoGenerateFlags & 7 /* KindMask */) === 4 /* Node */) {
                // Node names generate unique names based on their original node
                // and are cached based on that node's id.
                return generateNameCached(getNodeForGeneratedName(name), name.autoGenerateFlags);
            }
            else {
                // Auto, Loop, and Unique names are cached based on their unique
                // autoGenerateId.
                var autoGenerateId = name.autoGenerateId;
                return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
            }
        }
        function generateNameCached(node, flags) {
            var nodeId = ts.getNodeId(node);
            return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node, flags));
        }
        /**
         * Returns a value indicating whether a name is unique globally, within the current file,
         * or within the NameGenerator.
         */
        function isUniqueName(name) {
            return isFileLevelUniqueName(name)
                && !generatedNames.has(name)
                && !(reservedNames && reservedNames.has(name));
        }
        /**
         * Returns a value indicating whether a name is unique globally or within the current file.
         */
        function isFileLevelUniqueName(name) {
            return currentSourceFile ? ts.isFileLevelUniqueName(currentSourceFile, name, hasGlobalName) : true;
        }
        /**
         * Returns a value indicating whether a name is unique within a container.
         */
        function isUniqueLocalName(name, container) {
            for (var node = container; ts.isNodeDescendantOf(node, container); node = node.nextContainer) {
                if (node.locals) {
                    var local = node.locals.get(ts.escapeLeadingUnderscores(name));
                    // We conservatively include alias symbols to cover cases where they're emitted as locals
                    if (local && local.flags & (111551 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */)) {
                        return false;
                    }
                }
            }
            return true;
        }
        /**
         * Return the next available name in the pattern _a ... _z, _0, _1, ...
         * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name.
         * Note that names generated by makeTempVariableName and makeUniqueName will never conflict.
         */
        function makeTempVariableName(flags, reservedInNestedScopes) {
            if (flags && !(tempFlags & flags)) {
                var name = flags === 268435456 /* _i */ ? "_i" : "_n";
                if (isUniqueName(name)) {
                    tempFlags |= flags;
                    if (reservedInNestedScopes) {
                        reserveNameInNestedScopes(name);
                    }
                    return name;
                }
            }
            while (true) {
                var count = tempFlags & 268435455 /* CountMask */;
                tempFlags++;
                // Skip over 'i' and 'n'
                if (count !== 8 && count !== 13) {
                    var name = count < 26
                        ? "_" + String.fromCharCode(97 /* a */ + count)
                        : "_" + (count - 26);
                    if (isUniqueName(name)) {
                        if (reservedInNestedScopes) {
                            reserveNameInNestedScopes(name);
                        }
                        return name;
                    }
                }
            }
        }
        /**
         * Generate a name that is unique within the current file and doesn't conflict with any names
         * in global scope. The name is formed by adding an '_n' suffix to the specified base name,
         * where n is a positive integer. Note that names generated by makeTempVariableName and
         * makeUniqueName are guaranteed to never conflict.
         * If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1'
         */
        function makeUniqueName(baseName, checkFn, optimistic, scoped) {
            if (checkFn === void 0) { checkFn = isUniqueName; }
            if (optimistic) {
                if (checkFn(baseName)) {
                    if (scoped) {
                        reserveNameInNestedScopes(baseName);
                    }
                    else {
                        generatedNames.set(baseName, true);
                    }
                    return baseName;
                }
            }
            // Find the first unique 'name_n', where n is a positive number
            if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) {
                baseName += "_";
            }
            var i = 1;
            while (true) {
                var generatedName = baseName + i;
                if (checkFn(generatedName)) {
                    if (scoped) {
                        reserveNameInNestedScopes(generatedName);
                    }
                    else {
                        generatedNames.set(generatedName, true);
                    }
                    return generatedName;
                }
                i++;
            }
        }
        function makeFileLevelOptimisticUniqueName(name) {
            return makeUniqueName(name, isFileLevelUniqueName, /*optimistic*/ true);
        }
        /**
         * Generates a unique name for a ModuleDeclaration or EnumDeclaration.
         */
        function generateNameForModuleOrEnum(node) {
            var name = getTextOfNode(node.name);
            // Use module/enum name itself if it is unique, otherwise make a unique variation
            return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
        }
        /**
         * Generates a unique name for an ImportDeclaration or ExportDeclaration.
         */
        function generateNameForImportOrExportDeclaration(node) {
            var expr = ts.getExternalModuleName(node); // TODO: GH#18217
            var baseName = ts.isStringLiteral(expr) ?
                ts.makeIdentifierFromModuleName(expr.text) : "module";
            return makeUniqueName(baseName);
        }
        /**
         * Generates a unique name for a default export.
         */
        function generateNameForExportDefault() {
            return makeUniqueName("default");
        }
        /**
         * Generates a unique name for a class expression.
         */
        function generateNameForClassExpression() {
            return makeUniqueName("class");
        }
        function generateNameForMethodOrAccessor(node) {
            if (ts.isIdentifier(node.name)) {
                return generateNameCached(node.name);
            }
            return makeTempVariableName(0 /* Auto */);
        }
        /**
         * Generates a unique name from a node.
         */
        function generateNameForNode(node, flags) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return makeUniqueName(getTextOfNode(node), isUniqueName, !!(flags & 16 /* Optimistic */), !!(flags & 8 /* ReservedInNestedScopes */));
                case 249 /* ModuleDeclaration */:
                case 248 /* EnumDeclaration */:
                    return generateNameForModuleOrEnum(node);
                case 254 /* ImportDeclaration */:
                case 260 /* ExportDeclaration */:
                    return generateNameForImportOrExportDeclaration(node);
                case 244 /* FunctionDeclaration */:
                case 245 /* ClassDeclaration */:
                case 259 /* ExportAssignment */:
                    return generateNameForExportDefault();
                case 214 /* ClassExpression */:
                    return generateNameForClassExpression();
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return generateNameForMethodOrAccessor(node);
                case 154 /* ComputedPropertyName */:
                    return makeTempVariableName(0 /* Auto */, /*reserveInNestedScopes*/ true);
                default:
                    return makeTempVariableName(0 /* Auto */);
            }
        }
        /**
         * Generates a unique identifier for a node.
         */
        function makeName(name) {
            switch (name.autoGenerateFlags & 7 /* KindMask */) {
                case 1 /* Auto */:
                    return makeTempVariableName(0 /* Auto */, !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
                case 2 /* Loop */:
                    return makeTempVariableName(268435456 /* _i */, !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
                case 3 /* Unique */:
                    return makeUniqueName(ts.idText(name), (name.autoGenerateFlags & 32 /* FileLevel */) ? isFileLevelUniqueName : isUniqueName, !!(name.autoGenerateFlags & 16 /* Optimistic */), !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
            }
            return ts.Debug.fail("Unsupported GeneratedIdentifierKind.");
        }
        /**
         * Gets the node from which a name should be generated.
         */
        function getNodeForGeneratedName(name) {
            var autoGenerateId = name.autoGenerateId;
            var node = name;
            var original = node.original;
            while (original) {
                node = original;
                // if "node" is a different generated name (having a different
                // "autoGenerateId"), use it and stop traversing.
                if (ts.isIdentifier(node)
                    && !!(node.autoGenerateFlags & 4 /* Node */)
                    && node.autoGenerateId !== autoGenerateId) {
                    break;
                }
                original = node.original;
            }
            // otherwise, return the original node for the source;
            return node;
        }
        // Comments
        function pipelineEmitWithComments(hint, node) {
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
            enterComment();
            hasWrittenComment = false;
            var emitFlags = ts.getEmitFlags(node);
            var _a = ts.getCommentRange(node), pos = _a.pos, end = _a.end;
            var isEmittedNode = node.kind !== 325 /* NotEmittedStatement */;
            // We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
            // It is expensive to walk entire tree just to set one kind of node to have no comments.
            var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0 || node.kind === 11 /* JsxText */;
            var skipTrailingComments = end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0 || node.kind === 11 /* JsxText */;
            // Save current container state on the stack.
            var savedContainerPos = containerPos;
            var savedContainerEnd = containerEnd;
            var savedDeclarationListContainerEnd = declarationListContainerEnd;
            if ((pos > 0 || end > 0) && pos !== end) {
                // Emit leading comments if the position is not synthesized and the node
                // has not opted out from emitting leading comments.
                if (!skipLeadingComments) {
                    emitLeadingComments(pos, isEmittedNode);
                }
                if (!skipLeadingComments || (pos >= 0 && (emitFlags & 512 /* NoLeadingComments */) !== 0)) {
                    // Advance the container position if comments get emitted or if they've been disabled explicitly using NoLeadingComments.
                    containerPos = pos;
                }
                if (!skipTrailingComments || (end >= 0 && (emitFlags & 1024 /* NoTrailingComments */) !== 0)) {
                    // As above.
                    containerEnd = end;
                    // To avoid invalid comment emit in a down-level binding pattern, we
                    // keep track of the last declaration list container's end
                    if (node.kind === 243 /* VariableDeclarationList */) {
                        declarationListContainerEnd = end;
                    }
                }
            }
            ts.forEach(ts.getSyntheticLeadingComments(node), emitLeadingSynthesizedComment);
            exitComment();
            var pipelinePhase = getNextPipelinePhase(2 /* Comments */, hint, node);
            if (emitFlags & 2048 /* NoNestedComments */) {
                commentsDisabled = true;
                pipelinePhase(hint, node);
                commentsDisabled = false;
            }
            else {
                pipelinePhase(hint, node);
            }
            enterComment();
            ts.forEach(ts.getSyntheticTrailingComments(node), emitTrailingSynthesizedComment);
            if ((pos > 0 || end > 0) && pos !== end) {
                // Restore previous container state.
                containerPos = savedContainerPos;
                containerEnd = savedContainerEnd;
                declarationListContainerEnd = savedDeclarationListContainerEnd;
                // Emit trailing comments if the position is not synthesized and the node
                // has not opted out from emitting leading comments and is an emitted node.
                if (!skipTrailingComments && isEmittedNode) {
                    emitTrailingComments(end);
                }
            }
            exitComment();
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
        }
        function emitLeadingSynthesizedComment(comment) {
            if (comment.kind === 2 /* SingleLineCommentTrivia */) {
                writer.writeLine();
            }
            writeSynthesizedComment(comment);
            if (comment.hasTrailingNewLine || comment.kind === 2 /* SingleLineCommentTrivia */) {
                writer.writeLine();
            }
            else {
                writer.writeSpace(" ");
            }
        }
        function emitTrailingSynthesizedComment(comment) {
            if (!writer.isAtStartOfLine()) {
                writer.writeSpace(" ");
            }
            writeSynthesizedComment(comment);
            if (comment.hasTrailingNewLine) {
                writer.writeLine();
            }
        }
        function writeSynthesizedComment(comment) {
            var text = formatSynthesizedComment(comment);
            var lineMap = comment.kind === 3 /* MultiLineCommentTrivia */ ? ts.computeLineStarts(text) : undefined;
            ts.writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
        }
        function formatSynthesizedComment(comment) {
            return comment.kind === 3 /* MultiLineCommentTrivia */
                ? "/*" + comment.text + "*/"
                : "//" + comment.text;
        }
        function emitBodyWithDetachedComments(node, detachedRange, emitCallback) {
            enterComment();
            var pos = detachedRange.pos, end = detachedRange.end;
            var emitFlags = ts.getEmitFlags(node);
            var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0;
            var skipTrailingComments = commentsDisabled || end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0;
            if (!skipLeadingComments) {
                emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
            }
            exitComment();
            if (emitFlags & 2048 /* NoNestedComments */ && !commentsDisabled) {
                commentsDisabled = true;
                emitCallback(node);
                commentsDisabled = false;
            }
            else {
                emitCallback(node);
            }
            enterComment();
            if (!skipTrailingComments) {
                emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true);
                if (hasWrittenComment && !writer.isAtStartOfLine()) {
                    writer.writeLine();
                }
            }
            exitComment();
        }
        function emitLeadingComments(pos, isEmittedNode) {
            hasWrittenComment = false;
            if (isEmittedNode) {
                forEachLeadingCommentToEmit(pos, emitLeadingComment);
            }
            else if (pos === 0) {
                // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node,
                // unless it is a triple slash comment at the top of the file.
                // For Example:
                //      /// <reference-path ...>
                //      declare var x;
                //      /// <reference-path ...>
                //      interface F {}
                //  The first /// will NOT be removed while the second one will be removed even though both node will not be emitted
                forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment);
            }
        }
        function emitTripleSlashLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
            if (isTripleSlashComment(commentPos, commentEnd)) {
                emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos);
            }
        }
        function shouldWriteComment(text, pos) {
            if (printerOptions.onlyPrintJsDocStyle) {
                return (ts.isJSDocLikeText(text, pos) || ts.isPinnedComment(text, pos));
            }
            return true;
        }
        function emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            if (!hasWrittenComment) {
                ts.emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos);
                hasWrittenComment = true;
            }
            // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
            else if (kind === 3 /* MultiLineCommentTrivia */) {
                writer.writeSpace(" ");
            }
        }
        function emitLeadingCommentsOfPosition(pos) {
            if (commentsDisabled || pos === -1) {
                return;
            }
            emitLeadingComments(pos, /*isEmittedNode*/ true);
        }
        function emitTrailingComments(pos) {
            forEachTrailingCommentToEmit(pos, emitTrailingComment);
        }
        function emitTrailingComment(commentPos, commentEnd, _kind, hasTrailingNewLine) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
            if (!writer.isAtStartOfLine()) {
                writer.writeSpace(" ");
            }
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
        }
        function emitTrailingCommentsOfPosition(pos, prefixSpace) {
            if (commentsDisabled) {
                return;
            }
            enterComment();
            forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition);
            exitComment();
        }
        function emitTrailingCommentOfPosition(commentPos, commentEnd, _kind, hasTrailingNewLine) {
            // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
            else {
                writer.writeSpace(" ");
            }
        }
        function forEachLeadingCommentToEmit(pos, cb) {
            // Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments
            if (currentSourceFile && (containerPos === -1 || pos !== containerPos)) {
                if (hasDetachedComments(pos)) {
                    forEachLeadingCommentWithoutDetachedComments(cb);
                }
                else {
                    ts.forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
                }
            }
        }
        function forEachTrailingCommentToEmit(end, cb) {
            // Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments
            if (currentSourceFile && (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd))) {
                ts.forEachTrailingCommentRange(currentSourceFile.text, end, cb);
            }
        }
        function hasDetachedComments(pos) {
            return detachedCommentsInfo !== undefined && ts.last(detachedCommentsInfo).nodePos === pos;
        }
        function forEachLeadingCommentWithoutDetachedComments(cb) {
            // get the leading comments from detachedPos
            var pos = ts.last(detachedCommentsInfo).detachedCommentEndPos;
            if (detachedCommentsInfo.length - 1) {
                detachedCommentsInfo.pop();
            }
            else {
                detachedCommentsInfo = undefined;
            }
            ts.forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
        }
        function emitDetachedCommentsAndUpdateCommentsInfo(range) {
            var currentDetachedCommentInfo = ts.emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
            if (currentDetachedCommentInfo) {
                if (detachedCommentsInfo) {
                    detachedCommentsInfo.push(currentDetachedCommentInfo);
                }
                else {
                    detachedCommentsInfo = [currentDetachedCommentInfo];
                }
            }
        }
        function emitComment(text, lineMap, writer, commentPos, commentEnd, newLine) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            emitPos(commentPos);
            ts.writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
        }
        /**
         * Determine if the given comment is a triple-slash
         *
         * @return true if the comment is a triple-slash comment else false
         */
        function isTripleSlashComment(commentPos, commentEnd) {
            return ts.isRecognizedTripleSlashComment(currentSourceFile.text, commentPos, commentEnd);
        }
        // Source Maps
        function getParsedSourceMap(node) {
            if (node.parsedSourceMap === undefined && node.sourceMapText !== undefined) {
                node.parsedSourceMap = ts.tryParseRawSourceMap(node.sourceMapText) || false;
            }
            return node.parsedSourceMap || undefined;
        }
        function pipelineEmitWithSourceMap(hint, node) {
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
            var pipelinePhase = getNextPipelinePhase(3 /* SourceMaps */, hint, node);
            if (ts.isUnparsedSource(node) || ts.isUnparsedPrepend(node)) {
                pipelinePhase(hint, node);
            }
            else if (ts.isUnparsedNode(node)) {
                var parsed = getParsedSourceMap(node.parent);
                if (parsed && sourceMapGenerator) {
                    sourceMapGenerator.appendSourceMap(writer.getLine(), writer.getColumn(), parsed, node.parent.sourceMapPath, node.parent.getLineAndCharacterOfPosition(node.pos), node.parent.getLineAndCharacterOfPosition(node.end));
                }
                pipelinePhase(hint, node);
            }
            else {
                var _a = ts.getSourceMapRange(node), pos = _a.pos, end = _a.end, _b = _a.source, source = _b === void 0 ? sourceMapSource : _b;
                var emitFlags = ts.getEmitFlags(node);
                if (node.kind !== 325 /* NotEmittedStatement */
                    && (emitFlags & 16 /* NoLeadingSourceMap */) === 0
                    && pos >= 0) {
                    emitSourcePos(source, skipSourceTrivia(source, pos));
                }
                if (emitFlags & 64 /* NoNestedSourceMaps */) {
                    sourceMapsDisabled = true;
                    pipelinePhase(hint, node);
                    sourceMapsDisabled = false;
                }
                else {
                    pipelinePhase(hint, node);
                }
                if (node.kind !== 325 /* NotEmittedStatement */
                    && (emitFlags & 32 /* NoTrailingSourceMap */) === 0
                    && end >= 0) {
                    emitSourcePos(source, end);
                }
            }
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
        }
        /**
         * Skips trivia such as comments and white-space that can be optionally overridden by the source-map source
         */
        function skipSourceTrivia(source, pos) {
            return source.skipTrivia ? source.skipTrivia(pos) : ts.skipTrivia(source.text, pos);
        }
        /**
         * Emits a mapping.
         *
         * If the position is synthetic (undefined or a negative value), no mapping will be
         * created.
         *
         * @param pos The position.
         */
        function emitPos(pos) {
            if (sourceMapsDisabled || ts.positionIsSynthesized(pos) || isJsonSourceMapSource(sourceMapSource)) {
                return;
            }
            var _a = ts.getLineAndCharacterOfPosition(sourceMapSource, pos), sourceLine = _a.line, sourceCharacter = _a.character;
            sourceMapGenerator.addMapping(writer.getLine(), writer.getColumn(), sourceMapSourceIndex, sourceLine, sourceCharacter, 
            /*nameIndex*/ undefined);
        }
        function emitSourcePos(source, pos) {
            if (source !== sourceMapSource) {
                var savedSourceMapSource = sourceMapSource;
                setSourceMapSource(source);
                emitPos(pos);
                setSourceMapSource(savedSourceMapSource);
            }
            else {
                emitPos(pos);
            }
        }
        /**
         * Emits a token of a node with possible leading and trailing source maps.
         *
         * @param node The node containing the token.
         * @param token The token to emit.
         * @param tokenStartPos The start pos of the token.
         * @param emitCallback The callback used to emit the token.
         */
        function emitTokenWithSourceMap(node, token, writer, tokenPos, emitCallback) {
            if (sourceMapsDisabled || node && ts.isInJsonFile(node)) {
                return emitCallback(token, writer, tokenPos);
            }
            var emitNode = node && node.emitNode;
            var emitFlags = emitNode && emitNode.flags || 0 /* None */;
            var range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
            var source = range && range.source || sourceMapSource;
            tokenPos = skipSourceTrivia(source, range ? range.pos : tokenPos);
            if ((emitFlags & 128 /* NoTokenLeadingSourceMaps */) === 0 && tokenPos >= 0) {
                emitSourcePos(source, tokenPos);
            }
            tokenPos = emitCallback(token, writer, tokenPos);
            if (range)
                tokenPos = range.end;
            if ((emitFlags & 256 /* NoTokenTrailingSourceMaps */) === 0 && tokenPos >= 0) {
                emitSourcePos(source, tokenPos);
            }
            return tokenPos;
        }
        function setSourceMapSource(source) {
            if (sourceMapsDisabled) {
                return;
            }
            sourceMapSource = source;
            if (isJsonSourceMapSource(source)) {
                return;
            }
            sourceMapSourceIndex = sourceMapGenerator.addSource(source.fileName);
            if (printerOptions.inlineSources) {
                sourceMapGenerator.setSourceContent(sourceMapSourceIndex, source.text);
            }
        }
        function isJsonSourceMapSource(sourceFile) {
            return ts.fileExtensionIs(sourceFile.fileName, ".json" /* Json */);
        }
    }
    ts.createPrinter = createPrinter;
    function createBracketsMap() {
        var brackets = [];
        brackets[1024 /* Braces */] = ["{", "}"];
        brackets[2048 /* Parenthesis */] = ["(", ")"];
        brackets[4096 /* AngleBrackets */] = ["<", ">"];
        brackets[8192 /* SquareBrackets */] = ["[", "]"];
        return brackets;
    }
    function getOpeningBracket(format) {
        return brackets[format & 15360 /* BracketsMask */][0];
    }
    function getClosingBracket(format) {
        return brackets[format & 15360 /* BracketsMask */][1];
    }
    // Flags enum to track count of temp variables and a few dedicated names
    var TempFlags;
    (function (TempFlags) {
        TempFlags[TempFlags["Auto"] = 0] = "Auto";
        TempFlags[TempFlags["CountMask"] = 268435455] = "CountMask";
        TempFlags[TempFlags["_i"] = 268435456] = "_i";
    })(TempFlags || (TempFlags = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames) {
        if (!host.getDirectories || !host.readDirectory) {
            return undefined;
        }
        var cachedReadDirectoryResult = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        return {
            useCaseSensitiveFileNames: useCaseSensitiveFileNames,
            fileExists: fileExists,
            readFile: function (path, encoding) { return host.readFile(path, encoding); },
            directoryExists: host.directoryExists && directoryExists,
            getDirectories: getDirectories,
            readDirectory: readDirectory,
            createDirectory: host.createDirectory && createDirectory,
            writeFile: host.writeFile && writeFile,
            addOrDeleteFileOrDirectory: addOrDeleteFileOrDirectory,
            addOrDeleteFile: addOrDeleteFile,
            clearCache: clearCache,
            realpath: host.realpath && realpath
        };
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getCachedFileSystemEntries(rootDirPath) {
            return cachedReadDirectoryResult.get(ts.ensureTrailingDirectorySeparator(rootDirPath));
        }
        function getCachedFileSystemEntriesForBaseDir(path) {
            return getCachedFileSystemEntries(ts.getDirectoryPath(path));
        }
        function getBaseNameOfFileName(fileName) {
            return ts.getBaseFileName(ts.normalizePath(fileName));
        }
        function createCachedFileSystemEntries(rootDir, rootDirPath) {
            var resultFromHost = {
                files: ts.map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/ ["*.*"]), getBaseNameOfFileName) || [],
                directories: host.getDirectories(rootDir) || []
            };
            cachedReadDirectoryResult.set(ts.ensureTrailingDirectorySeparator(rootDirPath), resultFromHost);
            return resultFromHost;
        }
        /**
         * If the readDirectory result was already cached, it returns that
         * Otherwise gets result from host and caches it.
         * The host request is done under try catch block to avoid caching incorrect result
         */
        function tryReadDirectory(rootDir, rootDirPath) {
            rootDirPath = ts.ensureTrailingDirectorySeparator(rootDirPath);
            var cachedResult = getCachedFileSystemEntries(rootDirPath);
            if (cachedResult) {
                return cachedResult;
            }
            try {
                return createCachedFileSystemEntries(rootDir, rootDirPath);
            }
            catch (_e) {
                // If there is exception to read directories, dont cache the result and direct the calls to host
                ts.Debug.assert(!cachedReadDirectoryResult.has(ts.ensureTrailingDirectorySeparator(rootDirPath)));
                return undefined;
            }
        }
        function fileNameEqual(name1, name2) {
            return getCanonicalFileName(name1) === getCanonicalFileName(name2);
        }
        function hasEntry(entries, name) {
            return ts.some(entries, function (file) { return fileNameEqual(file, name); });
        }
        function updateFileSystemEntry(entries, baseName, isValid) {
            if (hasEntry(entries, baseName)) {
                if (!isValid) {
                    return ts.filterMutate(entries, function (entry) { return !fileNameEqual(entry, baseName); });
                }
            }
            else if (isValid) {
                return entries.push(baseName);
            }
        }
        function writeFile(fileName, data, writeByteOrderMark) {
            var path = toPath(fileName);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            if (result) {
                updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true);
            }
            return host.writeFile(fileName, data, writeByteOrderMark);
        }
        function fileExists(fileName) {
            var path = toPath(fileName);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            return result && hasEntry(result.files, getBaseNameOfFileName(fileName)) ||
                host.fileExists(fileName);
        }
        function directoryExists(dirPath) {
            var path = toPath(dirPath);
            return cachedReadDirectoryResult.has(ts.ensureTrailingDirectorySeparator(path)) || host.directoryExists(dirPath);
        }
        function createDirectory(dirPath) {
            var path = toPath(dirPath);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            var baseFileName = getBaseNameOfFileName(dirPath);
            if (result) {
                updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true);
            }
            host.createDirectory(dirPath);
        }
        function getDirectories(rootDir) {
            var rootDirPath = toPath(rootDir);
            var result = tryReadDirectory(rootDir, rootDirPath);
            if (result) {
                return result.directories.slice();
            }
            return host.getDirectories(rootDir);
        }
        function readDirectory(rootDir, extensions, excludes, includes, depth) {
            var rootDirPath = toPath(rootDir);
            var result = tryReadDirectory(rootDir, rootDirPath);
            if (result) {
                return ts.matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath);
            }
            return host.readDirectory(rootDir, extensions, excludes, includes, depth);
            function getFileSystemEntries(dir) {
                var path = toPath(dir);
                if (path === rootDirPath) {
                    return result;
                }
                return tryReadDirectory(dir, path) || ts.emptyFileSystemEntries;
            }
        }
        function realpath(s) {
            return host.realpath ? host.realpath(s) : s;
        }
        function addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath) {
            var existingResult = getCachedFileSystemEntries(fileOrDirectoryPath);
            if (existingResult) {
                // Just clear the cache for now
                // For now just clear the cache, since this could mean that multiple level entries might need to be re-evaluated
                clearCache();
                return undefined;
            }
            var parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath);
            if (!parentResult) {
                return undefined;
            }
            // This was earlier a file (hence not in cached directory contents)
            // or we never cached the directory containing it
            if (!host.directoryExists) {
                // Since host doesnt support directory exists, clear the cache as otherwise it might not be same
                clearCache();
                return undefined;
            }
            var baseName = getBaseNameOfFileName(fileOrDirectory);
            var fsQueryResult = {
                fileExists: host.fileExists(fileOrDirectoryPath),
                directoryExists: host.directoryExists(fileOrDirectoryPath)
            };
            if (fsQueryResult.directoryExists || hasEntry(parentResult.directories, baseName)) {
                // Folder added or removed, clear the cache instead of updating the folder and its structure
                clearCache();
            }
            else {
                // No need to update the directory structure, just files
                updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
            }
            return fsQueryResult;
        }
        function addOrDeleteFile(fileName, filePath, eventKind) {
            if (eventKind === ts.FileWatcherEventKind.Changed) {
                return;
            }
            var parentResult = getCachedFileSystemEntriesForBaseDir(filePath);
            if (parentResult) {
                updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === ts.FileWatcherEventKind.Created);
            }
        }
        function updateFilesOfFileSystemEntry(parentResult, baseName, fileExists) {
            updateFileSystemEntry(parentResult.files, baseName, fileExists);
        }
        function clearCache() {
            cachedReadDirectoryResult.clear();
        }
    }
    ts.createCachedDirectoryStructureHost = createCachedDirectoryStructureHost;
    var ConfigFileProgramReloadLevel;
    (function (ConfigFileProgramReloadLevel) {
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["None"] = 0] = "None";
        /** Update the file name list from the disk */
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
        /** Reload completely by re-reading contents of config file from disk and updating program */
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
    })(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
    /**
     * Updates the existing missing file watches with the new set of missing files after new program is created
     */
    function updateMissingFilePathsWatch(program, missingFileWatches, createMissingFileWatch) {
        var missingFilePaths = program.getMissingFilePaths();
        var newMissingFilePathMap = ts.arrayToSet(missingFilePaths);
        // Update the missing file paths watcher
        ts.mutateMap(missingFileWatches, newMissingFilePathMap, {
            // Watch the missing files
            createNewValue: createMissingFileWatch,
            // Files that are no longer missing (e.g. because they are no longer required)
            // should no longer be watched.
            onDeleteValue: ts.closeFileWatcher
        });
    }
    ts.updateMissingFilePathsWatch = updateMissingFilePathsWatch;
    /**
     * Updates the existing wild card directory watches with the new set of wild card directories from the config file
     * after new program is created because the config file was reloaded or program was created first time from the config file
     * Note that there is no need to call this function when the program is updated with additional files without reloading config files,
     * as wildcard directories wont change unless reloading config file
     */
    function updateWatchingWildcardDirectories(existingWatchedForWildcards, wildcardDirectories, watchDirectory) {
        ts.mutateMap(existingWatchedForWildcards, wildcardDirectories, {
            // Create new watch and recursive info
            createNewValue: createWildcardDirectoryWatcher,
            // Close existing watch thats not needed any more
            onDeleteValue: closeFileWatcherOf,
            // Close existing watch that doesnt match in the flags
            onExistingValue: updateWildcardDirectoryWatcher
        });
        function createWildcardDirectoryWatcher(directory, flags) {
            // Create new watch and recursive info
            return {
                watcher: watchDirectory(directory, flags),
                flags: flags
            };
        }
        function updateWildcardDirectoryWatcher(existingWatcher, flags, directory) {
            // Watcher needs to be updated if the recursive flags dont match
            if (existingWatcher.flags === flags) {
                return;
            }
            existingWatcher.watcher.close();
            existingWatchedForWildcards.set(directory, createWildcardDirectoryWatcher(directory, flags));
        }
    }
    ts.updateWatchingWildcardDirectories = updateWatchingWildcardDirectories;
    function isEmittedFileOfProgram(program, file) {
        if (!program) {
            return false;
        }
        return program.isEmittedFile(file);
    }
    ts.isEmittedFileOfProgram = isEmittedFileOfProgram;
    var WatchLogLevel;
    (function (WatchLogLevel) {
        WatchLogLevel[WatchLogLevel["None"] = 0] = "None";
        WatchLogLevel[WatchLogLevel["TriggerOnly"] = 1] = "TriggerOnly";
        WatchLogLevel[WatchLogLevel["Verbose"] = 2] = "Verbose";
    })(WatchLogLevel = ts.WatchLogLevel || (ts.WatchLogLevel = {}));
    function getWatchFactory(watchLogLevel, log, getDetailWatchInfo) {
        return getWatchFactoryWith(watchLogLevel, log, getDetailWatchInfo, watchFile, watchDirectory);
    }
    ts.getWatchFactory = getWatchFactory;
    function getWatchFactoryWith(watchLogLevel, log, getDetailWatchInfo, watchFile, watchDirectory) {
        var createFileWatcher = getCreateFileWatcher(watchLogLevel, watchFile);
        var createFilePathWatcher = watchLogLevel === WatchLogLevel.None ? watchFilePath : createFileWatcher;
        var createDirectoryWatcher = getCreateFileWatcher(watchLogLevel, watchDirectory);
        if (watchLogLevel === WatchLogLevel.Verbose && ts.sysLog === ts.noop) {
            ts.setSysLog(function (s) { return log(s); });
        }
        return {
            watchFile: function (host, file, callback, pollingInterval, options, detailInfo1, detailInfo2) {
                return createFileWatcher(host, file, callback, pollingInterval, options, /*passThrough*/ undefined, detailInfo1, detailInfo2, watchFile, log, "FileWatcher", getDetailWatchInfo);
            },
            watchFilePath: function (host, file, callback, pollingInterval, options, path, detailInfo1, detailInfo2) {
                return createFilePathWatcher(host, file, callback, pollingInterval, options, path, detailInfo1, detailInfo2, watchFile, log, "FileWatcher", getDetailWatchInfo);
            },
            watchDirectory: function (host, directory, callback, flags, options, detailInfo1, detailInfo2) {
                return createDirectoryWatcher(host, directory, callback, flags, options, /*passThrough*/ undefined, detailInfo1, detailInfo2, watchDirectory, log, "DirectoryWatcher", getDetailWatchInfo);
            }
        };
    }
    function watchFile(host, file, callback, pollingInterval, options) {
        return host.watchFile(file, callback, pollingInterval, options);
    }
    function watchFilePath(host, file, callback, pollingInterval, options, path) {
        return watchFile(host, file, function (fileName, eventKind) { return callback(fileName, eventKind, path); }, pollingInterval, options);
    }
    function watchDirectory(host, directory, callback, flags, options) {
        return host.watchDirectory(directory, callback, (flags & 1 /* Recursive */) !== 0, options);
    }
    function getCreateFileWatcher(watchLogLevel, addWatch) {
        switch (watchLogLevel) {
            case WatchLogLevel.None:
                return addWatch;
            case WatchLogLevel.TriggerOnly:
                return createFileWatcherWithTriggerLogging;
            case WatchLogLevel.Verbose:
                return addWatch === watchDirectory ? createDirectoryWatcherWithLogging : createFileWatcherWithLogging;
        }
    }
    function createFileWatcherWithLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        log(watchCaption + ":: Added:: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo));
        var watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
        return {
            close: function () {
                log(watchCaption + ":: Close:: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo));
                watcher.close();
            }
        };
    }
    function createDirectoryWatcherWithLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        var watchInfo = watchCaption + ":: Added:: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo);
        log(watchInfo);
        var start = ts.timestamp();
        var watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
        var elapsed = ts.timestamp() - start;
        log("Elapsed:: " + elapsed + "ms " + watchInfo);
        return {
            close: function () {
                var watchInfo = watchCaption + ":: Close:: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo);
                log(watchInfo);
                var start = ts.timestamp();
                watcher.close();
                var elapsed = ts.timestamp() - start;
                log("Elapsed:: " + elapsed + "ms " + watchInfo);
            }
        };
    }
    function createFileWatcherWithTriggerLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        return addWatch(host, file, function (fileName, cbOptional) {
            var triggerredInfo = watchCaption + ":: Triggered with " + fileName + " " + (cbOptional !== undefined ? cbOptional : "") + ":: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo);
            log(triggerredInfo);
            var start = ts.timestamp();
            cb(fileName, cbOptional, passThrough);
            var elapsed = ts.timestamp() - start;
            log("Elapsed:: " + elapsed + "ms " + triggerredInfo);
        }, flags, options);
    }
    function getFallbackOptions(options) {
        var fallbackPolling = options === null || options === void 0 ? void 0 : options.fallbackPolling;
        return {
            watchFile: fallbackPolling !== undefined ?
                fallbackPolling :
                ts.WatchFileKind.PriorityPollingInterval
        };
    }
    ts.getFallbackOptions = getFallbackOptions;
    function getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo) {
        return "WatchInfo: " + file + " " + flags + " " + JSON.stringify(options) + " " + (getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : detailInfo2 === undefined ? detailInfo1 : detailInfo1 + " " + detailInfo2);
    }
    function closeFileWatcherOf(objWithWatcher) {
        objWithWatcher.watcher.close();
    }
    ts.closeFileWatcherOf = closeFileWatcherOf;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function findConfigFile(searchPath, fileExists, configName) {
        if (configName === void 0) { configName = "tsconfig.json"; }
        return ts.forEachAncestorDirectory(searchPath, function (ancestor) {
            var fileName = ts.combinePaths(ancestor, configName);
            return fileExists(fileName) ? fileName : undefined;
        });
    }
    ts.findConfigFile = findConfigFile;
    function resolveTripleslashReference(moduleName, containingFile) {
        var basePath = ts.getDirectoryPath(containingFile);
        var referencedFileName = ts.isRootedDiskPath(moduleName) ? moduleName : ts.combinePaths(basePath, moduleName);
        return ts.normalizePath(referencedFileName);
    }
    ts.resolveTripleslashReference = resolveTripleslashReference;
    /* @internal */
    function computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName) {
        var commonPathComponents;
        var failed = ts.forEach(fileNames, function (sourceFile) {
            // Each file contributes into common source file path
            var sourcePathComponents = ts.getNormalizedPathComponents(sourceFile, currentDirectory);
            sourcePathComponents.pop(); // The base file name is not part of the common directory path
            if (!commonPathComponents) {
                // first file
                commonPathComponents = sourcePathComponents;
                return;
            }
            var n = Math.min(commonPathComponents.length, sourcePathComponents.length);
            for (var i = 0; i < n; i++) {
                if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) {
                    if (i === 0) {
                        // Failed to find any common path component
                        return true;
                    }
                    // New common path found that is 0 -> i-1
                    commonPathComponents.length = i;
                    break;
                }
            }
            // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents
            if (sourcePathComponents.length < commonPathComponents.length) {
                commonPathComponents.length = sourcePathComponents.length;
            }
        });
        // A common path can not be found when paths span multiple drives on windows, for example
        if (failed) {
            return "";
        }
        if (!commonPathComponents) { // Can happen when all input files are .d.ts files
            return currentDirectory;
        }
        return ts.getPathFromPathComponents(commonPathComponents);
    }
    ts.computeCommonSourceDirectoryOfFilenames = computeCommonSourceDirectoryOfFilenames;
    function createCompilerHost(options, setParentNodes) {
        return createCompilerHostWorker(options, setParentNodes);
    }
    ts.createCompilerHost = createCompilerHost;
    /*@internal*/
    // TODO(shkamat): update this after reworking ts build API
    function createCompilerHostWorker(options, setParentNodes, system) {
        if (system === void 0) { system = ts.sys; }
        var existingDirectories = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(system.useCaseSensitiveFileNames);
        function getSourceFile(fileName, languageVersion, onError) {
            var text;
            try {
                ts.performance.mark("beforeIORead");
                text = compilerHost.readFile(fileName);
                ts.performance.mark("afterIORead");
                ts.performance.measure("I/O Read", "beforeIORead", "afterIORead");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
                text = "";
            }
            return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined;
        }
        function directoryExists(directoryPath) {
            if (existingDirectories.has(directoryPath)) {
                return true;
            }
            if ((compilerHost.directoryExists || system.directoryExists)(directoryPath)) {
                existingDirectories.set(directoryPath, true);
                return true;
            }
            return false;
        }
        function writeFile(fileName, data, writeByteOrderMark, onError) {
            try {
                ts.performance.mark("beforeIOWrite");
                // NOTE: If patchWriteFileEnsuringDirectory has been called,
                // the system.writeFile will do its own directory creation and
                // the ensureDirectoriesExist call will always be redundant.
                ts.writeFileEnsuringDirectories(fileName, data, writeByteOrderMark, function (path, data, writeByteOrderMark) { return writeFileWorker(path, data, writeByteOrderMark); }, function (path) { return (compilerHost.createDirectory || system.createDirectory)(path); }, function (path) { return directoryExists(path); });
                ts.performance.mark("afterIOWrite");
                ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
            }
        }
        var outputFingerprints;
        function writeFileWorker(fileName, data, writeByteOrderMark) {
            if (!ts.isWatchSet(options) || !system.createHash || !system.getModifiedTime) {
                system.writeFile(fileName, data, writeByteOrderMark);
                return;
            }
            if (!outputFingerprints) {
                outputFingerprints = ts.createMap();
            }
            var hash = system.createHash(data);
            var mtimeBefore = system.getModifiedTime(fileName);
            if (mtimeBefore) {
                var fingerprint = outputFingerprints.get(fileName);
                // If output has not been changed, and the file has no external modification
                if (fingerprint &&
                    fingerprint.byteOrderMark === writeByteOrderMark &&
                    fingerprint.hash === hash &&
                    fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
                    return;
                }
            }
            system.writeFile(fileName, data, writeByteOrderMark);
            var mtimeAfter = system.getModifiedTime(fileName) || ts.missingFileModifiedTime;
            outputFingerprints.set(fileName, {
                hash: hash,
                byteOrderMark: writeByteOrderMark,
                mtime: mtimeAfter
            });
        }
        function getDefaultLibLocation() {
            return ts.getDirectoryPath(ts.normalizePath(system.getExecutingFilePath()));
        }
        var newLine = ts.getNewLineCharacter(options, function () { return system.newLine; });
        var realpath = system.realpath && (function (path) { return system.realpath(path); });
        var compilerHost = {
            getSourceFile: getSourceFile,
            getDefaultLibLocation: getDefaultLibLocation,
            getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); },
            writeFile: writeFile,
            getCurrentDirectory: ts.memoize(function () { return system.getCurrentDirectory(); }),
            useCaseSensitiveFileNames: function () { return system.useCaseSensitiveFileNames; },
            getCanonicalFileName: getCanonicalFileName,
            getNewLine: function () { return newLine; },
            fileExists: function (fileName) { return system.fileExists(fileName); },
            readFile: function (fileName) { return system.readFile(fileName); },
            trace: function (s) { return system.write(s + newLine); },
            directoryExists: function (directoryName) { return system.directoryExists(directoryName); },
            getEnvironmentVariable: function (name) { return system.getEnvironmentVariable ? system.getEnvironmentVariable(name) : ""; },
            getDirectories: function (path) { return system.getDirectories(path); },
            realpath: realpath,
            readDirectory: function (path, extensions, include, exclude, depth) { return system.readDirectory(path, extensions, include, exclude, depth); },
            createDirectory: function (d) { return system.createDirectory(d); },
            createHash: ts.maybeBind(system, system.createHash)
        };
        return compilerHost;
    }
    ts.createCompilerHostWorker = createCompilerHostWorker;
    /*@internal*/
    function changeCompilerHostLikeToUseCache(host, toPath, getSourceFile) {
        var originalReadFile = host.readFile;
        var originalFileExists = host.fileExists;
        var originalDirectoryExists = host.directoryExists;
        var originalCreateDirectory = host.createDirectory;
        var originalWriteFile = host.writeFile;
        var readFileCache = ts.createMap();
        var fileExistsCache = ts.createMap();
        var directoryExistsCache = ts.createMap();
        var sourceFileCache = ts.createMap();
        var readFileWithCache = function (fileName) {
            var key = toPath(fileName);
            var value = readFileCache.get(key);
            if (value !== undefined)
                return value !== false ? value : undefined;
            return setReadFileCache(key, fileName);
        };
        var setReadFileCache = function (key, fileName) {
            var newValue = originalReadFile.call(host, fileName);
            readFileCache.set(key, newValue !== undefined ? newValue : false);
            return newValue;
        };
        host.readFile = function (fileName) {
            var key = toPath(fileName);
            var value = readFileCache.get(key);
            if (value !== undefined)
                return value !== false ? value : undefined; // could be .d.ts from output
            // Cache json or buildInfo
            if (!ts.fileExtensionIs(fileName, ".json" /* Json */) && !ts.isBuildInfoFile(fileName)) {
                return originalReadFile.call(host, fileName);
            }
            return setReadFileCache(key, fileName);
        };
        var getSourceFileWithCache = getSourceFile ? function (fileName, languageVersion, onError, shouldCreateNewSourceFile) {
            var key = toPath(fileName);
            var value = sourceFileCache.get(key);
            if (value)
                return value;
            var sourceFile = getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
            if (sourceFile && (ts.isDeclarationFileName(fileName) || ts.fileExtensionIs(fileName, ".json" /* Json */))) {
                sourceFileCache.set(key, sourceFile);
            }
            return sourceFile;
        } : undefined;
        // fileExists for any kind of extension
        host.fileExists = function (fileName) {
            var key = toPath(fileName);
            var value = fileExistsCache.get(key);
            if (value !== undefined)
                return value;
            var newValue = originalFileExists.call(host, fileName);
            fileExistsCache.set(key, !!newValue);
            return newValue;
        };
        if (originalWriteFile) {
            host.writeFile = function (fileName, data, writeByteOrderMark, onError, sourceFiles) {
                var key = toPath(fileName);
                fileExistsCache.delete(key);
                var value = readFileCache.get(key);
                if (value !== undefined && value !== data) {
                    readFileCache.delete(key);
                    sourceFileCache.delete(key);
                }
                else if (getSourceFileWithCache) {
                    var sourceFile = sourceFileCache.get(key);
                    if (sourceFile && sourceFile.text !== data) {
                        sourceFileCache.delete(key);
                    }
                }
                originalWriteFile.call(host, fileName, data, writeByteOrderMark, onError, sourceFiles);
            };
        }
        // directoryExists
        if (originalDirectoryExists && originalCreateDirectory) {
            host.directoryExists = function (directory) {
                var key = toPath(directory);
                var value = directoryExistsCache.get(key);
                if (value !== undefined)
                    return value;
                var newValue = originalDirectoryExists.call(host, directory);
                directoryExistsCache.set(key, !!newValue);
                return newValue;
            };
            host.createDirectory = function (directory) {
                var key = toPath(directory);
                directoryExistsCache.delete(key);
                originalCreateDirectory.call(host, directory);
            };
        }
        return {
            originalReadFile: originalReadFile,
            originalFileExists: originalFileExists,
            originalDirectoryExists: originalDirectoryExists,
            originalCreateDirectory: originalCreateDirectory,
            originalWriteFile: originalWriteFile,
            getSourceFileWithCache: getSourceFileWithCache,
            readFileWithCache: readFileWithCache
        };
    }
    ts.changeCompilerHostLikeToUseCache = changeCompilerHostLikeToUseCache;
    function getPreEmitDiagnostics(program, sourceFile, cancellationToken) {
        var diagnostics;
        diagnostics = ts.addRange(diagnostics, program.getConfigFileParsingDiagnostics());
        diagnostics = ts.addRange(diagnostics, program.getOptionsDiagnostics(cancellationToken));
        diagnostics = ts.addRange(diagnostics, program.getSyntacticDiagnostics(sourceFile, cancellationToken));
        diagnostics = ts.addRange(diagnostics, program.getGlobalDiagnostics(cancellationToken));
        diagnostics = ts.addRange(diagnostics, program.getSemanticDiagnostics(sourceFile, cancellationToken));
        if (ts.getEmitDeclarations(program.getCompilerOptions())) {
            diagnostics = ts.addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
        }
        return ts.sortAndDeduplicateDiagnostics(diagnostics || ts.emptyArray);
    }
    ts.getPreEmitDiagnostics = getPreEmitDiagnostics;
    function formatDiagnostics(diagnostics, host) {
        var output = "";
        for (var _i = 0, diagnostics_2 = diagnostics; _i < diagnostics_2.length; _i++) {
            var diagnostic = diagnostics_2[_i];
            output += formatDiagnostic(diagnostic, host);
        }
        return output;
    }
    ts.formatDiagnostics = formatDiagnostics;
    function formatDiagnostic(diagnostic, host) {
        var errorMessage = ts.diagnosticCategoryName(diagnostic) + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine();
        if (diagnostic.file) {
            var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; // TODO: GH#18217
            var fileName = diagnostic.file.fileName;
            var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); });
            return relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): " + errorMessage;
        }
        return errorMessage;
    }
    ts.formatDiagnostic = formatDiagnostic;
    /** @internal */
    var ForegroundColorEscapeSequences;
    (function (ForegroundColorEscapeSequences) {
        ForegroundColorEscapeSequences["Grey"] = "\u001B[90m";
        ForegroundColorEscapeSequences["Red"] = "\u001B[91m";
        ForegroundColorEscapeSequences["Yellow"] = "\u001B[93m";
        ForegroundColorEscapeSequences["Blue"] = "\u001B[94m";
        ForegroundColorEscapeSequences["Cyan"] = "\u001B[96m";
    })(ForegroundColorEscapeSequences = ts.ForegroundColorEscapeSequences || (ts.ForegroundColorEscapeSequences = {}));
    var gutterStyleSequence = "\u001b[7m";
    var gutterSeparator = " ";
    var resetEscapeSequence = "\u001b[0m";
    var ellipsis = "...";
    var halfIndent = "  ";
    var indent = "    ";
    function getCategoryFormat(category) {
        switch (category) {
            case ts.DiagnosticCategory.Error: return ForegroundColorEscapeSequences.Red;
            case ts.DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow;
            case ts.DiagnosticCategory.Suggestion: return ts.Debug.fail("Should never get an Info diagnostic on the command line.");
            case ts.DiagnosticCategory.Message: return ForegroundColorEscapeSequences.Blue;
        }
    }
    /** @internal */
    function formatColorAndReset(text, formatStyle) {
        return formatStyle + text + resetEscapeSequence;
    }
    ts.formatColorAndReset = formatColorAndReset;
    function formatCodeSpan(file, start, length, indent, squiggleColor, host) {
        var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character;
        var _b = ts.getLineAndCharacterOfPosition(file, start + length), lastLine = _b.line, lastLineChar = _b.character;
        var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line;
        var hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
        var gutterWidth = (lastLine + 1 + "").length;
        if (hasMoreThanFiveLines) {
            gutterWidth = Math.max(ellipsis.length, gutterWidth);
        }
        var context = "";
        for (var i = firstLine; i <= lastLine; i++) {
            context += host.getNewLine();
            // If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
            // so we'll skip ahead to the second-to-last line.
            if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
                context += indent + formatColorAndReset(ts.padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
                i = lastLine - 1;
            }
            var lineStart = ts.getPositionOfLineAndCharacter(file, i, 0);
            var lineEnd = i < lastLineInFile ? ts.getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
            var lineContent = file.text.slice(lineStart, lineEnd);
            lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
            lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
            // Output the gutter and the actual contents of the line.
            context += indent + formatColorAndReset(ts.padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
            context += lineContent + host.getNewLine();
            // Output the gutter and the error span for the line using tildes.
            context += indent + formatColorAndReset(ts.padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
            context += squiggleColor;
            if (i === firstLine) {
                // If we're on the last line, then limit it to the last character of the last line.
                // Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position.
                var lastCharForLine = i === lastLine ? lastLineChar : undefined;
                context += lineContent.slice(0, firstLineChar).replace(/\S/g, " ");
                context += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~");
            }
            else if (i === lastLine) {
                context += lineContent.slice(0, lastLineChar).replace(/./g, "~");
            }
            else {
                // Squiggle the entire line.
                context += lineContent.replace(/./g, "~");
            }
            context += resetEscapeSequence;
        }
        return context;
    }
    /* @internal */
    function formatLocation(file, start, host, color) {
        if (color === void 0) { color = formatColorAndReset; }
        var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character; // TODO: GH#18217
        var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName;
        var output = "";
        output += color(relativeFileName, ForegroundColorEscapeSequences.Cyan);
        output += ":";
        output += color("" + (firstLine + 1), ForegroundColorEscapeSequences.Yellow);
        output += ":";
        output += color("" + (firstLineChar + 1), ForegroundColorEscapeSequences.Yellow);
        return output;
    }
    ts.formatLocation = formatLocation;
    function formatDiagnosticsWithColorAndContext(diagnostics, host) {
        var output = "";
        for (var _i = 0, diagnostics_3 = diagnostics; _i < diagnostics_3.length; _i++) {
            var diagnostic = diagnostics_3[_i];
            if (diagnostic.file) {
                var file = diagnostic.file, start = diagnostic.start;
                output += formatLocation(file, start, host); // TODO: GH#18217
                output += " - ";
            }
            output += formatColorAndReset(ts.diagnosticCategoryName(diagnostic), getCategoryFormat(diagnostic.category));
            output += formatColorAndReset(" TS" + diagnostic.code + ": ", ForegroundColorEscapeSequences.Grey);
            output += flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine());
            if (diagnostic.file) {
                output += host.getNewLine();
                output += formatCodeSpan(diagnostic.file, diagnostic.start, diagnostic.length, "", getCategoryFormat(diagnostic.category), host); // TODO: GH#18217
                if (diagnostic.relatedInformation) {
                    output += host.getNewLine();
                    for (var _a = 0, _b = diagnostic.relatedInformation; _a < _b.length; _a++) {
                        var _c = _b[_a], file = _c.file, start = _c.start, length_8 = _c.length, messageText = _c.messageText;
                        if (file) {
                            output += host.getNewLine();
                            output += halfIndent + formatLocation(file, start, host); // TODO: GH#18217
                            output += formatCodeSpan(file, start, length_8, indent, ForegroundColorEscapeSequences.Cyan, host); // TODO: GH#18217
                        }
                        output += host.getNewLine();
                        output += indent + flattenDiagnosticMessageText(messageText, host.getNewLine());
                    }
                }
            }
            output += host.getNewLine();
        }
        return output;
    }
    ts.formatDiagnosticsWithColorAndContext = formatDiagnosticsWithColorAndContext;
    function flattenDiagnosticMessageText(diag, newLine, indent) {
        if (indent === void 0) { indent = 0; }
        if (ts.isString(diag)) {
            return diag;
        }
        else if (diag === undefined) {
            return "";
        }
        var result = "";
        if (indent) {
            result += newLine;
            for (var i = 0; i < indent; i++) {
                result += "  ";
            }
        }
        result += diag.messageText;
        indent++;
        if (diag.next) {
            for (var _i = 0, _a = diag.next; _i < _a.length; _i++) {
                var kid = _a[_i];
                result += flattenDiagnosticMessageText(kid, newLine, indent);
            }
        }
        return result;
    }
    ts.flattenDiagnosticMessageText = flattenDiagnosticMessageText;
    /* @internal */
    function loadWithLocalCache(names, containingFile, redirectedReference, loader) {
        if (names.length === 0) {
            return [];
        }
        var resolutions = [];
        var cache = ts.createMap();
        for (var _i = 0, names_2 = names; _i < names_2.length; _i++) {
            var name = names_2[_i];
            var result = void 0;
            if (cache.has(name)) {
                result = cache.get(name);
            }
            else {
                cache.set(name, result = loader(name, containingFile, redirectedReference));
            }
            resolutions.push(result);
        }
        return resolutions;
    }
    ts.loadWithLocalCache = loadWithLocalCache;
    /* @internal */
    ts.inferredTypesContainingFile = "__inferred type names__.ts";
    /**
     * Determines if program structure is upto date or needs to be recreated
     */
    /* @internal */
    function isProgramUptoDate(program, rootFileNames, newOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, projectReferences) {
        // If we haven't created a program yet or have changed automatic type directives, then it is not up-to-date
        if (!program || hasChangedAutomaticTypeDirectiveNames) {
            return false;
        }
        // If root file names don't match
        if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) {
            return false;
        }
        var seenResolvedRefs;
        // If project references don't match
        if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) {
            return false;
        }
        // If any file is not up-to-date, then the whole program is not up-to-date
        if (program.getSourceFiles().some(sourceFileNotUptoDate)) {
            return false;
        }
        // If any of the missing file paths are now created
        if (program.getMissingFilePaths().some(fileExists)) {
            return false;
        }
        var currentOptions = program.getCompilerOptions();
        // If the compilation settings do no match, then the program is not up-to-date
        if (!ts.compareDataObjects(currentOptions, newOptions)) {
            return false;
        }
        // If everything matches but the text of config file is changed,
        // error locations can change for program options, so update the program
        if (currentOptions.configFile && newOptions.configFile) {
            return currentOptions.configFile.text === newOptions.configFile.text;
        }
        return true;
        function sourceFileNotUptoDate(sourceFile) {
            return !sourceFileVersionUptoDate(sourceFile) ||
                hasInvalidatedResolution(sourceFile.path);
        }
        function sourceFileVersionUptoDate(sourceFile) {
            return sourceFile.version === getSourceVersion(sourceFile.resolvedPath, sourceFile.fileName);
        }
        function projectReferenceUptoDate(oldRef, newRef, index) {
            if (!ts.projectReferenceIsEqualTo(oldRef, newRef)) {
                return false;
            }
            return resolvedProjectReferenceUptoDate(program.getResolvedProjectReferences()[index], oldRef);
        }
        function resolvedProjectReferenceUptoDate(oldResolvedRef, oldRef) {
            if (oldResolvedRef) {
                if (ts.contains(seenResolvedRefs, oldResolvedRef)) {
                    // Assume true
                    return true;
                }
                // If sourceFile for the oldResolvedRef existed, check the version for uptodate
                if (!sourceFileVersionUptoDate(oldResolvedRef.sourceFile)) {
                    return false;
                }
                // Add to seen before checking the referenced paths of this config file
                (seenResolvedRefs || (seenResolvedRefs = [])).push(oldResolvedRef);
                // If child project references are upto date, this project reference is uptodate
                return !ts.forEach(oldResolvedRef.references, function (childResolvedRef, index) {
                    return !resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences[index]);
                });
            }
            // In old program, not able to resolve project reference path,
            // so if config file doesnt exist, it is uptodate.
            return !fileExists(resolveProjectReferencePath(oldRef));
        }
    }
    ts.isProgramUptoDate = isProgramUptoDate;
    function getConfigFileParsingDiagnostics(configFileParseResult) {
        return configFileParseResult.options.configFile ? __spreadArrays(configFileParseResult.options.configFile.parseDiagnostics, configFileParseResult.errors) :
            configFileParseResult.errors;
    }
    ts.getConfigFileParsingDiagnostics = getConfigFileParsingDiagnostics;
    /**
     * Determine if source file needs to be re-created even if its text hasn't changed
     */
    function shouldProgramCreateNewSourceFiles(program, newOptions) {
        if (!program)
            return false;
        // If any compiler options change, we can't reuse old source file even if version match
        // The change in options like these could result in change in syntax tree or `sourceFile.bindDiagnostics`.
        var oldOptions = program.getCompilerOptions();
        return !!ts.sourceFileAffectingCompilerOptions.some(function (option) {
            return !ts.isJsonEqual(ts.getCompilerOptionValue(oldOptions, option), ts.getCompilerOptionValue(newOptions, option));
        });
    }
    function createCreateProgramOptions(rootNames, options, host, oldProgram, configFileParsingDiagnostics) {
        return {
            rootNames: rootNames,
            options: options,
            host: host,
            oldProgram: oldProgram,
            configFileParsingDiagnostics: configFileParsingDiagnostics
        };
    }
    function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {
        var _a;
        var createProgramOptions = ts.isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217
        var rootNames = createProgramOptions.rootNames, options = createProgramOptions.options, configFileParsingDiagnostics = createProgramOptions.configFileParsingDiagnostics, projectReferences = createProgramOptions.projectReferences;
        var oldProgram = createProgramOptions.oldProgram;
        var processingDefaultLibFiles;
        var processingOtherFiles;
        var files;
        var symlinks;
        var commonSourceDirectory;
        var diagnosticsProducingTypeChecker;
        var noDiagnosticsTypeChecker;
        var classifiableNames;
        var ambientModuleNameToUnmodifiedFileName = ts.createMap();
        // Todo:: Use this to report why file was included in --extendedDiagnostics
        var refFileMap;
        var cachedBindAndCheckDiagnosticsForFile = {};
        var cachedDeclarationDiagnosticsForFile = {};
        var resolvedTypeReferenceDirectives = ts.createMap();
        var fileProcessingDiagnostics = ts.createDiagnosticCollection();
        // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules.
        // This works as imported modules are discovered recursively in a depth first manner, specifically:
        // - For each root file, findSourceFile is called.
        // - This calls processImportedModules for each module imported in the source file.
        // - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
        // As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
        // The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
        var maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
        var currentNodeModulesDepth = 0;
        // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
        // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed.
        var modulesWithElidedImports = ts.createMap();
        // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled.
        var sourceFilesFoundSearchingNodeModules = ts.createMap();
        ts.performance.mark("beforeProgram");
        var host = createProgramOptions.host || createCompilerHost(options);
        var configParsingHost = parseConfigHostFromCompilerHostLike(host);
        var skipDefaultLib = options.noLib;
        var getDefaultLibraryFileName = ts.memoize(function () { return host.getDefaultLibFileName(options); });
        var defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : ts.getDirectoryPath(getDefaultLibraryFileName());
        var programDiagnostics = ts.createDiagnosticCollection();
        var currentDirectory = host.getCurrentDirectory();
        var supportedExtensions = ts.getSupportedExtensions(options);
        var supportedExtensionsWithJsonIfResolveJsonModule = ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
        // Map storing if there is emit blocking diagnostics for given input
        var hasEmitBlockingDiagnostics = ts.createMap();
        var _compilerOptionsObjectLiteralSyntax;
        var moduleResolutionCache;
        var actualResolveModuleNamesWorker;
        var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
        if (host.resolveModuleNames) {
            actualResolveModuleNamesWorker = function (moduleNames, containingFile, reusedNames, redirectedReference) { return host.resolveModuleNames(ts.Debug.checkEachDefined(moduleNames), containingFile, reusedNames, redirectedReference, options).map(function (resolved) {
                // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
                if (!resolved || resolved.extension !== undefined) {
                    return resolved;
                }
                var withExtension = ts.clone(resolved);
                withExtension.extension = ts.extensionFromPath(resolved.resolvedFileName);
                return withExtension;
            }); };
        }
        else {
            moduleResolutionCache = ts.createModuleResolutionCache(currentDirectory, function (x) { return host.getCanonicalFileName(x); }, options);
            var loader_1 = function (moduleName, containingFile, redirectedReference) { return ts.resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache, redirectedReference).resolvedModule; }; // TODO: GH#18217
            actualResolveModuleNamesWorker = function (moduleNames, containingFile, _reusedNames, redirectedReference) { return loadWithLocalCache(ts.Debug.checkEachDefined(moduleNames), containingFile, redirectedReference, loader_1); };
        }
        var actualResolveTypeReferenceDirectiveNamesWorker;
        if (host.resolveTypeReferenceDirectives) {
            actualResolveTypeReferenceDirectiveNamesWorker = function (typeDirectiveNames, containingFile, redirectedReference) { return host.resolveTypeReferenceDirectives(ts.Debug.checkEachDefined(typeDirectiveNames), containingFile, redirectedReference, options); };
        }
        else {
            var loader_2 = function (typesRef, containingFile, redirectedReference) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host, redirectedReference).resolvedTypeReferenceDirective; }; // TODO: GH#18217
            actualResolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile, redirectedReference) { return loadWithLocalCache(ts.Debug.checkEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader_2); };
        }
        // Map from a stringified PackageId to the source file with that id.
        // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile).
        // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around.
        var packageIdToSourceFile = ts.createMap();
        // Maps from a SourceFile's `.path` to the name of the package it was imported with.
        var sourceFileToPackageName = ts.createMap();
        // Key is a file name. Value is the (non-empty, or undefined) list of files that redirect to it.
        var redirectTargetsMap = ts.createMultiMap();
        /**
         * map with
         * - SourceFile if present
         * - false if sourceFile missing for source of project reference redirect
         * - undefined otherwise
         */
        var filesByName = ts.createMap();
        var missingFilePaths;
        // stores 'filename -> file association' ignoring case
        // used to track cases when two file names differ only in casing
        var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined;
        // A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
        var resolvedProjectReferences;
        var projectReferenceRedirects;
        var mapFromFileToProjectReferenceRedirects;
        var mapFromToProjectReferenceRedirectSource;
        var useSourceOfProjectReferenceRedirect = !!((_a = host.useSourceOfProjectReferenceRedirect) === null || _a === void 0 ? void 0 : _a.call(host)) &&
            !options.disableSourceOfProjectReferenceRedirect;
        var _b = updateHostForUseSourceOfProjectReferenceRedirect({
            compilerHost: host,
            useSourceOfProjectReferenceRedirect: useSourceOfProjectReferenceRedirect,
            toPath: toPath,
            getResolvedProjectReferences: getResolvedProjectReferences,
            getSourceOfProjectReferenceRedirect: getSourceOfProjectReferenceRedirect,
            forEachResolvedProjectReference: forEachResolvedProjectReference
        }), onProgramCreateComplete = _b.onProgramCreateComplete, fileExists = _b.fileExists;
        var shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
        // We set `structuralIsReused` to `undefined` because `tryReuseStructureFromOldProgram` calls `tryReuseStructureFromOldProgram` which checks
        // `structuralIsReused`, which would be a TDZ violation if it was not set in advance to `undefined`.
        var structuralIsReused;
        structuralIsReused = tryReuseStructureFromOldProgram(); // eslint-disable-line prefer-const
        if (structuralIsReused !== 2 /* Completely */) {
            processingDefaultLibFiles = [];
            processingOtherFiles = [];
            if (projectReferences) {
                if (!resolvedProjectReferences) {
                    resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
                }
                if (rootNames.length) {
                    for (var _i = 0, resolvedProjectReferences_1 = resolvedProjectReferences; _i < resolvedProjectReferences_1.length; _i++) {
                        var parsedRef = resolvedProjectReferences_1[_i];
                        if (!parsedRef)
                            continue;
                        var out = parsedRef.commandLine.options.outFile || parsedRef.commandLine.options.out;
                        if (useSourceOfProjectReferenceRedirect) {
                            if (out || ts.getEmitModuleKind(parsedRef.commandLine.options) === ts.ModuleKind.None) {
                                for (var _c = 0, _d = parsedRef.commandLine.fileNames; _c < _d.length; _c++) {
                                    var fileName = _d[_c];
                                    processSourceFile(fileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
                                }
                            }
                        }
                        else {
                            if (out) {
                                processSourceFile(ts.changeExtension(out, ".d.ts"), /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
                            }
                            else if (ts.getEmitModuleKind(parsedRef.commandLine.options) === ts.ModuleKind.None) {
                                for (var _e = 0, _f = parsedRef.commandLine.fileNames; _e < _f.length; _e++) {
                                    var fileName = _f[_e];
                                    if (!ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) && !ts.fileExtensionIs(fileName, ".json" /* Json */)) {
                                        processSourceFile(ts.getOutputDeclarationFileName(fileName, parsedRef.commandLine, !host.useCaseSensitiveFileNames()), /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false); });
            // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
            var typeReferences = rootNames.length ? ts.getAutomaticTypeDirectiveNames(options, host) : ts.emptyArray;
            if (typeReferences.length) {
                // This containingFilename needs to match with the one used in managed-side
                var containingDirectory = options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
                var containingFilename = ts.combinePaths(containingDirectory, ts.inferredTypesContainingFile);
                var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
                for (var i = 0; i < typeReferences.length; i++) {
                    processTypeReferenceDirective(typeReferences[i], resolutions[i]);
                }
            }
            // Do not process the default library if:
            //  - The '--noLib' flag is used.
            //  - A 'no-default-lib' reference comment is encountered in
            //      processing the root files.
            if (rootNames.length && !skipDefaultLib) {
                // If '--lib' is not specified, include default library file according to '--target'
                // otherwise, using options specified in '--lib' instead of '--target' default library file
                var defaultLibraryFileName = getDefaultLibraryFileName();
                if (!options.lib && defaultLibraryFileName) {
                    processRootFile(defaultLibraryFileName, /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false);
                }
                else {
                    ts.forEach(options.lib, function (libFileName) {
                        processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false);
                    });
                }
            }
            missingFilePaths = ts.arrayFrom(ts.mapDefinedIterator(filesByName.entries(), function (_a) {
                var path = _a[0], file = _a[1];
                return file === undefined ? path : undefined;
            }));
            files = ts.stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
            processingDefaultLibFiles = undefined;
            processingOtherFiles = undefined;
        }
        ts.Debug.assert(!!missingFilePaths);
        // Release any files we have acquired in the old program but are
        // not part of the new program.
        if (oldProgram && host.onReleaseOldSourceFile) {
            var oldSourceFiles = oldProgram.getSourceFiles();
            for (var _g = 0, oldSourceFiles_1 = oldSourceFiles; _g < oldSourceFiles_1.length; _g++) {
                var oldSourceFile = oldSourceFiles_1[_g];
                var newFile = getSourceFileByPath(oldSourceFile.resolvedPath);
                if (shouldCreateNewSourceFile || !newFile ||
                    // old file wasnt redirect but new file is
                    (oldSourceFile.resolvedPath === oldSourceFile.path && newFile.resolvedPath !== oldSourceFile.path)) {
                    host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions(), !!getSourceFileByPath(oldSourceFile.path));
                }
            }
            oldProgram.forEachResolvedProjectReference(function (resolvedProjectReference, resolvedProjectReferencePath) {
                if (resolvedProjectReference && !getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
                    host.onReleaseOldSourceFile(resolvedProjectReference.sourceFile, oldProgram.getCompilerOptions(), /*hasSourceFileByPath*/ false);
                }
            });
        }
        // unconditionally set oldProgram to undefined to prevent it from being captured in closure
        oldProgram = undefined;
        var program = {
            getRootFileNames: function () { return rootNames; },
            getSourceFile: getSourceFile,
            getSourceFileByPath: getSourceFileByPath,
            getSourceFiles: function () { return files; },
            getMissingFilePaths: function () { return missingFilePaths; },
            getRefFileMap: function () { return refFileMap; },
            getFilesByNameMap: function () { return filesByName; },
            getCompilerOptions: function () { return options; },
            getSyntacticDiagnostics: getSyntacticDiagnostics,
            getOptionsDiagnostics: getOptionsDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getSemanticDiagnostics: getSemanticDiagnostics,
            getSuggestionDiagnostics: getSuggestionDiagnostics,
            getDeclarationDiagnostics: getDeclarationDiagnostics,
            getBindAndCheckDiagnostics: getBindAndCheckDiagnostics,
            getProgramDiagnostics: getProgramDiagnostics,
            getTypeChecker: getTypeChecker,
            getClassifiableNames: getClassifiableNames,
            getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker,
            getCommonSourceDirectory: getCommonSourceDirectory,
            emit: emit,
            getCurrentDirectory: function () { return currentDirectory; },
            getNodeCount: function () { return getDiagnosticsProducingTypeChecker().getNodeCount(); },
            getIdentifierCount: function () { return getDiagnosticsProducingTypeChecker().getIdentifierCount(); },
            getSymbolCount: function () { return getDiagnosticsProducingTypeChecker().getSymbolCount(); },
            getTypeCount: function () { return getDiagnosticsProducingTypeChecker().getTypeCount(); },
            getInstantiationCount: function () { return getDiagnosticsProducingTypeChecker().getInstantiationCount(); },
            getRelationCacheSizes: function () { return getDiagnosticsProducingTypeChecker().getRelationCacheSizes(); },
            getFileProcessingDiagnostics: function () { return fileProcessingDiagnostics; },
            getResolvedTypeReferenceDirectives: function () { return resolvedTypeReferenceDirectives; },
            isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
            isSourceFileDefaultLibrary: isSourceFileDefaultLibrary,
            dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker,
            getSourceFileFromReference: getSourceFileFromReference,
            getLibFileFromReference: getLibFileFromReference,
            sourceFileToPackageName: sourceFileToPackageName,
            redirectTargetsMap: redirectTargetsMap,
            isEmittedFile: isEmittedFile,
            getConfigFileParsingDiagnostics: getConfigFileParsingDiagnostics,
            getResolvedModuleWithFailedLookupLocationsFromCache: getResolvedModuleWithFailedLookupLocationsFromCache,
            getProjectReferences: getProjectReferences,
            getResolvedProjectReferences: getResolvedProjectReferences,
            getProjectReferenceRedirect: getProjectReferenceRedirect,
            getResolvedProjectReferenceToRedirect: getResolvedProjectReferenceToRedirect,
            getResolvedProjectReferenceByPath: getResolvedProjectReferenceByPath,
            forEachResolvedProjectReference: forEachResolvedProjectReference,
            isSourceOfProjectReferenceRedirect: isSourceOfProjectReferenceRedirect,
            emitBuildInfo: emitBuildInfo,
            fileExists: fileExists,
            getProbableSymlinks: getProbableSymlinks,
            useCaseSensitiveFileNames: function () { return host.useCaseSensitiveFileNames(); },
        };
        onProgramCreateComplete();
        verifyCompilerOptions();
        ts.performance.mark("afterProgram");
        ts.performance.measure("Program", "beforeProgram", "afterProgram");
        return program;
        function resolveModuleNamesWorker(moduleNames, containingFile, reusedNames, redirectedReference) {
            ts.performance.mark("beforeResolveModule");
            var result = actualResolveModuleNamesWorker(moduleNames, containingFile, reusedNames, redirectedReference);
            ts.performance.mark("afterResolveModule");
            ts.performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule");
            return result;
        }
        function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFile, redirectedReference) {
            ts.performance.mark("beforeResolveTypeReference");
            var result = actualResolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFile, redirectedReference);
            ts.performance.mark("afterResolveTypeReference");
            ts.performance.measure("ResolveTypeReference", "beforeResolveTypeReference", "afterResolveTypeReference");
            return result;
        }
        function compareDefaultLibFiles(a, b) {
            return ts.compareValues(getDefaultLibFilePriority(a), getDefaultLibFilePriority(b));
        }
        function getDefaultLibFilePriority(a) {
            if (ts.containsPath(defaultLibraryPath, a.fileName, /*ignoreCase*/ false)) {
                var basename = ts.getBaseFileName(a.fileName);
                if (basename === "lib.d.ts" || basename === "lib.es6.d.ts")
                    return 0;
                var name = ts.removeSuffix(ts.removePrefix(basename, "lib."), ".d.ts");
                var index = ts.libs.indexOf(name);
                if (index !== -1)
                    return index + 1;
            }
            return ts.libs.length + 2;
        }
        function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile) {
            return moduleResolutionCache && ts.resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache);
        }
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getCommonSourceDirectory() {
            if (commonSourceDirectory === undefined) {
                var emittedFiles = ts.filter(files, function (file) { return ts.sourceFileMayBeEmitted(file, program); });
                if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) {
                    // If a rootDir is specified use it as the commonSourceDirectory
                    commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
                }
                else if (options.composite && options.configFilePath) {
                    // Project compilations never infer their root from the input source paths
                    commonSourceDirectory = ts.getDirectoryPath(ts.normalizeSlashes(options.configFilePath));
                    checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory);
                }
                else {
                    commonSourceDirectory = computeCommonSourceDirectory(emittedFiles);
                }
                if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== ts.directorySeparator) {
                    // Make sure directory path ends with directory separator so this string can directly
                    // used to replace with "" to get the relative path of the source file and the relative path doesn't
                    // start with / making it rooted path
                    commonSourceDirectory += ts.directorySeparator;
                }
            }
            return commonSourceDirectory;
        }
        function getClassifiableNames() {
            if (!classifiableNames) {
                // Initialize a checker so that all our files are bound.
                getTypeChecker();
                classifiableNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, files_2 = files; _i < files_2.length; _i++) {
                    var sourceFile = files_2[_i];
                    ts.copyEntries(sourceFile.classifiableNames, classifiableNames);
                }
            }
            return classifiableNames;
        }
        function resolveModuleNamesReusingOldState(moduleNames, containingFile, file) {
            if (structuralIsReused === 0 /* Not */ && !file.ambientModuleNames.length) {
                // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
                // the best we can do is fallback to the default logic.
                return resolveModuleNamesWorker(moduleNames, containingFile, /*reusedNames*/ undefined, getResolvedProjectReferenceToRedirect(file.originalFileName));
            }
            var oldSourceFile = oldProgram && oldProgram.getSourceFile(containingFile);
            if (oldSourceFile !== file && file.resolvedModules) {
                // `file` was created for the new program.
                //
                // We only set `file.resolvedModules` via work from the current function,
                // so it is defined iff we already called the current function on `file`.
                // That call happened no later than the creation of the `file` object,
                // which per above occurred during the current program creation.
                // Since we assume the filesystem does not change during program creation,
                // it is safe to reuse resolutions from the earlier call.
                var result_11 = [];
                for (var _i = 0, moduleNames_1 = moduleNames; _i < moduleNames_1.length; _i++) {
                    var moduleName = moduleNames_1[_i];
                    var resolvedModule = file.resolvedModules.get(moduleName);
                    result_11.push(resolvedModule);
                }
                return result_11;
            }
            // At this point, we know at least one of the following hold:
            // - file has local declarations for ambient modules
            // - old program state is available
            // With this information, we can infer some module resolutions without performing resolution.
            /** An ordered list of module names for which we cannot recover the resolution. */
            var unknownModuleNames;
            /**
             * The indexing of elements in this list matches that of `moduleNames`.
             *
             * Before combining results, result[i] is in one of the following states:
             * * undefined: needs to be recomputed,
             * * predictedToResolveToAmbientModuleMarker: known to be an ambient module.
             * Needs to be reset to undefined before returning,
             * * ResolvedModuleFull instance: can be reused.
             */
            var result;
            var reusedNames;
            /** A transient placeholder used to mark predicted resolution in the result list. */
            var predictedToResolveToAmbientModuleMarker = {};
            for (var i = 0; i < moduleNames.length; i++) {
                var moduleName = moduleNames[i];
                // If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
                if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) {
                    var oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules.get(moduleName);
                    if (oldResolvedModule) {
                        if (ts.isTraceEnabled(options, host)) {
                            ts.trace(host, ts.Diagnostics.Reusing_resolution_of_module_0_to_file_1_from_old_program, moduleName, containingFile);
                        }
                        (result || (result = new Array(moduleNames.length)))[i] = oldResolvedModule;
                        (reusedNames || (reusedNames = [])).push(moduleName);
                        continue;
                    }
                }
                // We know moduleName resolves to an ambient module provided that moduleName:
                // - is in the list of ambient modules locally declared in the current source file.
                // - resolved to an ambient module in the old program whose declaration is in an unmodified file
                //   (so the same module declaration will land in the new program)
                var resolvesToAmbientModuleInNonModifiedFile = false;
                if (ts.contains(file.ambientModuleNames, moduleName)) {
                    resolvesToAmbientModuleInNonModifiedFile = true;
                    if (ts.isTraceEnabled(options, host)) {
                        ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, containingFile);
                    }
                }
                else {
                    resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName);
                }
                if (resolvesToAmbientModuleInNonModifiedFile) {
                    (result || (result = new Array(moduleNames.length)))[i] = predictedToResolveToAmbientModuleMarker;
                }
                else {
                    // Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
                    (unknownModuleNames || (unknownModuleNames = [])).push(moduleName);
                }
            }
            var resolutions = unknownModuleNames && unknownModuleNames.length
                ? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames, getResolvedProjectReferenceToRedirect(file.originalFileName))
                : ts.emptyArray;
            // Combine results of resolutions and predicted results
            if (!result) {
                // There were no unresolved/ambient resolutions.
                ts.Debug.assert(resolutions.length === moduleNames.length);
                return resolutions;
            }
            var j = 0;
            for (var i = 0; i < result.length; i++) {
                if (result[i]) {
                    // `result[i]` is either a `ResolvedModuleFull` or a marker.
                    // If it is the former, we can leave it as is.
                    if (result[i] === predictedToResolveToAmbientModuleMarker) {
                        result[i] = undefined; // TODO: GH#18217
                    }
                }
                else {
                    result[i] = resolutions[j];
                    j++;
                }
            }
            ts.Debug.assert(j === resolutions.length);
            return result;
            // If we change our policy of rechecking failed lookups on each program create,
            // we should adjust the value returned here.
            function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName) {
                var resolutionToFile = ts.getResolvedModule(oldSourceFile, moduleName);
                var resolvedFile = resolutionToFile && oldProgram.getSourceFile(resolutionToFile.resolvedFileName);
                if (resolutionToFile && resolvedFile) {
                    // In the old program, we resolved to an ambient module that was in the same
                    //   place as we expected to find an actual module file.
                    // We actually need to return 'false' here even though this seems like a 'true' case
                    //   because the normal module resolution algorithm will find this anyway.
                    return false;
                }
                // at least one of declarations should come from non-modified source file
                var unmodifiedFile = ambientModuleNameToUnmodifiedFileName.get(moduleName);
                if (!unmodifiedFile) {
                    return false;
                }
                if (ts.isTraceEnabled(options, host)) {
                    ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, unmodifiedFile);
                }
                return true;
            }
        }
        function canReuseProjectReferences() {
            return !forEachProjectReference(oldProgram.getProjectReferences(), oldProgram.getResolvedProjectReferences(), function (oldResolvedRef, index, parent) {
                var newRef = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var newResolvedRef = parseProjectReferenceConfigFile(newRef);
                if (oldResolvedRef) {
                    // Resolved project reference has gone missing or changed
                    return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile;
                }
                else {
                    // A previously-unresolved reference may be resolved now
                    return newResolvedRef !== undefined;
                }
            }, function (oldProjectReferences, parent) {
                // If array of references is changed, we cant resue old program
                var newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path).commandLine.projectReferences : projectReferences;
                return !ts.arrayIsEqualTo(oldProjectReferences, newReferences, ts.projectReferenceIsEqualTo);
            });
        }
        function tryReuseStructureFromOldProgram() {
            if (!oldProgram) {
                return 0 /* Not */;
            }
            // check properties that can affect structure of the program or module resolution strategy
            // if any of these properties has changed - structure cannot be reused
            var oldOptions = oldProgram.getCompilerOptions();
            if (ts.changesAffectModuleResolution(oldOptions, options)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            ts.Debug.assert(!(oldProgram.structureIsReused & (2 /* Completely */ | 1 /* SafeModules */)));
            // there is an old program, check if we can reuse its structure
            var oldRootNames = oldProgram.getRootFileNames();
            if (!ts.arrayIsEqualTo(oldRootNames, rootNames)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            if (!ts.arrayIsEqualTo(options.types, oldOptions.types)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            // Check if any referenced project tsconfig files are different
            if (!canReuseProjectReferences()) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            if (projectReferences) {
                resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
            }
            // check if program source files has changed in the way that can affect structure of the program
            var newSourceFiles = [];
            var modifiedSourceFiles = [];
            oldProgram.structureIsReused = 2 /* Completely */;
            // If the missing file paths are now present, it can change the progam structure,
            // and hence cant reuse the structure.
            // This is same as how we dont reuse the structure if one of the file from old program is now missing
            if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            var oldSourceFiles = oldProgram.getSourceFiles();
            var SeenPackageName;
            (function (SeenPackageName) {
                SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists";
                SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified";
            })(SeenPackageName || (SeenPackageName = {}));
            var seenPackageNames = ts.createMap();
            for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) {
                var oldSourceFile = oldSourceFiles_2[_i];
                var newSourceFile = host.getSourceFileByPath
                    ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, options.target, /*onError*/ undefined, shouldCreateNewSourceFile)
                    : host.getSourceFile(oldSourceFile.fileName, options.target, /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217
                if (!newSourceFile) {
                    return oldProgram.structureIsReused = 0 /* Not */;
                }
                ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`");
                var fileChanged = void 0;
                if (oldSourceFile.redirectInfo) {
                    // We got `newSourceFile` by path, so it is actually for the unredirected file.
                    // This lets us know if the unredirected file has changed. If it has we should break the redirect.
                    if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
                        // Underlying file has changed. Might not redirect anymore. Must rebuild program.
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    fileChanged = false;
                    newSourceFile = oldSourceFile; // Use the redirect.
                }
                else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
                    // If a redirected-to source file changes, the redirect may be broken.
                    if (newSourceFile !== oldSourceFile) {
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    fileChanged = false;
                }
                else {
                    fileChanged = newSourceFile !== oldSourceFile;
                }
                // Since the project references havent changed, its right to set originalFileName and resolvedPath here
                newSourceFile.path = oldSourceFile.path;
                newSourceFile.originalFileName = oldSourceFile.originalFileName;
                newSourceFile.resolvedPath = oldSourceFile.resolvedPath;
                newSourceFile.fileName = oldSourceFile.fileName;
                var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
                if (packageName !== undefined) {
                    // If there are 2 different source files for the same package name and at least one of them changes,
                    // they might become redirects. So we must rebuild the program.
                    var prevKind = seenPackageNames.get(packageName);
                    var newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
                    if ((prevKind !== undefined && newKind === 1 /* Modified */) || prevKind === 1 /* Modified */) {
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    seenPackageNames.set(packageName, newKind);
                }
                if (fileChanged) {
                    // The `newSourceFile` object was created for the new program.
                    if (!ts.arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
                        // 'lib' references has changed. Matches behavior in changesAffectModuleResolution
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
                        // value of no-default-lib has changed
                        // this will affect if default library is injected into the list of files
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // check tripleslash references
                    if (!ts.arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
                        // tripleslash references has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // check imports and module augmentations
                    collectExternalModuleReferences(newSourceFile);
                    if (!ts.arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
                        // imports has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
                        // moduleAugmentations has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if ((oldSourceFile.flags & 3145728 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 3145728 /* PermanentlySetIncrementalFlags */)) {
                        // dynamicImport has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
                        // 'types' references has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // tentatively approve the file
                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
                }
                else if (hasInvalidatedResolution(oldSourceFile.path)) {
                    // 'module/types' references could have changed
                    oldProgram.structureIsReused = 1 /* SafeModules */;
                    // add file to the modified list so that we will resolve it later
                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
                }
                // if file has passed all checks it should be safe to reuse it
                newSourceFiles.push(newSourceFile);
            }
            if (oldProgram.structureIsReused !== 2 /* Completely */) {
                return oldProgram.structureIsReused;
            }
            var modifiedFiles = modifiedSourceFiles.map(function (f) { return f.oldFile; });
            for (var _a = 0, oldSourceFiles_3 = oldSourceFiles; _a < oldSourceFiles_3.length; _a++) {
                var oldFile = oldSourceFiles_3[_a];
                if (!ts.contains(modifiedFiles, oldFile)) {
                    for (var _b = 0, _c = oldFile.ambientModuleNames; _b < _c.length; _b++) {
                        var moduleName = _c[_b];
                        ambientModuleNameToUnmodifiedFileName.set(moduleName, oldFile.fileName);
                    }
                }
            }
            // try to verify results of module resolution
            for (var _d = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _d < modifiedSourceFiles_1.length; _d++) {
                var _e = modifiedSourceFiles_1[_d], oldSourceFile = _e.oldFile, newSourceFile = _e.newFile;
                var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.originalFileName, currentDirectory);
                var moduleNames = getModuleNames(newSourceFile);
                var resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile);
                // ensure that module resolution results are still correct
                var resolutionsChanged = ts.hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, ts.moduleResolutionIsEqualTo);
                if (resolutionsChanged) {
                    oldProgram.structureIsReused = 1 /* SafeModules */;
                    newSourceFile.resolvedModules = ts.zipToMap(moduleNames, resolutions);
                }
                else {
                    newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
                }
                if (resolveTypeReferenceDirectiveNamesWorker) {
                    // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
                    var typesReferenceDirectives = ts.map(newSourceFile.typeReferenceDirectives, function (ref) { return ts.toFileNameLowerCase(ref.fileName); });
                    var resolutions_1 = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath, getResolvedProjectReferenceToRedirect(newSourceFile.originalFileName));
                    // ensure that types resolutions are still correct
                    var resolutionsChanged_1 = ts.hasChangesInResolutions(typesReferenceDirectives, resolutions_1, oldSourceFile.resolvedTypeReferenceDirectiveNames, ts.typeDirectiveIsEqualTo);
                    if (resolutionsChanged_1) {
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                        newSourceFile.resolvedTypeReferenceDirectiveNames = ts.zipToMap(typesReferenceDirectives, resolutions_1);
                    }
                    else {
                        newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
                    }
                }
            }
            if (oldProgram.structureIsReused !== 2 /* Completely */) {
                return oldProgram.structureIsReused;
            }
            if (host.hasChangedAutomaticTypeDirectiveNames) {
                return oldProgram.structureIsReused = 1 /* SafeModules */;
            }
            missingFilePaths = oldProgram.getMissingFilePaths();
            refFileMap = oldProgram.getRefFileMap();
            // update fileName -> file mapping
            ts.Debug.assert(newSourceFiles.length === oldProgram.getSourceFiles().length);
            for (var _f = 0, newSourceFiles_1 = newSourceFiles; _f < newSourceFiles_1.length; _f++) {
                var newSourceFile = newSourceFiles_1[_f];
                filesByName.set(newSourceFile.path, newSourceFile);
            }
            var oldFilesByNameMap = oldProgram.getFilesByNameMap();
            oldFilesByNameMap.forEach(function (oldFile, path) {
                if (!oldFile) {
                    filesByName.set(path, oldFile);
                    return;
                }
                if (oldFile.path === path) {
                    // Set the file as found during node modules search if it was found that way in old progra,
                    if (oldProgram.isSourceFileFromExternalLibrary(oldFile)) {
                        sourceFilesFoundSearchingNodeModules.set(oldFile.path, true);
                    }
                    return;
                }
                filesByName.set(path, filesByName.get(oldFile.path));
            });
            files = newSourceFiles;
            fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
            for (var _g = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _g < modifiedSourceFiles_2.length; _g++) {
                var modifiedFile = modifiedSourceFiles_2[_g];
                fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
            }
            resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
            sourceFileToPackageName = oldProgram.sourceFileToPackageName;
            redirectTargetsMap = oldProgram.redirectTargetsMap;
            return oldProgram.structureIsReused = 2 /* Completely */;
        }
        function getEmitHost(writeFileCallback) {
            return {
                getPrependNodes: getPrependNodes,
                getCanonicalFileName: getCanonicalFileName,
                getCommonSourceDirectory: program.getCommonSourceDirectory,
                getCompilerOptions: program.getCompilerOptions,
                getCurrentDirectory: function () { return currentDirectory; },
                getNewLine: function () { return host.getNewLine(); },
                getSourceFile: program.getSourceFile,
                getSourceFileByPath: program.getSourceFileByPath,
                getSourceFiles: program.getSourceFiles,
                getLibFileFromReference: program.getLibFileFromReference,
                isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
                getResolvedProjectReferenceToRedirect: getResolvedProjectReferenceToRedirect,
                getProjectReferenceRedirect: getProjectReferenceRedirect,
                isSourceOfProjectReferenceRedirect: isSourceOfProjectReferenceRedirect,
                getProbableSymlinks: getProbableSymlinks,
                writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }),
                isEmitBlocked: isEmitBlocked,
                readFile: function (f) { return host.readFile(f); },
                fileExists: function (f) {
                    // Use local caches
                    var path = toPath(f);
                    if (getSourceFileByPath(path))
                        return true;
                    if (ts.contains(missingFilePaths, path))
                        return false;
                    // Before falling back to the host
                    return host.fileExists(f);
                },
                useCaseSensitiveFileNames: function () { return host.useCaseSensitiveFileNames(); },
                getProgramBuildInfo: function () { return program.getProgramBuildInfo && program.getProgramBuildInfo(); },
                getSourceFileFromReference: function (file, ref) { return program.getSourceFileFromReference(file, ref); },
                redirectTargetsMap: redirectTargetsMap,
            };
        }
        function emitBuildInfo(writeFileCallback) {
            ts.Debug.assert(!options.out && !options.outFile);
            ts.performance.mark("beforeEmit");
            var emitResult = ts.emitFiles(ts.notImplementedResolver, getEmitHost(writeFileCallback), 
            /*targetSourceFile*/ undefined, 
            /*transformers*/ ts.noTransformers, 
            /*emitOnlyDtsFiles*/ false, 
            /*onlyBuildInfo*/ true);
            ts.performance.mark("afterEmit");
            ts.performance.measure("Emit", "beforeEmit", "afterEmit");
            return emitResult;
        }
        function getResolvedProjectReferences() {
            return resolvedProjectReferences;
        }
        function getProjectReferences() {
            return projectReferences;
        }
        function getPrependNodes() {
            return createPrependNodes(projectReferences, function (_ref, index) { return resolvedProjectReferences[index].commandLine; }, function (fileName) {
                var path = toPath(fileName);
                var sourceFile = getSourceFileByPath(path);
                return sourceFile ? sourceFile.text : filesByName.has(path) ? undefined : host.readFile(path);
            });
        }
        function isSourceFileFromExternalLibrary(file) {
            return !!sourceFilesFoundSearchingNodeModules.get(file.path);
        }
        function isSourceFileDefaultLibrary(file) {
            if (file.hasNoDefaultLib) {
                return true;
            }
            if (!options.noLib) {
                return false;
            }
            // If '--lib' is not specified, include default library file according to '--target'
            // otherwise, using options specified in '--lib' instead of '--target' default library file
            var equalityComparer = host.useCaseSensitiveFileNames() ? ts.equateStringsCaseSensitive : ts.equateStringsCaseInsensitive;
            if (!options.lib) {
                return equalityComparer(file.fileName, getDefaultLibraryFileName());
            }
            else {
                return ts.some(options.lib, function (libFileName) { return equalityComparer(file.fileName, ts.combinePaths(defaultLibraryPath, libFileName)); });
            }
        }
        function getDiagnosticsProducingTypeChecker() {
            return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ true));
        }
        function dropDiagnosticsProducingTypeChecker() {
            diagnosticsProducingTypeChecker = undefined;
        }
        function getTypeChecker() {
            return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false));
        }
        function emit(sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers, forceDtsEmit) {
            return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers, forceDtsEmit); });
        }
        function isEmitBlocked(emitFileName) {
            return hasEmitBlockingDiagnostics.has(toPath(emitFileName));
        }
        function emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, customTransformers, forceDtsEmit) {
            if (!forceDtsEmit) {
                var result = handleNoEmitOptions(program, sourceFile, cancellationToken);
                if (result)
                    return result;
            }
            // Create the emit resolver outside of the "emitTime" tracking code below.  That way
            // any cost associated with it (like type checking) are appropriate associated with
            // the type-checking counter.
            //
            // If the -out option is specified, we should not pass the source file to getEmitResolver.
            // This is because in the -out scenario all files need to be emitted, and therefore all
            // files need to be type checked. And the way to specify that all files need to be type
            // checked is to not pass the file to getEmitResolver.
            var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken);
            ts.performance.mark("beforeEmit");
            var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile, ts.getTransformers(options, customTransformers, emitOnlyDtsFiles), emitOnlyDtsFiles, 
            /*onlyBuildInfo*/ false, forceDtsEmit);
            ts.performance.mark("afterEmit");
            ts.performance.measure("Emit", "beforeEmit", "afterEmit");
            return emitResult;
        }
        function getSourceFile(fileName) {
            return getSourceFileByPath(toPath(fileName));
        }
        function getSourceFileByPath(path) {
            return filesByName.get(path) || undefined;
        }
        function getDiagnosticsHelper(sourceFile, getDiagnostics, cancellationToken) {
            if (sourceFile) {
                return getDiagnostics(sourceFile, cancellationToken);
            }
            return ts.sortAndDeduplicateDiagnostics(ts.flatMap(program.getSourceFiles(), function (sourceFile) {
                if (cancellationToken) {
                    cancellationToken.throwIfCancellationRequested();
                }
                return getDiagnostics(sourceFile, cancellationToken);
            }));
        }
        function getSyntacticDiagnostics(sourceFile, cancellationToken) {
            return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
        }
        function getSemanticDiagnostics(sourceFile, cancellationToken) {
            return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
        }
        function getBindAndCheckDiagnostics(sourceFile, cancellationToken) {
            return getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken);
        }
        function getProgramDiagnostics(sourceFile) {
            if (ts.skipTypeChecking(sourceFile, options, program)) {
                return ts.emptyArray;
            }
            var fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
            var programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
            return getMergedProgramDiagnostics(sourceFile, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
        }
        function getMergedProgramDiagnostics(sourceFile) {
            var _a;
            var allDiagnostics = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                allDiagnostics[_i - 1] = arguments[_i];
            }
            var flatDiagnostics = ts.flatten(allDiagnostics);
            if (!((_a = sourceFile.commentDirectives) === null || _a === void 0 ? void 0 : _a.length)) {
                return flatDiagnostics;
            }
            return getDiagnosticsWithPrecedingDirectives(sourceFile, sourceFile.commentDirectives, flatDiagnostics).diagnostics;
        }
        function getDeclarationDiagnostics(sourceFile, cancellationToken) {
            var options = program.getCompilerOptions();
            // collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
            if (!sourceFile || options.out || options.outFile) {
                return getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
            }
            else {
                return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken);
            }
        }
        function getSyntacticDiagnosticsForFile(sourceFile) {
            // For JavaScript files, we report semantic errors for using TypeScript-only
            // constructs from within a JavaScript file as syntactic errors.
            if (ts.isSourceFileJS(sourceFile)) {
                if (!sourceFile.additionalSyntacticDiagnostics) {
                    sourceFile.additionalSyntacticDiagnostics = getJSSyntacticDiagnosticsForFile(sourceFile);
                }
                return ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
            }
            return sourceFile.parseDiagnostics;
        }
        function runWithCancellationToken(func) {
            try {
                return func();
            }
            catch (e) {
                if (e instanceof ts.OperationCanceledException) {
                    // We were canceled while performing the operation.  Because our type checker
                    // might be a bad state, we need to throw it away.
                    //
                    // Note: we are overly aggressive here.  We do not actually *have* to throw away
                    // the "noDiagnosticsTypeChecker".  However, for simplicity, i'd like to keep
                    // the lifetimes of these two TypeCheckers the same.  Also, we generally only
                    // cancel when the user has made a change anyways.  And, in that case, we (the
                    // program instance) will get thrown away anyways.  So trying to keep one of
                    // these type checkers alive doesn't serve much purpose.
                    noDiagnosticsTypeChecker = undefined;
                    diagnosticsProducingTypeChecker = undefined;
                }
                throw e;
            }
        }
        function getSemanticDiagnosticsForFile(sourceFile, cancellationToken) {
            return ts.concatenate(getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken), getProgramDiagnostics(sourceFile));
        }
        function getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken) {
            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedBindAndCheckDiagnosticsForFile, getBindAndCheckDiagnosticsForFileNoCache);
        }
        function getBindAndCheckDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                if (ts.skipTypeChecking(sourceFile, options, program)) {
                    return ts.emptyArray;
                }
                var typeChecker = getDiagnosticsProducingTypeChecker();
                ts.Debug.assert(!!sourceFile.bindDiagnostics);
                var isCheckJs = ts.isCheckJsEnabledForFile(sourceFile, options);
                var isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false;
                // By default, only type-check .ts, .tsx, 'Deferred' and 'External' files (external files are added by plugins)
                var includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === 3 /* TS */ || sourceFile.scriptKind === 4 /* TSX */ ||
                    sourceFile.scriptKind === 5 /* External */ || isCheckJs || sourceFile.scriptKind === 7 /* Deferred */);
                var bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : ts.emptyArray;
                var checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : ts.emptyArray;
                return getMergedBindAndCheckDiagnostics(sourceFile, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined);
            });
        }
        function getMergedBindAndCheckDiagnostics(sourceFile) {
            var _a;
            var allDiagnostics = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                allDiagnostics[_i - 1] = arguments[_i];
            }
            var flatDiagnostics = ts.flatten(allDiagnostics);
            if (!((_a = sourceFile.commentDirectives) === null || _a === void 0 ? void 0 : _a.length)) {
                return flatDiagnostics;
            }
            var _b = getDiagnosticsWithPrecedingDirectives(sourceFile, sourceFile.commentDirectives, flatDiagnostics), diagnostics = _b.diagnostics, directives = _b.directives;
            for (var _c = 0, _d = directives.getUnusedExpectations(); _c < _d.length; _c++) {
                var errorExpectation = _d[_c];
                diagnostics.push(ts.createDiagnosticForRange(sourceFile, errorExpectation.range, ts.Diagnostics.Unused_ts_expect_error_directive));
            }
            return diagnostics;
        }
        /**
         * Creates a map of comment directives along with the diagnostics immediately preceded by one of them.
         * Comments that match to any of those diagnostics are marked as used.
         */
        function getDiagnosticsWithPrecedingDirectives(sourceFile, commentDirectives, flatDiagnostics) {
            // Diagnostics are only reported if there is no comment directive preceding them
            // This will modify the directives map by marking "used" ones with a corresponding diagnostic
            var directives = ts.createCommentDirectivesMap(sourceFile, commentDirectives);
            var diagnostics = flatDiagnostics.filter(function (diagnostic) { return markPrecedingCommentDirectiveLine(diagnostic, directives) === -1; });
            return { diagnostics: diagnostics, directives: directives };
        }
        function getSuggestionDiagnostics(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                return getDiagnosticsProducingTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken);
            });
        }
        /**
         * @returns The line index marked as preceding the diagnostic, or -1 if none was.
         */
        function markPrecedingCommentDirectiveLine(diagnostic, directives) {
            var file = diagnostic.file, start = diagnostic.start;
            if (!file) {
                return -1;
            }
            // Start out with the line just before the text
            var lineStarts = ts.getLineStarts(file);
            var line = ts.computeLineAndCharacterOfPosition(lineStarts, start).line - 1; // TODO: GH#18217
            while (line >= 0) {
                // As soon as that line is known to have a comment directive, use that
                if (directives.markUsed(line)) {
                    return line;
                }
                // Stop searching if the line is not empty and not a comment
                var lineText = file.text.slice(lineStarts[line], lineStarts[line + 1]).trim();
                if (lineText !== "" && !/^(\s*)\/\/(.*)$/.test(lineText)) {
                    return -1;
                }
                line--;
            }
            return -1;
        }
        function getJSSyntacticDiagnosticsForFile(sourceFile) {
            return runWithCancellationToken(function () {
                var diagnostics = [];
                walk(sourceFile, sourceFile);
                ts.forEachChildRecursively(sourceFile, walk, walkArray);
                return diagnostics;
                function walk(node, parent) {
                    // Return directly from the case if the given node doesnt want to visit each child
                    // Otherwise break to visit each child
                    switch (parent.kind) {
                        case 156 /* Parameter */:
                        case 159 /* PropertyDeclaration */:
                        case 161 /* MethodDeclaration */:
                            if (parent.questionToken === node) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?"));
                                return "skip";
                            }
                        // falls through
                        case 160 /* MethodSignature */:
                        case 162 /* Constructor */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                        case 201 /* FunctionExpression */:
                        case 244 /* FunctionDeclaration */:
                        case 202 /* ArrowFunction */:
                        case 242 /* VariableDeclaration */:
                            // type annotation
                            if (parent.type === node) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Type_annotations_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                    }
                    switch (node.kind) {
                        case 255 /* ImportClause */:
                            if (node.isTypeOnly) {
                                diagnostics.push(createDiagnosticForNode(node.parent, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "import type"));
                                return "skip";
                            }
                            break;
                        case 260 /* ExportDeclaration */:
                            if (node.isTypeOnly) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "export type"));
                                return "skip";
                            }
                            break;
                        case 253 /* ImportEqualsDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.import_can_only_be_used_in_TypeScript_files));
                            return "skip";
                        case 259 /* ExportAssignment */:
                            if (node.isExportEquals) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.export_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                            break;
                        case 279 /* HeritageClause */:
                            var heritageClause = node;
                            if (heritageClause.token === 113 /* ImplementsKeyword */) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.implements_clauses_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                            break;
                        case 246 /* InterfaceDeclaration */:
                            var interfaceKeyword = ts.tokenToString(114 /* InterfaceKeyword */);
                            ts.Debug.assertIsDefined(interfaceKeyword);
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, interfaceKeyword));
                            return "skip";
                        case 249 /* ModuleDeclaration */:
                            var moduleKeyword = node.flags & 16 /* Namespace */ ? ts.tokenToString(136 /* NamespaceKeyword */) : ts.tokenToString(135 /* ModuleKeyword */);
                            ts.Debug.assertIsDefined(moduleKeyword);
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, moduleKeyword));
                            return "skip";
                        case 247 /* TypeAliasDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Type_aliases_can_only_be_used_in_TypeScript_files));
                            return "skip";
                        case 248 /* EnumDeclaration */:
                            var enumKeyword = ts.Debug.checkDefined(ts.tokenToString(88 /* EnumKeyword */));
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, enumKeyword));
                            return "skip";
                        case 218 /* NonNullExpression */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Non_null_assertions_can_only_be_used_in_TypeScript_files));
                            return "skip";
                        case 217 /* AsExpression */:
                            diagnostics.push(createDiagnosticForNode(node.type, ts.Diagnostics.Type_assertion_expressions_can_only_be_used_in_TypeScript_files));
                            return "skip";
                        case 199 /* TypeAssertionExpression */:
                            ts.Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX.
                    }
                }
                function walkArray(nodes, parent) {
                    if (parent.decorators === nodes && !options.experimentalDecorators) {
                        diagnostics.push(createDiagnosticForNode(parent, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning));
                    }
                    switch (parent.kind) {
                        case 245 /* ClassDeclaration */:
                        case 214 /* ClassExpression */:
                        case 161 /* MethodDeclaration */:
                        case 162 /* Constructor */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                        case 201 /* FunctionExpression */:
                        case 244 /* FunctionDeclaration */:
                        case 202 /* ArrowFunction */:
                            // Check type parameters
                            if (nodes === parent.typeParameters) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Type_parameter_declarations_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                        // falls through
                        case 225 /* VariableStatement */:
                            // Check modifiers
                            if (nodes === parent.modifiers) {
                                checkModifiers(parent.modifiers, parent.kind === 225 /* VariableStatement */);
                                return "skip";
                            }
                            break;
                        case 159 /* PropertyDeclaration */:
                            // Check modifiers of property declaration
                            if (nodes === parent.modifiers) {
                                for (var _i = 0, _a = nodes; _i < _a.length; _i++) {
                                    var modifier = _a[_i];
                                    if (modifier.kind !== 120 /* StaticKeyword */) {
                                        diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, ts.tokenToString(modifier.kind)));
                                    }
                                }
                                return "skip";
                            }
                            break;
                        case 156 /* Parameter */:
                            // Check modifiers of parameter declaration
                            if (nodes === parent.modifiers) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Parameter_modifiers_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                            break;
                        case 196 /* CallExpression */:
                        case 197 /* NewExpression */:
                        case 216 /* ExpressionWithTypeArguments */:
                        case 267 /* JsxSelfClosingElement */:
                        case 268 /* JsxOpeningElement */:
                        case 198 /* TaggedTemplateExpression */:
                            // Check type arguments
                            if (nodes === parent.typeArguments) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Type_arguments_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                            break;
                    }
                }
                function checkModifiers(modifiers, isConstValid) {
                    for (var _i = 0, modifiers_1 = modifiers; _i < modifiers_1.length; _i++) {
                        var modifier = modifiers_1[_i];
                        switch (modifier.kind) {
                            case 81 /* ConstKeyword */:
                                if (isConstValid) {
                                    continue;
                                }
                            // to report error,
                            // falls through
                            case 119 /* PublicKeyword */:
                            case 117 /* PrivateKeyword */:
                            case 118 /* ProtectedKeyword */:
                            case 138 /* ReadonlyKeyword */:
                            case 130 /* DeclareKeyword */:
                            case 122 /* AbstractKeyword */:
                                diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, ts.tokenToString(modifier.kind)));
                                break;
                            // These are all legal modifiers.
                            case 120 /* StaticKeyword */:
                            case 89 /* ExportKeyword */:
                            case 84 /* DefaultKeyword */:
                        }
                    }
                }
                function createDiagnosticForNodeArray(nodes, message, arg0, arg1, arg2) {
                    var start = nodes.pos;
                    return ts.createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2);
                }
                // Since these are syntactic diagnostics, parent might not have been set
                // this means the sourceFile cannot be infered from the node
                function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
                    return ts.createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
                }
            });
        }
        function getDeclarationDiagnosticsWorker(sourceFile, cancellationToken) {
            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
        }
        function getDeclarationDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
                // Don't actually write any files since we're just getting diagnostics.
                return ts.getDeclarationDiagnostics(getEmitHost(ts.noop), resolver, sourceFile) || ts.emptyArray;
            });
        }
        function getAndCacheDiagnostics(sourceFile, cancellationToken, cache, getDiagnostics) {
            var cachedResult = sourceFile
                ? cache.perFile && cache.perFile.get(sourceFile.path)
                : cache.allDiagnostics;
            if (cachedResult) {
                return cachedResult;
            }
            var result = getDiagnostics(sourceFile, cancellationToken);
            if (sourceFile) {
                if (!cache.perFile) {
                    cache.perFile = ts.createMap();
                }
                cache.perFile.set(sourceFile.path, result);
            }
            else {
                cache.allDiagnostics = result;
            }
            return result;
        }
        function getDeclarationDiagnosticsForFile(sourceFile, cancellationToken) {
            return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
        }
        function getOptionsDiagnostics() {
            return ts.sortAndDeduplicateDiagnostics(ts.concatenate(fileProcessingDiagnostics.getGlobalDiagnostics(), ts.concatenate(programDiagnostics.getGlobalDiagnostics(), getOptionsDiagnosticsOfConfigFile())));
        }
        function getOptionsDiagnosticsOfConfigFile() {
            if (!options.configFile) {
                return ts.emptyArray;
            }
            var diagnostics = programDiagnostics.getDiagnostics(options.configFile.fileName);
            forEachResolvedProjectReference(function (resolvedRef) {
                if (resolvedRef) {
                    diagnostics = ts.concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName));
                }
            });
            return diagnostics;
        }
        function getGlobalDiagnostics() {
            return rootNames.length ? ts.sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice()) : ts.emptyArray;
        }
        function getConfigFileParsingDiagnostics() {
            return configFileParsingDiagnostics || ts.emptyArray;
        }
        function processRootFile(fileName, isDefaultLib, ignoreNoDefaultLib) {
            processSourceFile(ts.normalizePath(fileName), isDefaultLib, ignoreNoDefaultLib, /*packageId*/ undefined);
        }
        function fileReferenceIsEqualTo(a, b) {
            return a.fileName === b.fileName;
        }
        function moduleNameIsEqualTo(a, b) {
            return a.kind === 75 /* Identifier */
                ? b.kind === 75 /* Identifier */ && a.escapedText === b.escapedText
                : b.kind === 10 /* StringLiteral */ && a.text === b.text;
        }
        function collectExternalModuleReferences(file) {
            if (file.imports) {
                return;
            }
            var isJavaScriptFile = ts.isSourceFileJS(file);
            var isExternalModuleFile = ts.isExternalModule(file);
            // file.imports may not be undefined if there exists dynamic import
            var imports;
            var moduleAugmentations;
            var ambientModules;
            // If we are importing helpers, we need to add a synthetic reference to resolve the
            // helpers library.
            if (options.importHelpers
                && (options.isolatedModules || isExternalModuleFile)
                && !file.isDeclarationFile) {
                // synthesize 'import "tslib"' declaration
                var externalHelpersModuleReference = ts.createLiteral(ts.externalHelpersModuleNameText);
                var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference);
                ts.addEmitFlags(importDecl, 67108864 /* NeverApplyImportHelper */);
                externalHelpersModuleReference.parent = importDecl;
                importDecl.parent = file;
                imports = [externalHelpersModuleReference];
            }
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var node = _a[_i];
                collectModuleReferences(node, /*inAmbientModule*/ false);
            }
            if ((file.flags & 1048576 /* PossiblyContainsDynamicImport */) || isJavaScriptFile) {
                collectDynamicImportOrRequireCalls(file);
            }
            file.imports = imports || ts.emptyArray;
            file.moduleAugmentations = moduleAugmentations || ts.emptyArray;
            file.ambientModuleNames = ambientModules || ts.emptyArray;
            return;
            function collectModuleReferences(node, inAmbientModule) {
                if (ts.isAnyImportOrReExport(node)) {
                    var moduleNameExpr = ts.getExternalModuleName(node);
                    // TypeScript 1.0 spec (April 2014): 12.1.6
                    // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules
                    // only through top - level external module names. Relative external module names are not permitted.
                    if (moduleNameExpr && ts.isStringLiteral(moduleNameExpr) && moduleNameExpr.text && (!inAmbientModule || !ts.isExternalModuleNameRelative(moduleNameExpr.text))) {
                        imports = ts.append(imports, moduleNameExpr);
                    }
                }
                else if (ts.isModuleDeclaration(node)) {
                    if (ts.isAmbientModule(node) && (inAmbientModule || ts.hasModifier(node, 2 /* Ambient */) || file.isDeclarationFile)) {
                        var nameText = ts.getTextOfIdentifierOrLiteral(node.name);
                        // Ambient module declarations can be interpreted as augmentations for some existing external modules.
                        // This will happen in two cases:
                        // - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
                        // - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name
                        //   immediately nested in top level ambient module declaration .
                        if (isExternalModuleFile || (inAmbientModule && !ts.isExternalModuleNameRelative(nameText))) {
                            (moduleAugmentations || (moduleAugmentations = [])).push(node.name);
                        }
                        else if (!inAmbientModule) {
                            if (file.isDeclarationFile) {
                                // for global .d.ts files record name of ambient module
                                (ambientModules || (ambientModules = [])).push(nameText);
                            }
                            // An AmbientExternalModuleDeclaration declares an external module.
                            // This type of declaration is permitted only in the global module.
                            // The StringLiteral must specify a top - level external module name.
                            // Relative external module names are not permitted
                            // NOTE: body of ambient module is always a module block, if it exists
                            var body = node.body;
                            if (body) {
                                for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
                                    var statement = _a[_i];
                                    collectModuleReferences(statement, /*inAmbientModule*/ true);
                                }
                            }
                        }
                    }
                }
            }
            function collectDynamicImportOrRequireCalls(file) {
                var r = /import|require/g;
                while (r.exec(file.text) !== null) { // eslint-disable-line no-null/no-null
                    var node = getNodeAtPosition(file, r.lastIndex);
                    if (ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
                        imports = ts.append(imports, node.arguments[0]);
                    }
                    // we have to check the argument list has length of 1. We will still have to process these even though we have parsing error.
                    else if (ts.isImportCall(node) && node.arguments.length === 1 && ts.isStringLiteralLike(node.arguments[0])) {
                        imports = ts.append(imports, node.arguments[0]);
                    }
                    else if (ts.isLiteralImportTypeNode(node)) {
                        imports = ts.append(imports, node.argument.literal);
                    }
                }
            }
            /** Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only in JS files */
            function getNodeAtPosition(sourceFile, position) {
                var current = sourceFile;
                var getContainingChild = function (child) {
                    if (child.pos <= position && (position < child.end || (position === child.end && (child.kind === 1 /* EndOfFileToken */)))) {
                        return child;
                    }
                };
                while (true) {
                    var child = isJavaScriptFile && ts.hasJSDocNodes(current) && ts.forEach(current.jsDoc, getContainingChild) || ts.forEachChild(current, getContainingChild);
                    if (!child) {
                        return current;
                    }
                    current = child;
                }
            }
        }
        function getLibFileFromReference(ref) {
            var libName = ts.toFileNameLowerCase(ref.fileName);
            var libFileName = ts.libMap.get(libName);
            if (libFileName) {
                return getSourceFile(ts.combinePaths(defaultLibraryPath, libFileName));
            }
        }
        /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
        function getSourceFileFromReference(referencingFile, ref) {
            return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), function (fileName) { return filesByName.get(toPath(fileName)) || undefined; });
        }
        function getSourceFileFromReferenceWorker(fileName, getSourceFile, fail, refFile) {
            if (ts.hasExtension(fileName)) {
                var canonicalFileName_1 = host.getCanonicalFileName(fileName);
                if (!options.allowNonTsExtensions && !ts.forEach(supportedExtensionsWithJsonIfResolveJsonModule, function (extension) { return ts.fileExtensionIs(canonicalFileName_1, extension); })) {
                    if (fail) {
                        if (ts.hasJSFileExtension(canonicalFileName_1)) {
                            fail(ts.Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName);
                        }
                        else {
                            fail(ts.Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
                        }
                    }
                    return undefined;
                }
                var sourceFile = getSourceFile(fileName);
                if (fail) {
                    if (!sourceFile) {
                        var redirect = getProjectReferenceRedirect(fileName);
                        if (redirect) {
                            fail(ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, fileName);
                        }
                        else {
                            fail(ts.Diagnostics.File_0_not_found, fileName);
                        }
                    }
                    else if (refFile && canonicalFileName_1 === host.getCanonicalFileName(refFile.fileName)) {
                        fail(ts.Diagnostics.A_file_cannot_have_a_reference_to_itself);
                    }
                }
                return sourceFile;
            }
            else {
                var sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile(fileName);
                if (sourceFileNoExtension)
                    return sourceFileNoExtension;
                if (fail && options.allowNonTsExtensions) {
                    fail(ts.Diagnostics.File_0_not_found, fileName);
                    return undefined;
                }
                var sourceFileWithAddedExtension = ts.forEach(supportedExtensions, function (extension) { return getSourceFile(fileName + extension); });
                if (fail && !sourceFileWithAddedExtension)
                    fail(ts.Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + supportedExtensions.join("', '") + "'");
                return sourceFileWithAddedExtension;
            }
        }
        /** This has side effects through `findSourceFile`. */
        function processSourceFile(fileName, isDefaultLib, ignoreNoDefaultLib, packageId, refFile) {
            getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, ignoreNoDefaultLib, refFile, packageId); }, // TODO: GH#18217
            function (diagnostic) {
                var args = [];
                for (var _i = 1; _i < arguments.length; _i++) {
                    args[_i - 1] = arguments[_i];
                }
                return fileProcessingDiagnostics.add(createRefFileDiagnostic.apply(void 0, __spreadArrays([refFile, diagnostic], args)));
            }, refFile && refFile.file);
        }
        function reportFileNamesDifferOnlyInCasingError(fileName, existingFile, refFile) {
            var refs = !refFile ? refFileMap && refFileMap.get(existingFile.path) : undefined;
            var refToReportErrorOn = refs && ts.find(refs, function (ref) { return ref.referencedFileName === existingFile.fileName; });
            fileProcessingDiagnostics.add(refToReportErrorOn ?
                createFileDiagnosticAtReference(refToReportErrorOn, ts.Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, existingFile.fileName, fileName) :
                createRefFileDiagnostic(refFile, ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFile.fileName));
        }
        function createRedirectSourceFile(redirectTarget, unredirected, fileName, path, resolvedPath, originalFileName) {
            var redirect = Object.create(redirectTarget);
            redirect.fileName = fileName;
            redirect.path = path;
            redirect.resolvedPath = resolvedPath;
            redirect.originalFileName = originalFileName;
            redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected };
            sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
            Object.defineProperties(redirect, {
                id: {
                    get: function () { return this.redirectInfo.redirectTarget.id; },
                    set: function (value) { this.redirectInfo.redirectTarget.id = value; },
                },
                symbol: {
                    get: function () { return this.redirectInfo.redirectTarget.symbol; },
                    set: function (value) { this.redirectInfo.redirectTarget.symbol = value; },
                },
            });
            return redirect;
        }
        // Get source file from normalized fileName
        function findSourceFile(fileName, path, isDefaultLib, ignoreNoDefaultLib, refFile, packageId) {
            if (useSourceOfProjectReferenceRedirect) {
                var source = getSourceOfProjectReferenceRedirect(fileName);
                // If preserveSymlinks is true, module resolution wont jump the symlink
                // but the resolved real path may be the .d.ts from project reference
                // Note:: Currently we try the real path only if the
                // file is from node_modules to avoid having to run real path on all file paths
                if (!source &&
                    host.realpath &&
                    options.preserveSymlinks &&
                    ts.isDeclarationFileName(fileName) &&
                    ts.stringContains(fileName, ts.nodeModulesPathPart)) {
                    var realPath = host.realpath(fileName);
                    if (realPath !== fileName)
                        source = getSourceOfProjectReferenceRedirect(realPath);
                }
                if (source) {
                    var file_1 = ts.isString(source) ?
                        findSourceFile(source, toPath(source), isDefaultLib, ignoreNoDefaultLib, refFile, packageId) :
                        undefined;
                    if (file_1)
                        addFileToFilesByName(file_1, path, /*redirectedPath*/ undefined);
                    return file_1;
                }
            }
            var originalFileName = fileName;
            if (filesByName.has(path)) {
                var file_2 = filesByName.get(path);
                addFileToRefFileMap(fileName, file_2 || undefined, refFile);
                // try to check if we've already seen this file but with a different casing in path
                // NOTE: this only makes sense for case-insensitive file systems, and only on files which are not redirected
                if (file_2 && options.forceConsistentCasingInFileNames) {
                    var checkedName = file_2.fileName;
                    var isRedirect = toPath(checkedName) !== toPath(fileName);
                    if (isRedirect) {
                        fileName = getProjectReferenceRedirect(fileName) || fileName;
                    }
                    // Check if it differs only in drive letters its ok to ignore that error:
                    var checkedAbsolutePath = ts.getNormalizedAbsolutePathWithoutRoot(checkedName, currentDirectory);
                    var inputAbsolutePath = ts.getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory);
                    if (checkedAbsolutePath !== inputAbsolutePath) {
                        reportFileNamesDifferOnlyInCasingError(fileName, file_2, refFile);
                    }
                }
                // If the file was previously found via a node_modules search, but is now being processed as a root file,
                // then everything it sucks in may also be marked incorrectly, and needs to be checked again.
                if (file_2 && sourceFilesFoundSearchingNodeModules.get(file_2.path) && currentNodeModulesDepth === 0) {
                    sourceFilesFoundSearchingNodeModules.set(file_2.path, false);
                    if (!options.noResolve) {
                        processReferencedFiles(file_2, isDefaultLib);
                        processTypeReferenceDirectives(file_2);
                    }
                    if (!options.noLib) {
                        processLibReferenceDirectives(file_2);
                    }
                    modulesWithElidedImports.set(file_2.path, false);
                    processImportedModules(file_2);
                }
                // See if we need to reprocess the imports due to prior skipped imports
                else if (file_2 && modulesWithElidedImports.get(file_2.path)) {
                    if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
                        modulesWithElidedImports.set(file_2.path, false);
                        processImportedModules(file_2);
                    }
                }
                return file_2 || undefined;
            }
            var redirectedPath;
            if (refFile && !useSourceOfProjectReferenceRedirect) {
                var redirectProject = getProjectReferenceRedirectProject(fileName);
                if (redirectProject) {
                    if (redirectProject.commandLine.options.outFile || redirectProject.commandLine.options.out) {
                        // Shouldnt create many to 1 mapping file in --out scenario
                        return undefined;
                    }
                    var redirect = getProjectReferenceOutputName(redirectProject, fileName);
                    fileName = redirect;
                    // Once we start redirecting to a file, we can potentially come back to it
                    // via a back-reference from another file in the .d.ts folder. If that happens we'll
                    // end up trying to add it to the program *again* because we were tracking it via its
                    // original (un-redirected) name. So we have to map both the original path and the redirected path
                    // to the source file we're about to find/create
                    redirectedPath = toPath(redirect);
                }
            }
            // We haven't looked for this file, do so now and cache result
            var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) { return fileProcessingDiagnostics.add(createRefFileDiagnostic(refFile, ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); }, shouldCreateNewSourceFile);
            if (packageId) {
                var packageIdKey = ts.packageIdToString(packageId);
                var fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
                if (fileFromPackageId) {
                    // Some other SourceFile already exists with this package name and version.
                    // Instead of creating a duplicate, just redirect to the existing one.
                    var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path, toPath(fileName), originalFileName); // TODO: GH#18217
                    redirectTargetsMap.add(fileFromPackageId.path, fileName);
                    addFileToFilesByName(dupFile, path, redirectedPath);
                    sourceFileToPackageName.set(path, packageId.name);
                    processingOtherFiles.push(dupFile);
                    return dupFile;
                }
                else if (file) {
                    // This is the first source file to have this packageId.
                    packageIdToSourceFile.set(packageIdKey, file);
                    sourceFileToPackageName.set(path, packageId.name);
                }
            }
            addFileToFilesByName(file, path, redirectedPath);
            if (file) {
                sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
                file.fileName = fileName; // Ensure that source file has same name as what we were looking for
                file.path = path;
                file.resolvedPath = toPath(fileName);
                file.originalFileName = originalFileName;
                addFileToRefFileMap(fileName, file, refFile);
                if (host.useCaseSensitiveFileNames()) {
                    var pathLowerCase = ts.toFileNameLowerCase(path);
                    // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
                    var existingFile = filesByNameIgnoreCase.get(pathLowerCase);
                    if (existingFile) {
                        reportFileNamesDifferOnlyInCasingError(fileName, existingFile, refFile);
                    }
                    else {
                        filesByNameIgnoreCase.set(pathLowerCase, file);
                    }
                }
                skipDefaultLib = skipDefaultLib || (file.hasNoDefaultLib && !ignoreNoDefaultLib);
                if (!options.noResolve) {
                    processReferencedFiles(file, isDefaultLib);
                    processTypeReferenceDirectives(file);
                }
                if (!options.noLib) {
                    processLibReferenceDirectives(file);
                }
                // always process imported modules to record module name resolutions
                processImportedModules(file);
                if (isDefaultLib) {
                    processingDefaultLibFiles.push(file);
                }
                else {
                    processingOtherFiles.push(file);
                }
            }
            return file;
        }
        function addFileToRefFileMap(referencedFileName, file, refFile) {
            if (refFile && file) {
                (refFileMap || (refFileMap = ts.createMultiMap())).add(file.path, {
                    referencedFileName: referencedFileName,
                    kind: refFile.kind,
                    index: refFile.index,
                    file: refFile.file.path
                });
            }
        }
        function addFileToFilesByName(file, path, redirectedPath) {
            if (redirectedPath) {
                filesByName.set(redirectedPath, file);
                filesByName.set(path, file || false);
            }
            else {
                filesByName.set(path, file);
            }
        }
        function getProjectReferenceRedirect(fileName) {
            var referencedProject = getProjectReferenceRedirectProject(fileName);
            return referencedProject && getProjectReferenceOutputName(referencedProject, fileName);
        }
        function getProjectReferenceRedirectProject(fileName) {
            // Ignore dts or any json files
            if (!resolvedProjectReferences || !resolvedProjectReferences.length || ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) || ts.fileExtensionIs(fileName, ".json" /* Json */)) {
                return undefined;
            }
            // If this file is produced by a referenced project, we need to rewrite it to
            // look in the output folder of the referenced project rather than the input
            return getResolvedProjectReferenceToRedirect(fileName);
        }
        function getProjectReferenceOutputName(referencedProject, fileName) {
            var out = referencedProject.commandLine.options.outFile || referencedProject.commandLine.options.out;
            return out ?
                ts.changeExtension(out, ".d.ts" /* Dts */) :
                ts.getOutputDeclarationFileName(fileName, referencedProject.commandLine, !host.useCaseSensitiveFileNames());
        }
        /**
         * Get the referenced project if the file is input file from that reference project
         */
        function getResolvedProjectReferenceToRedirect(fileName) {
            if (mapFromFileToProjectReferenceRedirects === undefined) {
                mapFromFileToProjectReferenceRedirects = ts.createMap();
                forEachResolvedProjectReference(function (referencedProject, referenceProjectPath) {
                    // not input file from the referenced project, ignore
                    if (referencedProject &&
                        toPath(options.configFilePath) !== referenceProjectPath) {
                        referencedProject.commandLine.fileNames.forEach(function (f) {
                            return mapFromFileToProjectReferenceRedirects.set(toPath(f), referenceProjectPath);
                        });
                    }
                });
            }
            var referencedProjectPath = mapFromFileToProjectReferenceRedirects.get(toPath(fileName));
            return referencedProjectPath && getResolvedProjectReferenceByPath(referencedProjectPath);
        }
        function forEachResolvedProjectReference(cb) {
            return forEachProjectReference(projectReferences, resolvedProjectReferences, function (resolvedRef, index, parent) {
                var ref = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var resolvedRefPath = toPath(resolveProjectReferencePath(ref));
                return cb(resolvedRef, resolvedRefPath);
            });
        }
        function getSourceOfProjectReferenceRedirect(file) {
            if (!ts.isDeclarationFileName(file))
                return undefined;
            if (mapFromToProjectReferenceRedirectSource === undefined) {
                mapFromToProjectReferenceRedirectSource = ts.createMap();
                forEachResolvedProjectReference(function (resolvedRef) {
                    if (resolvedRef) {
                        var out = resolvedRef.commandLine.options.outFile || resolvedRef.commandLine.options.out;
                        if (out) {
                            // Dont know which source file it means so return true?
                            var outputDts = ts.changeExtension(out, ".d.ts" /* Dts */);
                            mapFromToProjectReferenceRedirectSource.set(toPath(outputDts), true);
                        }
                        else {
                            ts.forEach(resolvedRef.commandLine.fileNames, function (fileName) {
                                if (!ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) && !ts.fileExtensionIs(fileName, ".json" /* Json */)) {
                                    var outputDts = ts.getOutputDeclarationFileName(fileName, resolvedRef.commandLine, host.useCaseSensitiveFileNames());
                                    mapFromToProjectReferenceRedirectSource.set(toPath(outputDts), fileName);
                                }
                            });
                        }
                    }
                });
            }
            return mapFromToProjectReferenceRedirectSource.get(toPath(file));
        }
        function isSourceOfProjectReferenceRedirect(fileName) {
            return useSourceOfProjectReferenceRedirect && !!getResolvedProjectReferenceToRedirect(fileName);
        }
        function forEachProjectReference(projectReferences, resolvedProjectReferences, cbResolvedRef, cbRef) {
            var seenResolvedRefs;
            return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined, cbResolvedRef, cbRef);
            function worker(projectReferences, resolvedProjectReferences, parent, cbResolvedRef, cbRef) {
                // Visit project references first
                if (cbRef) {
                    var result = cbRef(projectReferences, parent);
                    if (result) {
                        return result;
                    }
                }
                return ts.forEach(resolvedProjectReferences, function (resolvedRef, index) {
                    if (ts.contains(seenResolvedRefs, resolvedRef)) {
                        // ignore recursives
                        return undefined;
                    }
                    var result = cbResolvedRef(resolvedRef, index, parent);
                    if (result) {
                        return result;
                    }
                    if (!resolvedRef)
                        return undefined;
                    (seenResolvedRefs || (seenResolvedRefs = [])).push(resolvedRef);
                    return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef, cbResolvedRef, cbRef);
                });
            }
        }
        function getResolvedProjectReferenceByPath(projectReferencePath) {
            if (!projectReferenceRedirects) {
                return undefined;
            }
            return projectReferenceRedirects.get(projectReferencePath) || undefined;
        }
        function processReferencedFiles(file, isDefaultLib) {
            ts.forEach(file.referencedFiles, function (ref, index) {
                var referencedFileName = resolveTripleslashReference(ref.fileName, file.originalFileName);
                processSourceFile(referencedFileName, isDefaultLib, 
                /*ignoreNoDefaultLib*/ false, 
                /*packageId*/ undefined, {
                    kind: ts.RefFileKind.ReferenceFile,
                    index: index,
                    file: file,
                    pos: ref.pos,
                    end: ref.end
                });
            });
        }
        function processTypeReferenceDirectives(file) {
            // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
            var typeDirectives = ts.map(file.typeReferenceDirectives, function (ref) { return ts.toFileNameLowerCase(ref.fileName); });
            if (!typeDirectives) {
                return;
            }
            var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName, getResolvedProjectReferenceToRedirect(file.originalFileName));
            for (var i = 0; i < typeDirectives.length; i++) {
                var ref = file.typeReferenceDirectives[i];
                var resolvedTypeReferenceDirective = resolutions[i];
                // store resolved type directive on the file
                var fileName = ts.toFileNameLowerCase(ref.fileName);
                ts.setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective);
                processTypeReferenceDirective(fileName, resolvedTypeReferenceDirective, {
                    kind: ts.RefFileKind.TypeReferenceDirective,
                    index: i,
                    file: file,
                    pos: ref.pos,
                    end: ref.end
                });
            }
        }
        function processTypeReferenceDirective(typeReferenceDirective, resolvedTypeReferenceDirective, refFile) {
            // If we already found this library as a primary reference - nothing to do
            var previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective);
            if (previousResolution && previousResolution.primary) {
                return;
            }
            var saveResolution = true;
            if (resolvedTypeReferenceDirective) {
                if (resolvedTypeReferenceDirective.isExternalLibraryImport)
                    currentNodeModulesDepth++;
                if (resolvedTypeReferenceDirective.primary) {
                    // resolved from the primary path
                    processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile); // TODO: GH#18217
                }
                else {
                    // If we already resolved to this file, it must have been a secondary reference. Check file contents
                    // for sameness and possibly issue an error
                    if (previousResolution) {
                        // Don't bother reading the file again if it's the same file.
                        if (resolvedTypeReferenceDirective.resolvedFileName !== previousResolution.resolvedFileName) {
                            var otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName);
                            var existingFile_1 = getSourceFile(previousResolution.resolvedFileName);
                            if (otherFileText !== existingFile_1.text) {
                                // Try looking up ref for original file
                                var refs = !refFile ? refFileMap && refFileMap.get(existingFile_1.path) : undefined;
                                var refToReportErrorOn = refs && ts.find(refs, function (ref) { return ref.referencedFileName === existingFile_1.fileName; });
                                fileProcessingDiagnostics.add(refToReportErrorOn ?
                                    createFileDiagnosticAtReference(refToReportErrorOn, ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName) :
                                    createRefFileDiagnostic(refFile, ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName));
                            }
                        }
                        // don't overwrite previous resolution result
                        saveResolution = false;
                    }
                    else {
                        // First resolution of this library
                        processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile);
                    }
                }
                if (resolvedTypeReferenceDirective.isExternalLibraryImport)
                    currentNodeModulesDepth--;
            }
            else {
                fileProcessingDiagnostics.add(createRefFileDiagnostic(refFile, ts.Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective));
            }
            if (saveResolution) {
                resolvedTypeReferenceDirectives.set(typeReferenceDirective, resolvedTypeReferenceDirective);
            }
        }
        function processLibReferenceDirectives(file) {
            ts.forEach(file.libReferenceDirectives, function (libReference) {
                var libName = ts.toFileNameLowerCase(libReference.fileName);
                var libFileName = ts.libMap.get(libName);
                if (libFileName) {
                    // we ignore any 'no-default-lib' reference set on this file.
                    processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true);
                }
                else {
                    var unqualifiedLibName = ts.removeSuffix(ts.removePrefix(libName, "lib."), ".d.ts");
                    var suggestion = ts.getSpellingSuggestion(unqualifiedLibName, ts.libs, ts.identity);
                    var message = suggestion ? ts.Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : ts.Diagnostics.Cannot_find_lib_definition_for_0;
                    fileProcessingDiagnostics.add(ts.createFileDiagnostic(file, libReference.pos, libReference.end - libReference.pos, message, libName, suggestion));
                }
            });
        }
        function createRefFileDiagnostic(refFile, message) {
            var args = [];
            for (var _i = 2; _i < arguments.length; _i++) {
                args[_i - 2] = arguments[_i];
            }
            if (!refFile) {
                return ts.createCompilerDiagnostic.apply(void 0, __spreadArrays([message], args));
            }
            else {
                return ts.createFileDiagnostic.apply(void 0, __spreadArrays([refFile.file, refFile.pos, refFile.end - refFile.pos, message], args));
            }
        }
        function getCanonicalFileName(fileName) {
            return host.getCanonicalFileName(fileName);
        }
        function processImportedModules(file) {
            collectExternalModuleReferences(file);
            if (file.imports.length || file.moduleAugmentations.length) {
                // Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
                var moduleNames = getModuleNames(file);
                var resolutions = resolveModuleNamesReusingOldState(moduleNames, ts.getNormalizedAbsolutePath(file.originalFileName, currentDirectory), file);
                ts.Debug.assert(resolutions.length === moduleNames.length);
                for (var i = 0; i < moduleNames.length; i++) {
                    var resolution = resolutions[i];
                    ts.setResolvedModule(file, moduleNames[i], resolution);
                    if (!resolution) {
                        continue;
                    }
                    var isFromNodeModulesSearch = resolution.isExternalLibraryImport;
                    var isJsFile = !ts.resolutionExtensionIsTSOrJson(resolution.extension);
                    var isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile;
                    var resolvedFileName = resolution.resolvedFileName;
                    if (isFromNodeModulesSearch) {
                        currentNodeModulesDepth++;
                    }
                    // add file to program only if:
                    // - resolution was successful
                    // - noResolve is falsy
                    // - module name comes from the list of imports
                    // - it's not a top level JavaScript module that exceeded the search max
                    var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
                    // Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
                    // This may still end up being an untyped module -- the file won't be included but imports will be allowed.
                    var shouldAddFile = resolvedFileName
                        && !getResolutionDiagnostic(options, resolution)
                        && !options.noResolve
                        && i < file.imports.length
                        && !elideImport
                        && !(isJsFile && !options.allowJs)
                        && (ts.isInJSFile(file.imports[i]) || !(file.imports[i].flags & 4194304 /* JSDoc */));
                    if (elideImport) {
                        modulesWithElidedImports.set(file.path, true);
                    }
                    else if (shouldAddFile) {
                        var path = toPath(resolvedFileName);
                        var pos = ts.skipTrivia(file.text, file.imports[i].pos);
                        findSourceFile(resolvedFileName, path, 
                        /*isDefaultLib*/ false, 
                        /*ignoreNoDefaultLib*/ false, {
                            kind: ts.RefFileKind.Import,
                            index: i,
                            file: file,
                            pos: pos,
                            end: file.imports[i].end
                        }, resolution.packageId);
                    }
                    if (isFromNodeModulesSearch) {
                        currentNodeModulesDepth--;
                    }
                }
            }
            else {
                // no imports - drop cached module resolutions
                file.resolvedModules = undefined;
            }
        }
        function computeCommonSourceDirectory(sourceFiles) {
            var fileNames = ts.mapDefined(sourceFiles, function (file) { return file.isDeclarationFile ? undefined : file.fileName; });
            return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName);
        }
        function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
            var allFilesBelongToPath = true;
            var absoluteRootDirectoryPath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(rootDirectory, currentDirectory));
            var rootPaths;
            for (var _i = 0, sourceFiles_2 = sourceFiles; _i < sourceFiles_2.length; _i++) {
                var sourceFile = sourceFiles_2[_i];
                if (!sourceFile.isDeclarationFile) {
                    var absoluteSourceFilePath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
                    if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
                        if (!rootPaths)
                            rootPaths = ts.arrayToSet(rootNames, toPath);
                        addProgramDiagnosticAtRefPath(sourceFile, rootPaths, ts.Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, rootDirectory);
                        allFilesBelongToPath = false;
                    }
                }
            }
            return allFilesBelongToPath;
        }
        function parseProjectReferenceConfigFile(ref) {
            if (!projectReferenceRedirects) {
                projectReferenceRedirects = ts.createMap();
            }
            // The actual filename (i.e. add "/tsconfig.json" if necessary)
            var refPath = resolveProjectReferencePath(ref);
            var sourceFilePath = toPath(refPath);
            var fromCache = projectReferenceRedirects.get(sourceFilePath);
            if (fromCache !== undefined) {
                return fromCache || undefined;
            }
            var commandLine;
            var sourceFile;
            if (host.getParsedCommandLine) {
                commandLine = host.getParsedCommandLine(refPath);
                if (!commandLine) {
                    addFileToFilesByName(/*sourceFile*/ undefined, sourceFilePath, /*redirectedPath*/ undefined);
                    projectReferenceRedirects.set(sourceFilePath, false);
                    return undefined;
                }
                sourceFile = ts.Debug.checkDefined(commandLine.options.configFile);
                ts.Debug.assert(!sourceFile.path || sourceFile.path === sourceFilePath);
                addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
            }
            else {
                // An absolute path pointing to the containing directory of the config file
                var basePath = ts.getNormalizedAbsolutePath(ts.getDirectoryPath(refPath), host.getCurrentDirectory());
                sourceFile = host.getSourceFile(refPath, 100 /* JSON */);
                addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
                if (sourceFile === undefined) {
                    projectReferenceRedirects.set(sourceFilePath, false);
                    return undefined;
                }
                commandLine = ts.parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
            }
            sourceFile.fileName = refPath;
            sourceFile.path = sourceFilePath;
            sourceFile.resolvedPath = sourceFilePath;
            sourceFile.originalFileName = refPath;
            var resolvedRef = { commandLine: commandLine, sourceFile: sourceFile };
            projectReferenceRedirects.set(sourceFilePath, resolvedRef);
            if (commandLine.projectReferences) {
                resolvedRef.references = commandLine.projectReferences.map(parseProjectReferenceConfigFile);
            }
            return resolvedRef;
        }
        function verifyCompilerOptions() {
            if (options.strictPropertyInitialization && !ts.getStrictOptionValue(options, "strictNullChecks")) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
            }
            if (options.isolatedModules) {
                if (options.out) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules");
                }
                if (options.outFile) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules");
                }
            }
            if (options.inlineSourceMap) {
                if (options.sourceMap) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
                }
                if (options.mapRoot) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap");
                }
            }
            if (options.paths && options.baseUrl === undefined) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths");
            }
            if (options.composite) {
                if (options.declaration === false) {
                    createDiagnosticForOptionName(ts.Diagnostics.Composite_projects_may_not_disable_declaration_emit, "declaration");
                }
                if (options.incremental === false) {
                    createDiagnosticForOptionName(ts.Diagnostics.Composite_projects_may_not_disable_incremental_compilation, "declaration");
                }
            }
            if (options.tsBuildInfoFile) {
                if (!ts.isIncrementalCompilation(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "tsBuildInfoFile", "incremental", "composite");
                }
            }
            else if (options.incremental && !options.outFile && !options.out && !options.configFilePath) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified));
            }
            if (!options.listFilesOnly && options.noEmit && ts.isIncrementalCompilation(options)) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", options.incremental ? "incremental" : "composite");
            }
            verifyProjectReferences();
            // List of collected files is complete; validate exhautiveness if this is a project with a file list
            if (options.composite) {
                var rootPaths = ts.arrayToSet(rootNames, toPath);
                for (var _i = 0, files_3 = files; _i < files_3.length; _i++) {
                    var file = files_3[_i];
                    // Ignore file that is not emitted
                    if (ts.sourceFileMayBeEmitted(file, program) && !rootPaths.has(file.path)) {
                        addProgramDiagnosticAtRefPath(file, rootPaths, ts.Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern, file.fileName, options.configFilePath || "");
                    }
                }
            }
            if (options.paths) {
                for (var key in options.paths) {
                    if (!ts.hasProperty(options.paths, key)) {
                        continue;
                    }
                    if (!ts.hasZeroOrOneAsteriskCharacter(key)) {
                        createDiagnosticForOptionPaths(/*onKey*/ true, key, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key);
                    }
                    if (ts.isArray(options.paths[key])) {
                        var len = options.paths[key].length;
                        if (len === 0) {
                            createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key);
                        }
                        for (var i = 0; i < len; i++) {
                            var subst = options.paths[key][i];
                            var typeOfSubst = typeof subst;
                            if (typeOfSubst === "string") {
                                if (!ts.hasZeroOrOneAsteriskCharacter(subst)) {
                                    createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character, subst, key);
                                }
                            }
                            else {
                                createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst);
                            }
                        }
                    }
                    else {
                        createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key);
                    }
                }
            }
            if (!options.sourceMap && !options.inlineSourceMap) {
                if (options.inlineSources) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources");
                }
                if (options.sourceRoot) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot");
                }
            }
            if (options.out && options.outFile) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile");
            }
            if (options.mapRoot && !(options.sourceMap || options.declarationMap)) {
                // Error to specify --mapRoot without --sourcemap
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "mapRoot", "sourceMap", "declarationMap");
            }
            if (options.declarationDir) {
                if (!ts.getEmitDeclarations(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationDir", "declaration", "composite");
                }
                if (options.out || options.outFile) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
                }
            }
            if (options.declarationMap && !ts.getEmitDeclarations(options)) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationMap", "declaration", "composite");
            }
            if (options.lib && options.noLib) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
            }
            if (options.noImplicitUseStrict && ts.getStrictOptionValue(options, "alwaysStrict")) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
            }
            var languageVersion = options.target || 0 /* ES3 */;
            var outFile = options.outFile || options.out;
            var firstNonAmbientExternalModuleSourceFile = ts.find(files, function (f) { return ts.isExternalModule(f) && !f.isDeclarationFile; });
            if (options.isolatedModules) {
                if (options.module === ts.ModuleKind.None && languageVersion < 2 /* ES2015 */) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
                }
                var firstNonExternalModuleSourceFile = ts.find(files, function (f) { return !ts.isExternalModule(f) && !ts.isSourceFileJS(f) && !f.isDeclarationFile && f.scriptKind !== 6 /* JSON */; });
                if (firstNonExternalModuleSourceFile) {
                    var span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.All_files_must_be_modules_when_the_isolatedModules_flag_is_provided));
                }
            }
            else if (firstNonAmbientExternalModuleSourceFile && languageVersion < 2 /* ES2015 */ && options.module === ts.ModuleKind.None) {
                // We cannot use createDiagnosticFromNode because nodes do not have parents yet
                var span = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
                programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
            }
            // Cannot specify module gen that isn't amd or system with --out
            if (outFile && !options.emitDeclarationOnly) {
                if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
                }
                else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) {
                    var span = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile"));
                }
            }
            if (options.resolveJsonModule) {
                if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
                }
                // Any emit other than common js, amd, es2015 or esnext is error
                else if (!ts.hasJsonModuleEmitEnabled(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module");
                }
            }
            // there has to be common source directory if user specified --outdir || --sourceRoot
            // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
            if (options.outDir || // there is --outDir specified
                options.sourceRoot || // there is --sourceRoot specified
                options.mapRoot) { // there is --mapRoot specified
                // Precalculate and cache the common source directory
                var dir = getCommonSourceDirectory();
                // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
                if (options.outDir && dir === "" && files.some(function (file) { return ts.getRootLength(file.fileName) > 1; })) {
                    createDiagnosticForOptionName(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
                }
            }
            if (options.useDefineForClassFields && languageVersion === 0 /* ES3 */) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_when_option_target_is_ES3, "useDefineForClassFields");
            }
            if (options.checkJs && !options.allowJs) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
            }
            if (options.emitDeclarationOnly) {
                if (!ts.getEmitDeclarations(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite");
                }
                if (options.noEmit) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationOnly", "noEmit");
                }
            }
            if (options.emitDecoratorMetadata &&
                !options.experimentalDecorators) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
            }
            if (options.jsxFactory) {
                if (options.reactNamespace) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory");
                }
                if (!ts.parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
                    createOptionValueDiagnostic("jsxFactory", ts.Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory);
                }
            }
            else if (options.reactNamespace && !ts.isIdentifierText(options.reactNamespace, languageVersion)) {
                createOptionValueDiagnostic("reactNamespace", ts.Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
            }
            // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
            if (!options.noEmit && !options.suppressOutputPathCheck) {
                var emitHost = getEmitHost();
                var emitFilesSeen_1 = ts.createMap();
                ts.forEachEmittedFile(emitHost, function (emitFileNames) {
                    if (!options.emitDeclarationOnly) {
                        verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen_1);
                    }
                    verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen_1);
                });
            }
            // Verify that all the emit files are unique and don't overwrite input files
            function verifyEmitFilePath(emitFileName, emitFilesSeen) {
                if (emitFileName) {
                    var emitFilePath = toPath(emitFileName);
                    // Report error if the output overwrites input file
                    if (filesByName.has(emitFilePath)) {
                        var chain = void 0;
                        if (!options.configFilePath) {
                            // The program is from either an inferred project or an external project
                            chain = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
                        }
                        chain = ts.chainDiagnosticMessages(chain, ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnosticFromMessageChain(chain));
                    }
                    var emitFileKey = !host.useCaseSensitiveFileNames() ? ts.toFileNameLowerCase(emitFilePath) : emitFilePath;
                    // Report error if multiple files write into same file
                    if (emitFilesSeen.has(emitFileKey)) {
                        // Already seen the same emit file - report error
                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
                    }
                    else {
                        emitFilesSeen.set(emitFileKey, true);
                    }
                }
            }
        }
        function createFileDiagnosticAtReference(refPathToReportErrorOn, message) {
            var _a, _b;
            var args = [];
            for (var _i = 2; _i < arguments.length; _i++) {
                args[_i - 2] = arguments[_i];
            }
            var refFile = ts.Debug.checkDefined(getSourceFileByPath(refPathToReportErrorOn.file));
            var kind = refPathToReportErrorOn.kind, index = refPathToReportErrorOn.index;
            var pos, end;
            switch (kind) {
                case ts.RefFileKind.Import:
                    pos = ts.skipTrivia(refFile.text, refFile.imports[index].pos);
                    end = refFile.imports[index].end;
                    break;
                case ts.RefFileKind.ReferenceFile:
                    (_a = refFile.referencedFiles[index], pos = _a.pos, end = _a.end);
                    break;
                case ts.RefFileKind.TypeReferenceDirective:
                    (_b = refFile.typeReferenceDirectives[index], pos = _b.pos, end = _b.end);
                    break;
                default:
                    return ts.Debug.assertNever(kind);
            }
            return ts.createFileDiagnostic.apply(void 0, __spreadArrays([refFile, pos, end - pos, message], args));
        }
        function addProgramDiagnosticAtRefPath(file, rootPaths, message) {
            var args = [];
            for (var _i = 3; _i < arguments.length; _i++) {
                args[_i - 3] = arguments[_i];
            }
            var refPaths = refFileMap && refFileMap.get(file.path);
            var refPathToReportErrorOn = ts.forEach(refPaths, function (refPath) { return rootPaths.has(refPath.file) ? refPath : undefined; }) ||
                ts.elementAt(refPaths, 0);
            programDiagnostics.add(refPathToReportErrorOn ? createFileDiagnosticAtReference.apply(void 0, __spreadArrays([refPathToReportErrorOn, message], args)) : ts.createCompilerDiagnostic.apply(void 0, __spreadArrays([message], args)));
        }
        function verifyProjectReferences() {
            var buildInfoPath = !options.noEmit && !options.suppressOutputPathCheck ? ts.getTsBuildInfoEmitOutputFilePath(options) : undefined;
            forEachProjectReference(projectReferences, resolvedProjectReferences, function (resolvedRef, index, parent) {
                var ref = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var parentFile = parent && parent.sourceFile;
                if (!resolvedRef) {
                    createDiagnosticForReference(parentFile, index, ts.Diagnostics.File_0_not_found, ref.path);
                    return;
                }
                var options = resolvedRef.commandLine.options;
                if (!options.composite) {
                    // ok to not have composite if the current program is container only
                    var inputs = parent ? parent.commandLine.fileNames : rootNames;
                    if (inputs.length) {
                        createDiagnosticForReference(parentFile, index, ts.Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
                    }
                }
                if (ref.prepend) {
                    var out = options.outFile || options.out;
                    if (out) {
                        if (!host.fileExists(out)) {
                            createDiagnosticForReference(parentFile, index, ts.Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path);
                        }
                    }
                    else {
                        createDiagnosticForReference(parentFile, index, ts.Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path);
                    }
                }
                if (!parent && buildInfoPath && buildInfoPath === ts.getTsBuildInfoEmitOutputFilePath(options)) {
                    createDiagnosticForReference(parentFile, index, ts.Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path);
                    hasEmitBlockingDiagnostics.set(toPath(buildInfoPath), true);
                }
            });
        }
        function createDiagnosticForOptionPathKeyValue(key, valueIndex, message, arg0, arg1, arg2) {
            var needCompilerDiagnostic = true;
            var pathsSyntax = getOptionPathsSyntax();
            for (var _i = 0, pathsSyntax_1 = pathsSyntax; _i < pathsSyntax_1.length; _i++) {
                var pathProp = pathsSyntax_1[_i];
                if (ts.isObjectLiteralExpression(pathProp.initializer)) {
                    for (var _a = 0, _b = ts.getPropertyAssignment(pathProp.initializer, key); _a < _b.length; _a++) {
                        var keyProps = _b[_a];
                        var initializer = keyProps.initializer;
                        if (ts.isArrayLiteralExpression(initializer) && initializer.elements.length > valueIndex) {
                            programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, initializer.elements[valueIndex], message, arg0, arg1, arg2));
                            needCompilerDiagnostic = false;
                        }
                    }
                }
            }
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2));
            }
        }
        function createDiagnosticForOptionPaths(onKey, key, message, arg0) {
            var needCompilerDiagnostic = true;
            var pathsSyntax = getOptionPathsSyntax();
            for (var _i = 0, pathsSyntax_2 = pathsSyntax; _i < pathsSyntax_2.length; _i++) {
                var pathProp = pathsSyntax_2[_i];
                if (ts.isObjectLiteralExpression(pathProp.initializer) &&
                    createOptionDiagnosticInObjectLiteralSyntax(pathProp.initializer, onKey, key, /*key2*/ undefined, message, arg0)) {
                    needCompilerDiagnostic = false;
                }
            }
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0));
            }
        }
        function getOptionsSyntaxByName(name) {
            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
            if (compilerOptionsObjectLiteralSyntax) {
                return ts.getPropertyAssignment(compilerOptionsObjectLiteralSyntax, name);
            }
            return undefined;
        }
        function getOptionPathsSyntax() {
            return getOptionsSyntaxByName("paths") || ts.emptyArray;
        }
        function createDiagnosticForOptionName(message, option1, option2, option3) {
            createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3);
        }
        function createOptionValueDiagnostic(option1, message, arg0) {
            createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
        }
        function createDiagnosticForReference(sourceFile, index, message, arg0, arg1) {
            var referencesSyntax = ts.firstDefined(ts.getTsConfigPropArray(sourceFile || options.configFile, "references"), function (property) { return ts.isArrayLiteralExpression(property.initializer) ? property.initializer : undefined; });
            if (referencesSyntax && referencesSyntax.elements.length > index) {
                programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(sourceFile || options.configFile, referencesSyntax.elements[index], message, arg0, arg1));
            }
            else {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1));
            }
        }
        function createDiagnosticForOption(onKey, option1, option2, message, arg0, arg1, arg2) {
            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
            var needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
                !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2);
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2));
            }
        }
        function getCompilerOptionsObjectLiteralSyntax() {
            if (_compilerOptionsObjectLiteralSyntax === undefined) {
                _compilerOptionsObjectLiteralSyntax = null; // eslint-disable-line no-null/no-null
                var jsonObjectLiteral = ts.getTsConfigObjectLiteralExpression(options.configFile);
                if (jsonObjectLiteral) {
                    for (var _i = 0, _a = ts.getPropertyAssignment(jsonObjectLiteral, "compilerOptions"); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        if (ts.isObjectLiteralExpression(prop.initializer)) {
                            _compilerOptionsObjectLiteralSyntax = prop.initializer;
                            break;
                        }
                    }
                }
            }
            return _compilerOptionsObjectLiteralSyntax;
        }
        function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral, onKey, key1, key2, message, arg0, arg1, arg2) {
            var props = ts.getPropertyAssignment(objectLiteral, key1, key2);
            for (var _i = 0, props_3 = props; _i < props_3.length; _i++) {
                var prop = props_3[_i];
                programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2));
            }
            return !!props.length;
        }
        function blockEmittingOfFile(emitFileName, diag) {
            hasEmitBlockingDiagnostics.set(toPath(emitFileName), true);
            programDiagnostics.add(diag);
        }
        function isEmittedFile(file) {
            if (options.noEmit) {
                return false;
            }
            // If this is source file, its not emitted file
            var filePath = toPath(file);
            if (getSourceFileByPath(filePath)) {
                return false;
            }
            // If options have --outFile or --out just check that
            var out = options.outFile || options.out;
            if (out) {
                return isSameFile(filePath, out) || isSameFile(filePath, ts.removeFileExtension(out) + ".d.ts" /* Dts */);
            }
            // If declarationDir is specified, return if its a file in that directory
            if (options.declarationDir && ts.containsPath(options.declarationDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames())) {
                return true;
            }
            // If --outDir, check if file is in that directory
            if (options.outDir) {
                return ts.containsPath(options.outDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames());
            }
            if (ts.fileExtensionIsOneOf(filePath, ts.supportedJSExtensions) || ts.fileExtensionIs(filePath, ".d.ts" /* Dts */)) {
                // Otherwise just check if sourceFile with the name exists
                var filePathWithoutExtension = ts.removeFileExtension(filePath);
                return !!getSourceFileByPath((filePathWithoutExtension + ".ts" /* Ts */)) ||
                    !!getSourceFileByPath((filePathWithoutExtension + ".tsx" /* Tsx */));
            }
            return false;
        }
        function isSameFile(file1, file2) {
            return ts.comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
        }
        function getProbableSymlinks() {
            if (host.getSymlinks) {
                return host.getSymlinks();
            }
            return symlinks || (symlinks = ts.discoverProbableSymlinks(files, getCanonicalFileName, host.getCurrentDirectory()));
        }
    }
    ts.createProgram = createProgram;
    function updateHostForUseSourceOfProjectReferenceRedirect(host) {
        var mapOfDeclarationDirectories;
        var symlinkedDirectories;
        var symlinkedFiles;
        var originalFileExists = host.compilerHost.fileExists;
        var originalDirectoryExists = host.compilerHost.directoryExists;
        var originalGetDirectories = host.compilerHost.getDirectories;
        var originalRealpath = host.compilerHost.realpath;
        if (!host.useSourceOfProjectReferenceRedirect)
            return { onProgramCreateComplete: ts.noop, fileExists: fileExists };
        host.compilerHost.fileExists = fileExists;
        if (originalDirectoryExists) {
            // This implementation of directoryExists checks if the directory being requested is
            // directory of .d.ts file for the referenced Project.
            // If it is it returns true irrespective of whether that directory exists on host
            host.compilerHost.directoryExists = function (path) {
                if (originalDirectoryExists.call(host.compilerHost, path)) {
                    handleDirectoryCouldBeSymlink(path);
                    return true;
                }
                if (!host.getResolvedProjectReferences())
                    return false;
                if (!mapOfDeclarationDirectories) {
                    mapOfDeclarationDirectories = ts.createMap();
                    host.forEachResolvedProjectReference(function (ref) {
                        if (!ref)
                            return;
                        var out = ref.commandLine.options.outFile || ref.commandLine.options.out;
                        if (out) {
                            mapOfDeclarationDirectories.set(ts.getDirectoryPath(host.toPath(out)), true);
                        }
                        else {
                            // Set declaration's in different locations only, if they are next to source the directory present doesnt change
                            var declarationDir = ref.commandLine.options.declarationDir || ref.commandLine.options.outDir;
                            if (declarationDir) {
                                mapOfDeclarationDirectories.set(host.toPath(declarationDir), true);
                            }
                        }
                    });
                }
                return fileOrDirectoryExistsUsingSource(path, /*isFile*/ false);
            };
        }
        if (originalGetDirectories) {
            // Call getDirectories only if directory actually present on the host
            // This is needed to ensure that we arent getting directories that we fake about presence for
            host.compilerHost.getDirectories = function (path) {
                return !host.getResolvedProjectReferences() || (originalDirectoryExists && originalDirectoryExists.call(host.compilerHost, path)) ?
                    originalGetDirectories.call(host.compilerHost, path) :
                    [];
            };
        }
        // This is something we keep for life time of the host
        if (originalRealpath) {
            host.compilerHost.realpath = function (s) {
                return (symlinkedFiles === null || symlinkedFiles === void 0 ? void 0 : symlinkedFiles.get(host.toPath(s))) ||
                    originalRealpath.call(host.compilerHost, s);
            };
        }
        return { onProgramCreateComplete: onProgramCreateComplete, fileExists: fileExists };
        function onProgramCreateComplete() {
            host.compilerHost.fileExists = originalFileExists;
            host.compilerHost.directoryExists = originalDirectoryExists;
            host.compilerHost.getDirectories = originalGetDirectories;
            // DO not revert realpath as it could be used later
        }
        // This implementation of fileExists checks if the file being requested is
        // .d.ts file for the referenced Project.
        // If it is it returns true irrespective of whether that file exists on host
        function fileExists(file) {
            if (originalFileExists.call(host.compilerHost, file))
                return true;
            if (!host.getResolvedProjectReferences())
                return false;
            if (!ts.isDeclarationFileName(file))
                return false;
            // Project references go to source file instead of .d.ts file
            return fileOrDirectoryExistsUsingSource(file, /*isFile*/ true);
        }
        function fileExistsIfProjectReferenceDts(file) {
            var source = host.getSourceOfProjectReferenceRedirect(file);
            return source !== undefined ?
                ts.isString(source) ? originalFileExists.call(host.compilerHost, source) : true :
                undefined;
        }
        function directoryExistsIfProjectReferenceDeclDir(dir) {
            var dirPath = host.toPath(dir);
            var dirPathWithTrailingDirectorySeparator = "" + dirPath + ts.directorySeparator;
            return ts.forEachKey(mapOfDeclarationDirectories, function (declDirPath) { return dirPath === declDirPath ||
                // Any parent directory of declaration dir
                ts.startsWith(declDirPath, dirPathWithTrailingDirectorySeparator) ||
                // Any directory inside declaration dir
                ts.startsWith(dirPath, declDirPath + "/"); });
        }
        function handleDirectoryCouldBeSymlink(directory) {
            if (!host.getResolvedProjectReferences())
                return;
            // Because we already watch node_modules, handle symlinks in there
            if (!originalRealpath || !ts.stringContains(directory, ts.nodeModulesPathPart))
                return;
            if (!symlinkedDirectories)
                symlinkedDirectories = ts.createMap();
            var directoryPath = ts.ensureTrailingDirectorySeparator(host.toPath(directory));
            if (symlinkedDirectories.has(directoryPath))
                return;
            var real = ts.normalizePath(originalRealpath.call(host.compilerHost, directory));
            var realPath;
            if (real === directory ||
                (realPath = ts.ensureTrailingDirectorySeparator(host.toPath(real))) === directoryPath) {
                // not symlinked
                symlinkedDirectories.set(directoryPath, false);
                return;
            }
            symlinkedDirectories.set(directoryPath, {
                real: ts.ensureTrailingDirectorySeparator(real),
                realPath: realPath
            });
        }
        function fileOrDirectoryExistsUsingSource(fileOrDirectory, isFile) {
            var fileOrDirectoryExistsUsingSource = isFile ?
                function (file) { return fileExistsIfProjectReferenceDts(file); } :
                function (dir) { return directoryExistsIfProjectReferenceDeclDir(dir); };
            // Check current directory or file
            var result = fileOrDirectoryExistsUsingSource(fileOrDirectory);
            if (result !== undefined)
                return result;
            if (!symlinkedDirectories)
                return false;
            var fileOrDirectoryPath = host.toPath(fileOrDirectory);
            if (!ts.stringContains(fileOrDirectoryPath, ts.nodeModulesPathPart))
                return false;
            if (isFile && symlinkedFiles && symlinkedFiles.has(fileOrDirectoryPath))
                return true;
            // If it contains node_modules check if its one of the symlinked path we know of
            return ts.firstDefinedIterator(symlinkedDirectories.entries(), function (_a) {
                var directoryPath = _a[0], symlinkedDirectory = _a[1];
                if (!symlinkedDirectory || !ts.startsWith(fileOrDirectoryPath, directoryPath))
                    return undefined;
                var result = fileOrDirectoryExistsUsingSource(fileOrDirectoryPath.replace(directoryPath, symlinkedDirectory.realPath));
                if (isFile && result) {
                    if (!symlinkedFiles)
                        symlinkedFiles = ts.createMap();
                    // Store the real path for the file'
                    var absolutePath = ts.getNormalizedAbsolutePath(fileOrDirectory, host.compilerHost.getCurrentDirectory());
                    symlinkedFiles.set(fileOrDirectoryPath, "" + symlinkedDirectory.real + absolutePath.replace(new RegExp(directoryPath, "i"), ""));
                }
                return result;
            }) || false;
        }
    }
    /*@internal*/
    function handleNoEmitOptions(program, sourceFile, cancellationToken) {
        var options = program.getCompilerOptions();
        if (options.noEmit) {
            return { diagnostics: ts.emptyArray, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
        }
        // If the noEmitOnError flag is set, then check if we have any errors so far.  If so,
        // immediately bail out.  Note that we pass 'undefined' for 'sourceFile' so that we
        // get any preEmit diagnostics, not just the ones
        if (!options.noEmitOnError)
            return undefined;
        var diagnostics = __spreadArrays(program.getOptionsDiagnostics(cancellationToken), program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken));
        if (diagnostics.length === 0 && ts.getEmitDeclarations(program.getCompilerOptions())) {
            diagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
        }
        return diagnostics.length > 0 ?
            { diagnostics: diagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true } :
            undefined;
    }
    ts.handleNoEmitOptions = handleNoEmitOptions;
    /* @internal */
    function parseConfigHostFromCompilerHostLike(host, directoryStructureHost) {
        if (directoryStructureHost === void 0) { directoryStructureHost = host; }
        return {
            fileExists: function (f) { return directoryStructureHost.fileExists(f); },
            readDirectory: function (root, extensions, excludes, includes, depth) {
                ts.Debug.assertIsDefined(directoryStructureHost.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'");
                return directoryStructureHost.readDirectory(root, extensions, excludes, includes, depth);
            },
            readFile: function (f) { return directoryStructureHost.readFile(f); },
            useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
            onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || ts.returnUndefined,
            trace: host.trace ? function (s) { return host.trace(s); } : undefined
        };
    }
    ts.parseConfigHostFromCompilerHostLike = parseConfigHostFromCompilerHostLike;
    /* @internal */
    function createPrependNodes(projectReferences, getCommandLine, readFile) {
        if (!projectReferences)
            return ts.emptyArray;
        var nodes;
        for (var i = 0; i < projectReferences.length; i++) {
            var ref = projectReferences[i];
            var resolvedRefOpts = getCommandLine(ref, i);
            if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
                var out = resolvedRefOpts.options.outFile || resolvedRefOpts.options.out;
                // Upstream project didn't have outFile set -- skip (error will have been issued earlier)
                if (!out)
                    continue;
                var _a = ts.getOutputPathsForBundle(resolvedRefOpts.options, /*forceDtsPaths*/ true), jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
                var node = ts.createInputFiles(readFile, jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath);
                (nodes || (nodes = [])).push(node);
            }
        }
        return nodes || ts.emptyArray;
    }
    ts.createPrependNodes = createPrependNodes;
    function resolveProjectReferencePath(hostOrRef, ref) {
        var passedInRef = ref ? ref : hostOrRef;
        return ts.resolveConfigFileProjectName(passedInRef.path);
    }
    ts.resolveProjectReferencePath = resolveProjectReferencePath;
    /* @internal */
    /**
     * Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
     * The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
     * This returns a diagnostic even if the module will be an untyped module.
     */
    function getResolutionDiagnostic(options, _a) {
        var extension = _a.extension;
        switch (extension) {
            case ".ts" /* Ts */:
            case ".d.ts" /* Dts */:
                // These are always allowed.
                return undefined;
            case ".tsx" /* Tsx */:
                return needJsx();
            case ".jsx" /* Jsx */:
                return needJsx() || needAllowJs();
            case ".js" /* Js */:
                return needAllowJs();
            case ".json" /* Json */:
                return needResolveJsonModule();
        }
        function needJsx() {
            return options.jsx ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
        }
        function needAllowJs() {
            return options.allowJs || !ts.getStrictOptionValue(options, "noImplicitAny") ? undefined : ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
        }
        function needResolveJsonModule() {
            return options.resolveJsonModule ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used;
        }
    }
    ts.getResolutionDiagnostic = getResolutionDiagnostic;
    function getModuleNames(_a) {
        var imports = _a.imports, moduleAugmentations = _a.moduleAugmentations;
        var res = imports.map(function (i) { return i.text; });
        for (var _i = 0, moduleAugmentations_1 = moduleAugmentations; _i < moduleAugmentations_1.length; _i++) {
            var aug = moduleAugmentations_1[_i];
            if (aug.kind === 10 /* StringLiteral */) {
                res.push(aug.text);
            }
            // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
        }
        return res;
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers, forceDtsEmit) {
        var outputFiles = [];
        var _a = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers, forceDtsEmit), emitSkipped = _a.emitSkipped, diagnostics = _a.diagnostics, exportedModulesFromDeclarationEmit = _a.exportedModulesFromDeclarationEmit;
        return { outputFiles: outputFiles, emitSkipped: emitSkipped, diagnostics: diagnostics, exportedModulesFromDeclarationEmit: exportedModulesFromDeclarationEmit };
        function writeFile(fileName, text, writeByteOrderMark) {
            outputFiles.push({ name: fileName, writeByteOrderMark: writeByteOrderMark, text: text });
        }
    }
    ts.getFileEmitOutput = getFileEmitOutput;
    var BuilderState;
    (function (BuilderState) {
        /**
         * Get the referencedFile from the imported module symbol
         */
        function getReferencedFileFromImportedModuleSymbol(symbol) {
            if (symbol.declarations && symbol.declarations[0]) {
                var declarationSourceFile = ts.getSourceFileOfNode(symbol.declarations[0]);
                return declarationSourceFile && declarationSourceFile.resolvedPath;
            }
        }
        /**
         * Get the referencedFile from the import name node from file
         */
        function getReferencedFileFromImportLiteral(checker, importName) {
            var symbol = checker.getSymbolAtLocation(importName);
            return symbol && getReferencedFileFromImportedModuleSymbol(symbol);
        }
        /**
         * Gets the path to reference file from file name, it could be resolvedPath if present otherwise path
         */
        function getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName) {
            return ts.toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName);
        }
        /**
         * Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
         */
        function getReferencedFiles(program, sourceFile, getCanonicalFileName) {
            var referencedFiles;
            // We need to use a set here since the code can contain the same import twice,
            // but that will only be one dependency.
            // To avoid invernal conversion, the key of the referencedFiles map must be of type Path
            if (sourceFile.imports && sourceFile.imports.length > 0) {
                var checker = program.getTypeChecker();
                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                    var importName = _a[_i];
                    var declarationSourceFilePath = getReferencedFileFromImportLiteral(checker, importName);
                    if (declarationSourceFilePath) {
                        addReferencedFile(declarationSourceFilePath);
                    }
                }
            }
            var sourceFileDirectory = ts.getDirectoryPath(sourceFile.resolvedPath);
            // Handle triple slash references
            if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
                for (var _b = 0, _c = sourceFile.referencedFiles; _b < _c.length; _b++) {
                    var referencedFile = _c[_b];
                    var referencedPath = getReferencedFileFromFileName(program, referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
                    addReferencedFile(referencedPath);
                }
            }
            // Handle type reference directives
            if (sourceFile.resolvedTypeReferenceDirectiveNames) {
                sourceFile.resolvedTypeReferenceDirectiveNames.forEach(function (resolvedTypeReferenceDirective) {
                    if (!resolvedTypeReferenceDirective) {
                        return;
                    }
                    var fileName = resolvedTypeReferenceDirective.resolvedFileName; // TODO: GH#18217
                    var typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
                    addReferencedFile(typeFilePath);
                });
            }
            // Add module augmentation as references
            if (sourceFile.moduleAugmentations.length) {
                var checker = program.getTypeChecker();
                for (var _d = 0, _e = sourceFile.moduleAugmentations; _d < _e.length; _d++) {
                    var moduleName = _e[_d];
                    if (!ts.isStringLiteral(moduleName)) {
                        continue;
                    }
                    var symbol = checker.getSymbolAtLocation(moduleName);
                    if (!symbol) {
                        continue;
                    }
                    // Add any file other than our own as reference
                    addReferenceFromAmbientModule(symbol);
                }
            }
            // From ambient modules
            for (var _f = 0, _g = program.getTypeChecker().getAmbientModules(); _f < _g.length; _f++) {
                var ambientModule = _g[_f];
                if (ambientModule.declarations.length > 1) {
                    addReferenceFromAmbientModule(ambientModule);
                }
            }
            return referencedFiles;
            function addReferenceFromAmbientModule(symbol) {
                // Add any file other than our own as reference
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    var declarationSourceFile = ts.getSourceFileOfNode(declaration);
                    if (declarationSourceFile &&
                        declarationSourceFile !== sourceFile) {
                        addReferencedFile(declarationSourceFile.resolvedPath);
                    }
                }
            }
            function addReferencedFile(referencedPath) {
                if (!referencedFiles) {
                    referencedFiles = ts.createMap();
                }
                referencedFiles.set(referencedPath, true);
            }
        }
        /**
         * Returns true if oldState is reusable, that is the emitKind = module/non module has not changed
         */
        function canReuseOldState(newReferencedMap, oldState) {
            return oldState && !oldState.referencedMap === !newReferencedMap;
        }
        BuilderState.canReuseOldState = canReuseOldState;
        /**
         * Creates the state of file references and signature for the new program from oldState if it is safe
         */
        function create(newProgram, getCanonicalFileName, oldState) {
            var fileInfos = ts.createMap();
            var referencedMap = newProgram.getCompilerOptions().module !== ts.ModuleKind.None ? ts.createMap() : undefined;
            var exportedModulesMap = referencedMap ? ts.createMap() : undefined;
            var hasCalledUpdateShapeSignature = ts.createMap();
            var useOldState = canReuseOldState(referencedMap, oldState);
            // Create the reference map, and set the file infos
            for (var _i = 0, _a = newProgram.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                var version_1 = ts.Debug.checkDefined(sourceFile.version, "Program intended to be used with Builder should have source files with versions set");
                var oldInfo = useOldState ? oldState.fileInfos.get(sourceFile.resolvedPath) : undefined;
                if (referencedMap) {
                    var newReferences = getReferencedFiles(newProgram, sourceFile, getCanonicalFileName);
                    if (newReferences) {
                        referencedMap.set(sourceFile.resolvedPath, newReferences);
                    }
                    // Copy old visible to outside files map
                    if (useOldState) {
                        var exportedModules = oldState.exportedModulesMap.get(sourceFile.resolvedPath);
                        if (exportedModules) {
                            exportedModulesMap.set(sourceFile.resolvedPath, exportedModules);
                        }
                    }
                }
                fileInfos.set(sourceFile.resolvedPath, { version: version_1, signature: oldInfo && oldInfo.signature, affectsGlobalScope: isFileAffectingGlobalScope(sourceFile) });
            }
            return {
                fileInfos: fileInfos,
                referencedMap: referencedMap,
                exportedModulesMap: exportedModulesMap,
                hasCalledUpdateShapeSignature: hasCalledUpdateShapeSignature
            };
        }
        BuilderState.create = create;
        /**
         * Releases needed properties
         */
        function releaseCache(state) {
            state.allFilesExcludingDefaultLibraryFile = undefined;
            state.allFileNames = undefined;
        }
        BuilderState.releaseCache = releaseCache;
        /**
         * Creates a clone of the state
         */
        function clone(state) {
            var fileInfos = ts.createMap();
            state.fileInfos.forEach(function (value, key) {
                fileInfos.set(key, __assign({}, value));
            });
            // Dont need to backup allFiles info since its cache anyway
            return {
                fileInfos: fileInfos,
                referencedMap: cloneMapOrUndefined(state.referencedMap),
                exportedModulesMap: cloneMapOrUndefined(state.exportedModulesMap),
                hasCalledUpdateShapeSignature: ts.cloneMap(state.hasCalledUpdateShapeSignature),
            };
        }
        BuilderState.clone = clone;
        /**
         * Gets the files affected by the path from the program
         */
        function getFilesAffectedBy(state, programOfThisState, path, cancellationToken, computeHash, cacheToUpdateSignature, exportedModulesMapCache) {
            // Since the operation could be cancelled, the signatures are always stored in the cache
            // They will be committed once it is safe to use them
            // eg when calling this api from tsserver, if there is no cancellation of the operation
            // In the other cases the affected files signatures are committed only after the iteration through the result is complete
            var signatureCache = cacheToUpdateSignature || ts.createMap();
            var sourceFile = programOfThisState.getSourceFileByPath(path);
            if (!sourceFile) {
                return ts.emptyArray;
            }
            if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache)) {
                return [sourceFile];
            }
            var result = (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache);
            if (!cacheToUpdateSignature) {
                // Commit all the signatures in the signature cache
                updateSignaturesFromCache(state, signatureCache);
            }
            return result;
        }
        BuilderState.getFilesAffectedBy = getFilesAffectedBy;
        /**
         * Updates the signatures from the cache into state's fileinfo signatures
         * This should be called whenever it is safe to commit the state of the builder
         */
        function updateSignaturesFromCache(state, signatureCache) {
            signatureCache.forEach(function (signature, path) { return updateSignatureOfFile(state, signature, path); });
        }
        BuilderState.updateSignaturesFromCache = updateSignaturesFromCache;
        function updateSignatureOfFile(state, signature, path) {
            state.fileInfos.get(path).signature = signature;
            state.hasCalledUpdateShapeSignature.set(path, true);
        }
        BuilderState.updateSignatureOfFile = updateSignatureOfFile;
        /**
         * Returns if the shape of the signature has changed since last emit
         */
        function updateShapeSignature(state, programOfThisState, sourceFile, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache) {
            ts.Debug.assert(!!sourceFile);
            ts.Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state");
            // If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
            if (state.hasCalledUpdateShapeSignature.has(sourceFile.resolvedPath) || cacheToUpdateSignature.has(sourceFile.resolvedPath)) {
                return false;
            }
            var info = state.fileInfos.get(sourceFile.resolvedPath);
            if (!info)
                return ts.Debug.fail();
            var prevSignature = info.signature;
            var latestSignature;
            if (sourceFile.isDeclarationFile) {
                latestSignature = sourceFile.version;
                if (exportedModulesMapCache && latestSignature !== prevSignature) {
                    // All the references in this file are exported
                    var references = state.referencedMap ? state.referencedMap.get(sourceFile.resolvedPath) : undefined;
                    exportedModulesMapCache.set(sourceFile.resolvedPath, references || false);
                }
            }
            else {
                var emitOutput_1 = getFileEmitOutput(programOfThisState, sourceFile, 
                /*emitOnlyDtsFiles*/ true, cancellationToken, 
                /*customTransformers*/ undefined, 
                /*forceDtsEmit*/ true);
                var firstDts_1 = emitOutput_1.outputFiles &&
                    programOfThisState.getCompilerOptions().declarationMap ?
                    emitOutput_1.outputFiles.length > 1 ? emitOutput_1.outputFiles[1] : undefined :
                    emitOutput_1.outputFiles.length > 0 ? emitOutput_1.outputFiles[0] : undefined;
                if (firstDts_1) {
                    ts.Debug.assert(ts.fileExtensionIs(firstDts_1.name, ".d.ts" /* Dts */), "File extension for signature expected to be dts", function () { return "Found: " + ts.getAnyExtensionFromPath(firstDts_1.name) + " for " + firstDts_1.name + ":: All output files: " + JSON.stringify(emitOutput_1.outputFiles.map(function (f) { return f.name; })); });
                    latestSignature = computeHash(firstDts_1.text);
                    if (exportedModulesMapCache && latestSignature !== prevSignature) {
                        updateExportedModules(sourceFile, emitOutput_1.exportedModulesFromDeclarationEmit, exportedModulesMapCache);
                    }
                }
                else {
                    latestSignature = prevSignature; // TODO: GH#18217
                }
            }
            cacheToUpdateSignature.set(sourceFile.resolvedPath, latestSignature);
            return !prevSignature || latestSignature !== prevSignature;
        }
        BuilderState.updateShapeSignature = updateShapeSignature;
        /**
         * Coverts the declaration emit result into exported modules map
         */
        function updateExportedModules(sourceFile, exportedModulesFromDeclarationEmit, exportedModulesMapCache) {
            if (!exportedModulesFromDeclarationEmit) {
                exportedModulesMapCache.set(sourceFile.resolvedPath, false);
                return;
            }
            var exportedModules;
            exportedModulesFromDeclarationEmit.forEach(function (symbol) { return addExportedModule(getReferencedFileFromImportedModuleSymbol(symbol)); });
            exportedModulesMapCache.set(sourceFile.resolvedPath, exportedModules || false);
            function addExportedModule(exportedModulePath) {
                if (exportedModulePath) {
                    if (!exportedModules) {
                        exportedModules = ts.createMap();
                    }
                    exportedModules.set(exportedModulePath, true);
                }
            }
        }
        /**
         * Updates the exported modules from cache into state's exported modules map
         * This should be called whenever it is safe to commit the state of the builder
         */
        function updateExportedFilesMapFromCache(state, exportedModulesMapCache) {
            if (exportedModulesMapCache) {
                ts.Debug.assert(!!state.exportedModulesMap);
                exportedModulesMapCache.forEach(function (exportedModules, path) {
                    if (exportedModules) {
                        state.exportedModulesMap.set(path, exportedModules);
                    }
                    else {
                        state.exportedModulesMap.delete(path);
                    }
                });
            }
        }
        BuilderState.updateExportedFilesMapFromCache = updateExportedFilesMapFromCache;
        /**
         * Get all the dependencies of the sourceFile
         */
        function getAllDependencies(state, programOfThisState, sourceFile) {
            var compilerOptions = programOfThisState.getCompilerOptions();
            // With --out or --outFile all outputs go into single file, all files depend on each other
            if (compilerOptions.outFile || compilerOptions.out) {
                return getAllFileNames(state, programOfThisState);
            }
            // If this is non module emit, or its a global file, it depends on all the source files
            if (!state.referencedMap || isFileAffectingGlobalScope(sourceFile)) {
                return getAllFileNames(state, programOfThisState);
            }
            // Get the references, traversing deep from the referenceMap
            var seenMap = ts.createMap();
            var queue = [sourceFile.resolvedPath];
            while (queue.length) {
                var path = queue.pop();
                if (!seenMap.has(path)) {
                    seenMap.set(path, true);
                    var references = state.referencedMap.get(path);
                    if (references) {
                        var iterator = references.keys();
                        for (var iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
                            queue.push(iterResult.value);
                        }
                    }
                }
            }
            return ts.arrayFrom(ts.mapDefinedIterator(seenMap.keys(), function (path) {
                var file = programOfThisState.getSourceFileByPath(path);
                return file ? file.fileName : path;
            }));
        }
        BuilderState.getAllDependencies = getAllDependencies;
        /**
         * Gets the names of all files from the program
         */
        function getAllFileNames(state, programOfThisState) {
            if (!state.allFileNames) {
                var sourceFiles = programOfThisState.getSourceFiles();
                state.allFileNames = sourceFiles === ts.emptyArray ? ts.emptyArray : sourceFiles.map(function (file) { return file.fileName; });
            }
            return state.allFileNames;
        }
        /**
         * Gets the files referenced by the the file path
         */
        function getReferencedByPaths(state, referencedFilePath) {
            return ts.arrayFrom(ts.mapDefinedIterator(state.referencedMap.entries(), function (_a) {
                var filePath = _a[0], referencesInFile = _a[1];
                return referencesInFile.has(referencedFilePath) ? filePath : undefined;
            }));
        }
        BuilderState.getReferencedByPaths = getReferencedByPaths;
        /**
         * For script files that contains only ambient external modules, although they are not actually external module files,
         * they can only be consumed via importing elements from them. Regular script files cannot consume them. Therefore,
         * there are no point to rebuild all script files if these special files have changed. However, if any statement
         * in the file is not ambient external module, we treat it as a regular script file.
         */
        function containsOnlyAmbientModules(sourceFile) {
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (!ts.isModuleWithStringLiteralName(statement)) {
                    return false;
                }
            }
            return true;
        }
        /**
         * Return true if file contains anything that augments to global scope we need to build them as if
         * they are global files as well as module
         */
        function containsGlobalScopeAugmentation(sourceFile) {
            return ts.some(sourceFile.moduleAugmentations, function (augmentation) { return ts.isGlobalScopeAugmentation(augmentation.parent); });
        }
        /**
         * Return true if the file will invalidate all files because it affectes global scope
         */
        function isFileAffectingGlobalScope(sourceFile) {
            return containsGlobalScopeAugmentation(sourceFile) ||
                !ts.isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile);
        }
        /**
         * Gets all files of the program excluding the default library file
         */
        function getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, firstSourceFile) {
            // Use cached result
            if (state.allFilesExcludingDefaultLibraryFile) {
                return state.allFilesExcludingDefaultLibraryFile;
            }
            var result;
            if (firstSourceFile)
                addSourceFile(firstSourceFile);
            for (var _i = 0, _a = programOfThisState.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                if (sourceFile !== firstSourceFile) {
                    addSourceFile(sourceFile);
                }
            }
            state.allFilesExcludingDefaultLibraryFile = result || ts.emptyArray;
            return state.allFilesExcludingDefaultLibraryFile;
            function addSourceFile(sourceFile) {
                if (!programOfThisState.isSourceFileDefaultLibrary(sourceFile)) {
                    (result || (result = [])).push(sourceFile);
                }
            }
        }
        BuilderState.getAllFilesExcludingDefaultLibraryFile = getAllFilesExcludingDefaultLibraryFile;
        /**
         * When program emits non modular code, gets the files affected by the sourceFile whose shape has changed
         */
        function getFilesAffectedByUpdatedShapeWhenNonModuleEmit(state, programOfThisState, sourceFileWithUpdatedShape) {
            var compilerOptions = programOfThisState.getCompilerOptions();
            // If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
            // so returning the file itself is good enough.
            if (compilerOptions && (compilerOptions.out || compilerOptions.outFile)) {
                return [sourceFileWithUpdatedShape];
            }
            return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
        }
        /**
         * When program emits modular code, gets the files affected by the sourceFile whose shape has changed
         */
        function getFilesAffectedByUpdatedShapeWhenModuleEmit(state, programOfThisState, sourceFileWithUpdatedShape, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache) {
            if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) {
                return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
            }
            var compilerOptions = programOfThisState.getCompilerOptions();
            if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) {
                return [sourceFileWithUpdatedShape];
            }
            // Now we need to if each file in the referencedBy list has a shape change as well.
            // Because if so, its own referencedBy files need to be saved as well to make the
            // emitting result consistent with files on disk.
            var seenFileNamesMap = ts.createMap();
            // Start with the paths this file was referenced by
            seenFileNamesMap.set(sourceFileWithUpdatedShape.resolvedPath, sourceFileWithUpdatedShape);
            var queue = getReferencedByPaths(state, sourceFileWithUpdatedShape.resolvedPath);
            while (queue.length > 0) {
                var currentPath = queue.pop();
                if (!seenFileNamesMap.has(currentPath)) {
                    var currentSourceFile = programOfThisState.getSourceFileByPath(currentPath);
                    seenFileNamesMap.set(currentPath, currentSourceFile);
                    if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache)) { // TODO: GH#18217
                        queue.push.apply(// TODO: GH#18217
                        queue, getReferencedByPaths(state, currentSourceFile.resolvedPath));
                    }
                }
            }
            // Return array of values that needs emit
            // Return array of values that needs emit
            return ts.arrayFrom(ts.mapDefinedIterator(seenFileNamesMap.values(), function (value) { return value; }));
        }
    })(BuilderState = ts.BuilderState || (ts.BuilderState = {}));
    function cloneMapOrUndefined(map) {
        return map ? ts.cloneMap(map) : undefined;
    }
    ts.cloneMapOrUndefined = cloneMapOrUndefined;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var BuilderFileEmit;
    (function (BuilderFileEmit) {
        BuilderFileEmit[BuilderFileEmit["DtsOnly"] = 0] = "DtsOnly";
        BuilderFileEmit[BuilderFileEmit["Full"] = 1] = "Full";
    })(BuilderFileEmit = ts.BuilderFileEmit || (ts.BuilderFileEmit = {}));
    function hasSameKeys(map1, map2) {
        // Has same size and every key is present in both maps
        return map1 === map2 || map1 !== undefined && map2 !== undefined && map1.size === map2.size && !ts.forEachKey(map1, function (key) { return !map2.has(key); });
    }
    /**
     * Create the state so that we can iterate on changedFiles/affected files
     */
    function createBuilderProgramState(newProgram, getCanonicalFileName, oldState) {
        var state = ts.BuilderState.create(newProgram, getCanonicalFileName, oldState);
        state.program = newProgram;
        var compilerOptions = newProgram.getCompilerOptions();
        state.compilerOptions = compilerOptions;
        // With --out or --outFile, any change affects all semantic diagnostics so no need to cache them
        if (!compilerOptions.outFile && !compilerOptions.out) {
            state.semanticDiagnosticsPerFile = ts.createMap();
        }
        state.changedFilesSet = ts.createMap();
        var useOldState = ts.BuilderState.canReuseOldState(state.referencedMap, oldState);
        var oldCompilerOptions = useOldState ? oldState.compilerOptions : undefined;
        var canCopySemanticDiagnostics = useOldState && oldState.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile &&
            !ts.compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldCompilerOptions);
        if (useOldState) {
            // Verify the sanity of old state
            if (!oldState.currentChangedFilePath) {
                var affectedSignatures = oldState.currentAffectedFilesSignatures;
                ts.Debug.assert(!oldState.affectedFiles && (!affectedSignatures || !affectedSignatures.size), "Cannot reuse if only few affected files of currentChangedFile were iterated");
            }
            var changedFilesSet = oldState.changedFilesSet;
            if (canCopySemanticDiagnostics) {
                ts.Debug.assert(!changedFilesSet || !ts.forEachKey(changedFilesSet, function (path) { return oldState.semanticDiagnosticsPerFile.has(path); }), "Semantic diagnostics shouldnt be available for changed files");
            }
            // Copy old state's changed files set
            if (changedFilesSet) {
                ts.copyEntries(changedFilesSet, state.changedFilesSet);
            }
            if (!compilerOptions.outFile && !compilerOptions.out && oldState.affectedFilesPendingEmit) {
                state.affectedFilesPendingEmit = oldState.affectedFilesPendingEmit.slice();
                state.affectedFilesPendingEmitKind = ts.cloneMapOrUndefined(oldState.affectedFilesPendingEmitKind);
                state.affectedFilesPendingEmitIndex = oldState.affectedFilesPendingEmitIndex;
                state.seenAffectedFiles = ts.createMap();
            }
        }
        // Update changed files and copy semantic diagnostics if we can
        var referencedMap = state.referencedMap;
        var oldReferencedMap = useOldState ? oldState.referencedMap : undefined;
        var copyDeclarationFileDiagnostics = canCopySemanticDiagnostics && !compilerOptions.skipLibCheck === !oldCompilerOptions.skipLibCheck;
        var copyLibFileDiagnostics = copyDeclarationFileDiagnostics && !compilerOptions.skipDefaultLibCheck === !oldCompilerOptions.skipDefaultLibCheck;
        state.fileInfos.forEach(function (info, sourceFilePath) {
            var oldInfo;
            var newReferences;
            // if not using old state, every file is changed
            if (!useOldState ||
                // File wasnt present in old state
                !(oldInfo = oldState.fileInfos.get(sourceFilePath)) ||
                // versions dont match
                oldInfo.version !== info.version ||
                // Referenced files changed
                !hasSameKeys(newReferences = referencedMap && referencedMap.get(sourceFilePath), oldReferencedMap && oldReferencedMap.get(sourceFilePath)) ||
                // Referenced file was deleted in the new program
                newReferences && ts.forEachKey(newReferences, function (path) { return !state.fileInfos.has(path) && oldState.fileInfos.has(path); })) {
                // Register file as changed file and do not copy semantic diagnostics, since all changed files need to be re-evaluated
                state.changedFilesSet.set(sourceFilePath, true);
            }
            else if (canCopySemanticDiagnostics) {
                var sourceFile = newProgram.getSourceFileByPath(sourceFilePath);
                if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) {
                    return;
                }
                if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) {
                    return;
                }
                // Unchanged file copy diagnostics
                var diagnostics = oldState.semanticDiagnosticsPerFile.get(sourceFilePath);
                if (diagnostics) {
                    state.semanticDiagnosticsPerFile.set(sourceFilePath, oldState.hasReusableDiagnostic ? convertToDiagnostics(diagnostics, newProgram, getCanonicalFileName) : diagnostics);
                    if (!state.semanticDiagnosticsFromOldState) {
                        state.semanticDiagnosticsFromOldState = ts.createMap();
                    }
                    state.semanticDiagnosticsFromOldState.set(sourceFilePath, true);
                }
            }
        });
        // If the global file is removed, add all files as changed
        if (useOldState && ts.forEachEntry(oldState.fileInfos, function (info, sourceFilePath) { return info.affectsGlobalScope && !state.fileInfos.has(sourceFilePath); })) {
            ts.BuilderState.getAllFilesExcludingDefaultLibraryFile(state, newProgram, /*firstSourceFile*/ undefined)
                .forEach(function (file) { return state.changedFilesSet.set(file.resolvedPath, true); });
        }
        else if (oldCompilerOptions && ts.compilerOptionsAffectEmit(compilerOptions, oldCompilerOptions)) {
            // Add all files to affectedFilesPendingEmit since emit changed
            newProgram.getSourceFiles().forEach(function (f) { return addToAffectedFilesPendingEmit(state, f.resolvedPath, 1 /* Full */); });
            ts.Debug.assert(!state.seenAffectedFiles || !state.seenAffectedFiles.size);
            state.seenAffectedFiles = state.seenAffectedFiles || ts.createMap();
        }
        state.emittedBuildInfo = !state.changedFilesSet.size && !state.affectedFilesPendingEmit;
        return state;
    }
    function convertToDiagnostics(diagnostics, newProgram, getCanonicalFileName) {
        if (!diagnostics.length)
            return ts.emptyArray;
        var buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(ts.getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions()), newProgram.getCurrentDirectory()));
        return diagnostics.map(function (diagnostic) {
            var result = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath);
            result.reportsUnnecessary = diagnostic.reportsUnnecessary;
            result.source = diagnostic.source;
            var relatedInformation = diagnostic.relatedInformation;
            result.relatedInformation = relatedInformation ?
                relatedInformation.length ?
                    relatedInformation.map(function (r) { return convertToDiagnosticRelatedInformation(r, newProgram, toPath); }) :
                    ts.emptyArray :
                undefined;
            return result;
        });
        function toPath(path) {
            return ts.toPath(path, buildInfoDirectory, getCanonicalFileName);
        }
    }
    function convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath) {
        var file = diagnostic.file;
        return __assign(__assign({}, diagnostic), { file: file ? newProgram.getSourceFileByPath(toPath(file)) : undefined });
    }
    /**
     * Releases program and other related not needed properties
     */
    function releaseCache(state) {
        ts.BuilderState.releaseCache(state);
        state.program = undefined;
    }
    /**
     * Creates a clone of the state
     */
    function cloneBuilderProgramState(state) {
        var newState = ts.BuilderState.clone(state);
        newState.semanticDiagnosticsPerFile = ts.cloneMapOrUndefined(state.semanticDiagnosticsPerFile);
        newState.changedFilesSet = ts.cloneMap(state.changedFilesSet);
        newState.affectedFiles = state.affectedFiles;
        newState.affectedFilesIndex = state.affectedFilesIndex;
        newState.currentChangedFilePath = state.currentChangedFilePath;
        newState.currentAffectedFilesSignatures = ts.cloneMapOrUndefined(state.currentAffectedFilesSignatures);
        newState.currentAffectedFilesExportedModulesMap = ts.cloneMapOrUndefined(state.currentAffectedFilesExportedModulesMap);
        newState.seenAffectedFiles = ts.cloneMapOrUndefined(state.seenAffectedFiles);
        newState.cleanedDiagnosticsOfLibFiles = state.cleanedDiagnosticsOfLibFiles;
        newState.semanticDiagnosticsFromOldState = ts.cloneMapOrUndefined(state.semanticDiagnosticsFromOldState);
        newState.program = state.program;
        newState.compilerOptions = state.compilerOptions;
        newState.affectedFilesPendingEmit = state.affectedFilesPendingEmit && state.affectedFilesPendingEmit.slice();
        newState.affectedFilesPendingEmitKind = ts.cloneMapOrUndefined(state.affectedFilesPendingEmitKind);
        newState.affectedFilesPendingEmitIndex = state.affectedFilesPendingEmitIndex;
        newState.seenEmittedFiles = ts.cloneMapOrUndefined(state.seenEmittedFiles);
        newState.programEmitComplete = state.programEmitComplete;
        return newState;
    }
    /**
     * Verifies that source file is ok to be used in calls that arent handled by next
     */
    function assertSourceFileOkWithoutNextAffectedCall(state, sourceFile) {
        ts.Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex - 1] !== sourceFile || !state.semanticDiagnosticsPerFile.has(sourceFile.resolvedPath));
    }
    /**
     * This function returns the next affected file to be processed.
     * Note that until doneAffected is called it would keep reporting same result
     * This is to allow the callers to be able to actually remove affected file only when the operation is complete
     * eg. if during diagnostics check cancellation token ends up cancelling the request, the affected file should be retained
     */
    function getNextAffectedFile(state, cancellationToken, computeHash) {
        while (true) {
            var affectedFiles = state.affectedFiles;
            if (affectedFiles) {
                var seenAffectedFiles = state.seenAffectedFiles;
                var affectedFilesIndex = state.affectedFilesIndex; // TODO: GH#18217
                while (affectedFilesIndex < affectedFiles.length) {
                    var affectedFile = affectedFiles[affectedFilesIndex];
                    if (!seenAffectedFiles.has(affectedFile.resolvedPath)) {
                        // Set the next affected file as seen and remove the cached semantic diagnostics
                        state.affectedFilesIndex = affectedFilesIndex;
                        handleDtsMayChangeOfAffectedFile(state, affectedFile, cancellationToken, computeHash);
                        return affectedFile;
                    }
                    affectedFilesIndex++;
                }
                // Remove the changed file from the change set
                state.changedFilesSet.delete(state.currentChangedFilePath);
                state.currentChangedFilePath = undefined;
                // Commit the changes in file signature
                ts.BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures);
                state.currentAffectedFilesSignatures.clear();
                ts.BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap);
                state.affectedFiles = undefined;
            }
            // Get next changed file
            var nextKey = state.changedFilesSet.keys().next();
            if (nextKey.done) {
                // Done
                return undefined;
            }
            // With --out or --outFile all outputs go into single file
            // so operations are performed directly on program, return program
            var program = ts.Debug.checkDefined(state.program);
            var compilerOptions = program.getCompilerOptions();
            if (compilerOptions.outFile || compilerOptions.out) {
                ts.Debug.assert(!state.semanticDiagnosticsPerFile);
                return program;
            }
            // Get next batch of affected files
            state.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures || ts.createMap();
            if (state.exportedModulesMap) {
                state.currentAffectedFilesExportedModulesMap = state.currentAffectedFilesExportedModulesMap || ts.createMap();
            }
            state.affectedFiles = ts.BuilderState.getFilesAffectedBy(state, program, nextKey.value, cancellationToken, computeHash, state.currentAffectedFilesSignatures, state.currentAffectedFilesExportedModulesMap);
            state.currentChangedFilePath = nextKey.value;
            state.affectedFilesIndex = 0;
            state.seenAffectedFiles = state.seenAffectedFiles || ts.createMap();
        }
    }
    /**
     * Returns next file to be emitted from files that retrieved semantic diagnostics but did not emit yet
     */
    function getNextAffectedFilePendingEmit(state) {
        var affectedFilesPendingEmit = state.affectedFilesPendingEmit;
        if (affectedFilesPendingEmit) {
            var seenEmittedFiles = state.seenEmittedFiles || (state.seenEmittedFiles = ts.createMap());
            for (var i = state.affectedFilesPendingEmitIndex; i < affectedFilesPendingEmit.length; i++) {
                var affectedFile = ts.Debug.checkDefined(state.program).getSourceFileByPath(affectedFilesPendingEmit[i]);
                if (affectedFile) {
                    var seenKind = seenEmittedFiles.get(affectedFile.resolvedPath);
                    var emitKind = ts.Debug.checkDefined(ts.Debug.checkDefined(state.affectedFilesPendingEmitKind).get(affectedFile.resolvedPath));
                    if (seenKind === undefined || seenKind < emitKind) {
                        // emit this file
                        state.affectedFilesPendingEmitIndex = i;
                        return { affectedFile: affectedFile, emitKind: emitKind };
                    }
                }
            }
            state.affectedFilesPendingEmit = undefined;
            state.affectedFilesPendingEmitKind = undefined;
            state.affectedFilesPendingEmitIndex = undefined;
        }
        return undefined;
    }
    /**
     *  Handles semantic diagnostics and dts emit for affectedFile and files, that are referencing modules that export entities from affected file
     *  This is because even though js emit doesnt change, dts emit / type used can change resulting in need for dts emit and js change
     */
    function handleDtsMayChangeOfAffectedFile(state, affectedFile, cancellationToken, computeHash) {
        removeSemanticDiagnosticsOf(state, affectedFile.resolvedPath);
        // If affected files is everything except default library, then nothing more to do
        if (state.allFilesExcludingDefaultLibraryFile === state.affectedFiles) {
            if (!state.cleanedDiagnosticsOfLibFiles) {
                state.cleanedDiagnosticsOfLibFiles = true;
                var program_1 = ts.Debug.checkDefined(state.program);
                var options_2 = program_1.getCompilerOptions();
                ts.forEach(program_1.getSourceFiles(), function (f) {
                    return program_1.isSourceFileDefaultLibrary(f) &&
                        !ts.skipTypeChecking(f, options_2, program_1) &&
                        removeSemanticDiagnosticsOf(state, f.resolvedPath);
                });
            }
            return;
        }
        if (!state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) {
            forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, function (state, path) { return handleDtsMayChangeOf(state, path, cancellationToken, computeHash); });
        }
    }
    /**
     * Handle the dts may change, so they need to be added to pending emit if dts emit is enabled,
     * Also we need to make sure signature is updated for these files
     */
    function handleDtsMayChangeOf(state, path, cancellationToken, computeHash) {
        removeSemanticDiagnosticsOf(state, path);
        if (!state.changedFilesSet.has(path)) {
            var program = ts.Debug.checkDefined(state.program);
            var sourceFile = program.getSourceFileByPath(path);
            if (sourceFile) {
                // Even though the js emit doesnt change and we are already handling dts emit and semantic diagnostics
                // we need to update the signature to reflect correctness of the signature(which is output d.ts emit) of this file
                // This ensures that we dont later during incremental builds considering wrong signature.
                // Eg where this also is needed to ensure that .tsbuildinfo generated by incremental build should be same as if it was first fresh build
                ts.BuilderState.updateShapeSignature(state, program, sourceFile, ts.Debug.checkDefined(state.currentAffectedFilesSignatures), cancellationToken, computeHash, state.currentAffectedFilesExportedModulesMap);
                // If not dts emit, nothing more to do
                if (ts.getEmitDeclarations(state.compilerOptions)) {
                    addToAffectedFilesPendingEmit(state, path, 0 /* DtsOnly */);
                }
            }
        }
        return false;
    }
    /**
     * Removes semantic diagnostics for path and
     * returns true if there are no more semantic diagnostics from the old state
     */
    function removeSemanticDiagnosticsOf(state, path) {
        if (!state.semanticDiagnosticsFromOldState) {
            return true;
        }
        state.semanticDiagnosticsFromOldState.delete(path);
        state.semanticDiagnosticsPerFile.delete(path);
        return !state.semanticDiagnosticsFromOldState.size;
    }
    function isChangedSignagure(state, path) {
        var newSignature = ts.Debug.checkDefined(state.currentAffectedFilesSignatures).get(path);
        var oldSignagure = ts.Debug.checkDefined(state.fileInfos.get(path)).signature;
        return newSignature !== oldSignagure;
    }
    /**
     * Iterate on referencing modules that export entities from affected file
     */
    function forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, fn) {
        // If there was change in signature (dts output) for the changed file,
        // then only we need to handle pending file emit
        if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) {
            return;
        }
        if (!isChangedSignagure(state, affectedFile.resolvedPath))
            return;
        // Since isolated modules dont change js files, files affected by change in signature is itself
        // But we need to cleanup semantic diagnostics and queue dts emit for affected files
        if (state.compilerOptions.isolatedModules) {
            var seenFileNamesMap = ts.createMap();
            seenFileNamesMap.set(affectedFile.resolvedPath, true);
            var queue = ts.BuilderState.getReferencedByPaths(state, affectedFile.resolvedPath);
            while (queue.length > 0) {
                var currentPath = queue.pop();
                if (!seenFileNamesMap.has(currentPath)) {
                    seenFileNamesMap.set(currentPath, true);
                    var result = fn(state, currentPath);
                    if (result && isChangedSignagure(state, currentPath)) {
                        var currentSourceFile = ts.Debug.checkDefined(state.program).getSourceFileByPath(currentPath);
                        queue.push.apply(queue, ts.BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath));
                    }
                }
            }
        }
        ts.Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
        var seenFileAndExportsOfFile = ts.createMap();
        // Go through exported modules from cache first
        // If exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.currentAffectedFilesExportedModulesMap, function (exportedModules, exportedFromPath) {
            return exportedModules &&
                exportedModules.has(affectedFile.resolvedPath) &&
                forEachFilesReferencingPath(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return;
        }
        // If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
        ts.forEachEntry(state.exportedModulesMap, function (exportedModules, exportedFromPath) {
            return !state.currentAffectedFilesExportedModulesMap.has(exportedFromPath) && // If we already iterated this through cache, ignore it
                exportedModules.has(affectedFile.resolvedPath) &&
                forEachFilesReferencingPath(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        });
    }
    /**
     * Iterate on files referencing referencedPath
     */
    function forEachFilesReferencingPath(state, referencedPath, seenFileAndExportsOfFile, fn) {
        return ts.forEachEntry(state.referencedMap, function (referencesInFile, filePath) {
            return referencesInFile.has(referencedPath) && forEachFileAndExportsOfFile(state, filePath, seenFileAndExportsOfFile, fn);
        });
    }
    /**
     * fn on file and iterate on anything that exports this file
     */
    function forEachFileAndExportsOfFile(state, filePath, seenFileAndExportsOfFile, fn) {
        if (!ts.addToSeen(seenFileAndExportsOfFile, filePath)) {
            return false;
        }
        if (fn(state, filePath)) {
            // If there are no more diagnostics from old cache, done
            return true;
        }
        ts.Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
        // Go through exported modules from cache first
        // If exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.currentAffectedFilesExportedModulesMap, function (exportedModules, exportedFromPath) {
            return exportedModules &&
                exportedModules.has(filePath) &&
                forEachFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return true;
        }
        // If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.exportedModulesMap, function (exportedModules, exportedFromPath) {
            return !state.currentAffectedFilesExportedModulesMap.has(exportedFromPath) && // If we already iterated this through cache, ignore it
                exportedModules.has(filePath) &&
                forEachFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return true;
        }
        // Remove diagnostics of files that import this file (without going to exports of referencing files)
        return !!ts.forEachEntry(state.referencedMap, function (referencesInFile, referencingFilePath) {
            return referencesInFile.has(filePath) &&
                !seenFileAndExportsOfFile.has(referencingFilePath) && // Not already removed diagnostic file
                fn(state, referencingFilePath);
        } // Dont add to seen since this is not yet done with the export removal
        );
    }
    /**
     * This is called after completing operation on the next affected file.
     * The operations here are postponed to ensure that cancellation during the iteration is handled correctly
     */
    function doneWithAffectedFile(state, affected, emitKind, isPendingEmit, isBuildInfoEmit) {
        if (isBuildInfoEmit) {
            state.emittedBuildInfo = true;
        }
        else if (affected === state.program) {
            state.changedFilesSet.clear();
            state.programEmitComplete = true;
        }
        else {
            state.seenAffectedFiles.set(affected.resolvedPath, true);
            if (emitKind !== undefined) {
                (state.seenEmittedFiles || (state.seenEmittedFiles = ts.createMap())).set(affected.resolvedPath, emitKind);
            }
            if (isPendingEmit) {
                state.affectedFilesPendingEmitIndex++;
            }
            else {
                state.affectedFilesIndex++;
            }
        }
    }
    /**
     * Returns the result with affected file
     */
    function toAffectedFileResult(state, result, affected) {
        doneWithAffectedFile(state, affected);
        return { result: result, affected: affected };
    }
    /**
     * Returns the result with affected file
     */
    function toAffectedFileEmitResult(state, result, affected, emitKind, isPendingEmit, isBuildInfoEmit) {
        doneWithAffectedFile(state, affected, emitKind, isPendingEmit, isBuildInfoEmit);
        return { result: result, affected: affected };
    }
    /**
     * Gets semantic diagnostics for the file which are
     * bindAndCheckDiagnostics (from cache) and program diagnostics
     */
    function getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken) {
        return ts.concatenate(getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken), ts.Debug.checkDefined(state.program).getProgramDiagnostics(sourceFile));
    }
    /**
     * Gets the binder and checker diagnostics either from cache if present, or otherwise from program and caches it
     * Note that it is assumed that when asked about binder and checker diagnostics, the file has been taken out of affected files/changed file set
     */
    function getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken) {
        var path = sourceFile.resolvedPath;
        if (state.semanticDiagnosticsPerFile) {
            var cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
            // Report the bind and check diagnostics from the cache if we already have those diagnostics present
            if (cachedDiagnostics) {
                return cachedDiagnostics;
            }
        }
        // Diagnostics werent cached, get them from program, and cache the result
        var diagnostics = ts.Debug.checkDefined(state.program).getBindAndCheckDiagnostics(sourceFile, cancellationToken);
        if (state.semanticDiagnosticsPerFile) {
            state.semanticDiagnosticsPerFile.set(path, diagnostics);
        }
        return diagnostics;
    }
    /**
     * Gets the program information to be emitted in buildInfo so that we can use it to create new program
     */
    function getProgramBuildInfo(state, getCanonicalFileName) {
        if (state.compilerOptions.outFile || state.compilerOptions.out)
            return undefined;
        var currentDirectory = ts.Debug.checkDefined(state.program).getCurrentDirectory();
        var buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(ts.getTsBuildInfoEmitOutputFilePath(state.compilerOptions), currentDirectory));
        var fileInfos = {};
        state.fileInfos.forEach(function (value, key) {
            var signature = state.currentAffectedFilesSignatures && state.currentAffectedFilesSignatures.get(key);
            fileInfos[relativeToBuildInfo(key)] = signature === undefined ? value : { version: value.version, signature: signature, affectsGlobalScope: value.affectsGlobalScope };
        });
        var result = {
            fileInfos: fileInfos,
            options: convertToReusableCompilerOptions(state.compilerOptions, relativeToBuildInfoEnsuringAbsolutePath)
        };
        if (state.referencedMap) {
            var referencedMap = {};
            for (var _i = 0, _a = ts.arrayFrom(state.referencedMap.keys()).sort(ts.compareStringsCaseSensitive); _i < _a.length; _i++) {
                var key = _a[_i];
                referencedMap[relativeToBuildInfo(key)] = ts.arrayFrom(state.referencedMap.get(key).keys(), relativeToBuildInfo).sort(ts.compareStringsCaseSensitive);
            }
            result.referencedMap = referencedMap;
        }
        if (state.exportedModulesMap) {
            var exportedModulesMap = {};
            for (var _b = 0, _c = ts.arrayFrom(state.exportedModulesMap.keys()).sort(ts.compareStringsCaseSensitive); _b < _c.length; _b++) {
                var key = _c[_b];
                var newValue = state.currentAffectedFilesExportedModulesMap && state.currentAffectedFilesExportedModulesMap.get(key);
                // Not in temporary cache, use existing value
                if (newValue === undefined)
                    exportedModulesMap[relativeToBuildInfo(key)] = ts.arrayFrom(state.exportedModulesMap.get(key).keys(), relativeToBuildInfo).sort(ts.compareStringsCaseSensitive);
                // Value in cache and has updated value map, use that
                else if (newValue)
                    exportedModulesMap[relativeToBuildInfo(key)] = ts.arrayFrom(newValue.keys(), relativeToBuildInfo).sort(ts.compareStringsCaseSensitive);
            }
            result.exportedModulesMap = exportedModulesMap;
        }
        if (state.semanticDiagnosticsPerFile) {
            var semanticDiagnosticsPerFile = [];
            for (var _d = 0, _e = ts.arrayFrom(state.semanticDiagnosticsPerFile.keys()).sort(ts.compareStringsCaseSensitive); _d < _e.length; _d++) {
                var key = _e[_d];
                var value = state.semanticDiagnosticsPerFile.get(key);
                semanticDiagnosticsPerFile.push(value.length ?
                    [
                        relativeToBuildInfo(key),
                        state.hasReusableDiagnostic ?
                            value :
                            convertToReusableDiagnostics(value, relativeToBuildInfo)
                    ] :
                    relativeToBuildInfo(key));
            }
            result.semanticDiagnosticsPerFile = semanticDiagnosticsPerFile;
        }
        return result;
        function relativeToBuildInfoEnsuringAbsolutePath(path) {
            return relativeToBuildInfo(ts.getNormalizedAbsolutePath(path, currentDirectory));
        }
        function relativeToBuildInfo(path) {
            return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(buildInfoDirectory, path, getCanonicalFileName));
        }
    }
    function convertToReusableCompilerOptions(options, relativeToBuildInfo) {
        var result = {};
        var optionsNameMap = ts.getOptionsNameMap().optionsNameMap;
        for (var name in options) {
            if (ts.hasProperty(options, name)) {
                result[name] = convertToReusableCompilerOptionValue(optionsNameMap.get(name.toLowerCase()), options[name], relativeToBuildInfo);
            }
        }
        if (result.configFilePath) {
            result.configFilePath = relativeToBuildInfo(result.configFilePath);
        }
        return result;
    }
    function convertToReusableCompilerOptionValue(option, value, relativeToBuildInfo) {
        if (option) {
            if (option.type === "list") {
                var values = value;
                if (option.element.isFilePath && values.length) {
                    return values.map(relativeToBuildInfo);
                }
            }
            else if (option.isFilePath) {
                return relativeToBuildInfo(value);
            }
        }
        return value;
    }
    function convertToReusableDiagnostics(diagnostics, relativeToBuildInfo) {
        ts.Debug.assert(!!diagnostics.length);
        return diagnostics.map(function (diagnostic) {
            var result = convertToReusableDiagnosticRelatedInformation(diagnostic, relativeToBuildInfo);
            result.reportsUnnecessary = diagnostic.reportsUnnecessary;
            result.source = diagnostic.source;
            var relatedInformation = diagnostic.relatedInformation;
            result.relatedInformation = relatedInformation ?
                relatedInformation.length ?
                    relatedInformation.map(function (r) { return convertToReusableDiagnosticRelatedInformation(r, relativeToBuildInfo); }) :
                    ts.emptyArray :
                undefined;
            return result;
        });
    }
    function convertToReusableDiagnosticRelatedInformation(diagnostic, relativeToBuildInfo) {
        var file = diagnostic.file;
        return __assign(__assign({}, diagnostic), { file: file ? relativeToBuildInfo(file.resolvedPath) : undefined });
    }
    var BuilderProgramKind;
    (function (BuilderProgramKind) {
        BuilderProgramKind[BuilderProgramKind["SemanticDiagnosticsBuilderProgram"] = 0] = "SemanticDiagnosticsBuilderProgram";
        BuilderProgramKind[BuilderProgramKind["EmitAndSemanticDiagnosticsBuilderProgram"] = 1] = "EmitAndSemanticDiagnosticsBuilderProgram";
    })(BuilderProgramKind = ts.BuilderProgramKind || (ts.BuilderProgramKind = {}));
    function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        var host;
        var newProgram;
        var oldProgram;
        if (newProgramOrRootNames === undefined) {
            ts.Debug.assert(hostOrOptions === undefined);
            host = oldProgramOrHost;
            oldProgram = configFileParsingDiagnosticsOrOldProgram;
            ts.Debug.assert(!!oldProgram);
            newProgram = oldProgram.getProgram();
        }
        else if (ts.isArray(newProgramOrRootNames)) {
            oldProgram = configFileParsingDiagnosticsOrOldProgram;
            newProgram = ts.createProgram({
                rootNames: newProgramOrRootNames,
                options: hostOrOptions,
                host: oldProgramOrHost,
                oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),
                configFileParsingDiagnostics: configFileParsingDiagnostics,
                projectReferences: projectReferences
            });
            host = oldProgramOrHost;
        }
        else {
            newProgram = newProgramOrRootNames;
            host = hostOrOptions;
            oldProgram = oldProgramOrHost;
            configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;
        }
        return { host: host, newProgram: newProgram, oldProgram: oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || ts.emptyArray };
    }
    ts.getBuilderCreationParameters = getBuilderCreationParameters;
    function createBuilderProgram(kind, _a) {
        var newProgram = _a.newProgram, host = _a.host, oldProgram = _a.oldProgram, configFileParsingDiagnostics = _a.configFileParsingDiagnostics;
        // Return same program if underlying program doesnt change
        var oldState = oldProgram && oldProgram.getState();
        if (oldState && newProgram === oldState.program && configFileParsingDiagnostics === newProgram.getConfigFileParsingDiagnostics()) {
            newProgram = undefined; // TODO: GH#18217
            oldState = undefined;
            return oldProgram;
        }
        /**
         * Create the canonical file name for identity
         */
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        /**
         * Computing hash to for signature verification
         */
        var computeHash = host.createHash || ts.generateDjb2Hash;
        var state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState);
        var backupState;
        newProgram.getProgramBuildInfo = function () { return getProgramBuildInfo(state, getCanonicalFileName); };
        // To ensure that we arent storing any references to old program or new program without state
        newProgram = undefined; // TODO: GH#18217
        oldProgram = undefined;
        oldState = undefined;
        var builderProgram = createRedirectedBuilderProgram(state, configFileParsingDiagnostics);
        builderProgram.getState = function () { return state; };
        builderProgram.backupState = function () {
            ts.Debug.assert(backupState === undefined);
            backupState = cloneBuilderProgramState(state);
        };
        builderProgram.restoreState = function () {
            state = ts.Debug.checkDefined(backupState);
            backupState = undefined;
        };
        builderProgram.getAllDependencies = function (sourceFile) { return ts.BuilderState.getAllDependencies(state, ts.Debug.checkDefined(state.program), sourceFile); };
        builderProgram.getSemanticDiagnostics = getSemanticDiagnostics;
        builderProgram.emit = emit;
        builderProgram.releaseProgram = function () {
            releaseCache(state);
            backupState = undefined;
        };
        if (kind === BuilderProgramKind.SemanticDiagnosticsBuilderProgram) {
            builderProgram.getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
        }
        else if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
            builderProgram.getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
            builderProgram.emitNextAffectedFile = emitNextAffectedFile;
        }
        else {
            ts.notImplemented();
        }
        return builderProgram;
        /**
         * Emits the next affected file's emit result (EmitResult and sourceFiles emitted) or returns undefined if iteration is complete
         * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
         * in that order would be used to write the files
         */
        function emitNextAffectedFile(writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
            var affected = getNextAffectedFile(state, cancellationToken, computeHash);
            var emitKind = 1 /* Full */;
            var isPendingEmitFile = false;
            if (!affected) {
                if (!state.compilerOptions.out && !state.compilerOptions.outFile) {
                    var pendingAffectedFile = getNextAffectedFilePendingEmit(state);
                    if (!pendingAffectedFile) {
                        if (state.emittedBuildInfo) {
                            return undefined;
                        }
                        var affected_1 = ts.Debug.checkDefined(state.program);
                        return toAffectedFileEmitResult(state, 
                        // When whole program is affected, do emit only once (eg when --out or --outFile is specified)
                        // Otherwise just affected file
                        affected_1.emitBuildInfo(writeFile || ts.maybeBind(host, host.writeFile), cancellationToken), affected_1, 1 /* Full */, 
                        /*isPendingEmitFile*/ false, 
                        /*isBuildInfoEmit*/ true);
                    }
                    (affected = pendingAffectedFile.affectedFile, emitKind = pendingAffectedFile.emitKind);
                    isPendingEmitFile = true;
                }
                else {
                    var program = ts.Debug.checkDefined(state.program);
                    if (state.programEmitComplete)
                        return undefined;
                    affected = program;
                }
            }
            return toAffectedFileEmitResult(state, 
            // When whole program is affected, do emit only once (eg when --out or --outFile is specified)
            // Otherwise just affected file
            ts.Debug.checkDefined(state.program).emit(affected === state.program ? undefined : affected, writeFile || ts.maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles || emitKind === 0 /* DtsOnly */, customTransformers), affected, emitKind, isPendingEmitFile);
        }
        /**
         * Emits the JavaScript and declaration files.
         * When targetSource file is specified, emits the files corresponding to that source file,
         * otherwise for the whole program.
         * In case of EmitAndSemanticDiagnosticsBuilderProgram, when targetSourceFile is specified,
         * it is assumed that that file is handled from affected file list. If targetSourceFile is not specified,
         * it will only emit all the affected files instead of whole program
         *
         * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
         * in that order would be used to write the files
         */
        function emit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
            if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
                assertSourceFileOkWithoutNextAffectedCall(state, targetSourceFile);
                var result = ts.handleNoEmitOptions(builderProgram, targetSourceFile, cancellationToken);
                if (result)
                    return result;
                if (!targetSourceFile) {
                    // Emit and report any errors we ran into.
                    var sourceMaps = [];
                    var emitSkipped = false;
                    var diagnostics = void 0;
                    var emittedFiles = [];
                    var affectedEmitResult = void 0;
                    while (affectedEmitResult = emitNextAffectedFile(writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers)) {
                        emitSkipped = emitSkipped || affectedEmitResult.result.emitSkipped;
                        diagnostics = ts.addRange(diagnostics, affectedEmitResult.result.diagnostics);
                        emittedFiles = ts.addRange(emittedFiles, affectedEmitResult.result.emittedFiles);
                        sourceMaps = ts.addRange(sourceMaps, affectedEmitResult.result.sourceMaps);
                    }
                    return {
                        emitSkipped: emitSkipped,
                        diagnostics: diagnostics || ts.emptyArray,
                        emittedFiles: emittedFiles,
                        sourceMaps: sourceMaps
                    };
                }
            }
            return ts.Debug.checkDefined(state.program).emit(targetSourceFile, writeFile || ts.maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
        }
        /**
         * Return the semantic diagnostics for the next affected file or undefined if iteration is complete
         * If provided ignoreSourceFile would be called before getting the diagnostics and would ignore the sourceFile if the returned value was true
         */
        function getSemanticDiagnosticsOfNextAffectedFile(cancellationToken, ignoreSourceFile) {
            while (true) {
                var affected = getNextAffectedFile(state, cancellationToken, computeHash);
                if (!affected) {
                    // Done
                    return undefined;
                }
                else if (affected === state.program) {
                    // When whole program is affected, get all semantic diagnostics (eg when --out or --outFile is specified)
                    return toAffectedFileResult(state, state.program.getSemanticDiagnostics(/*targetSourceFile*/ undefined, cancellationToken), affected);
                }
                // Add file to affected file pending emit to handle for later emit time
                if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
                    addToAffectedFilesPendingEmit(state, affected.resolvedPath, 1 /* Full */);
                }
                // Get diagnostics for the affected file if its not ignored
                if (ignoreSourceFile && ignoreSourceFile(affected)) {
                    // Get next affected file
                    doneWithAffectedFile(state, affected);
                    continue;
                }
                return toAffectedFileResult(state, getSemanticDiagnosticsOfFile(state, affected, cancellationToken), affected);
            }
        }
        /**
         * Gets the semantic diagnostics from the program corresponding to this state of file (if provided) or whole program
         * The semantic diagnostics are cached and managed here
         * Note that it is assumed that when asked about semantic diagnostics through this API,
         * the file has been taken out of affected files so it is safe to use cache or get from program and cache the diagnostics
         * In case of SemanticDiagnosticsBuilderProgram if the source file is not provided,
         * it will iterate through all the affected files, to ensure that cache stays valid and yet provide a way to get all semantic diagnostics
         */
        function getSemanticDiagnostics(sourceFile, cancellationToken) {
            assertSourceFileOkWithoutNextAffectedCall(state, sourceFile);
            var compilerOptions = ts.Debug.checkDefined(state.program).getCompilerOptions();
            if (compilerOptions.outFile || compilerOptions.out) {
                ts.Debug.assert(!state.semanticDiagnosticsPerFile);
                // We dont need to cache the diagnostics just return them from program
                return ts.Debug.checkDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken);
            }
            if (sourceFile) {
                return getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken);
            }
            // When semantic builder asks for diagnostics of the whole program,
            // ensure that all the affected files are handled
            // eslint-disable-next-line no-empty
            while (getSemanticDiagnosticsOfNextAffectedFile(cancellationToken)) {
            }
            var diagnostics;
            for (var _i = 0, _a = ts.Debug.checkDefined(state.program).getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile_1 = _a[_i];
                diagnostics = ts.addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile_1, cancellationToken));
            }
            return diagnostics || ts.emptyArray;
        }
    }
    ts.createBuilderProgram = createBuilderProgram;
    function addToAffectedFilesPendingEmit(state, affectedFilePendingEmit, kind) {
        if (!state.affectedFilesPendingEmit)
            state.affectedFilesPendingEmit = [];
        if (!state.affectedFilesPendingEmitKind)
            state.affectedFilesPendingEmitKind = ts.createMap();
        var existingKind = state.affectedFilesPendingEmitKind.get(affectedFilePendingEmit);
        state.affectedFilesPendingEmit.push(affectedFilePendingEmit);
        state.affectedFilesPendingEmitKind.set(affectedFilePendingEmit, existingKind || kind);
        // affectedFilesPendingEmitIndex === undefined
        // - means the emit state.affectedFilesPendingEmit was undefined before adding current affected files
        //   so start from 0 as array would be affectedFilesPendingEmit
        // else, continue to iterate from existing index, the current set is appended to existing files
        if (state.affectedFilesPendingEmitIndex === undefined) {
            state.affectedFilesPendingEmitIndex = 0;
        }
    }
    function getMapOfReferencedSet(mapLike, toPath) {
        if (!mapLike)
            return undefined;
        var map = ts.createMap();
        // Copies keys/values from template. Note that for..in will not throw if
        // template is undefined, and instead will just exit the loop.
        for (var key in mapLike) {
            if (ts.hasProperty(mapLike, key)) {
                map.set(toPath(key), ts.arrayToSet(mapLike[key], toPath));
            }
        }
        return map;
    }
    function createBuildProgramUsingProgramBuildInfo(program, buildInfoPath, host) {
        var buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        var fileInfos = ts.createMap();
        for (var key in program.fileInfos) {
            if (ts.hasProperty(program.fileInfos, key)) {
                fileInfos.set(toPath(key), program.fileInfos[key]);
            }
        }
        var state = {
            fileInfos: fileInfos,
            compilerOptions: ts.convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath),
            referencedMap: getMapOfReferencedSet(program.referencedMap, toPath),
            exportedModulesMap: getMapOfReferencedSet(program.exportedModulesMap, toPath),
            semanticDiagnosticsPerFile: program.semanticDiagnosticsPerFile && ts.arrayToMap(program.semanticDiagnosticsPerFile, function (value) { return toPath(ts.isString(value) ? value : value[0]); }, function (value) { return ts.isString(value) ? ts.emptyArray : value[1]; }),
            hasReusableDiagnostic: true
        };
        return {
            getState: function () { return state; },
            backupState: ts.noop,
            restoreState: ts.noop,
            getProgram: ts.notImplemented,
            getProgramOrUndefined: ts.returnUndefined,
            releaseProgram: ts.noop,
            getCompilerOptions: function () { return state.compilerOptions; },
            getSourceFile: ts.notImplemented,
            getSourceFiles: ts.notImplemented,
            getOptionsDiagnostics: ts.notImplemented,
            getGlobalDiagnostics: ts.notImplemented,
            getConfigFileParsingDiagnostics: ts.notImplemented,
            getSyntacticDiagnostics: ts.notImplemented,
            getDeclarationDiagnostics: ts.notImplemented,
            getSemanticDiagnostics: ts.notImplemented,
            emit: ts.notImplemented,
            getAllDependencies: ts.notImplemented,
            getCurrentDirectory: ts.notImplemented,
            emitNextAffectedFile: ts.notImplemented,
            getSemanticDiagnosticsOfNextAffectedFile: ts.notImplemented,
            close: ts.noop,
        };
        function toPath(path) {
            return ts.toPath(path, buildInfoDirectory, getCanonicalFileName);
        }
        function toAbsolutePath(path) {
            return ts.getNormalizedAbsolutePath(path, buildInfoDirectory);
        }
    }
    ts.createBuildProgramUsingProgramBuildInfo = createBuildProgramUsingProgramBuildInfo;
    function createRedirectedBuilderProgram(state, configFileParsingDiagnostics) {
        return {
            getState: ts.notImplemented,
            backupState: ts.noop,
            restoreState: ts.noop,
            getProgram: getProgram,
            getProgramOrUndefined: function () { return state.program; },
            releaseProgram: function () { return state.program = undefined; },
            getCompilerOptions: function () { return state.compilerOptions; },
            getSourceFile: function (fileName) { return getProgram().getSourceFile(fileName); },
            getSourceFiles: function () { return getProgram().getSourceFiles(); },
            getOptionsDiagnostics: function (cancellationToken) { return getProgram().getOptionsDiagnostics(cancellationToken); },
            getGlobalDiagnostics: function (cancellationToken) { return getProgram().getGlobalDiagnostics(cancellationToken); },
            getConfigFileParsingDiagnostics: function () { return configFileParsingDiagnostics; },
            getSyntacticDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getSyntacticDiagnostics(sourceFile, cancellationToken); },
            getDeclarationDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getDeclarationDiagnostics(sourceFile, cancellationToken); },
            getSemanticDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getSemanticDiagnostics(sourceFile, cancellationToken); },
            emit: function (sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers) { return getProgram().emit(sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers); },
            getAllDependencies: ts.notImplemented,
            getCurrentDirectory: function () { return getProgram().getCurrentDirectory(); },
            close: ts.noop,
        };
        function getProgram() {
            return ts.Debug.checkDefined(state.program);
        }
    }
    ts.createRedirectedBuilderProgram = createRedirectedBuilderProgram;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        return ts.createBuilderProgram(ts.BuilderProgramKind.SemanticDiagnosticsBuilderProgram, ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
    }
    ts.createSemanticDiagnosticsBuilderProgram = createSemanticDiagnosticsBuilderProgram;
    function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        return ts.createBuilderProgram(ts.BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
    }
    ts.createEmitAndSemanticDiagnosticsBuilderProgram = createEmitAndSemanticDiagnosticsBuilderProgram;
    function createAbstractBuilder(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        var _a = ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences), newProgram = _a.newProgram, newConfigFileParsingDiagnostics = _a.configFileParsingDiagnostics;
        return ts.createRedirectedBuilderProgram({ program: newProgram, compilerOptions: newProgram.getCompilerOptions() }, newConfigFileParsingDiagnostics);
    }
    ts.createAbstractBuilder = createAbstractBuilder;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function removeIgnoredPath(path) {
        // Consider whole staging folder as if node_modules changed.
        if (ts.endsWith(path, "/node_modules/.staging")) {
            return ts.removeSuffix(path, "/.staging");
        }
        return ts.some(ts.ignoredPaths, function (searchPath) { return ts.stringContains(path, searchPath); }) ?
            undefined :
            path;
    }
    ts.removeIgnoredPath = removeIgnoredPath;
    /**
     * Filter out paths like
     * "/", "/user", "/user/username", "/user/username/folderAtRoot",
     * "c:/", "c:/users", "c:/users/username", "c:/users/username/folderAtRoot", "c:/folderAtRoot"
     * @param dirPath
     */
    function canWatchDirectory(dirPath) {
        var rootLength = ts.getRootLength(dirPath);
        if (dirPath.length === rootLength) {
            // Ignore "/", "c:/"
            return false;
        }
        var nextDirectorySeparator = dirPath.indexOf(ts.directorySeparator, rootLength);
        if (nextDirectorySeparator === -1) {
            // ignore "/user", "c:/users" or "c:/folderAtRoot"
            return false;
        }
        var pathPartForUserCheck = dirPath.substring(rootLength, nextDirectorySeparator + 1);
        var isNonDirectorySeparatorRoot = rootLength > 1 || dirPath.charCodeAt(0) !== 47 /* slash */;
        if (isNonDirectorySeparatorRoot &&
            dirPath.search(/[a-zA-Z]:/) !== 0 && // Non dos style paths
            pathPartForUserCheck.search(/[a-zA-z]\$\//) === 0) { // Dos style nextPart
            nextDirectorySeparator = dirPath.indexOf(ts.directorySeparator, nextDirectorySeparator + 1);
            if (nextDirectorySeparator === -1) {
                // ignore "//vda1cs4850/c$/folderAtRoot"
                return false;
            }
            pathPartForUserCheck = dirPath.substring(rootLength + pathPartForUserCheck.length, nextDirectorySeparator + 1);
        }
        if (isNonDirectorySeparatorRoot &&
            pathPartForUserCheck.search(/users\//i) !== 0) {
            // Paths like c:/folderAtRoot/subFolder are allowed
            return true;
        }
        for (var searchIndex = nextDirectorySeparator + 1, searchLevels = 2; searchLevels > 0; searchLevels--) {
            searchIndex = dirPath.indexOf(ts.directorySeparator, searchIndex) + 1;
            if (searchIndex === 0) {
                // Folder isnt at expected minimum levels
                return false;
            }
        }
        return true;
    }
    ts.canWatchDirectory = canWatchDirectory;
    function createResolutionCache(resolutionHost, rootDirForResolution, logChangesWhenResolvingModule) {
        var filesWithChangedSetOfUnresolvedImports;
        var filesWithInvalidatedResolutions;
        var filesWithInvalidatedNonRelativeUnresolvedImports;
        var nonRelativeExternalModuleResolutions = ts.createMultiMap();
        var resolutionsWithFailedLookups = [];
        var resolvedFileToResolution = ts.createMultiMap();
        var getCurrentDirectory = ts.memoize(function () { return resolutionHost.getCurrentDirectory(); }); // TODO: GH#18217
        var cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
        // The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file.
        // The key in the map is source file's path.
        // The values are Map of resolutions with key being name lookedup.
        var resolvedModuleNames = ts.createMap();
        var perDirectoryResolvedModuleNames = ts.createCacheWithRedirects();
        var nonRelativeModuleNameCache = ts.createCacheWithRedirects();
        var moduleResolutionCache = ts.createModuleResolutionCacheWithMaps(perDirectoryResolvedModuleNames, nonRelativeModuleNameCache, getCurrentDirectory(), resolutionHost.getCanonicalFileName);
        var resolvedTypeReferenceDirectives = ts.createMap();
        var perDirectoryResolvedTypeReferenceDirectives = ts.createCacheWithRedirects();
        /**
         * These are the extensions that failed lookup files will have by default,
         * any other extension of failed lookup will be store that path in custom failed lookup path
         * This helps in not having to comb through all resolutions when files are added/removed
         * Note that .d.ts file also has .d.ts extension hence will be part of default extensions
         */
        var failedLookupDefaultExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".js" /* Js */, ".jsx" /* Jsx */, ".json" /* Json */];
        var customFailedLookupPaths = ts.createMap();
        var directoryWatchesOfFailedLookups = ts.createMap();
        var rootDir = rootDirForResolution && ts.removeTrailingDirectorySeparator(ts.getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory()));
        var rootPath = (rootDir && resolutionHost.toPath(rootDir)); // TODO: GH#18217
        var rootSplitLength = rootPath !== undefined ? rootPath.split(ts.directorySeparator).length : 0;
        // TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames
        var typeRootsWatches = ts.createMap();
        return {
            startRecordingFilesWithChangedResolutions: startRecordingFilesWithChangedResolutions,
            finishRecordingFilesWithChangedResolutions: finishRecordingFilesWithChangedResolutions,
            // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
            // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
            startCachingPerDirectoryResolution: clearPerDirectoryResolutions,
            finishCachingPerDirectoryResolution: finishCachingPerDirectoryResolution,
            resolveModuleNames: resolveModuleNames,
            getResolvedModuleWithFailedLookupLocationsFromCache: getResolvedModuleWithFailedLookupLocationsFromCache,
            resolveTypeReferenceDirectives: resolveTypeReferenceDirectives,
            removeResolutionsFromProjectReferenceRedirects: removeResolutionsFromProjectReferenceRedirects,
            removeResolutionsOfFile: removeResolutionsOfFile,
            invalidateResolutionOfFile: invalidateResolutionOfFile,
            setFilesWithInvalidatedNonRelativeUnresolvedImports: setFilesWithInvalidatedNonRelativeUnresolvedImports,
            createHasInvalidatedResolution: createHasInvalidatedResolution,
            updateTypeRootsWatch: updateTypeRootsWatch,
            closeTypeRootsWatch: closeTypeRootsWatch,
            clear: clear
        };
        function getResolvedModule(resolution) {
            return resolution.resolvedModule;
        }
        function getResolvedTypeReferenceDirective(resolution) {
            return resolution.resolvedTypeReferenceDirective;
        }
        function isInDirectoryPath(dir, file) {
            if (dir === undefined || file.length <= dir.length) {
                return false;
            }
            return ts.startsWith(file, dir) && file[dir.length] === ts.directorySeparator;
        }
        function clear() {
            ts.clearMap(directoryWatchesOfFailedLookups, ts.closeFileWatcherOf);
            customFailedLookupPaths.clear();
            nonRelativeExternalModuleResolutions.clear();
            closeTypeRootsWatch();
            resolvedModuleNames.clear();
            resolvedTypeReferenceDirectives.clear();
            resolvedFileToResolution.clear();
            resolutionsWithFailedLookups.length = 0;
            // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
            // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
            clearPerDirectoryResolutions();
        }
        function startRecordingFilesWithChangedResolutions() {
            filesWithChangedSetOfUnresolvedImports = [];
        }
        function finishRecordingFilesWithChangedResolutions() {
            var collected = filesWithChangedSetOfUnresolvedImports;
            filesWithChangedSetOfUnresolvedImports = undefined;
            return collected;
        }
        function isFileWithInvalidatedNonRelativeUnresolvedImports(path) {
            if (!filesWithInvalidatedNonRelativeUnresolvedImports) {
                return false;
            }
            // Invalidated if file has unresolved imports
            var value = filesWithInvalidatedNonRelativeUnresolvedImports.get(path);
            return !!value && !!value.length;
        }
        function createHasInvalidatedResolution(forceAllFilesAsInvalidated) {
            if (forceAllFilesAsInvalidated) {
                // Any file asked would have invalidated resolution
                filesWithInvalidatedResolutions = undefined;
                return ts.returnTrue;
            }
            var collected = filesWithInvalidatedResolutions;
            filesWithInvalidatedResolutions = undefined;
            return function (path) { return (!!collected && collected.has(path)) ||
                isFileWithInvalidatedNonRelativeUnresolvedImports(path); };
        }
        function clearPerDirectoryResolutions() {
            perDirectoryResolvedModuleNames.clear();
            nonRelativeModuleNameCache.clear();
            perDirectoryResolvedTypeReferenceDirectives.clear();
            nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
            nonRelativeExternalModuleResolutions.clear();
        }
        function finishCachingPerDirectoryResolution() {
            filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
            clearPerDirectoryResolutions();
            directoryWatchesOfFailedLookups.forEach(function (watcher, path) {
                if (watcher.refCount === 0) {
                    directoryWatchesOfFailedLookups.delete(path);
                    watcher.watcher.close();
                }
            });
        }
        function resolveModuleName(moduleName, containingFile, compilerOptions, host, redirectedReference) {
            var _a;
            var primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference);
            // return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts
            if (!resolutionHost.getGlobalCache) {
                return primaryResult;
            }
            // otherwise try to load typings from @types
            var globalCache = resolutionHost.getGlobalCache();
            if (globalCache !== undefined && !ts.isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && ts.extensionIsTS(primaryResult.resolvedModule.extension))) {
                // create different collection of failed lookup locations for second pass
                // if it will fail and we've already found something during the first pass - we don't want to pollute its results
                var _b = ts.loadModuleFromGlobalCache(ts.Debug.checkDefined(resolutionHost.globalCacheResolutionModuleName)(moduleName), resolutionHost.projectName, compilerOptions, host, globalCache), resolvedModule = _b.resolvedModule, failedLookupLocations = _b.failedLookupLocations;
                if (resolvedModule) {
                    // Modify existing resolution so its saved in the directory cache as well
                    primaryResult.resolvedModule = resolvedModule;
                    (_a = primaryResult.failedLookupLocations).push.apply(_a, failedLookupLocations);
                    return primaryResult;
                }
            }
            // Default return the result from the first pass
            return primaryResult;
        }
        function resolveNamesWithLocalCache(_a) {
            var _b;
            var names = _a.names, containingFile = _a.containingFile, redirectedReference = _a.redirectedReference, cache = _a.cache, perDirectoryCacheWithRedirects = _a.perDirectoryCacheWithRedirects, loader = _a.loader, getResolutionWithResolvedFileName = _a.getResolutionWithResolvedFileName, shouldRetryResolution = _a.shouldRetryResolution, reusedNames = _a.reusedNames, logChanges = _a.logChanges;
            var path = resolutionHost.toPath(containingFile);
            var resolutionsInFile = cache.get(path) || cache.set(path, ts.createMap()).get(path);
            var dirPath = ts.getDirectoryPath(path);
            var perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
            var perDirectoryResolution = perDirectoryCache.get(dirPath);
            if (!perDirectoryResolution) {
                perDirectoryResolution = ts.createMap();
                perDirectoryCache.set(dirPath, perDirectoryResolution);
            }
            var resolvedModules = [];
            var compilerOptions = resolutionHost.getCompilationSettings();
            var hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path);
            // All the resolutions in this file are invalidated if this file wasnt resolved using same redirect
            var program = resolutionHost.getCurrentProgram();
            var oldRedirect = program && program.getResolvedProjectReferenceToRedirect(containingFile);
            var unmatchedRedirects = oldRedirect ?
                !redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path :
                !!redirectedReference;
            var seenNamesInFile = ts.createMap();
            for (var _i = 0, names_3 = names; _i < names_3.length; _i++) {
                var name = names_3[_i];
                var resolution = resolutionsInFile.get(name);
                // Resolution is valid if it is present and not invalidated
                if (!seenNamesInFile.has(name) &&
                    unmatchedRedirects || !resolution || resolution.isInvalidated ||
                    // If the name is unresolved import that was invalidated, recalculate
                    (hasInvalidatedNonRelativeUnresolvedImport && !ts.isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) {
                    var existingResolution = resolution;
                    var resolutionInDirectory = perDirectoryResolution.get(name);
                    if (resolutionInDirectory) {
                        resolution = resolutionInDirectory;
                    }
                    else {
                        resolution = loader(name, containingFile, compilerOptions, ((_b = resolutionHost.getCompilerHost) === null || _b === void 0 ? void 0 : _b.call(resolutionHost)) || resolutionHost, redirectedReference);
                        perDirectoryResolution.set(name, resolution);
                    }
                    resolutionsInFile.set(name, resolution);
                    watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, path, getResolutionWithResolvedFileName);
                    if (existingResolution) {
                        stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolutionWithResolvedFileName);
                    }
                    if (logChanges && filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) {
                        filesWithChangedSetOfUnresolvedImports.push(path);
                        // reset log changes to avoid recording the same file multiple times
                        logChanges = false;
                    }
                }
                ts.Debug.assert(resolution !== undefined && !resolution.isInvalidated);
                seenNamesInFile.set(name, true);
                resolvedModules.push(getResolutionWithResolvedFileName(resolution));
            }
            // Stop watching and remove the unused name
            resolutionsInFile.forEach(function (resolution, name) {
                if (!seenNamesInFile.has(name) && !ts.contains(reusedNames, name)) {
                    stopWatchFailedLookupLocationOfResolution(resolution, path, getResolutionWithResolvedFileName);
                    resolutionsInFile.delete(name);
                }
            });
            return resolvedModules;
            function resolutionIsEqualTo(oldResolution, newResolution) {
                if (oldResolution === newResolution) {
                    return true;
                }
                if (!oldResolution || !newResolution) {
                    return false;
                }
                var oldResult = getResolutionWithResolvedFileName(oldResolution);
                var newResult = getResolutionWithResolvedFileName(newResolution);
                if (oldResult === newResult) {
                    return true;
                }
                if (!oldResult || !newResult) {
                    return false;
                }
                return oldResult.resolvedFileName === newResult.resolvedFileName;
            }
        }
        function resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference) {
            return resolveNamesWithLocalCache({
                names: typeDirectiveNames,
                containingFile: containingFile,
                redirectedReference: redirectedReference,
                cache: resolvedTypeReferenceDirectives,
                perDirectoryCacheWithRedirects: perDirectoryResolvedTypeReferenceDirectives,
                loader: ts.resolveTypeReferenceDirective,
                getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective,
                shouldRetryResolution: function (resolution) { return resolution.resolvedTypeReferenceDirective === undefined; },
            });
        }
        function resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference) {
            return resolveNamesWithLocalCache({
                names: moduleNames,
                containingFile: containingFile,
                redirectedReference: redirectedReference,
                cache: resolvedModuleNames,
                perDirectoryCacheWithRedirects: perDirectoryResolvedModuleNames,
                loader: resolveModuleName,
                getResolutionWithResolvedFileName: getResolvedModule,
                shouldRetryResolution: function (resolution) { return !resolution.resolvedModule || !ts.resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension); },
                reusedNames: reusedNames,
                logChanges: logChangesWhenResolvingModule
            });
        }
        function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile) {
            var cache = resolvedModuleNames.get(resolutionHost.toPath(containingFile));
            return cache && cache.get(moduleName);
        }
        function isNodeModulesAtTypesDirectory(dirPath) {
            return ts.endsWith(dirPath, "/node_modules/@types");
        }
        function getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath) {
            if (isInDirectoryPath(rootPath, failedLookupLocationPath)) {
                // Ensure failed look up is normalized path
                failedLookupLocation = ts.isRootedDiskPath(failedLookupLocation) ? ts.normalizePath(failedLookupLocation) : ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory());
                var failedLookupPathSplit = failedLookupLocationPath.split(ts.directorySeparator);
                var failedLookupSplit = failedLookupLocation.split(ts.directorySeparator);
                ts.Debug.assert(failedLookupSplit.length === failedLookupPathSplit.length, "FailedLookup: " + failedLookupLocation + " failedLookupLocationPath: " + failedLookupLocationPath);
                if (failedLookupPathSplit.length > rootSplitLength + 1) {
                    // Instead of watching root, watch directory in root to avoid watching excluded directories not needed for module resolution
                    return {
                        dir: failedLookupSplit.slice(0, rootSplitLength + 1).join(ts.directorySeparator),
                        dirPath: failedLookupPathSplit.slice(0, rootSplitLength + 1).join(ts.directorySeparator)
                    };
                }
                else {
                    // Always watch root directory non recursively
                    return {
                        dir: rootDir,
                        dirPath: rootPath,
                        nonRecursive: false
                    };
                }
            }
            return getDirectoryToWatchFromFailedLookupLocationDirectory(ts.getDirectoryPath(ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory())), ts.getDirectoryPath(failedLookupLocationPath));
        }
        function getDirectoryToWatchFromFailedLookupLocationDirectory(dir, dirPath) {
            // If directory path contains node module, get the most parent node_modules directory for watching
            while (ts.pathContainsNodeModules(dirPath)) {
                dir = ts.getDirectoryPath(dir);
                dirPath = ts.getDirectoryPath(dirPath);
            }
            // If the directory is node_modules use it to watch, always watch it recursively
            if (ts.isNodeModulesDirectory(dirPath)) {
                return canWatchDirectory(ts.getDirectoryPath(dirPath)) ? { dir: dir, dirPath: dirPath } : undefined;
            }
            var nonRecursive = true;
            // Use some ancestor of the root directory
            var subDirectoryPath, subDirectory;
            if (rootPath !== undefined) {
                while (!isInDirectoryPath(dirPath, rootPath)) {
                    var parentPath = ts.getDirectoryPath(dirPath);
                    if (parentPath === dirPath) {
                        break;
                    }
                    nonRecursive = false;
                    subDirectoryPath = dirPath;
                    subDirectory = dir;
                    dirPath = parentPath;
                    dir = ts.getDirectoryPath(dir);
                }
            }
            return canWatchDirectory(dirPath) ? { dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath, nonRecursive: nonRecursive } : undefined;
        }
        function isPathWithDefaultFailedLookupExtension(path) {
            return ts.fileExtensionIsOneOf(path, failedLookupDefaultExtensions);
        }
        function watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, filePath, getResolutionWithResolvedFileName) {
            if (resolution.refCount) {
                resolution.refCount++;
                ts.Debug.assertDefined(resolution.files);
            }
            else {
                resolution.refCount = 1;
                ts.Debug.assert(resolution.files === undefined);
                if (ts.isExternalModuleNameRelative(name)) {
                    watchFailedLookupLocationOfResolution(resolution);
                }
                else {
                    nonRelativeExternalModuleResolutions.add(name, resolution);
                }
                var resolved = getResolutionWithResolvedFileName(resolution);
                if (resolved && resolved.resolvedFileName) {
                    resolvedFileToResolution.add(resolutionHost.toPath(resolved.resolvedFileName), resolution);
                }
            }
            (resolution.files || (resolution.files = [])).push(filePath);
        }
        function watchFailedLookupLocationOfResolution(resolution) {
            ts.Debug.assert(!!resolution.refCount);
            var failedLookupLocations = resolution.failedLookupLocations;
            if (!failedLookupLocations.length)
                return;
            resolutionsWithFailedLookups.push(resolution);
            var setAtRoot = false;
            for (var _i = 0, failedLookupLocations_1 = failedLookupLocations; _i < failedLookupLocations_1.length; _i++) {
                var failedLookupLocation = failedLookupLocations_1[_i];
                var failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
                var toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
                if (toWatch) {
                    var dir = toWatch.dir, dirPath = toWatch.dirPath, nonRecursive = toWatch.nonRecursive;
                    // If the failed lookup location path is not one of the supported extensions,
                    // store it in the custom path
                    if (!isPathWithDefaultFailedLookupExtension(failedLookupLocationPath)) {
                        var refCount = customFailedLookupPaths.get(failedLookupLocationPath) || 0;
                        customFailedLookupPaths.set(failedLookupLocationPath, refCount + 1);
                    }
                    if (dirPath === rootPath) {
                        ts.Debug.assert(!nonRecursive);
                        setAtRoot = true;
                    }
                    else {
                        setDirectoryWatcher(dir, dirPath, nonRecursive);
                    }
                }
            }
            if (setAtRoot) {
                // This is always non recursive
                setDirectoryWatcher(rootDir, rootPath, /*nonRecursive*/ true); // TODO: GH#18217
            }
        }
        function watchFailedLookupLocationOfNonRelativeModuleResolutions(resolutions, name) {
            var program = resolutionHost.getCurrentProgram();
            if (!program || !program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(name)) {
                resolutions.forEach(watchFailedLookupLocationOfResolution);
            }
        }
        function setDirectoryWatcher(dir, dirPath, nonRecursive) {
            var dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
            if (dirWatcher) {
                ts.Debug.assert(!!nonRecursive === !!dirWatcher.nonRecursive);
                dirWatcher.refCount++;
            }
            else {
                directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath, nonRecursive), refCount: 1, nonRecursive: nonRecursive });
            }
        }
        function stopWatchFailedLookupLocationOfResolution(resolution, filePath, getResolutionWithResolvedFileName) {
            ts.unorderedRemoveItem(ts.Debug.assertDefined(resolution.files), filePath);
            resolution.refCount--;
            if (resolution.refCount) {
                return;
            }
            var resolved = getResolutionWithResolvedFileName(resolution);
            if (resolved && resolved.resolvedFileName) {
                resolvedFileToResolution.remove(resolutionHost.toPath(resolved.resolvedFileName), resolution);
            }
            if (!ts.unorderedRemoveItem(resolutionsWithFailedLookups, resolution)) {
                // If not watching failed lookups, it wont be there in resolutionsWithFailedLookups
                return;
            }
            var failedLookupLocations = resolution.failedLookupLocations;
            var removeAtRoot = false;
            for (var _i = 0, failedLookupLocations_2 = failedLookupLocations; _i < failedLookupLocations_2.length; _i++) {
                var failedLookupLocation = failedLookupLocations_2[_i];
                var failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
                var toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
                if (toWatch) {
                    var dirPath = toWatch.dirPath;
                    var refCount = customFailedLookupPaths.get(failedLookupLocationPath);
                    if (refCount) {
                        if (refCount === 1) {
                            customFailedLookupPaths.delete(failedLookupLocationPath);
                        }
                        else {
                            ts.Debug.assert(refCount > 1);
                            customFailedLookupPaths.set(failedLookupLocationPath, refCount - 1);
                        }
                    }
                    if (dirPath === rootPath) {
                        removeAtRoot = true;
                    }
                    else {
                        removeDirectoryWatcher(dirPath);
                    }
                }
            }
            if (removeAtRoot) {
                removeDirectoryWatcher(rootPath);
            }
        }
        function removeDirectoryWatcher(dirPath) {
            var dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
            // Do not close the watcher yet since it might be needed by other failed lookup locations.
            dirWatcher.refCount--;
        }
        function createDirectoryWatcher(directory, dirPath, nonRecursive) {
            return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, function (fileOrDirectory) {
                var fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
                if (cachedDirectoryStructureHost) {
                    // Since the file existence changed, update the sourceFiles cache
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                if (invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
                    resolutionHost.onInvalidatedResolution();
                }
            }, nonRecursive ? 0 /* None */ : 1 /* Recursive */);
        }
        function removeResolutionsOfFileFromCache(cache, filePath, getResolutionWithResolvedFileName) {
            // Deleted file, stop watching failed lookups for all the resolutions in the file
            var resolutions = cache.get(filePath);
            if (resolutions) {
                resolutions.forEach(function (resolution) { return stopWatchFailedLookupLocationOfResolution(resolution, filePath, getResolutionWithResolvedFileName); });
                cache.delete(filePath);
            }
        }
        function removeResolutionsFromProjectReferenceRedirects(filePath) {
            if (!ts.fileExtensionIs(filePath, ".json" /* Json */)) {
                return;
            }
            var program = resolutionHost.getCurrentProgram();
            if (!program) {
                return;
            }
            // If this file is input file for the referenced project, get it
            var resolvedProjectReference = program.getResolvedProjectReferenceByPath(filePath);
            if (!resolvedProjectReference) {
                return;
            }
            // filePath is for the projectReference and the containing file is from this project reference, invalidate the resolution
            resolvedProjectReference.commandLine.fileNames.forEach(function (f) { return removeResolutionsOfFile(resolutionHost.toPath(f)); });
        }
        function removeResolutionsOfFile(filePath) {
            removeResolutionsOfFileFromCache(resolvedModuleNames, filePath, getResolvedModule);
            removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath, getResolvedTypeReferenceDirective);
        }
        function invalidateResolution(resolution) {
            resolution.isInvalidated = true;
            var changedInAutoTypeReferenced = false;
            for (var _i = 0, _a = ts.Debug.assertDefined(resolution.files); _i < _a.length; _i++) {
                var containingFilePath = _a[_i];
                (filesWithInvalidatedResolutions || (filesWithInvalidatedResolutions = ts.createMap())).set(containingFilePath, true);
                // When its a file with inferred types resolution, invalidate type reference directive resolution
                changedInAutoTypeReferenced = changedInAutoTypeReferenced || containingFilePath.endsWith(ts.inferredTypesContainingFile);
            }
            if (changedInAutoTypeReferenced) {
                resolutionHost.onChangedAutomaticTypeDirectiveNames();
            }
        }
        function invalidateResolutionOfFile(filePath) {
            removeResolutionsOfFile(filePath);
            // Resolution is invalidated if the resulting file name is same as the deleted file path
            ts.forEach(resolvedFileToResolution.get(filePath), invalidateResolution);
        }
        function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap) {
            ts.Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined);
            filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
        }
        function invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, isCreatingWatchedDirectory) {
            var isChangedFailedLookupLocation;
            if (isCreatingWatchedDirectory) {
                // Watching directory is created
                // Invalidate any resolution has failed lookup in this directory
                isChangedFailedLookupLocation = function (location) { return isInDirectoryPath(fileOrDirectoryPath, resolutionHost.toPath(location)); };
            }
            else {
                // If something to do with folder/file starting with "." in node_modules folder, skip it
                var updatedPath = removeIgnoredPath(fileOrDirectoryPath);
                if (!updatedPath)
                    return false;
                fileOrDirectoryPath = updatedPath;
                // prevent saving an open file from over-eagerly triggering invalidation
                if (resolutionHost.fileIsOpen(fileOrDirectoryPath)) {
                    return false;
                }
                // Some file or directory in the watching directory is created
                // Return early if it does not have any of the watching extension or not the custom failed lookup path
                var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath);
                if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || ts.isNodeModulesDirectory(fileOrDirectoryPath) ||
                    isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || ts.isNodeModulesDirectory(dirOfFileOrDirectory)) {
                    // Invalidate any resolution from this directory
                    isChangedFailedLookupLocation = function (location) {
                        var locationPath = resolutionHost.toPath(location);
                        return locationPath === fileOrDirectoryPath || ts.startsWith(resolutionHost.toPath(location), fileOrDirectoryPath);
                    };
                }
                else {
                    if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
                        return false;
                    }
                    // Ignore emits from the program
                    if (ts.isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) {
                        return false;
                    }
                    // Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
                    isChangedFailedLookupLocation = function (location) { return resolutionHost.toPath(location) === fileOrDirectoryPath; };
                }
            }
            var invalidated = false;
            // Resolution is invalidated if the resulting file name is same as the deleted file path
            for (var _i = 0, resolutionsWithFailedLookups_1 = resolutionsWithFailedLookups; _i < resolutionsWithFailedLookups_1.length; _i++) {
                var resolution = resolutionsWithFailedLookups_1[_i];
                if (resolution.failedLookupLocations.some(isChangedFailedLookupLocation)) {
                    invalidateResolution(resolution);
                    invalidated = true;
                }
            }
            return invalidated;
        }
        function closeTypeRootsWatch() {
            ts.clearMap(typeRootsWatches, ts.closeFileWatcher);
        }
        function getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot, typeRootPath) {
            if (isInDirectoryPath(rootPath, typeRootPath)) {
                return rootPath;
            }
            var toWatch = getDirectoryToWatchFromFailedLookupLocationDirectory(typeRoot, typeRootPath);
            return toWatch && directoryWatchesOfFailedLookups.has(toWatch.dirPath) ? toWatch.dirPath : undefined;
        }
        function createTypeRootsWatch(typeRootPath, typeRoot) {
            // Create new watch and recursive info
            return resolutionHost.watchTypeRootsDirectory(typeRoot, function (fileOrDirectory) {
                var fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
                if (cachedDirectoryStructureHost) {
                    // Since the file existence changed, update the sourceFiles cache
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                // For now just recompile
                // We could potentially store more data here about whether it was/would be really be used or not
                // and with that determine to trigger compilation but for now this is enough
                resolutionHost.onChangedAutomaticTypeDirectiveNames();
                // Since directory watchers invoked are flaky, the failed lookup location events might not be triggered
                // So handle to failed lookup locations here as well to ensure we are invalidating resolutions
                var dirPath = getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot, typeRootPath);
                if (dirPath && invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
                    resolutionHost.onInvalidatedResolution();
                }
            }, 1 /* Recursive */);
        }
        /**
         * Watches the types that would get added as part of getAutomaticTypeDirectiveNames
         * To be called when compiler options change
         */
        function updateTypeRootsWatch() {
            var options = resolutionHost.getCompilationSettings();
            if (options.types) {
                // No need to do any watch since resolution cache is going to handle the failed lookups
                // for the types added by this
                closeTypeRootsWatch();
                return;
            }
            // we need to assume the directories exist to ensure that we can get all the type root directories that get included
            // But filter directories that are at root level to say directory doesnt exist, so that we arent watching them
            var typeRoots = ts.getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory: getCurrentDirectory });
            if (typeRoots) {
                ts.mutateMap(typeRootsWatches, ts.arrayToMap(typeRoots, function (tr) { return resolutionHost.toPath(tr); }), {
                    createNewValue: createTypeRootsWatch,
                    onDeleteValue: ts.closeFileWatcher
                });
            }
            else {
                closeTypeRootsWatch();
            }
        }
        /**
         * Use this function to return if directory exists to get type roots to watch
         * If we return directory exists then only the paths will be added to type roots
         * Hence return true for all directories except root directories which are filtered from watching
         */
        function directoryExistsForTypeRootWatch(nodeTypesDirectory) {
            var dir = ts.getDirectoryPath(ts.getDirectoryPath(nodeTypesDirectory));
            var dirPath = resolutionHost.toPath(dir);
            return dirPath === rootPath || canWatchDirectory(dirPath);
        }
    }
    ts.createResolutionCache = createResolutionCache;
})(ts || (ts = {}));
// Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers.
/* @internal */
var ts;
(function (ts) {
    var moduleSpecifiers;
    (function (moduleSpecifiers) {
        var RelativePreference;
        (function (RelativePreference) {
            RelativePreference[RelativePreference["Relative"] = 0] = "Relative";
            RelativePreference[RelativePreference["NonRelative"] = 1] = "NonRelative";
            RelativePreference[RelativePreference["Auto"] = 2] = "Auto";
        })(RelativePreference || (RelativePreference = {}));
        // See UserPreferences#importPathEnding
        var Ending;
        (function (Ending) {
            Ending[Ending["Minimal"] = 0] = "Minimal";
            Ending[Ending["Index"] = 1] = "Index";
            Ending[Ending["JsExtension"] = 2] = "JsExtension";
        })(Ending || (Ending = {}));
        function getPreferences(_a, compilerOptions, importingSourceFile) {
            var importModuleSpecifierPreference = _a.importModuleSpecifierPreference, importModuleSpecifierEnding = _a.importModuleSpecifierEnding;
            return {
                relativePreference: importModuleSpecifierPreference === "relative" ? 0 /* Relative */ : importModuleSpecifierPreference === "non-relative" ? 1 /* NonRelative */ : 2 /* Auto */,
                ending: getEnding(),
            };
            function getEnding() {
                switch (importModuleSpecifierEnding) {
                    case "minimal": return 0 /* Minimal */;
                    case "index": return 1 /* Index */;
                    case "js": return 2 /* JsExtension */;
                    default: return usesJsExtensionOnImports(importingSourceFile) ? 2 /* JsExtension */
                        : ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeJs ? 1 /* Index */ : 0 /* Minimal */;
                }
            }
        }
        function getPreferencesForUpdate(compilerOptions, oldImportSpecifier) {
            return {
                relativePreference: ts.isExternalModuleNameRelative(oldImportSpecifier) ? 0 /* Relative */ : 1 /* NonRelative */,
                ending: ts.hasJSFileExtension(oldImportSpecifier) ?
                    2 /* JsExtension */ :
                    ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeJs || ts.endsWith(oldImportSpecifier, "index") ? 1 /* Index */ : 0 /* Minimal */,
            };
        }
        function updateModuleSpecifier(compilerOptions, importingSourceFileName, toFileName, host, oldImportSpecifier) {
            var res = getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, getPreferencesForUpdate(compilerOptions, oldImportSpecifier));
            if (res === oldImportSpecifier)
                return undefined;
            return res;
        }
        moduleSpecifiers.updateModuleSpecifier = updateModuleSpecifier;
        // Note: importingSourceFile is just for usesJsExtensionOnImports
        function getModuleSpecifier(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, preferences) {
            if (preferences === void 0) { preferences = {}; }
            return getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, getPreferences(preferences, compilerOptions, importingSourceFile));
        }
        moduleSpecifiers.getModuleSpecifier = getModuleSpecifier;
        function getNodeModulesPackageName(compilerOptions, importingSourceFileName, nodeModulesFileName, host) {
            var info = getInfo(importingSourceFileName, host);
            var modulePaths = getAllModulePaths(importingSourceFileName, nodeModulesFileName, host);
            return ts.firstDefined(modulePaths, function (moduleFileName) { return tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions, /*packageNameOnly*/ true); });
        }
        moduleSpecifiers.getNodeModulesPackageName = getNodeModulesPackageName;
        function getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, preferences) {
            var info = getInfo(importingSourceFileName, host);
            var modulePaths = getAllModulePaths(importingSourceFileName, toFileName, host);
            return ts.firstDefined(modulePaths, function (moduleFileName) { return tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions); }) ||
                getLocalModuleSpecifier(toFileName, info, compilerOptions, preferences);
        }
        /** Returns an import for each symlink and for the realpath. */
        function getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, userPreferences) {
            var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol);
            if (ambient)
                return [ambient];
            var info = getInfo(importingSourceFile.path, host);
            var moduleSourceFile = ts.getSourceFileOfNode(moduleSymbol.valueDeclaration || ts.getNonAugmentationDeclaration(moduleSymbol));
            var modulePaths = getAllModulePaths(importingSourceFile.path, moduleSourceFile.originalFileName, host);
            var preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
            var global = ts.mapDefined(modulePaths, function (moduleFileName) { return tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions); });
            return global.length ? global : modulePaths.map(function (moduleFileName) { return getLocalModuleSpecifier(moduleFileName, info, compilerOptions, preferences); });
        }
        moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers;
        // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path
        function getInfo(importingSourceFileName, host) {
            var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true);
            var sourceDirectory = ts.getDirectoryPath(importingSourceFileName);
            return { getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory };
        }
        function getLocalModuleSpecifier(moduleFileName, _a, compilerOptions, _b) {
            var getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory;
            var ending = _b.ending, relativePreference = _b.relativePreference;
            var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths, rootDirs = compilerOptions.rootDirs;
            var relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) ||
                removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
            if (!baseUrl || relativePreference === 0 /* Relative */) {
                return relativePath;
            }
            var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
            if (!relativeToBaseUrl) {
                return relativePath;
            }
            var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions);
            var fromPaths = paths && tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
            var nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths;
            if (relativePreference === 1 /* NonRelative */) {
                return nonRelative;
            }
            if (relativePreference !== 2 /* Auto */)
                ts.Debug.assertNever(relativePreference);
            // Prefer a relative import over a baseUrl import if it has fewer components.
            return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative;
        }
        function countPathComponents(path) {
            var count = 0;
            for (var i = ts.startsWith(path, "./") ? 2 : 0; i < path.length; i++) {
                if (path.charCodeAt(i) === 47 /* slash */)
                    count++;
            }
            return count;
        }
        moduleSpecifiers.countPathComponents = countPathComponents;
        function usesJsExtensionOnImports(_a) {
            var imports = _a.imports;
            return ts.firstDefined(imports, function (_a) {
                var text = _a.text;
                return ts.pathIsRelative(text) ? ts.hasJSFileExtension(text) : undefined;
            }) || false;
        }
        function numberOfDirectorySeparators(str) {
            var match = str.match(/\//g);
            return match ? match.length : 0;
        }
        function comparePathsByNumberOfDirectorySeparators(a, b) {
            return ts.compareValues(numberOfDirectorySeparators(a), numberOfDirectorySeparators(b));
        }
        function forEachFileNameOfModule(importingFileName, importedFileName, host, preferSymlinks, cb) {
            var getCanonicalFileName = ts.hostGetCanonicalFileName(host);
            var cwd = host.getCurrentDirectory();
            var referenceRedirect = host.isSourceOfProjectReferenceRedirect(importedFileName) ? host.getProjectReferenceRedirect(importedFileName) : undefined;
            var redirects = host.redirectTargetsMap.get(ts.toPath(importedFileName, cwd, getCanonicalFileName)) || ts.emptyArray;
            var importedFileNames = __spreadArrays((referenceRedirect ? [referenceRedirect] : ts.emptyArray), [importedFileName], redirects);
            var targets = importedFileNames.map(function (f) { return ts.getNormalizedAbsolutePath(f, cwd); });
            if (!preferSymlinks) {
                var result_12 = ts.forEach(targets, cb);
                if (result_12)
                    return result_12;
            }
            var links = host.getProbableSymlinks
                ? host.getProbableSymlinks(host.getSourceFiles())
                : ts.discoverProbableSymlinks(host.getSourceFiles(), getCanonicalFileName, cwd);
            var compareStrings = (!host.useCaseSensitiveFileNames || host.useCaseSensitiveFileNames()) ? ts.compareStringsCaseSensitive : ts.compareStringsCaseInsensitive;
            var result = ts.forEachEntry(links, function (resolved, path) {
                if (ts.startsWithDirectory(importingFileName, resolved, getCanonicalFileName)) {
                    return undefined; // Don't want to a package to globally import from itself
                }
                var target = ts.find(targets, function (t) { return compareStrings(t.slice(0, resolved.length + 1), resolved + "/") === 0 /* EqualTo */; });
                if (target === undefined)
                    return undefined;
                var relative = ts.getRelativePathFromDirectory(resolved, target, getCanonicalFileName);
                var option = ts.resolvePath(path, relative);
                if (!host.fileExists || host.fileExists(option)) {
                    var result_13 = cb(option);
                    if (result_13)
                        return result_13;
                }
            });
            return result ||
                (preferSymlinks ? ts.forEach(targets, cb) : undefined);
        }
        moduleSpecifiers.forEachFileNameOfModule = forEachFileNameOfModule;
        /**
         * Looks for existing imports that use symlinks to this module.
         * Symlinks will be returned first so they are preferred over the real path.
         */
        function getAllModulePaths(importingFileName, importedFileName, host) {
            var cwd = host.getCurrentDirectory();
            var getCanonicalFileName = ts.hostGetCanonicalFileName(host);
            var allFileNames = ts.createMap();
            var importedFileFromNodeModules = false;
            forEachFileNameOfModule(importingFileName, importedFileName, host, 
            /*preferSymlinks*/ true, function (path) {
                // dont return value, so we collect everything
                allFileNames.set(path, getCanonicalFileName(path));
                importedFileFromNodeModules = importedFileFromNodeModules || ts.pathContainsNodeModules(path);
            });
            // Sort by paths closest to importing file Name directory
            var sortedPaths = [];
            var _loop_20 = function (directory) {
                var directoryStart = ts.ensureTrailingDirectorySeparator(directory);
                var pathsInDirectory;
                allFileNames.forEach(function (canonicalFileName, fileName) {
                    if (ts.startsWith(canonicalFileName, directoryStart)) {
                        // If the importedFile is from node modules, use only paths in node_modules folder as option
                        if (!importedFileFromNodeModules || ts.pathContainsNodeModules(fileName)) {
                            (pathsInDirectory || (pathsInDirectory = [])).push(fileName);
                        }
                        allFileNames.delete(fileName);
                    }
                });
                if (pathsInDirectory) {
                    if (pathsInDirectory.length > 1) {
                        pathsInDirectory.sort(comparePathsByNumberOfDirectorySeparators);
                    }
                    sortedPaths.push.apply(sortedPaths, pathsInDirectory);
                }
                var newDirectory = ts.getDirectoryPath(directory);
                if (newDirectory === directory)
                    return out_directory_1 = directory, "break";
                directory = newDirectory;
                out_directory_1 = directory;
            };
            var out_directory_1;
            for (var directory = ts.getDirectoryPath(ts.toPath(importingFileName, cwd, getCanonicalFileName)); allFileNames.size !== 0;) {
                var state_8 = _loop_20(directory);
                directory = out_directory_1;
                if (state_8 === "break")
                    break;
            }
            if (allFileNames.size) {
                var remainingPaths = ts.arrayFrom(allFileNames.values());
                if (remainingPaths.length > 1)
                    remainingPaths.sort(comparePathsByNumberOfDirectorySeparators);
                sortedPaths.push.apply(sortedPaths, remainingPaths);
            }
            return sortedPaths;
        }
        function tryGetModuleNameFromAmbientModule(moduleSymbol) {
            var decl = ts.find(moduleSymbol.declarations, function (d) { return ts.isNonGlobalAmbientModule(d) && (!ts.isExternalModuleAugmentation(d) || !ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(d.name))); });
            if (decl) {
                return decl.name.text;
            }
        }
        function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) {
            for (var key in paths) {
                for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) {
                    var patternText_1 = _a[_i];
                    var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1));
                    var indexOfStar = pattern.indexOf("*");
                    if (indexOfStar !== -1) {
                        var prefix = pattern.substr(0, indexOfStar);
                        var suffix = pattern.substr(indexOfStar + 1);
                        if (relativeToBaseUrl.length >= prefix.length + suffix.length &&
                            ts.startsWith(relativeToBaseUrl, prefix) &&
                            ts.endsWith(relativeToBaseUrl, suffix) ||
                            !suffix && relativeToBaseUrl === ts.removeTrailingDirectorySeparator(prefix)) {
                            var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length);
                            return key.replace("*", matchedStar);
                        }
                    }
                    else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) {
                        return key;
                    }
                }
            }
        }
        function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) {
            var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName);
            if (normalizedTargetPath === undefined) {
                return undefined;
            }
            var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName);
            var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath;
            return ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs
                ? removeExtensionAndIndexPostFix(relativePath, ending, compilerOptions)
                : ts.removeFileExtension(relativePath);
        }
        function tryGetModuleNameAsNodeModule(moduleFileName, _a, host, options, packageNameOnly) {
            var getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory;
            if (!host.fileExists || !host.readFile) {
                return undefined;
            }
            var parts = getNodeModulePathParts(moduleFileName);
            if (!parts) {
                return undefined;
            }
            // Simplify the full file path to something that can be resolved by Node.
            var moduleSpecifier = moduleFileName;
            if (!packageNameOnly) {
                var packageRootIndex = parts.packageRootIndex;
                var moduleFileNameForExtensionless = void 0;
                while (true) {
                    // If the module could be imported by a directory name, use that directory's name
                    var _b = tryDirectoryWithPackageJson(packageRootIndex), moduleFileToTry = _b.moduleFileToTry, packageRootPath = _b.packageRootPath;
                    if (packageRootPath) {
                        moduleSpecifier = packageRootPath;
                        break;
                    }
                    if (!moduleFileNameForExtensionless)
                        moduleFileNameForExtensionless = moduleFileToTry;
                    // try with next level of directory
                    packageRootIndex = moduleFileName.indexOf(ts.directorySeparator, packageRootIndex + 1);
                    if (packageRootIndex === -1) {
                        moduleSpecifier = getExtensionlessFileName(moduleFileNameForExtensionless);
                        break;
                    }
                }
            }
            var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
            // Get a path that's relative to node_modules or the importing file's path
            // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
            var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
            if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
                return undefined;
            }
            // If the module was found in @types, get the actual Node package name
            var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
            var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
            // For classic resolution, only allow importing from node_modules/@types, not other node_modules
            return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
            function tryDirectoryWithPackageJson(packageRootIndex) {
                var packageRootPath = moduleFileName.substring(0, packageRootIndex);
                var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
                var moduleFileToTry = moduleFileName;
                if (host.fileExists(packageJsonPath)) {
                    var packageJsonContent = JSON.parse(host.readFile(packageJsonPath));
                    var versionPaths = packageJsonContent.typesVersions
                        ? ts.getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
                        : undefined;
                    if (versionPaths) {
                        var subModuleName = moduleFileName.slice(packageRootPath.length + 1);
                        var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(subModuleName), removeExtensionAndIndexPostFix(subModuleName, 0 /* Minimal */, options), versionPaths.paths);
                        if (fromPaths !== undefined) {
                            moduleFileToTry = ts.combinePaths(packageRootPath, fromPaths);
                        }
                    }
                    // If the file is the main module, it can be imported by the package name
                    var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
                    if (ts.isString(mainFileRelative)) {
                        var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
                        if (ts.removeFileExtension(mainExportFile) === ts.removeFileExtension(getCanonicalFileName(moduleFileToTry))) {
                            return { packageRootPath: packageRootPath, moduleFileToTry: moduleFileToTry };
                        }
                    }
                }
                return { moduleFileToTry: moduleFileToTry };
            }
            function getExtensionlessFileName(path) {
                // We still have a file name - remove the extension
                var fullModulePathWithoutExtension = ts.removeFileExtension(path);
                // If the file is /index, it can be imported by its directory name
                // IFF there is not _also_ a file by the same name
                if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index" && !tryGetAnyFileFromPath(host, fullModulePathWithoutExtension.substring(0, parts.fileNameIndex))) {
                    return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex);
                }
                return fullModulePathWithoutExtension;
            }
        }
        function tryGetAnyFileFromPath(host, path) {
            if (!host.fileExists)
                return;
            // We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory
            var extensions = ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: 6 /* JSON */ }]);
            for (var _i = 0, extensions_3 = extensions; _i < extensions_3.length; _i++) {
                var e = extensions_3[_i];
                var fullPath = path + e;
                if (host.fileExists(fullPath)) {
                    return fullPath;
                }
            }
        }
        function getNodeModulePathParts(fullPath) {
            // If fullPath can't be valid module file within node_modules, returns undefined.
            // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js
            // Returns indices:                       ^            ^                                                      ^             ^
            var topLevelNodeModulesIndex = 0;
            var topLevelPackageNameIndex = 0;
            var packageRootIndex = 0;
            var fileNameIndex = 0;
            var States;
            (function (States) {
                States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules";
                States[States["NodeModules"] = 1] = "NodeModules";
                States[States["Scope"] = 2] = "Scope";
                States[States["PackageContent"] = 3] = "PackageContent";
            })(States || (States = {}));
            var partStart = 0;
            var partEnd = 0;
            var state = 0 /* BeforeNodeModules */;
            while (partEnd >= 0) {
                partStart = partEnd;
                partEnd = fullPath.indexOf("/", partStart + 1);
                switch (state) {
                    case 0 /* BeforeNodeModules */:
                        if (fullPath.indexOf(ts.nodeModulesPathPart, partStart) === partStart) {
                            topLevelNodeModulesIndex = partStart;
                            topLevelPackageNameIndex = partEnd;
                            state = 1 /* NodeModules */;
                        }
                        break;
                    case 1 /* NodeModules */:
                    case 2 /* Scope */:
                        if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") {
                            state = 2 /* Scope */;
                        }
                        else {
                            packageRootIndex = partEnd;
                            state = 3 /* PackageContent */;
                        }
                        break;
                    case 3 /* PackageContent */:
                        if (fullPath.indexOf(ts.nodeModulesPathPart, partStart) === partStart) {
                            state = 1 /* NodeModules */;
                        }
                        else {
                            state = 3 /* PackageContent */;
                        }
                        break;
                }
            }
            fileNameIndex = partStart;
            return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined;
        }
        function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) {
            return ts.firstDefined(rootDirs, function (rootDir) {
                var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); // TODO: GH#18217
                return isPathRelativeToParent(relativePath) ? undefined : relativePath;
            });
        }
        function removeExtensionAndIndexPostFix(fileName, ending, options) {
            if (ts.fileExtensionIs(fileName, ".json" /* Json */))
                return fileName;
            var noExtension = ts.removeFileExtension(fileName);
            switch (ending) {
                case 0 /* Minimal */:
                    return ts.removeSuffix(noExtension, "/index");
                case 1 /* Index */:
                    return noExtension;
                case 2 /* JsExtension */:
                    return noExtension + getJSExtensionForFile(fileName, options);
                default:
                    return ts.Debug.assertNever(ending);
            }
        }
        function getJSExtensionForFile(fileName, options) {
            var ext = ts.extensionFromPath(fileName);
            switch (ext) {
                case ".ts" /* Ts */:
                case ".d.ts" /* Dts */:
                    return ".js" /* Js */;
                case ".tsx" /* Tsx */:
                    return options.jsx === 1 /* Preserve */ ? ".jsx" /* Jsx */ : ".js" /* Js */;
                case ".js" /* Js */:
                case ".jsx" /* Jsx */:
                case ".json" /* Json */:
                    return ext;
                case ".tsbuildinfo" /* TsBuildInfo */:
                    return ts.Debug.fail("Extension " + ".tsbuildinfo" /* TsBuildInfo */ + " is unsupported:: FileName:: " + fileName);
                default:
                    return ts.Debug.assertNever(ext);
            }
        }
        function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) {
            var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
            return ts.isRootedDiskPath(relativePath) ? undefined : relativePath;
        }
        function isPathRelativeToParent(path) {
            return ts.startsWith(path, "..");
        }
    })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var sysFormatDiagnosticsHost = ts.sys ? {
        getCurrentDirectory: function () { return ts.sys.getCurrentDirectory(); },
        getNewLine: function () { return ts.sys.newLine; },
        getCanonicalFileName: ts.createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames)
    } : undefined; // TODO: GH#18217
    /**
     * Create a function that reports error by writing to the system and handles the formating of the diagnostic
     */
    function createDiagnosticReporter(system, pretty) {
        var host = system === ts.sys ? sysFormatDiagnosticsHost : {
            getCurrentDirectory: function () { return system.getCurrentDirectory(); },
            getNewLine: function () { return system.newLine; },
            getCanonicalFileName: ts.createGetCanonicalFileName(system.useCaseSensitiveFileNames),
        };
        if (!pretty) {
            return function (diagnostic) { return system.write(ts.formatDiagnostic(diagnostic, host)); };
        }
        var diagnostics = new Array(1);
        return function (diagnostic) {
            diagnostics[0] = diagnostic;
            system.write(ts.formatDiagnosticsWithColorAndContext(diagnostics, host) + host.getNewLine());
            diagnostics[0] = undefined; // TODO: GH#18217
        };
    }
    ts.createDiagnosticReporter = createDiagnosticReporter;
    /**
     * @returns Whether the screen was cleared.
     */
    function clearScreenIfNotWatchingForFileChanges(system, diagnostic, options) {
        if (system.clearScreen &&
            !options.preserveWatchOutput &&
            !options.extendedDiagnostics &&
            !options.diagnostics &&
            ts.contains(ts.screenStartingMessageCodes, diagnostic.code)) {
            system.clearScreen();
            return true;
        }
        return false;
    }
    ts.screenStartingMessageCodes = [
        ts.Diagnostics.Starting_compilation_in_watch_mode.code,
        ts.Diagnostics.File_change_detected_Starting_incremental_compilation.code,
    ];
    function getPlainDiagnosticFollowingNewLines(diagnostic, newLine) {
        return ts.contains(ts.screenStartingMessageCodes, diagnostic.code)
            ? newLine + newLine
            : newLine;
    }
    /**
     * Get locale specific time based on whether we are in test mode
     */
    function getLocaleTimeString(system) {
        return !system.now ?
            new Date().toLocaleTimeString() :
            system.now().toLocaleTimeString("en-US", { timeZone: "UTC" });
    }
    ts.getLocaleTimeString = getLocaleTimeString;
    /**
     * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
     */
    function createWatchStatusReporter(system, pretty) {
        return pretty ?
            function (diagnostic, newLine, options) {
                clearScreenIfNotWatchingForFileChanges(system, diagnostic, options);
                var output = "[" + ts.formatColorAndReset(getLocaleTimeString(system), ts.ForegroundColorEscapeSequences.Grey) + "] ";
                output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + (newLine + newLine);
                system.write(output);
            } :
            function (diagnostic, newLine, options) {
                var output = "";
                if (!clearScreenIfNotWatchingForFileChanges(system, diagnostic, options)) {
                    output += newLine;
                }
                output += getLocaleTimeString(system) + " - ";
                output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + getPlainDiagnosticFollowingNewLines(diagnostic, newLine);
                system.write(output);
            };
    }
    ts.createWatchStatusReporter = createWatchStatusReporter;
    /** Parses config file using System interface */
    function parseConfigFileWithSystem(configFileName, optionsToExtend, watchOptionsToExtend, system, reportDiagnostic) {
        var host = system;
        host.onUnRecoverableConfigFileDiagnostic = function (diagnostic) { return reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic); };
        var result = ts.getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host, /*extendedConfigCache*/ undefined, watchOptionsToExtend);
        host.onUnRecoverableConfigFileDiagnostic = undefined; // TODO: GH#18217
        return result;
    }
    ts.parseConfigFileWithSystem = parseConfigFileWithSystem;
    function getErrorCountForSummary(diagnostics) {
        return ts.countWhere(diagnostics, function (diagnostic) { return diagnostic.category === ts.DiagnosticCategory.Error; });
    }
    ts.getErrorCountForSummary = getErrorCountForSummary;
    function getWatchErrorSummaryDiagnosticMessage(errorCount) {
        return errorCount === 1 ?
            ts.Diagnostics.Found_1_error_Watching_for_file_changes :
            ts.Diagnostics.Found_0_errors_Watching_for_file_changes;
    }
    ts.getWatchErrorSummaryDiagnosticMessage = getWatchErrorSummaryDiagnosticMessage;
    function getErrorSummaryText(errorCount, newLine) {
        if (errorCount === 0)
            return "";
        var d = ts.createCompilerDiagnostic(errorCount === 1 ? ts.Diagnostics.Found_1_error : ts.Diagnostics.Found_0_errors, errorCount);
        return "" + newLine + ts.flattenDiagnosticMessageText(d.messageText, newLine) + newLine + newLine;
    }
    ts.getErrorSummaryText = getErrorSummaryText;
    function listFiles(program, writeFileName) {
        if (program.getCompilerOptions().listFiles || program.getCompilerOptions().listFilesOnly) {
            ts.forEach(program.getSourceFiles(), function (file) {
                writeFileName(file.fileName);
            });
        }
    }
    ts.listFiles = listFiles;
    /**
     * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
     */
    function emitFilesAndReportErrors(program, reportDiagnostic, writeFileName, reportSummary, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
        var isListFilesOnly = !!program.getCompilerOptions().listFilesOnly;
        // First get and report any syntactic errors.
        var allDiagnostics = program.getConfigFileParsingDiagnostics().slice();
        var configFileParsingDiagnosticsLength = allDiagnostics.length;
        ts.addRange(allDiagnostics, program.getSyntacticDiagnostics(/*sourceFile*/ undefined, cancellationToken));
        // If we didn't have any syntactic errors, then also try getting the global and
        // semantic errors.
        if (allDiagnostics.length === configFileParsingDiagnosticsLength) {
            ts.addRange(allDiagnostics, program.getOptionsDiagnostics(cancellationToken));
            if (!isListFilesOnly) {
                ts.addRange(allDiagnostics, program.getGlobalDiagnostics(cancellationToken));
                if (allDiagnostics.length === configFileParsingDiagnosticsLength) {
                    ts.addRange(allDiagnostics, program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken));
                }
            }
        }
        // Emit and report any errors we ran into.
        var emitResult = isListFilesOnly
            ? { emitSkipped: true, diagnostics: ts.emptyArray }
            : program.emit(/*targetSourceFile*/ undefined, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
        var emittedFiles = emitResult.emittedFiles, emitDiagnostics = emitResult.diagnostics;
        ts.addRange(allDiagnostics, emitDiagnostics);
        var diagnostics = ts.sortAndDeduplicateDiagnostics(allDiagnostics);
        diagnostics.forEach(reportDiagnostic);
        if (writeFileName) {
            var currentDir_1 = program.getCurrentDirectory();
            ts.forEach(emittedFiles, function (file) {
                var filepath = ts.getNormalizedAbsolutePath(file, currentDir_1);
                writeFileName("TSFILE: " + filepath);
            });
            listFiles(program, writeFileName);
        }
        if (reportSummary) {
            reportSummary(getErrorCountForSummary(diagnostics));
        }
        return {
            emitResult: emitResult,
            diagnostics: diagnostics,
        };
    }
    ts.emitFilesAndReportErrors = emitFilesAndReportErrors;
    function emitFilesAndReportErrorsAndGetExitStatus(program, reportDiagnostic, writeFileName, reportSummary, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
        var _a = emitFilesAndReportErrors(program, reportDiagnostic, writeFileName, reportSummary, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers), emitResult = _a.emitResult, diagnostics = _a.diagnostics;
        if (emitResult.emitSkipped && diagnostics.length > 0) {
            // If the emitter didn't emit anything, then pass that value along.
            return ts.ExitStatus.DiagnosticsPresent_OutputsSkipped;
        }
        else if (diagnostics.length > 0) {
            // The emitter emitted something, inform the caller if that happened in the presence
            // of diagnostics or not.
            return ts.ExitStatus.DiagnosticsPresent_OutputsGenerated;
        }
        return ts.ExitStatus.Success;
    }
    ts.emitFilesAndReportErrorsAndGetExitStatus = emitFilesAndReportErrorsAndGetExitStatus;
    ts.noopFileWatcher = { close: ts.noop };
    function createWatchHost(system, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system);
        return {
            onWatchStatusChange: onWatchStatusChange,
            watchFile: ts.maybeBind(system, system.watchFile) || (function () { return ts.noopFileWatcher; }),
            watchDirectory: ts.maybeBind(system, system.watchDirectory) || (function () { return ts.noopFileWatcher; }),
            setTimeout: ts.maybeBind(system, system.setTimeout) || ts.noop,
            clearTimeout: ts.maybeBind(system, system.clearTimeout) || ts.noop
        };
    }
    ts.createWatchHost = createWatchHost;
    ts.WatchType = {
        ConfigFile: "Config file",
        SourceFile: "Source file",
        MissingFile: "Missing file",
        WildcardDirectory: "Wild card directory",
        FailedLookupLocations: "Failed Lookup Locations",
        TypeRoots: "Type roots"
    };
    function createWatchFactory(host, options) {
        var watchLogLevel = host.trace ? options.extendedDiagnostics ? ts.WatchLogLevel.Verbose : options.diagnostics ? ts.WatchLogLevel.TriggerOnly : ts.WatchLogLevel.None : ts.WatchLogLevel.None;
        var writeLog = watchLogLevel !== ts.WatchLogLevel.None ? (function (s) { return host.trace(s); }) : ts.noop;
        var result = ts.getWatchFactory(watchLogLevel, writeLog);
        result.writeLog = writeLog;
        return result;
    }
    ts.createWatchFactory = createWatchFactory;
    function createCompilerHostFromProgramHost(host, getCompilerOptions, directoryStructureHost) {
        if (directoryStructureHost === void 0) { directoryStructureHost = host; }
        var useCaseSensitiveFileNames = host.useCaseSensitiveFileNames();
        var hostGetNewLine = ts.memoize(function () { return host.getNewLine(); });
        return {
            getSourceFile: function (fileName, languageVersion, onError) {
                var text;
                try {
                    ts.performance.mark("beforeIORead");
                    text = host.readFile(fileName, getCompilerOptions().charset);
                    ts.performance.mark("afterIORead");
                    ts.performance.measure("I/O Read", "beforeIORead", "afterIORead");
                }
                catch (e) {
                    if (onError) {
                        onError(e.message);
                    }
                    text = "";
                }
                return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion) : undefined;
            },
            getDefaultLibLocation: ts.maybeBind(host, host.getDefaultLibLocation),
            getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); },
            writeFile: writeFile,
            getCurrentDirectory: ts.memoize(function () { return host.getCurrentDirectory(); }),
            useCaseSensitiveFileNames: function () { return useCaseSensitiveFileNames; },
            getCanonicalFileName: ts.createGetCanonicalFileName(useCaseSensitiveFileNames),
            getNewLine: function () { return ts.getNewLineCharacter(getCompilerOptions(), hostGetNewLine); },
            fileExists: function (f) { return host.fileExists(f); },
            readFile: function (f) { return host.readFile(f); },
            trace: ts.maybeBind(host, host.trace),
            directoryExists: ts.maybeBind(directoryStructureHost, directoryStructureHost.directoryExists),
            getDirectories: ts.maybeBind(directoryStructureHost, directoryStructureHost.getDirectories),
            realpath: ts.maybeBind(host, host.realpath),
            getEnvironmentVariable: ts.maybeBind(host, host.getEnvironmentVariable) || (function () { return ""; }),
            createHash: ts.maybeBind(host, host.createHash),
            readDirectory: ts.maybeBind(host, host.readDirectory),
        };
        function writeFile(fileName, text, writeByteOrderMark, onError) {
            try {
                ts.performance.mark("beforeIOWrite");
                // NOTE: If patchWriteFileEnsuringDirectory has been called,
                // the host.writeFile will do its own directory creation and
                // the ensureDirectoriesExist call will always be redundant.
                ts.writeFileEnsuringDirectories(fileName, text, writeByteOrderMark, function (path, data, writeByteOrderMark) { return host.writeFile(path, data, writeByteOrderMark); }, function (path) { return host.createDirectory(path); }, function (path) { return host.directoryExists(path); });
                ts.performance.mark("afterIOWrite");
                ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
            }
        }
    }
    ts.createCompilerHostFromProgramHost = createCompilerHostFromProgramHost;
    function setGetSourceFileAsHashVersioned(compilerHost, host) {
        var originalGetSourceFile = compilerHost.getSourceFile;
        var computeHash = host.createHash || ts.generateDjb2Hash;
        compilerHost.getSourceFile = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            var result = originalGetSourceFile.call.apply(originalGetSourceFile, __spreadArrays([compilerHost], args));
            if (result) {
                result.version = computeHash.call(host, result.text);
            }
            return result;
        };
    }
    ts.setGetSourceFileAsHashVersioned = setGetSourceFileAsHashVersioned;
    /**
     * Creates the watch compiler host that can be extended with config file or root file names and options host
     */
    function createProgramHost(system, createProgram) {
        var getDefaultLibLocation = ts.memoize(function () { return ts.getDirectoryPath(ts.normalizePath(system.getExecutingFilePath())); });
        return {
            useCaseSensitiveFileNames: function () { return system.useCaseSensitiveFileNames; },
            getNewLine: function () { return system.newLine; },
            getCurrentDirectory: ts.memoize(function () { return system.getCurrentDirectory(); }),
            getDefaultLibLocation: getDefaultLibLocation,
            getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); },
            fileExists: function (path) { return system.fileExists(path); },
            readFile: function (path, encoding) { return system.readFile(path, encoding); },
            directoryExists: function (path) { return system.directoryExists(path); },
            getDirectories: function (path) { return system.getDirectories(path); },
            readDirectory: function (path, extensions, exclude, include, depth) { return system.readDirectory(path, extensions, exclude, include, depth); },
            realpath: ts.maybeBind(system, system.realpath),
            getEnvironmentVariable: ts.maybeBind(system, system.getEnvironmentVariable),
            trace: function (s) { return system.write(s + system.newLine); },
            createDirectory: function (path) { return system.createDirectory(path); },
            writeFile: function (path, data, writeByteOrderMark) { return system.writeFile(path, data, writeByteOrderMark); },
            createHash: ts.maybeBind(system, system.createHash),
            createProgram: createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram
        };
    }
    ts.createProgramHost = createProgramHost;
    /**
     * Creates the watch compiler host that can be extended with config file or root file names and options host
     */
    function createWatchCompilerHost(system, createProgram, reportDiagnostic, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var writeFileName = function (s) { return system.write(s + system.newLine); };
        var result = createProgramHost(system, createProgram);
        ts.copyProperties(result, createWatchHost(system, reportWatchStatus));
        result.afterProgramCreate = function (builderProgram) {
            var compilerOptions = builderProgram.getCompilerOptions();
            var newLine = ts.getNewLineCharacter(compilerOptions, function () { return system.newLine; });
            emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName, function (errorCount) { return result.onWatchStatusChange(ts.createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(errorCount), errorCount), newLine, compilerOptions, errorCount); });
        };
        return result;
    }
    /**
     * Report error and exit
     */
    function reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic) {
        reportDiagnostic(diagnostic);
        system.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped);
    }
    /**
     * Creates the watch compiler host from system for config file in watch mode
     */
    function createWatchCompilerHostOfConfigFile(_a) {
        var configFileName = _a.configFileName, optionsToExtend = _a.optionsToExtend, watchOptionsToExtend = _a.watchOptionsToExtend, extraFileExtensions = _a.extraFileExtensions, system = _a.system, createProgram = _a.createProgram, reportDiagnostic = _a.reportDiagnostic, reportWatchStatus = _a.reportWatchStatus;
        var diagnosticReporter = reportDiagnostic || createDiagnosticReporter(system);
        var host = createWatchCompilerHost(system, createProgram, diagnosticReporter, reportWatchStatus);
        host.onUnRecoverableConfigFileDiagnostic = function (diagnostic) { return reportUnrecoverableDiagnostic(system, diagnosticReporter, diagnostic); };
        host.configFileName = configFileName;
        host.optionsToExtend = optionsToExtend;
        host.watchOptionsToExtend = watchOptionsToExtend;
        host.extraFileExtensions = extraFileExtensions;
        return host;
    }
    ts.createWatchCompilerHostOfConfigFile = createWatchCompilerHostOfConfigFile;
    /**
     * Creates the watch compiler host from system for compiling root files and options in watch mode
     */
    function createWatchCompilerHostOfFilesAndCompilerOptions(_a) {
        var rootFiles = _a.rootFiles, options = _a.options, watchOptions = _a.watchOptions, projectReferences = _a.projectReferences, system = _a.system, createProgram = _a.createProgram, reportDiagnostic = _a.reportDiagnostic, reportWatchStatus = _a.reportWatchStatus;
        var host = createWatchCompilerHost(system, createProgram, reportDiagnostic || createDiagnosticReporter(system), reportWatchStatus);
        host.rootFiles = rootFiles;
        host.options = options;
        host.watchOptions = watchOptions;
        host.projectReferences = projectReferences;
        return host;
    }
    ts.createWatchCompilerHostOfFilesAndCompilerOptions = createWatchCompilerHostOfFilesAndCompilerOptions;
    function performIncrementalCompilation(input) {
        var system = input.system || ts.sys;
        var host = input.host || (input.host = ts.createIncrementalCompilerHost(input.options, system));
        var builderProgram = ts.createIncrementalProgram(input);
        var exitStatus = emitFilesAndReportErrorsAndGetExitStatus(builderProgram, input.reportDiagnostic || createDiagnosticReporter(system), function (s) { return host.trace && host.trace(s); }, input.reportErrorSummary || input.options.pretty ? function (errorCount) { return system.write(getErrorSummaryText(errorCount, system.newLine)); } : undefined);
        if (input.afterProgramEmitAndDiagnostics)
            input.afterProgramEmitAndDiagnostics(builderProgram);
        return exitStatus;
    }
    ts.performIncrementalCompilation = performIncrementalCompilation;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function readBuilderProgram(compilerOptions, host) {
        if (compilerOptions.out || compilerOptions.outFile)
            return undefined;
        var buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(compilerOptions);
        if (!buildInfoPath)
            return undefined;
        var content = host.readFile(buildInfoPath);
        if (!content)
            return undefined;
        var buildInfo = ts.getBuildInfo(content);
        if (buildInfo.version !== ts.version)
            return undefined;
        if (!buildInfo.program)
            return undefined;
        return ts.createBuildProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
    }
    ts.readBuilderProgram = readBuilderProgram;
    function createIncrementalCompilerHost(options, system) {
        if (system === void 0) { system = ts.sys; }
        var host = ts.createCompilerHostWorker(options, /*setParentNodes*/ undefined, system);
        host.createHash = ts.maybeBind(system, system.createHash);
        ts.setGetSourceFileAsHashVersioned(host, system);
        ts.changeCompilerHostLikeToUseCache(host, function (fileName) { return ts.toPath(fileName, host.getCurrentDirectory(), host.getCanonicalFileName); });
        return host;
    }
    ts.createIncrementalCompilerHost = createIncrementalCompilerHost;
    function createIncrementalProgram(_a) {
        var rootNames = _a.rootNames, options = _a.options, configFileParsingDiagnostics = _a.configFileParsingDiagnostics, projectReferences = _a.projectReferences, host = _a.host, createProgram = _a.createProgram;
        host = host || createIncrementalCompilerHost(options);
        createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram;
        var oldProgram = readBuilderProgram(options, host);
        return createProgram(rootNames, options, host, oldProgram, configFileParsingDiagnostics, projectReferences);
    }
    ts.createIncrementalProgram = createIncrementalProgram;
    function createWatchCompilerHost(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus, projectReferencesOrWatchOptionsToExtend, watchOptionsOrExtraFileExtensions) {
        if (ts.isArray(rootFilesOrConfigFileName)) {
            return ts.createWatchCompilerHostOfFilesAndCompilerOptions({
                rootFiles: rootFilesOrConfigFileName,
                options: options,
                watchOptions: watchOptionsOrExtraFileExtensions,
                projectReferences: projectReferencesOrWatchOptionsToExtend,
                system: system,
                createProgram: createProgram,
                reportDiagnostic: reportDiagnostic,
                reportWatchStatus: reportWatchStatus,
            });
        }
        else {
            return ts.createWatchCompilerHostOfConfigFile({
                configFileName: rootFilesOrConfigFileName,
                optionsToExtend: options,
                watchOptionsToExtend: projectReferencesOrWatchOptionsToExtend,
                extraFileExtensions: watchOptionsOrExtraFileExtensions,
                system: system,
                createProgram: createProgram,
                reportDiagnostic: reportDiagnostic,
                reportWatchStatus: reportWatchStatus,
            });
        }
    }
    ts.createWatchCompilerHost = createWatchCompilerHost;
    function createWatchProgram(host) {
        var builderProgram;
        var reloadLevel; // level to indicate if the program needs to be reloaded from config file/just filenames etc
        var missingFilesMap; // Map of file watchers for the missing files
        var watchedWildcardDirectories; // map of watchers for the wild card directories in the config file
        var timerToUpdateProgram; // timer callback to recompile the program
        var sourceFilesCache = ts.createMap(); // Cache that stores the source file and version info
        var missingFilePathsRequestedForRelease; // These paths are held temparirly so that we can remove the entry from source file cache if the file is not tracked by missing files
        var hasChangedCompilerOptions = false; // True if the compiler options have changed between compilations
        var hasChangedAutomaticTypeDirectiveNames = false; // True if the automatic type directives have changed
        var useCaseSensitiveFileNames = host.useCaseSensitiveFileNames();
        var currentDirectory = host.getCurrentDirectory();
        var configFileName = host.configFileName, _a = host.optionsToExtend, optionsToExtendForConfigFile = _a === void 0 ? {} : _a, watchOptionsToExtend = host.watchOptionsToExtend, extraFileExtensions = host.extraFileExtensions, createProgram = host.createProgram;
        var rootFileNames = host.rootFiles, compilerOptions = host.options, watchOptions = host.watchOptions, projectReferences = host.projectReferences;
        var configFileSpecs;
        var configFileParsingDiagnostics;
        var canConfigFileJsonReportNoInputFiles = false;
        var hasChangedConfigFileParsingErrors = false;
        var cachedDirectoryStructureHost = configFileName === undefined ? undefined : ts.createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames);
        var directoryStructureHost = cachedDirectoryStructureHost || host;
        var parseConfigFileHost = ts.parseConfigHostFromCompilerHostLike(host, directoryStructureHost);
        // From tsc we want to get already parsed result and hence check for rootFileNames
        var newLine = updateNewLine();
        if (configFileName && host.configFileParsingResult) {
            setConfigFileParsingResult(host.configFileParsingResult);
            newLine = updateNewLine();
        }
        reportWatchDiagnostic(ts.Diagnostics.Starting_compilation_in_watch_mode);
        if (configFileName && !host.configFileParsingResult) {
            newLine = ts.getNewLineCharacter(optionsToExtendForConfigFile, function () { return host.getNewLine(); });
            ts.Debug.assert(!rootFileNames);
            parseConfigFile();
            newLine = updateNewLine();
        }
        var _b = ts.createWatchFactory(host, compilerOptions), watchFile = _b.watchFile, watchFilePath = _b.watchFilePath, watchDirectory = _b.watchDirectory, writeLog = _b.writeLog;
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        writeLog("Current directory: " + currentDirectory + " CaseSensitiveFileNames: " + useCaseSensitiveFileNames);
        var configFileWatcher;
        if (configFileName) {
            configFileWatcher = watchFile(host, configFileName, scheduleProgramReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
        }
        var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
        ts.setGetSourceFileAsHashVersioned(compilerHost, host);
        // Members for CompilerHost
        var getNewSourceFile = compilerHost.getSourceFile;
        compilerHost.getSourceFile = function (fileName) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            return getVersionedSourceFileByPath.apply(void 0, __spreadArrays([fileName, toPath(fileName)], args));
        };
        compilerHost.getSourceFileByPath = getVersionedSourceFileByPath;
        compilerHost.getNewLine = function () { return newLine; };
        compilerHost.fileExists = fileExists;
        compilerHost.onReleaseOldSourceFile = onReleaseOldSourceFile;
        // Members for ResolutionCacheHost
        compilerHost.toPath = toPath;
        compilerHost.getCompilationSettings = function () { return compilerOptions; };
        compilerHost.useSourceOfProjectReferenceRedirect = ts.maybeBind(host, host.useSourceOfProjectReferenceRedirect);
        compilerHost.watchDirectoryOfFailedLookupLocation = function (dir, cb, flags) { return watchDirectory(host, dir, cb, flags, watchOptions, ts.WatchType.FailedLookupLocations); };
        compilerHost.watchTypeRootsDirectory = function (dir, cb, flags) { return watchDirectory(host, dir, cb, flags, watchOptions, ts.WatchType.TypeRoots); };
        compilerHost.getCachedDirectoryStructureHost = function () { return cachedDirectoryStructureHost; };
        compilerHost.onInvalidatedResolution = scheduleProgramUpdate;
        compilerHost.onChangedAutomaticTypeDirectiveNames = function () {
            hasChangedAutomaticTypeDirectiveNames = true;
            scheduleProgramUpdate();
        };
        compilerHost.fileIsOpen = ts.returnFalse;
        compilerHost.getCurrentProgram = getCurrentProgram;
        compilerHost.writeLog = writeLog;
        // Cache for the module resolution
        var resolutionCache = ts.createResolutionCache(compilerHost, configFileName ?
            ts.getDirectoryPath(ts.getNormalizedAbsolutePath(configFileName, currentDirectory)) :
            currentDirectory, 
        /*logChangesWhenResolvingModule*/ false);
        // Resolve module using host module resolution strategy if provided otherwise use resolution cache to resolve module names
        compilerHost.resolveModuleNames = host.resolveModuleNames ?
            (function () {
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                return host.resolveModuleNames.apply(host, args);
            }) :
            (function (moduleNames, containingFile, reusedNames, redirectedReference) { return resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference); });
        compilerHost.resolveTypeReferenceDirectives = host.resolveTypeReferenceDirectives ?
            (function () {
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                return host.resolveTypeReferenceDirectives.apply(host, args);
            }) :
            (function (typeDirectiveNames, containingFile, redirectedReference) { return resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference); });
        var userProvidedResolution = !!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
        builderProgram = readBuilderProgram(compilerOptions, compilerHost);
        synchronizeProgram();
        // Update the wild card directory watch
        watchConfigFileWildCardDirectories();
        return configFileName ?
            { getCurrentProgram: getCurrentBuilderProgram, getProgram: updateProgram, close: close } :
            { getCurrentProgram: getCurrentBuilderProgram, getProgram: updateProgram, updateRootFileNames: updateRootFileNames, close: close };
        function close() {
            resolutionCache.clear();
            ts.clearMap(sourceFilesCache, function (value) {
                if (value && value.fileWatcher) {
                    value.fileWatcher.close();
                    value.fileWatcher = undefined;
                }
            });
            if (configFileWatcher) {
                configFileWatcher.close();
                configFileWatcher = undefined;
            }
            if (watchedWildcardDirectories) {
                ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcherOf);
                watchedWildcardDirectories = undefined;
            }
            if (missingFilesMap) {
                ts.clearMap(missingFilesMap, ts.closeFileWatcher);
                missingFilesMap = undefined;
            }
        }
        function getCurrentBuilderProgram() {
            return builderProgram;
        }
        function getCurrentProgram() {
            return builderProgram && builderProgram.getProgramOrUndefined();
        }
        function synchronizeProgram() {
            writeLog("Synchronizing program");
            var program = getCurrentBuilderProgram();
            if (hasChangedCompilerOptions) {
                newLine = updateNewLine();
                if (program && ts.changesAffectModuleResolution(program.getCompilerOptions(), compilerOptions)) {
                    resolutionCache.clear();
                }
            }
            // All resolutions are invalid if user provided resolutions
            var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution);
            if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, projectReferences)) {
                if (hasChangedConfigFileParsingErrors) {
                    builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
                    hasChangedConfigFileParsingErrors = false;
                }
            }
            else {
                createNewProgram(hasInvalidatedResolution);
            }
            if (host.afterProgramCreate && program !== builderProgram) {
                host.afterProgramCreate(builderProgram);
            }
            return builderProgram;
        }
        function createNewProgram(hasInvalidatedResolution) {
            // Compile the program
            writeLog("CreatingProgramWith::");
            writeLog("  roots: " + JSON.stringify(rootFileNames));
            writeLog("  options: " + JSON.stringify(compilerOptions));
            var needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !getCurrentProgram();
            hasChangedCompilerOptions = false;
            hasChangedConfigFileParsingErrors = false;
            resolutionCache.startCachingPerDirectoryResolution();
            compilerHost.hasInvalidatedResolution = hasInvalidatedResolution;
            compilerHost.hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames;
            hasChangedAutomaticTypeDirectiveNames = false;
            builderProgram = createProgram(rootFileNames, compilerOptions, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
            resolutionCache.finishCachingPerDirectoryResolution();
            // Update watches
            ts.updateMissingFilePathsWatch(builderProgram.getProgram(), missingFilesMap || (missingFilesMap = ts.createMap()), watchMissingFilePath);
            if (needsUpdateInTypeRootWatch) {
                resolutionCache.updateTypeRootsWatch();
            }
            if (missingFilePathsRequestedForRelease) {
                // These are the paths that program creater told us as not in use any more but were missing on the disk.
                // We didnt remove the entry for them from sourceFiles cache so that we dont have to do File IO,
                // if there is already watcher for it (for missing files)
                // At this point our watches were updated, hence now we know that these paths are not tracked and need to be removed
                // so that at later time we have correct result of their presence
                for (var _i = 0, missingFilePathsRequestedForRelease_1 = missingFilePathsRequestedForRelease; _i < missingFilePathsRequestedForRelease_1.length; _i++) {
                    var missingFilePath = missingFilePathsRequestedForRelease_1[_i];
                    if (!missingFilesMap.has(missingFilePath)) {
                        sourceFilesCache.delete(missingFilePath);
                    }
                }
                missingFilePathsRequestedForRelease = undefined;
            }
        }
        function updateRootFileNames(files) {
            ts.Debug.assert(!configFileName, "Cannot update root file names with config file watch mode");
            rootFileNames = files;
            scheduleProgramUpdate();
        }
        function updateNewLine() {
            return ts.getNewLineCharacter(compilerOptions || optionsToExtendForConfigFile, function () { return host.getNewLine(); });
        }
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function isFileMissingOnHost(hostSourceFile) {
            return typeof hostSourceFile === "boolean";
        }
        function isFilePresenceUnknownOnHost(hostSourceFile) {
            return typeof hostSourceFile.version === "boolean";
        }
        function fileExists(fileName) {
            var path = toPath(fileName);
            // If file is missing on host from cache, we can definitely say file doesnt exist
            // otherwise we need to ensure from the disk
            if (isFileMissingOnHost(sourceFilesCache.get(path))) {
                return false;
            }
            return directoryStructureHost.fileExists(fileName);
        }
        function getVersionedSourceFileByPath(fileName, path, languageVersion, onError, shouldCreateNewSourceFile) {
            var hostSourceFile = sourceFilesCache.get(path);
            // No source file on the host
            if (isFileMissingOnHost(hostSourceFile)) {
                return undefined;
            }
            // Create new source file if requested or the versions dont match
            if (hostSourceFile === undefined || shouldCreateNewSourceFile || isFilePresenceUnknownOnHost(hostSourceFile)) {
                var sourceFile = getNewSourceFile(fileName, languageVersion, onError);
                if (hostSourceFile) {
                    if (sourceFile) {
                        // Set the source file and create file watcher now that file was present on the disk
                        hostSourceFile.sourceFile = sourceFile;
                        hostSourceFile.version = sourceFile.version;
                        if (!hostSourceFile.fileWatcher) {
                            hostSourceFile.fileWatcher = watchFilePath(host, fileName, onSourceFileChange, ts.PollingInterval.Low, watchOptions, path, ts.WatchType.SourceFile);
                        }
                    }
                    else {
                        // There is no source file on host any more, close the watch, missing file paths will track it
                        if (hostSourceFile.fileWatcher) {
                            hostSourceFile.fileWatcher.close();
                        }
                        sourceFilesCache.set(path, false);
                    }
                }
                else {
                    if (sourceFile) {
                        var fileWatcher = watchFilePath(host, fileName, onSourceFileChange, ts.PollingInterval.Low, watchOptions, path, ts.WatchType.SourceFile);
                        sourceFilesCache.set(path, { sourceFile: sourceFile, version: sourceFile.version, fileWatcher: fileWatcher });
                    }
                    else {
                        sourceFilesCache.set(path, false);
                    }
                }
                return sourceFile;
            }
            return hostSourceFile.sourceFile;
        }
        function nextSourceFileVersion(path) {
            var hostSourceFile = sourceFilesCache.get(path);
            if (hostSourceFile !== undefined) {
                if (isFileMissingOnHost(hostSourceFile)) {
                    // The next version, lets set it as presence unknown file
                    sourceFilesCache.set(path, { version: false });
                }
                else {
                    hostSourceFile.version = false;
                }
            }
        }
        function getSourceVersion(path) {
            var hostSourceFile = sourceFilesCache.get(path);
            return !hostSourceFile || !hostSourceFile.version ? undefined : hostSourceFile.version;
        }
        function onReleaseOldSourceFile(oldSourceFile, _oldOptions, hasSourceFileByPath) {
            var hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.resolvedPath);
            // If this is the source file thats in the cache and new program doesnt need it,
            // remove the cached entry.
            // Note we arent deleting entry if file became missing in new program or
            // there was version update and new source file was created.
            if (hostSourceFileInfo !== undefined) {
                // record the missing file paths so they can be removed later if watchers arent tracking them
                if (isFileMissingOnHost(hostSourceFileInfo)) {
                    (missingFilePathsRequestedForRelease || (missingFilePathsRequestedForRelease = [])).push(oldSourceFile.path);
                }
                else if (hostSourceFileInfo.sourceFile === oldSourceFile) {
                    if (hostSourceFileInfo.fileWatcher) {
                        hostSourceFileInfo.fileWatcher.close();
                    }
                    sourceFilesCache.delete(oldSourceFile.resolvedPath);
                    if (!hasSourceFileByPath) {
                        resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
                    }
                }
            }
        }
        function reportWatchDiagnostic(message) {
            if (host.onWatchStatusChange) {
                host.onWatchStatusChange(ts.createCompilerDiagnostic(message), newLine, compilerOptions || optionsToExtendForConfigFile);
            }
        }
        // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch
        // operations (such as saving all modified files in an editor) a chance to complete before we kick
        // off a new compilation.
        function scheduleProgramUpdate() {
            if (!host.setTimeout || !host.clearTimeout) {
                return;
            }
            if (timerToUpdateProgram) {
                host.clearTimeout(timerToUpdateProgram);
            }
            writeLog("Scheduling update");
            timerToUpdateProgram = host.setTimeout(updateProgramWithWatchStatus, 250);
        }
        function scheduleProgramReload() {
            ts.Debug.assert(!!configFileName);
            reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
            scheduleProgramUpdate();
        }
        function updateProgramWithWatchStatus() {
            timerToUpdateProgram = undefined;
            reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
            updateProgram();
        }
        function updateProgram() {
            switch (reloadLevel) {
                case ts.ConfigFileProgramReloadLevel.Partial:
                    ts.perfLogger.logStartUpdateProgram("PartialConfigReload");
                    reloadFileNamesFromConfigFile();
                    break;
                case ts.ConfigFileProgramReloadLevel.Full:
                    ts.perfLogger.logStartUpdateProgram("FullConfigReload");
                    reloadConfigFile();
                    break;
                default:
                    ts.perfLogger.logStartUpdateProgram("SynchronizeProgram");
                    synchronizeProgram();
                    break;
            }
            ts.perfLogger.logStopUpdateProgram("Done");
            return getCurrentBuilderProgram();
        }
        function reloadFileNamesFromConfigFile() {
            writeLog("Reloading new file names and options");
            var result = ts.getFileNamesFromConfigSpecs(configFileSpecs, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), currentDirectory), compilerOptions, parseConfigFileHost);
            if (ts.updateErrorForNoInputFiles(result, ts.getNormalizedAbsolutePath(configFileName, currentDirectory), configFileSpecs, configFileParsingDiagnostics, canConfigFileJsonReportNoInputFiles)) {
                hasChangedConfigFileParsingErrors = true;
            }
            rootFileNames = result.fileNames;
            // Update the program
            synchronizeProgram();
        }
        function reloadConfigFile() {
            writeLog("Reloading config file: " + configFileName);
            reloadLevel = ts.ConfigFileProgramReloadLevel.None;
            if (cachedDirectoryStructureHost) {
                cachedDirectoryStructureHost.clearCache();
            }
            parseConfigFile();
            hasChangedCompilerOptions = true;
            synchronizeProgram();
            // Update the wild card directory watch
            watchConfigFileWildCardDirectories();
        }
        function parseConfigFile() {
            setConfigFileParsingResult(ts.getParsedCommandLineOfConfigFile(configFileName, optionsToExtendForConfigFile, parseConfigFileHost, /*extendedConfigCache*/ undefined, watchOptionsToExtend, extraFileExtensions)); // TODO: GH#18217
        }
        function setConfigFileParsingResult(configFileParseResult) {
            rootFileNames = configFileParseResult.fileNames;
            compilerOptions = configFileParseResult.options;
            watchOptions = configFileParseResult.watchOptions;
            configFileSpecs = configFileParseResult.configFileSpecs; // TODO: GH#18217
            projectReferences = configFileParseResult.projectReferences;
            configFileParsingDiagnostics = ts.getConfigFileParsingDiagnostics(configFileParseResult).slice();
            canConfigFileJsonReportNoInputFiles = ts.canJsonReportNoInutFiles(configFileParseResult.raw);
            hasChangedConfigFileParsingErrors = true;
        }
        function onSourceFileChange(fileName, eventKind, path) {
            updateCachedSystemWithFile(fileName, path, eventKind);
            // Update the source file cache
            if (eventKind === ts.FileWatcherEventKind.Deleted && sourceFilesCache.has(path)) {
                resolutionCache.invalidateResolutionOfFile(path);
            }
            resolutionCache.removeResolutionsFromProjectReferenceRedirects(path);
            nextSourceFileVersion(path);
            // Update the program
            scheduleProgramUpdate();
        }
        function updateCachedSystemWithFile(fileName, path, eventKind) {
            if (cachedDirectoryStructureHost) {
                cachedDirectoryStructureHost.addOrDeleteFile(fileName, path, eventKind);
            }
        }
        function watchMissingFilePath(missingFilePath) {
            return watchFilePath(host, missingFilePath, onMissingFileChange, ts.PollingInterval.Medium, watchOptions, missingFilePath, ts.WatchType.MissingFile);
        }
        function onMissingFileChange(fileName, eventKind, missingFilePath) {
            updateCachedSystemWithFile(fileName, missingFilePath, eventKind);
            if (eventKind === ts.FileWatcherEventKind.Created && missingFilesMap.has(missingFilePath)) {
                missingFilesMap.get(missingFilePath).close();
                missingFilesMap.delete(missingFilePath);
                // Delete the entry in the source files cache so that new source file is created
                nextSourceFileVersion(missingFilePath);
                // When a missing file is created, we should update the graph.
                scheduleProgramUpdate();
            }
        }
        function watchConfigFileWildCardDirectories() {
            if (configFileSpecs) {
                ts.updateWatchingWildcardDirectories(watchedWildcardDirectories || (watchedWildcardDirectories = ts.createMap()), ts.createMapFromTemplate(configFileSpecs.wildcardDirectories), watchWildcardDirectory);
            }
            else if (watchedWildcardDirectories) {
                ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcherOf);
            }
        }
        function watchWildcardDirectory(directory, flags) {
            return watchDirectory(host, directory, function (fileOrDirectory) {
                ts.Debug.assert(!!configFileName);
                var fileOrDirectoryPath = toPath(fileOrDirectory);
                // Since the file existence changed, update the sourceFiles cache
                if (cachedDirectoryStructureHost) {
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                nextSourceFileVersion(fileOrDirectoryPath);
                fileOrDirectoryPath = ts.removeIgnoredPath(fileOrDirectoryPath);
                if (!fileOrDirectoryPath)
                    return;
                // If the the added or created file or directory is not supported file name, ignore the file
                // But when watched directory is added/removed, we need to reload the file list
                if (fileOrDirectoryPath !== directory && ts.hasExtension(fileOrDirectoryPath) && !ts.isSupportedSourceFileName(fileOrDirectory, compilerOptions)) {
                    writeLog("Project: " + configFileName + " Detected file add/remove of non supported extension: " + fileOrDirectory);
                    return;
                }
                // Reload is pending, do the reload
                if (reloadLevel !== ts.ConfigFileProgramReloadLevel.Full) {
                    reloadLevel = ts.ConfigFileProgramReloadLevel.Partial;
                    // Schedule Update the program
                    scheduleProgramUpdate();
                }
            }, flags, watchOptions, ts.WatchType.WildcardDirectory);
        }
    }
    ts.createWatchProgram = createWatchProgram;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var UpToDateStatusType;
    (function (UpToDateStatusType) {
        UpToDateStatusType[UpToDateStatusType["Unbuildable"] = 0] = "Unbuildable";
        UpToDateStatusType[UpToDateStatusType["UpToDate"] = 1] = "UpToDate";
        /**
         * The project appears out of date because its upstream inputs are newer than its outputs,
         * but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
         * This means we can Pseudo-build (just touch timestamps), as if we had actually built this project.
         */
        UpToDateStatusType[UpToDateStatusType["UpToDateWithUpstreamTypes"] = 2] = "UpToDateWithUpstreamTypes";
        /**
         * The project appears out of date because its upstream inputs are newer than its outputs,
         * but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
         * This means we can Pseudo-build (just manipulate outputs), as if we had actually built this project.
         */
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithPrepend"] = 3] = "OutOfDateWithPrepend";
        UpToDateStatusType[UpToDateStatusType["OutputMissing"] = 4] = "OutputMissing";
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithSelf"] = 5] = "OutOfDateWithSelf";
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithUpstream"] = 6] = "OutOfDateWithUpstream";
        UpToDateStatusType[UpToDateStatusType["UpstreamOutOfDate"] = 7] = "UpstreamOutOfDate";
        UpToDateStatusType[UpToDateStatusType["UpstreamBlocked"] = 8] = "UpstreamBlocked";
        UpToDateStatusType[UpToDateStatusType["ComputingUpstream"] = 9] = "ComputingUpstream";
        UpToDateStatusType[UpToDateStatusType["TsVersionOutputOfDate"] = 10] = "TsVersionOutputOfDate";
        /**
         * Projects with no outputs (i.e. "solution" files)
         */
        UpToDateStatusType[UpToDateStatusType["ContainerOnly"] = 11] = "ContainerOnly";
    })(UpToDateStatusType = ts.UpToDateStatusType || (ts.UpToDateStatusType = {}));
    function resolveConfigFileProjectName(project) {
        if (ts.fileExtensionIs(project, ".json" /* Json */)) {
            return project;
        }
        return ts.combinePaths(project, "tsconfig.json");
    }
    ts.resolveConfigFileProjectName = resolveConfigFileProjectName;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var minimumDate = new Date(-8640000000000000);
    var maximumDate = new Date(8640000000000000);
    var BuildResultFlags;
    (function (BuildResultFlags) {
        BuildResultFlags[BuildResultFlags["None"] = 0] = "None";
        /**
         * No errors of any kind occurred during build
         */
        BuildResultFlags[BuildResultFlags["Success"] = 1] = "Success";
        /**
         * None of the .d.ts files emitted by this build were
         * different from the existing files on disk
         */
        BuildResultFlags[BuildResultFlags["DeclarationOutputUnchanged"] = 2] = "DeclarationOutputUnchanged";
        BuildResultFlags[BuildResultFlags["ConfigFileErrors"] = 4] = "ConfigFileErrors";
        BuildResultFlags[BuildResultFlags["SyntaxErrors"] = 8] = "SyntaxErrors";
        BuildResultFlags[BuildResultFlags["TypeErrors"] = 16] = "TypeErrors";
        BuildResultFlags[BuildResultFlags["DeclarationEmitErrors"] = 32] = "DeclarationEmitErrors";
        BuildResultFlags[BuildResultFlags["EmitErrors"] = 64] = "EmitErrors";
        BuildResultFlags[BuildResultFlags["AnyErrors"] = 124] = "AnyErrors";
    })(BuildResultFlags || (BuildResultFlags = {}));
    function createConfigFileMap() {
        return ts.createMap();
    }
    function getOrCreateValueFromConfigFileMap(configFileMap, resolved, createT) {
        var existingValue = configFileMap.get(resolved);
        var newValue;
        if (!existingValue) {
            newValue = createT();
            configFileMap.set(resolved, newValue);
        }
        return existingValue || newValue;
    }
    function getOrCreateValueMapFromConfigFileMap(configFileMap, resolved) {
        return getOrCreateValueFromConfigFileMap(configFileMap, resolved, ts.createMap);
    }
    function newer(date1, date2) {
        return date2 > date1 ? date2 : date1;
    }
    function isDeclarationFile(fileName) {
        return ts.fileExtensionIs(fileName, ".d.ts" /* Dts */);
    }
    /*@internal*/
    function isCircularBuildOrder(buildOrder) {
        return !!buildOrder && !!buildOrder.buildOrder;
    }
    ts.isCircularBuildOrder = isCircularBuildOrder;
    /*@internal*/
    function getBuildOrderFromAnyBuildOrder(anyBuildOrder) {
        return isCircularBuildOrder(anyBuildOrder) ? anyBuildOrder.buildOrder : anyBuildOrder;
    }
    ts.getBuildOrderFromAnyBuildOrder = getBuildOrderFromAnyBuildOrder;
    /**
     * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
     */
    function createBuilderStatusReporter(system, pretty) {
        return function (diagnostic) {
            var output = pretty ? "[" + ts.formatColorAndReset(ts.getLocaleTimeString(system), ts.ForegroundColorEscapeSequences.Grey) + "] " : ts.getLocaleTimeString(system) + " - ";
            output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + (system.newLine + system.newLine);
            system.write(output);
        };
    }
    ts.createBuilderStatusReporter = createBuilderStatusReporter;
    function createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus) {
        var host = ts.createProgramHost(system, createProgram);
        host.getModifiedTime = system.getModifiedTime ? function (path) { return system.getModifiedTime(path); } : ts.returnUndefined;
        host.setModifiedTime = system.setModifiedTime ? function (path, date) { return system.setModifiedTime(path, date); } : ts.noop;
        host.deleteFile = system.deleteFile ? function (path) { return system.deleteFile(path); } : ts.noop;
        host.reportDiagnostic = reportDiagnostic || ts.createDiagnosticReporter(system);
        host.reportSolutionBuilderStatus = reportSolutionBuilderStatus || createBuilderStatusReporter(system);
        host.now = ts.maybeBind(system, system.now); // For testing
        return host;
    }
    function createSolutionBuilderHost(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus, reportErrorSummary) {
        if (system === void 0) { system = ts.sys; }
        var host = createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus);
        host.reportErrorSummary = reportErrorSummary;
        return host;
    }
    ts.createSolutionBuilderHost = createSolutionBuilderHost;
    function createSolutionBuilderWithWatchHost(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var host = createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus);
        var watchHost = ts.createWatchHost(system, reportWatchStatus);
        ts.copyProperties(host, watchHost);
        return host;
    }
    ts.createSolutionBuilderWithWatchHost = createSolutionBuilderWithWatchHost;
    function getCompilerOptionsOfBuildOptions(buildOptions) {
        var result = {};
        ts.commonOptionsWithBuild.forEach(function (option) {
            if (ts.hasProperty(buildOptions, option.name))
                result[option.name] = buildOptions[option.name];
        });
        return result;
    }
    function createSolutionBuilder(host, rootNames, defaultOptions) {
        return createSolutionBuilderWorker(/*watch*/ false, host, rootNames, defaultOptions);
    }
    ts.createSolutionBuilder = createSolutionBuilder;
    function createSolutionBuilderWithWatch(host, rootNames, defaultOptions, baseWatchOptions) {
        return createSolutionBuilderWorker(/*watch*/ true, host, rootNames, defaultOptions, baseWatchOptions);
    }
    ts.createSolutionBuilderWithWatch = createSolutionBuilderWithWatch;
    function createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions) {
        var host = hostOrHostWithWatch;
        var hostWithWatch = hostOrHostWithWatch;
        var currentDirectory = host.getCurrentDirectory();
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        // State of the solution
        var baseCompilerOptions = getCompilerOptionsOfBuildOptions(options);
        var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return state.projectCompilerOptions; });
        ts.setGetSourceFileAsHashVersioned(compilerHost, host);
        compilerHost.getParsedCommandLine = function (fileName) { return parseConfigFile(state, fileName, toResolvedConfigFilePath(state, fileName)); };
        compilerHost.resolveModuleNames = ts.maybeBind(host, host.resolveModuleNames);
        compilerHost.resolveTypeReferenceDirectives = ts.maybeBind(host, host.resolveTypeReferenceDirectives);
        var moduleResolutionCache = !compilerHost.resolveModuleNames ? ts.createModuleResolutionCache(currentDirectory, getCanonicalFileName) : undefined;
        if (!compilerHost.resolveModuleNames) {
            var loader_3 = function (moduleName, containingFile, redirectedReference) { return ts.resolveModuleName(moduleName, containingFile, state.projectCompilerOptions, compilerHost, moduleResolutionCache, redirectedReference).resolvedModule; };
            compilerHost.resolveModuleNames = function (moduleNames, containingFile, _reusedNames, redirectedReference) {
                return ts.loadWithLocalCache(ts.Debug.checkEachDefined(moduleNames), containingFile, redirectedReference, loader_3);
            };
        }
        var _a = ts.createWatchFactory(hostWithWatch, options), watchFile = _a.watchFile, watchFilePath = _a.watchFilePath, watchDirectory = _a.watchDirectory, writeLog = _a.writeLog;
        var state = {
            host: host,
            hostWithWatch: hostWithWatch,
            currentDirectory: currentDirectory,
            getCanonicalFileName: getCanonicalFileName,
            parseConfigFileHost: ts.parseConfigHostFromCompilerHostLike(host),
            writeFileName: host.trace ? function (s) { return host.trace(s); } : undefined,
            // State of solution
            options: options,
            baseCompilerOptions: baseCompilerOptions,
            rootNames: rootNames,
            baseWatchOptions: baseWatchOptions,
            resolvedConfigFilePaths: ts.createMap(),
            configFileCache: createConfigFileMap(),
            projectStatus: createConfigFileMap(),
            buildInfoChecked: createConfigFileMap(),
            extendedConfigCache: ts.createMap(),
            builderPrograms: createConfigFileMap(),
            diagnostics: createConfigFileMap(),
            projectPendingBuild: createConfigFileMap(),
            projectErrorsReported: createConfigFileMap(),
            compilerHost: compilerHost,
            moduleResolutionCache: moduleResolutionCache,
            // Mutable state
            buildOrder: undefined,
            readFileWithCache: function (f) { return host.readFile(f); },
            projectCompilerOptions: baseCompilerOptions,
            cache: undefined,
            allProjectBuildPending: true,
            needsSummary: true,
            watchAllProjectsPending: watch,
            currentInvalidatedProject: undefined,
            // Watch state
            watch: watch,
            allWatchedWildcardDirectories: createConfigFileMap(),
            allWatchedInputFiles: createConfigFileMap(),
            allWatchedConfigFiles: createConfigFileMap(),
            timerToBuildInvalidatedProject: undefined,
            reportFileChangeDetected: false,
            watchFile: watchFile,
            watchFilePath: watchFilePath,
            watchDirectory: watchDirectory,
            writeLog: writeLog,
        };
        return state;
    }
    function toPath(state, fileName) {
        return ts.toPath(fileName, state.currentDirectory, state.getCanonicalFileName);
    }
    function toResolvedConfigFilePath(state, fileName) {
        var resolvedConfigFilePaths = state.resolvedConfigFilePaths;
        var path = resolvedConfigFilePaths.get(fileName);
        if (path !== undefined)
            return path;
        var resolvedPath = toPath(state, fileName);
        resolvedConfigFilePaths.set(fileName, resolvedPath);
        return resolvedPath;
    }
    function isParsedCommandLine(entry) {
        return !!entry.options;
    }
    function parseConfigFile(state, configFileName, configFilePath) {
        var configFileCache = state.configFileCache;
        var value = configFileCache.get(configFilePath);
        if (value) {
            return isParsedCommandLine(value) ? value : undefined;
        }
        var diagnostic;
        var parseConfigFileHost = state.parseConfigFileHost, baseCompilerOptions = state.baseCompilerOptions, baseWatchOptions = state.baseWatchOptions, extendedConfigCache = state.extendedConfigCache, host = state.host;
        var parsed;
        if (host.getParsedCommandLine) {
            parsed = host.getParsedCommandLine(configFileName);
            if (!parsed)
                diagnostic = ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, configFileName);
        }
        else {
            parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = function (d) { return diagnostic = d; };
            parsed = ts.getParsedCommandLineOfConfigFile(configFileName, baseCompilerOptions, parseConfigFileHost, extendedConfigCache, baseWatchOptions);
            parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = ts.noop;
        }
        configFileCache.set(configFilePath, parsed || diagnostic);
        return parsed;
    }
    function resolveProjectName(state, name) {
        return ts.resolveConfigFileProjectName(ts.resolvePath(state.currentDirectory, name));
    }
    function createBuildOrder(state, roots) {
        var temporaryMarks = ts.createMap();
        var permanentMarks = ts.createMap();
        var circularityReportStack = [];
        var buildOrder;
        var circularDiagnostics;
        for (var _i = 0, roots_1 = roots; _i < roots_1.length; _i++) {
            var root = roots_1[_i];
            visit(root);
        }
        return circularDiagnostics ?
            { buildOrder: buildOrder || ts.emptyArray, circularDiagnostics: circularDiagnostics } :
            buildOrder || ts.emptyArray;
        function visit(configFileName, inCircularContext) {
            var projPath = toResolvedConfigFilePath(state, configFileName);
            // Already visited
            if (permanentMarks.has(projPath))
                return;
            // Circular
            if (temporaryMarks.has(projPath)) {
                if (!inCircularContext) {
                    (circularDiagnostics || (circularDiagnostics = [])).push(ts.createCompilerDiagnostic(ts.Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0, circularityReportStack.join("\r\n")));
                }
                return;
            }
            temporaryMarks.set(projPath, true);
            circularityReportStack.push(configFileName);
            var parsed = parseConfigFile(state, configFileName, projPath);
            if (parsed && parsed.projectReferences) {
                for (var _i = 0, _a = parsed.projectReferences; _i < _a.length; _i++) {
                    var ref = _a[_i];
                    var resolvedRefPath = resolveProjectName(state, ref.path);
                    visit(resolvedRefPath, inCircularContext || ref.circular);
                }
            }
            circularityReportStack.pop();
            permanentMarks.set(projPath, true);
            (buildOrder || (buildOrder = [])).push(configFileName);
        }
    }
    function getBuildOrder(state) {
        return state.buildOrder || createStateBuildOrder(state);
    }
    function createStateBuildOrder(state) {
        var buildOrder = createBuildOrder(state, state.rootNames.map(function (f) { return resolveProjectName(state, f); }));
        // Clear all to ResolvedConfigFilePaths cache to start fresh
        state.resolvedConfigFilePaths.clear();
        var currentProjects = ts.arrayToSet(getBuildOrderFromAnyBuildOrder(buildOrder), function (resolved) { return toResolvedConfigFilePath(state, resolved); });
        var noopOnDelete = { onDeleteValue: ts.noop };
        // Config file cache
        ts.mutateMapSkippingNewValues(state.configFileCache, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.projectStatus, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.buildInfoChecked, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.builderPrograms, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.diagnostics, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.projectPendingBuild, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.projectErrorsReported, currentProjects, noopOnDelete);
        // Remove watches for the program no longer in the solution
        if (state.watch) {
            ts.mutateMapSkippingNewValues(state.allWatchedConfigFiles, currentProjects, { onDeleteValue: ts.closeFileWatcher });
            ts.mutateMapSkippingNewValues(state.allWatchedWildcardDirectories, currentProjects, { onDeleteValue: function (existingMap) { return existingMap.forEach(ts.closeFileWatcherOf); } });
            ts.mutateMapSkippingNewValues(state.allWatchedInputFiles, currentProjects, { onDeleteValue: function (existingMap) { return existingMap.forEach(ts.closeFileWatcher); } });
        }
        return state.buildOrder = buildOrder;
    }
    function getBuildOrderFor(state, project, onlyReferences) {
        var resolvedProject = project && resolveProjectName(state, project);
        var buildOrderFromState = getBuildOrder(state);
        if (isCircularBuildOrder(buildOrderFromState))
            return buildOrderFromState;
        if (resolvedProject) {
            var projectPath_1 = toResolvedConfigFilePath(state, resolvedProject);
            var projectIndex = ts.findIndex(buildOrderFromState, function (configFileName) { return toResolvedConfigFilePath(state, configFileName) === projectPath_1; });
            if (projectIndex === -1)
                return undefined;
        }
        var buildOrder = resolvedProject ? createBuildOrder(state, [resolvedProject]) : buildOrderFromState;
        ts.Debug.assert(!isCircularBuildOrder(buildOrder));
        ts.Debug.assert(!onlyReferences || resolvedProject !== undefined);
        ts.Debug.assert(!onlyReferences || buildOrder[buildOrder.length - 1] === resolvedProject);
        return onlyReferences ? buildOrder.slice(0, buildOrder.length - 1) : buildOrder;
    }
    function enableCache(state) {
        if (state.cache) {
            disableCache(state);
        }
        var compilerHost = state.compilerHost, host = state.host;
        var originalReadFileWithCache = state.readFileWithCache;
        var originalGetSourceFile = compilerHost.getSourceFile;
        var _a = ts.changeCompilerHostLikeToUseCache(host, function (fileName) { return toPath(state, fileName); }, function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            return originalGetSourceFile.call.apply(originalGetSourceFile, __spreadArrays([compilerHost], args));
        }), originalReadFile = _a.originalReadFile, originalFileExists = _a.originalFileExists, originalDirectoryExists = _a.originalDirectoryExists, originalCreateDirectory = _a.originalCreateDirectory, originalWriteFile = _a.originalWriteFile, getSourceFileWithCache = _a.getSourceFileWithCache, readFileWithCache = _a.readFileWithCache;
        state.readFileWithCache = readFileWithCache;
        compilerHost.getSourceFile = getSourceFileWithCache;
        state.cache = {
            originalReadFile: originalReadFile,
            originalFileExists: originalFileExists,
            originalDirectoryExists: originalDirectoryExists,
            originalCreateDirectory: originalCreateDirectory,
            originalWriteFile: originalWriteFile,
            originalReadFileWithCache: originalReadFileWithCache,
            originalGetSourceFile: originalGetSourceFile,
        };
    }
    function disableCache(state) {
        if (!state.cache)
            return;
        var cache = state.cache, host = state.host, compilerHost = state.compilerHost, extendedConfigCache = state.extendedConfigCache, moduleResolutionCache = state.moduleResolutionCache;
        host.readFile = cache.originalReadFile;
        host.fileExists = cache.originalFileExists;
        host.directoryExists = cache.originalDirectoryExists;
        host.createDirectory = cache.originalCreateDirectory;
        host.writeFile = cache.originalWriteFile;
        compilerHost.getSourceFile = cache.originalGetSourceFile;
        state.readFileWithCache = cache.originalReadFileWithCache;
        extendedConfigCache.clear();
        if (moduleResolutionCache) {
            moduleResolutionCache.directoryToModuleNameMap.clear();
            moduleResolutionCache.moduleNameToDirectoryMap.clear();
        }
        state.cache = undefined;
    }
    function clearProjectStatus(state, resolved) {
        state.projectStatus.delete(resolved);
        state.diagnostics.delete(resolved);
    }
    function addProjToQueue(_a, proj, reloadLevel) {
        var projectPendingBuild = _a.projectPendingBuild;
        var value = projectPendingBuild.get(proj);
        if (value === undefined) {
            projectPendingBuild.set(proj, reloadLevel);
        }
        else if (value < reloadLevel) {
            projectPendingBuild.set(proj, reloadLevel);
        }
    }
    function setupInitialBuild(state, cancellationToken) {
        // Set initial build if not already built
        if (!state.allProjectBuildPending)
            return;
        state.allProjectBuildPending = false;
        if (state.options.watch) {
            reportWatchStatus(state, ts.Diagnostics.Starting_compilation_in_watch_mode);
        }
        enableCache(state);
        var buildOrder = getBuildOrderFromAnyBuildOrder(getBuildOrder(state));
        buildOrder.forEach(function (configFileName) {
            return state.projectPendingBuild.set(toResolvedConfigFilePath(state, configFileName), ts.ConfigFileProgramReloadLevel.None);
        });
        if (cancellationToken) {
            cancellationToken.throwIfCancellationRequested();
        }
    }
    var InvalidatedProjectKind;
    (function (InvalidatedProjectKind) {
        InvalidatedProjectKind[InvalidatedProjectKind["Build"] = 0] = "Build";
        InvalidatedProjectKind[InvalidatedProjectKind["UpdateBundle"] = 1] = "UpdateBundle";
        InvalidatedProjectKind[InvalidatedProjectKind["UpdateOutputFileStamps"] = 2] = "UpdateOutputFileStamps";
    })(InvalidatedProjectKind = ts.InvalidatedProjectKind || (ts.InvalidatedProjectKind = {}));
    function doneInvalidatedProject(state, projectPath) {
        state.projectPendingBuild.delete(projectPath);
        state.currentInvalidatedProject = undefined;
        return state.diagnostics.has(projectPath) ?
            ts.ExitStatus.DiagnosticsPresent_OutputsSkipped :
            ts.ExitStatus.Success;
    }
    function createUpdateOutputFileStampsProject(state, project, projectPath, config, buildOrder) {
        var updateOutputFileStampsPending = true;
        return {
            kind: InvalidatedProjectKind.UpdateOutputFileStamps,
            project: project,
            projectPath: projectPath,
            buildOrder: buildOrder,
            getCompilerOptions: function () { return config.options; },
            getCurrentDirectory: function () { return state.currentDirectory; },
            updateOutputFileStatmps: function () {
                updateOutputTimestamps(state, config, projectPath);
                updateOutputFileStampsPending = false;
            },
            done: function () {
                if (updateOutputFileStampsPending) {
                    updateOutputTimestamps(state, config, projectPath);
                }
                return doneInvalidatedProject(state, projectPath);
            }
        };
    }
    function createBuildOrUpdateInvalidedProject(kind, state, project, projectPath, projectIndex, config, buildOrder) {
        var Step;
        (function (Step) {
            Step[Step["CreateProgram"] = 0] = "CreateProgram";
            Step[Step["SyntaxDiagnostics"] = 1] = "SyntaxDiagnostics";
            Step[Step["SemanticDiagnostics"] = 2] = "SemanticDiagnostics";
            Step[Step["Emit"] = 3] = "Emit";
            Step[Step["EmitBundle"] = 4] = "EmitBundle";
            Step[Step["BuildInvalidatedProjectOfBundle"] = 5] = "BuildInvalidatedProjectOfBundle";
            Step[Step["QueueReferencingProjects"] = 6] = "QueueReferencingProjects";
            Step[Step["Done"] = 7] = "Done";
        })(Step || (Step = {}));
        var step = kind === InvalidatedProjectKind.Build ? Step.CreateProgram : Step.EmitBundle;
        var program;
        var buildResult;
        var invalidatedProjectOfBundle;
        return kind === InvalidatedProjectKind.Build ?
            {
                kind: kind,
                project: project,
                projectPath: projectPath,
                buildOrder: buildOrder,
                getCompilerOptions: function () { return config.options; },
                getCurrentDirectory: function () { return state.currentDirectory; },
                getBuilderProgram: function () { return withProgramOrUndefined(ts.identity); },
                getProgram: function () {
                    return withProgramOrUndefined(function (program) { return program.getProgramOrUndefined(); });
                },
                getSourceFile: function (fileName) {
                    return withProgramOrUndefined(function (program) { return program.getSourceFile(fileName); });
                },
                getSourceFiles: function () {
                    return withProgramOrEmptyArray(function (program) { return program.getSourceFiles(); });
                },
                getOptionsDiagnostics: function (cancellationToken) {
                    return withProgramOrEmptyArray(function (program) { return program.getOptionsDiagnostics(cancellationToken); });
                },
                getGlobalDiagnostics: function (cancellationToken) {
                    return withProgramOrEmptyArray(function (program) { return program.getGlobalDiagnostics(cancellationToken); });
                },
                getConfigFileParsingDiagnostics: function () {
                    return withProgramOrEmptyArray(function (program) { return program.getConfigFileParsingDiagnostics(); });
                },
                getSyntacticDiagnostics: function (sourceFile, cancellationToken) {
                    return withProgramOrEmptyArray(function (program) { return program.getSyntacticDiagnostics(sourceFile, cancellationToken); });
                },
                getAllDependencies: function (sourceFile) {
                    return withProgramOrEmptyArray(function (program) { return program.getAllDependencies(sourceFile); });
                },
                getSemanticDiagnostics: function (sourceFile, cancellationToken) {
                    return withProgramOrEmptyArray(function (program) { return program.getSemanticDiagnostics(sourceFile, cancellationToken); });
                },
                getSemanticDiagnosticsOfNextAffectedFile: function (cancellationToken, ignoreSourceFile) {
                    return withProgramOrUndefined(function (program) {
                        return (program.getSemanticDiagnosticsOfNextAffectedFile) &&
                            program.getSemanticDiagnosticsOfNextAffectedFile(cancellationToken, ignoreSourceFile);
                    });
                },
                emit: function (targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
                    if (targetSourceFile || emitOnlyDtsFiles) {
                        return withProgramOrUndefined(function (program) { return program.emit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers); });
                    }
                    executeSteps(Step.SemanticDiagnostics, cancellationToken);
                    if (step !== Step.Emit)
                        return undefined;
                    return emit(writeFile, cancellationToken, customTransformers);
                },
                done: done
            } :
            {
                kind: kind,
                project: project,
                projectPath: projectPath,
                buildOrder: buildOrder,
                getCompilerOptions: function () { return config.options; },
                getCurrentDirectory: function () { return state.currentDirectory; },
                emit: function (writeFile, customTransformers) {
                    if (step !== Step.EmitBundle)
                        return invalidatedProjectOfBundle;
                    return emitBundle(writeFile, customTransformers);
                },
                done: done,
            };
        function done(cancellationToken, writeFile, customTransformers) {
            executeSteps(Step.Done, cancellationToken, writeFile, customTransformers);
            return doneInvalidatedProject(state, projectPath);
        }
        function withProgramOrUndefined(action) {
            executeSteps(Step.CreateProgram);
            return program && action(program);
        }
        function withProgramOrEmptyArray(action) {
            return withProgramOrUndefined(action) || ts.emptyArray;
        }
        function createProgram() {
            ts.Debug.assert(program === undefined);
            if (state.options.dry) {
                reportStatus(state, ts.Diagnostics.A_non_dry_build_would_build_project_0, project);
                buildResult = BuildResultFlags.Success;
                step = Step.QueueReferencingProjects;
                return;
            }
            if (state.options.verbose)
                reportStatus(state, ts.Diagnostics.Building_project_0, project);
            if (config.fileNames.length === 0) {
                reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                // Nothing to build - must be a solution file, basically
                buildResult = BuildResultFlags.None;
                step = Step.QueueReferencingProjects;
                return;
            }
            var host = state.host, compilerHost = state.compilerHost;
            state.projectCompilerOptions = config.options;
            // Update module resolution cache if needed
            updateModuleResolutionCache(state, project, config);
            // Create program
            program = host.createProgram(config.fileNames, config.options, compilerHost, getOldProgram(state, projectPath, config), ts.getConfigFileParsingDiagnostics(config), config.projectReferences);
            step++;
        }
        function handleDiagnostics(diagnostics, errorFlags, errorType) {
            if (diagnostics.length) {
                buildResult = buildErrors(state, projectPath, program, config, diagnostics, errorFlags, errorType);
                step = Step.QueueReferencingProjects;
            }
            else {
                step++;
            }
        }
        function getSyntaxDiagnostics(cancellationToken) {
            ts.Debug.assertIsDefined(program);
            handleDiagnostics(__spreadArrays(program.getConfigFileParsingDiagnostics(), program.getOptionsDiagnostics(cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSyntacticDiagnostics(/*sourceFile*/ undefined, cancellationToken)), BuildResultFlags.SyntaxErrors, "Syntactic");
        }
        function getSemanticDiagnostics(cancellationToken) {
            handleDiagnostics(ts.Debug.checkDefined(program).getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken), BuildResultFlags.TypeErrors, "Semantic");
        }
        function emit(writeFileCallback, cancellationToken, customTransformers) {
            ts.Debug.assertIsDefined(program);
            ts.Debug.assert(step === Step.Emit);
            // Before emitting lets backup state, so we can revert it back if there are declaration errors to handle emit and declaration errors correctly
            program.backupState();
            var declDiagnostics;
            var reportDeclarationDiagnostics = function (d) { return (declDiagnostics || (declDiagnostics = [])).push(d); };
            var outputFiles = [];
            var emitResult = ts.emitFilesAndReportErrors(program, reportDeclarationDiagnostics, 
            /*writeFileName*/ undefined, 
            /*reportSummary*/ undefined, function (name, text, writeByteOrderMark) { return outputFiles.push({ name: name, text: text, writeByteOrderMark: writeByteOrderMark }); }, cancellationToken, 
            /*emitOnlyDts*/ false, customTransformers).emitResult;
            // Don't emit .d.ts if there are decl file errors
            if (declDiagnostics) {
                program.restoreState();
                buildResult = buildErrors(state, projectPath, program, config, declDiagnostics, BuildResultFlags.DeclarationEmitErrors, "Declaration file");
                step = Step.QueueReferencingProjects;
                return {
                    emitSkipped: true,
                    diagnostics: emitResult.diagnostics
                };
            }
            // Actual Emit
            var host = state.host, compilerHost = state.compilerHost;
            var resultFlags = BuildResultFlags.DeclarationOutputUnchanged;
            var newestDeclarationFileContentChangedTime = minimumDate;
            var anyDtsChanged = false;
            var emitterDiagnostics = ts.createDiagnosticCollection();
            var emittedOutputs = ts.createMap();
            outputFiles.forEach(function (_a) {
                var name = _a.name, text = _a.text, writeByteOrderMark = _a.writeByteOrderMark;
                var priorChangeTime;
                if (!anyDtsChanged && isDeclarationFile(name)) {
                    // Check for unchanged .d.ts files
                    if (host.fileExists(name) && state.readFileWithCache(name) === text) {
                        priorChangeTime = host.getModifiedTime(name);
                    }
                    else {
                        resultFlags &= ~BuildResultFlags.DeclarationOutputUnchanged;
                        anyDtsChanged = true;
                    }
                }
                emittedOutputs.set(toPath(state, name), name);
                ts.writeFile(writeFileCallback ? { writeFile: writeFileCallback } : compilerHost, emitterDiagnostics, name, text, writeByteOrderMark);
                if (priorChangeTime !== undefined) {
                    newestDeclarationFileContentChangedTime = newer(priorChangeTime, newestDeclarationFileContentChangedTime);
                }
            });
            finishEmit(emitterDiagnostics, emittedOutputs, newestDeclarationFileContentChangedTime, 
            /*newestDeclarationFileContentChangedTimeIsMaximumDate*/ anyDtsChanged, outputFiles.length ? outputFiles[0].name : ts.getFirstProjectOutput(config, !host.useCaseSensitiveFileNames()), resultFlags);
            return emitResult;
        }
        function finishEmit(emitterDiagnostics, emittedOutputs, priorNewestUpdateTime, newestDeclarationFileContentChangedTimeIsMaximumDate, oldestOutputFileName, resultFlags) {
            var emitDiagnostics = emitterDiagnostics.getDiagnostics();
            if (emitDiagnostics.length) {
                buildResult = buildErrors(state, projectPath, program, config, emitDiagnostics, BuildResultFlags.EmitErrors, "Emit");
                step = Step.QueueReferencingProjects;
                return emitDiagnostics;
            }
            if (state.writeFileName) {
                emittedOutputs.forEach(function (name) { return listEmittedFile(state, config, name); });
                if (program)
                    ts.listFiles(program, state.writeFileName);
            }
            // Update time stamps for rest of the outputs
            var newestDeclarationFileContentChangedTime = updateOutputTimestampsWorker(state, config, priorNewestUpdateTime, ts.Diagnostics.Updating_unchanged_output_timestamps_of_project_0, emittedOutputs);
            state.diagnostics.delete(projectPath);
            state.projectStatus.set(projectPath, {
                type: ts.UpToDateStatusType.UpToDate,
                newestDeclarationFileContentChangedTime: newestDeclarationFileContentChangedTimeIsMaximumDate ?
                    maximumDate :
                    newestDeclarationFileContentChangedTime,
                oldestOutputFileName: oldestOutputFileName
            });
            afterProgramDone(state, projectPath, program, config);
            state.projectCompilerOptions = state.baseCompilerOptions;
            step = Step.QueueReferencingProjects;
            buildResult = resultFlags;
            return emitDiagnostics;
        }
        function emitBundle(writeFileCallback, customTransformers) {
            ts.Debug.assert(kind === InvalidatedProjectKind.UpdateBundle);
            if (state.options.dry) {
                reportStatus(state, ts.Diagnostics.A_non_dry_build_would_update_output_of_project_0, project);
                buildResult = BuildResultFlags.Success;
                step = Step.QueueReferencingProjects;
                return undefined;
            }
            if (state.options.verbose)
                reportStatus(state, ts.Diagnostics.Updating_output_of_project_0, project);
            // Update js, and source map
            var compilerHost = state.compilerHost;
            state.projectCompilerOptions = config.options;
            var outputFiles = ts.emitUsingBuildInfo(config, compilerHost, function (ref) {
                var refName = resolveProjectName(state, ref.path);
                return parseConfigFile(state, refName, toResolvedConfigFilePath(state, refName));
            }, customTransformers);
            if (ts.isString(outputFiles)) {
                reportStatus(state, ts.Diagnostics.Cannot_update_output_of_project_0_because_there_was_error_reading_file_1, project, relName(state, outputFiles));
                step = Step.BuildInvalidatedProjectOfBundle;
                return invalidatedProjectOfBundle = createBuildOrUpdateInvalidedProject(InvalidatedProjectKind.Build, state, project, projectPath, projectIndex, config, buildOrder);
            }
            // Actual Emit
            ts.Debug.assert(!!outputFiles.length);
            var emitterDiagnostics = ts.createDiagnosticCollection();
            var emittedOutputs = ts.createMap();
            outputFiles.forEach(function (_a) {
                var name = _a.name, text = _a.text, writeByteOrderMark = _a.writeByteOrderMark;
                emittedOutputs.set(toPath(state, name), name);
                ts.writeFile(writeFileCallback ? { writeFile: writeFileCallback } : compilerHost, emitterDiagnostics, name, text, writeByteOrderMark);
            });
            var emitDiagnostics = finishEmit(emitterDiagnostics, emittedOutputs, minimumDate, 
            /*newestDeclarationFileContentChangedTimeIsMaximumDate*/ false, outputFiles[0].name, BuildResultFlags.DeclarationOutputUnchanged);
            return { emitSkipped: false, diagnostics: emitDiagnostics };
        }
        function executeSteps(till, cancellationToken, writeFile, customTransformers) {
            while (step <= till && step < Step.Done) {
                var currentStep = step;
                switch (step) {
                    case Step.CreateProgram:
                        createProgram();
                        break;
                    case Step.SyntaxDiagnostics:
                        getSyntaxDiagnostics(cancellationToken);
                        break;
                    case Step.SemanticDiagnostics:
                        getSemanticDiagnostics(cancellationToken);
                        break;
                    case Step.Emit:
                        emit(writeFile, cancellationToken, customTransformers);
                        break;
                    case Step.EmitBundle:
                        emitBundle(writeFile, customTransformers);
                        break;
                    case Step.BuildInvalidatedProjectOfBundle:
                        ts.Debug.checkDefined(invalidatedProjectOfBundle).done(cancellationToken);
                        step = Step.Done;
                        break;
                    case Step.QueueReferencingProjects:
                        queueReferencingProjects(state, project, projectPath, projectIndex, config, buildOrder, ts.Debug.checkDefined(buildResult));
                        step++;
                        break;
                    // Should never be done
                    case Step.Done:
                    default:
                        ts.assertType(step);
                }
                ts.Debug.assert(step > currentStep);
            }
        }
    }
    function needsBuild(_a, status, config) {
        var options = _a.options;
        if (status.type !== ts.UpToDateStatusType.OutOfDateWithPrepend || options.force)
            return true;
        return config.fileNames.length === 0 ||
            !!ts.getConfigFileParsingDiagnostics(config).length ||
            !ts.isIncrementalCompilation(config.options);
    }
    function getNextInvalidatedProject(state, buildOrder, reportQueue) {
        if (!state.projectPendingBuild.size)
            return undefined;
        if (isCircularBuildOrder(buildOrder))
            return undefined;
        if (state.currentInvalidatedProject) {
            // Only if same buildOrder the currentInvalidated project can be sent again
            return ts.arrayIsEqualTo(state.currentInvalidatedProject.buildOrder, buildOrder) ?
                state.currentInvalidatedProject :
                undefined;
        }
        var options = state.options, projectPendingBuild = state.projectPendingBuild;
        for (var projectIndex = 0; projectIndex < buildOrder.length; projectIndex++) {
            var project = buildOrder[projectIndex];
            var projectPath = toResolvedConfigFilePath(state, project);
            var reloadLevel = state.projectPendingBuild.get(projectPath);
            if (reloadLevel === undefined)
                continue;
            if (reportQueue) {
                reportQueue = false;
                reportBuildQueue(state, buildOrder);
            }
            var config = parseConfigFile(state, project, projectPath);
            if (!config) {
                reportParseConfigFileDiagnostic(state, projectPath);
                projectPendingBuild.delete(projectPath);
                continue;
            }
            if (reloadLevel === ts.ConfigFileProgramReloadLevel.Full) {
                watchConfigFile(state, project, projectPath, config);
                watchWildCardDirectories(state, project, projectPath, config);
                watchInputFiles(state, project, projectPath, config);
            }
            else if (reloadLevel === ts.ConfigFileProgramReloadLevel.Partial) {
                // Update file names
                var result = ts.getFileNamesFromConfigSpecs(config.configFileSpecs, ts.getDirectoryPath(project), config.options, state.parseConfigFileHost);
                ts.updateErrorForNoInputFiles(result, project, config.configFileSpecs, config.errors, ts.canJsonReportNoInutFiles(config.raw));
                config.fileNames = result.fileNames;
                watchInputFiles(state, project, projectPath, config);
            }
            var status = getUpToDateStatus(state, config, projectPath);
            verboseReportProjectStatus(state, project, status);
            if (!options.force) {
                if (status.type === ts.UpToDateStatusType.UpToDate) {
                    reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                    projectPendingBuild.delete(projectPath);
                    // Up to date, skip
                    if (options.dry) {
                        // In a dry build, inform the user of this fact
                        reportStatus(state, ts.Diagnostics.Project_0_is_up_to_date, project);
                    }
                    continue;
                }
                if (status.type === ts.UpToDateStatusType.UpToDateWithUpstreamTypes) {
                    reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                    return createUpdateOutputFileStampsProject(state, project, projectPath, config, buildOrder);
                }
            }
            if (status.type === ts.UpToDateStatusType.UpstreamBlocked) {
                reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                projectPendingBuild.delete(projectPath);
                if (options.verbose) {
                    reportStatus(state, status.upstreamProjectBlocked ?
                        ts.Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_was_not_built :
                        ts.Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, project, status.upstreamProjectName);
                }
                continue;
            }
            if (status.type === ts.UpToDateStatusType.ContainerOnly) {
                reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                projectPendingBuild.delete(projectPath);
                // Do nothing
                continue;
            }
            return createBuildOrUpdateInvalidedProject(needsBuild(state, status, config) ?
                InvalidatedProjectKind.Build :
                InvalidatedProjectKind.UpdateBundle, state, project, projectPath, projectIndex, config, buildOrder);
        }
        return undefined;
    }
    function listEmittedFile(_a, proj, file) {
        var writeFileName = _a.writeFileName;
        if (writeFileName && proj.options.listEmittedFiles) {
            writeFileName("TSFILE: " + file);
        }
    }
    function getOldProgram(_a, proj, parsed) {
        var options = _a.options, builderPrograms = _a.builderPrograms, compilerHost = _a.compilerHost;
        if (options.force)
            return undefined;
        var value = builderPrograms.get(proj);
        if (value)
            return value;
        return ts.readBuilderProgram(parsed.options, compilerHost);
    }
    function afterProgramDone(_a, proj, program, config) {
        var host = _a.host, watch = _a.watch, builderPrograms = _a.builderPrograms;
        if (program) {
            if (host.afterProgramEmitAndDiagnostics) {
                host.afterProgramEmitAndDiagnostics(program);
            }
            if (watch) {
                program.releaseProgram();
                builderPrograms.set(proj, program);
            }
        }
        else if (host.afterEmitBundle) {
            host.afterEmitBundle(config);
        }
    }
    function buildErrors(state, resolvedPath, program, config, diagnostics, errorFlags, errorType) {
        reportAndStoreErrors(state, resolvedPath, diagnostics);
        // List files if any other build error using program (emit errors already report files)
        if (program && state.writeFileName)
            ts.listFiles(program, state.writeFileName);
        state.projectStatus.set(resolvedPath, { type: ts.UpToDateStatusType.Unbuildable, reason: errorType + " errors" });
        afterProgramDone(state, resolvedPath, program, config);
        state.projectCompilerOptions = state.baseCompilerOptions;
        return errorFlags;
    }
    function updateModuleResolutionCache(state, proj, config) {
        if (!state.moduleResolutionCache)
            return;
        // Update module resolution cache if needed
        var moduleResolutionCache = state.moduleResolutionCache;
        var projPath = toPath(state, proj);
        if (moduleResolutionCache.directoryToModuleNameMap.redirectsMap.size === 0) {
            // The own map will be for projectCompilerOptions
            ts.Debug.assert(moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.size === 0);
            moduleResolutionCache.directoryToModuleNameMap.redirectsMap.set(projPath, moduleResolutionCache.directoryToModuleNameMap.ownMap);
            moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.set(projPath, moduleResolutionCache.moduleNameToDirectoryMap.ownMap);
        }
        else {
            // Set correct own map
            ts.Debug.assert(moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.size > 0);
            var ref = {
                sourceFile: config.options.configFile,
                commandLine: config
            };
            moduleResolutionCache.directoryToModuleNameMap.setOwnMap(moduleResolutionCache.directoryToModuleNameMap.getOrCreateMapOfCacheRedirects(ref));
            moduleResolutionCache.moduleNameToDirectoryMap.setOwnMap(moduleResolutionCache.moduleNameToDirectoryMap.getOrCreateMapOfCacheRedirects(ref));
        }
        moduleResolutionCache.directoryToModuleNameMap.setOwnOptions(config.options);
        moduleResolutionCache.moduleNameToDirectoryMap.setOwnOptions(config.options);
    }
    function checkConfigFileUpToDateStatus(state, configFile, oldestOutputFileTime, oldestOutputFileName) {
        // Check tsconfig time
        var tsconfigTime = state.host.getModifiedTime(configFile) || ts.missingFileModifiedTime;
        if (oldestOutputFileTime < tsconfigTime) {
            return {
                type: ts.UpToDateStatusType.OutOfDateWithSelf,
                outOfDateOutputFileName: oldestOutputFileName,
                newerInputFileName: configFile
            };
        }
    }
    function getUpToDateStatusWorker(state, project, resolvedPath) {
        var newestInputFileName = undefined;
        var newestInputFileTime = minimumDate;
        var host = state.host;
        // Get timestamps of input files
        for (var _i = 0, _a = project.fileNames; _i < _a.length; _i++) {
            var inputFile = _a[_i];
            if (!host.fileExists(inputFile)) {
                return {
                    type: ts.UpToDateStatusType.Unbuildable,
                    reason: inputFile + " does not exist"
                };
            }
            var inputTime = host.getModifiedTime(inputFile) || ts.missingFileModifiedTime;
            if (inputTime > newestInputFileTime) {
                newestInputFileName = inputFile;
                newestInputFileTime = inputTime;
            }
        }
        // Container if no files are specified in the project
        if (!project.fileNames.length && !ts.canJsonReportNoInutFiles(project.raw)) {
            return {
                type: ts.UpToDateStatusType.ContainerOnly
            };
        }
        // Collect the expected outputs of this project
        var outputs = ts.getAllProjectOutputs(project, !host.useCaseSensitiveFileNames());
        // Now see if all outputs are newer than the newest input
        var oldestOutputFileName = "(none)";
        var oldestOutputFileTime = maximumDate;
        var newestOutputFileName = "(none)";
        var newestOutputFileTime = minimumDate;
        var missingOutputFileName;
        var newestDeclarationFileContentChangedTime = minimumDate;
        var isOutOfDateWithInputs = false;
        for (var _b = 0, outputs_1 = outputs; _b < outputs_1.length; _b++) {
            var output = outputs_1[_b];
            // Output is missing; can stop checking
            // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
            if (!host.fileExists(output)) {
                missingOutputFileName = output;
                break;
            }
            var outputTime = host.getModifiedTime(output) || ts.missingFileModifiedTime;
            if (outputTime < oldestOutputFileTime) {
                oldestOutputFileTime = outputTime;
                oldestOutputFileName = output;
            }
            // If an output is older than the newest input, we can stop checking
            // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
            if (outputTime < newestInputFileTime) {
                isOutOfDateWithInputs = true;
                break;
            }
            if (outputTime > newestOutputFileTime) {
                newestOutputFileTime = outputTime;
                newestOutputFileName = output;
            }
            // Keep track of when the most recent time a .d.ts file was changed.
            // In addition to file timestamps, we also keep track of when a .d.ts file
            // had its file touched but not had its contents changed - this allows us
            // to skip a downstream typecheck
            if (isDeclarationFile(output)) {
                var outputModifiedTime = host.getModifiedTime(output) || ts.missingFileModifiedTime;
                newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime);
            }
        }
        var pseudoUpToDate = false;
        var usesPrepend = false;
        var upstreamChangedProject;
        if (project.projectReferences) {
            state.projectStatus.set(resolvedPath, { type: ts.UpToDateStatusType.ComputingUpstream });
            for (var _c = 0, _d = project.projectReferences; _c < _d.length; _c++) {
                var ref = _d[_c];
                usesPrepend = usesPrepend || !!(ref.prepend);
                var resolvedRef = ts.resolveProjectReferencePath(ref);
                var resolvedRefPath = toResolvedConfigFilePath(state, resolvedRef);
                var refStatus = getUpToDateStatus(state, parseConfigFile(state, resolvedRef, resolvedRefPath), resolvedRefPath);
                // Its a circular reference ignore the status of this project
                if (refStatus.type === ts.UpToDateStatusType.ComputingUpstream ||
                    refStatus.type === ts.UpToDateStatusType.ContainerOnly) { // Container only ignore this project
                    continue;
                }
                // An upstream project is blocked
                if (refStatus.type === ts.UpToDateStatusType.Unbuildable ||
                    refStatus.type === ts.UpToDateStatusType.UpstreamBlocked) {
                    return {
                        type: ts.UpToDateStatusType.UpstreamBlocked,
                        upstreamProjectName: ref.path,
                        upstreamProjectBlocked: refStatus.type === ts.UpToDateStatusType.UpstreamBlocked
                    };
                }
                // If the upstream project is out of date, then so are we (someone shouldn't have asked, though?)
                if (refStatus.type !== ts.UpToDateStatusType.UpToDate) {
                    return {
                        type: ts.UpToDateStatusType.UpstreamOutOfDate,
                        upstreamProjectName: ref.path
                    };
                }
                // Check oldest output file name only if there is no missing output file name
                if (!missingOutputFileName) {
                    // If the upstream project's newest file is older than our oldest output, we
                    // can't be out of date because of it
                    if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) {
                        continue;
                    }
                    // If the upstream project has only change .d.ts files, and we've built
                    // *after* those files, then we're "psuedo up to date" and eligible for a fast rebuild
                    if (refStatus.newestDeclarationFileContentChangedTime && refStatus.newestDeclarationFileContentChangedTime <= oldestOutputFileTime) {
                        pseudoUpToDate = true;
                        upstreamChangedProject = ref.path;
                        continue;
                    }
                    // We have an output older than an upstream output - we are out of date
                    ts.Debug.assert(oldestOutputFileName !== undefined, "Should have an oldest output filename here");
                    return {
                        type: ts.UpToDateStatusType.OutOfDateWithUpstream,
                        outOfDateOutputFileName: oldestOutputFileName,
                        newerProjectName: ref.path
                    };
                }
            }
        }
        if (missingOutputFileName !== undefined) {
            return {
                type: ts.UpToDateStatusType.OutputMissing,
                missingOutputFileName: missingOutputFileName
            };
        }
        if (isOutOfDateWithInputs) {
            return {
                type: ts.UpToDateStatusType.OutOfDateWithSelf,
                outOfDateOutputFileName: oldestOutputFileName,
                newerInputFileName: newestInputFileName
            };
        }
        else {
            // Check tsconfig time
            var configStatus = checkConfigFileUpToDateStatus(state, project.options.configFilePath, oldestOutputFileTime, oldestOutputFileName);
            if (configStatus)
                return configStatus;
            // Check extended config time
            var extendedConfigStatus = ts.forEach(project.options.configFile.extendedSourceFiles || ts.emptyArray, function (configFile) { return checkConfigFileUpToDateStatus(state, configFile, oldestOutputFileTime, oldestOutputFileName); });
            if (extendedConfigStatus)
                return extendedConfigStatus;
        }
        if (!state.buildInfoChecked.has(resolvedPath)) {
            state.buildInfoChecked.set(resolvedPath, true);
            var buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(project.options);
            if (buildInfoPath) {
                var value = state.readFileWithCache(buildInfoPath);
                var buildInfo = value && ts.getBuildInfo(value);
                if (buildInfo && (buildInfo.bundle || buildInfo.program) && buildInfo.version !== ts.version) {
                    return {
                        type: ts.UpToDateStatusType.TsVersionOutputOfDate,
                        version: buildInfo.version
                    };
                }
            }
        }
        if (usesPrepend && pseudoUpToDate) {
            return {
                type: ts.UpToDateStatusType.OutOfDateWithPrepend,
                outOfDateOutputFileName: oldestOutputFileName,
                newerProjectName: upstreamChangedProject
            };
        }
        // Up to date
        return {
            type: pseudoUpToDate ? ts.UpToDateStatusType.UpToDateWithUpstreamTypes : ts.UpToDateStatusType.UpToDate,
            newestDeclarationFileContentChangedTime: newestDeclarationFileContentChangedTime,
            newestInputFileTime: newestInputFileTime,
            newestOutputFileTime: newestOutputFileTime,
            newestInputFileName: newestInputFileName,
            newestOutputFileName: newestOutputFileName,
            oldestOutputFileName: oldestOutputFileName
        };
    }
    function getUpToDateStatus(state, project, resolvedPath) {
        if (project === undefined) {
            return { type: ts.UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" };
        }
        var prior = state.projectStatus.get(resolvedPath);
        if (prior !== undefined) {
            return prior;
        }
        var actual = getUpToDateStatusWorker(state, project, resolvedPath);
        state.projectStatus.set(resolvedPath, actual);
        return actual;
    }
    function updateOutputTimestampsWorker(state, proj, priorNewestUpdateTime, verboseMessage, skipOutputs) {
        var host = state.host;
        var outputs = ts.getAllProjectOutputs(proj, !host.useCaseSensitiveFileNames());
        if (!skipOutputs || outputs.length !== skipOutputs.size) {
            var reportVerbose = !!state.options.verbose;
            var now = host.now ? host.now() : new Date();
            for (var _i = 0, outputs_2 = outputs; _i < outputs_2.length; _i++) {
                var file = outputs_2[_i];
                if (skipOutputs && skipOutputs.has(toPath(state, file))) {
                    continue;
                }
                if (reportVerbose) {
                    reportVerbose = false;
                    reportStatus(state, verboseMessage, proj.options.configFilePath);
                }
                if (isDeclarationFile(file)) {
                    priorNewestUpdateTime = newer(priorNewestUpdateTime, host.getModifiedTime(file) || ts.missingFileModifiedTime);
                }
                host.setModifiedTime(file, now);
            }
        }
        return priorNewestUpdateTime;
    }
    function updateOutputTimestamps(state, proj, resolvedPath) {
        if (state.options.dry) {
            return reportStatus(state, ts.Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath);
        }
        var priorNewestUpdateTime = updateOutputTimestampsWorker(state, proj, minimumDate, ts.Diagnostics.Updating_output_timestamps_of_project_0);
        state.projectStatus.set(resolvedPath, {
            type: ts.UpToDateStatusType.UpToDate,
            newestDeclarationFileContentChangedTime: priorNewestUpdateTime,
            oldestOutputFileName: ts.getFirstProjectOutput(proj, !state.host.useCaseSensitiveFileNames())
        });
    }
    function queueReferencingProjects(state, project, projectPath, projectIndex, config, buildOrder, buildResult) {
        // Queue only if there are no errors
        if (buildResult & BuildResultFlags.AnyErrors)
            return;
        // Only composite projects can be referenced by other projects
        if (!config.options.composite)
            return;
        // Always use build order to queue projects
        for (var index = projectIndex + 1; index < buildOrder.length; index++) {
            var nextProject = buildOrder[index];
            var nextProjectPath = toResolvedConfigFilePath(state, nextProject);
            if (state.projectPendingBuild.has(nextProjectPath))
                continue;
            var nextProjectConfig = parseConfigFile(state, nextProject, nextProjectPath);
            if (!nextProjectConfig || !nextProjectConfig.projectReferences)
                continue;
            for (var _i = 0, _a = nextProjectConfig.projectReferences; _i < _a.length; _i++) {
                var ref = _a[_i];
                var resolvedRefPath = resolveProjectName(state, ref.path);
                if (toResolvedConfigFilePath(state, resolvedRefPath) !== projectPath)
                    continue;
                // If the project is referenced with prepend, always build downstream projects,
                // If declaration output is changed, build the project
                // otherwise mark the project UpToDateWithUpstreamTypes so it updates output time stamps
                var status = state.projectStatus.get(nextProjectPath);
                if (status) {
                    switch (status.type) {
                        case ts.UpToDateStatusType.UpToDate:
                            if (buildResult & BuildResultFlags.DeclarationOutputUnchanged) {
                                if (ref.prepend) {
                                    state.projectStatus.set(nextProjectPath, {
                                        type: ts.UpToDateStatusType.OutOfDateWithPrepend,
                                        outOfDateOutputFileName: status.oldestOutputFileName,
                                        newerProjectName: project
                                    });
                                }
                                else {
                                    status.type = ts.UpToDateStatusType.UpToDateWithUpstreamTypes;
                                }
                                break;
                            }
                        // falls through
                        case ts.UpToDateStatusType.UpToDateWithUpstreamTypes:
                        case ts.UpToDateStatusType.OutOfDateWithPrepend:
                            if (!(buildResult & BuildResultFlags.DeclarationOutputUnchanged)) {
                                state.projectStatus.set(nextProjectPath, {
                                    type: ts.UpToDateStatusType.OutOfDateWithUpstream,
                                    outOfDateOutputFileName: status.type === ts.UpToDateStatusType.OutOfDateWithPrepend ? status.outOfDateOutputFileName : status.oldestOutputFileName,
                                    newerProjectName: project
                                });
                            }
                            break;
                        case ts.UpToDateStatusType.UpstreamBlocked:
                            if (toResolvedConfigFilePath(state, resolveProjectName(state, status.upstreamProjectName)) === projectPath) {
                                clearProjectStatus(state, nextProjectPath);
                            }
                            break;
                    }
                }
                addProjToQueue(state, nextProjectPath, ts.ConfigFileProgramReloadLevel.None);
                break;
            }
        }
    }
    function build(state, project, cancellationToken, onlyReferences) {
        var buildOrder = getBuildOrderFor(state, project, onlyReferences);
        if (!buildOrder)
            return ts.ExitStatus.InvalidProject_OutputsSkipped;
        setupInitialBuild(state, cancellationToken);
        var reportQueue = true;
        var successfulProjects = 0;
        while (true) {
            var invalidatedProject = getNextInvalidatedProject(state, buildOrder, reportQueue);
            if (!invalidatedProject)
                break;
            reportQueue = false;
            invalidatedProject.done(cancellationToken);
            if (!state.diagnostics.has(invalidatedProject.projectPath))
                successfulProjects++;
        }
        disableCache(state);
        reportErrorSummary(state, buildOrder);
        startWatching(state, buildOrder);
        return isCircularBuildOrder(buildOrder)
            ? ts.ExitStatus.ProjectReferenceCycle_OutputsSkipped
            : !buildOrder.some(function (p) { return state.diagnostics.has(toResolvedConfigFilePath(state, p)); })
                ? ts.ExitStatus.Success
                : successfulProjects
                    ? ts.ExitStatus.DiagnosticsPresent_OutputsGenerated
                    : ts.ExitStatus.DiagnosticsPresent_OutputsSkipped;
    }
    function clean(state, project, onlyReferences) {
        var buildOrder = getBuildOrderFor(state, project, onlyReferences);
        if (!buildOrder)
            return ts.ExitStatus.InvalidProject_OutputsSkipped;
        if (isCircularBuildOrder(buildOrder)) {
            reportErrors(state, buildOrder.circularDiagnostics);
            return ts.ExitStatus.ProjectReferenceCycle_OutputsSkipped;
        }
        var options = state.options, host = state.host;
        var filesToDelete = options.dry ? [] : undefined;
        for (var _i = 0, buildOrder_1 = buildOrder; _i < buildOrder_1.length; _i++) {
            var proj = buildOrder_1[_i];
            var resolvedPath = toResolvedConfigFilePath(state, proj);
            var parsed = parseConfigFile(state, proj, resolvedPath);
            if (parsed === undefined) {
                // File has gone missing; fine to ignore here
                reportParseConfigFileDiagnostic(state, resolvedPath);
                continue;
            }
            var outputs = ts.getAllProjectOutputs(parsed, !host.useCaseSensitiveFileNames());
            for (var _a = 0, outputs_3 = outputs; _a < outputs_3.length; _a++) {
                var output = outputs_3[_a];
                if (host.fileExists(output)) {
                    if (filesToDelete) {
                        filesToDelete.push(output);
                    }
                    else {
                        host.deleteFile(output);
                        invalidateProject(state, resolvedPath, ts.ConfigFileProgramReloadLevel.None);
                    }
                }
            }
        }
        if (filesToDelete) {
            reportStatus(state, ts.Diagnostics.A_non_dry_build_would_delete_the_following_files_Colon_0, filesToDelete.map(function (f) { return "\r\n * " + f; }).join(""));
        }
        return ts.ExitStatus.Success;
    }
    function invalidateProject(state, resolved, reloadLevel) {
        // If host implements getParsedCommandLine, we cant get list of files from parseConfigFileHost
        if (state.host.getParsedCommandLine && reloadLevel === ts.ConfigFileProgramReloadLevel.Partial) {
            reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
        }
        if (reloadLevel === ts.ConfigFileProgramReloadLevel.Full) {
            state.configFileCache.delete(resolved);
            state.buildOrder = undefined;
        }
        state.needsSummary = true;
        clearProjectStatus(state, resolved);
        addProjToQueue(state, resolved, reloadLevel);
        enableCache(state);
    }
    function invalidateProjectAndScheduleBuilds(state, resolvedPath, reloadLevel) {
        state.reportFileChangeDetected = true;
        invalidateProject(state, resolvedPath, reloadLevel);
        scheduleBuildInvalidatedProject(state);
    }
    function scheduleBuildInvalidatedProject(state) {
        var hostWithWatch = state.hostWithWatch;
        if (!hostWithWatch.setTimeout || !hostWithWatch.clearTimeout) {
            return;
        }
        if (state.timerToBuildInvalidatedProject) {
            hostWithWatch.clearTimeout(state.timerToBuildInvalidatedProject);
        }
        state.timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildNextInvalidatedProject, 250, state);
    }
    function buildNextInvalidatedProject(state) {
        state.timerToBuildInvalidatedProject = undefined;
        if (state.reportFileChangeDetected) {
            state.reportFileChangeDetected = false;
            state.projectErrorsReported.clear();
            reportWatchStatus(state, ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
        }
        var buildOrder = getBuildOrder(state);
        var invalidatedProject = getNextInvalidatedProject(state, buildOrder, /*reportQueue*/ false);
        if (invalidatedProject) {
            invalidatedProject.done();
            if (state.projectPendingBuild.size) {
                // Schedule next project for build
                if (state.watch && !state.timerToBuildInvalidatedProject) {
                    scheduleBuildInvalidatedProject(state);
                }
                return;
            }
        }
        disableCache(state);
        reportErrorSummary(state, buildOrder);
    }
    function watchConfigFile(state, resolved, resolvedPath, parsed) {
        if (!state.watch || state.allWatchedConfigFiles.has(resolvedPath))
            return;
        state.allWatchedConfigFiles.set(resolvedPath, state.watchFile(state.hostWithWatch, resolved, function () {
            invalidateProjectAndScheduleBuilds(state, resolvedPath, ts.ConfigFileProgramReloadLevel.Full);
        }, ts.PollingInterval.High, parsed === null || parsed === void 0 ? void 0 : parsed.watchOptions, ts.WatchType.ConfigFile, resolved));
    }
    function isSameFile(state, file1, file2) {
        return ts.comparePaths(file1, file2, state.currentDirectory, !state.host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
    }
    function isOutputFile(state, fileName, configFile) {
        if (configFile.options.noEmit)
            return false;
        // ts or tsx files are not output
        if (!ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) &&
            (ts.fileExtensionIs(fileName, ".ts" /* Ts */) || ts.fileExtensionIs(fileName, ".tsx" /* Tsx */))) {
            return false;
        }
        // If options have --outFile or --out, check if its that
        var out = configFile.options.outFile || configFile.options.out;
        if (out && (isSameFile(state, fileName, out) || isSameFile(state, fileName, ts.removeFileExtension(out) + ".d.ts" /* Dts */))) {
            return true;
        }
        // If declarationDir is specified, return if its a file in that directory
        if (configFile.options.declarationDir && ts.containsPath(configFile.options.declarationDir, fileName, state.currentDirectory, !state.host.useCaseSensitiveFileNames())) {
            return true;
        }
        // If --outDir, check if file is in that directory
        if (configFile.options.outDir && ts.containsPath(configFile.options.outDir, fileName, state.currentDirectory, !state.host.useCaseSensitiveFileNames())) {
            return true;
        }
        return !ts.forEach(configFile.fileNames, function (inputFile) { return isSameFile(state, fileName, inputFile); });
    }
    function watchWildCardDirectories(state, resolved, resolvedPath, parsed) {
        if (!state.watch)
            return;
        ts.updateWatchingWildcardDirectories(getOrCreateValueMapFromConfigFileMap(state.allWatchedWildcardDirectories, resolvedPath), ts.createMapFromTemplate(parsed.configFileSpecs.wildcardDirectories), function (dir, flags) { return state.watchDirectory(state.hostWithWatch, dir, function (fileOrDirectory) {
            var fileOrDirectoryPath = toPath(state, fileOrDirectory);
            if (fileOrDirectoryPath !== toPath(state, dir) && ts.hasExtension(fileOrDirectoryPath) && !ts.isSupportedSourceFileName(fileOrDirectory, parsed.options)) {
                state.writeLog("Project: " + resolved + " Detected file add/remove of non supported extension: " + fileOrDirectory);
                return;
            }
            if (isOutputFile(state, fileOrDirectory, parsed)) {
                state.writeLog(fileOrDirectory + " is output file");
                return;
            }
            invalidateProjectAndScheduleBuilds(state, resolvedPath, ts.ConfigFileProgramReloadLevel.Partial);
        }, flags, parsed === null || parsed === void 0 ? void 0 : parsed.watchOptions, ts.WatchType.WildcardDirectory, resolved); });
    }
    function watchInputFiles(state, resolved, resolvedPath, parsed) {
        if (!state.watch)
            return;
        ts.mutateMap(getOrCreateValueMapFromConfigFileMap(state.allWatchedInputFiles, resolvedPath), ts.arrayToMap(parsed.fileNames, function (fileName) { return toPath(state, fileName); }), {
            createNewValue: function (path, input) { return state.watchFilePath(state.hostWithWatch, input, function () { return invalidateProjectAndScheduleBuilds(state, resolvedPath, ts.ConfigFileProgramReloadLevel.None); }, ts.PollingInterval.Low, parsed === null || parsed === void 0 ? void 0 : parsed.watchOptions, path, ts.WatchType.SourceFile, resolved); },
            onDeleteValue: ts.closeFileWatcher,
        });
    }
    function startWatching(state, buildOrder) {
        if (!state.watchAllProjectsPending)
            return;
        state.watchAllProjectsPending = false;
        for (var _i = 0, _a = getBuildOrderFromAnyBuildOrder(buildOrder); _i < _a.length; _i++) {
            var resolved = _a[_i];
            var resolvedPath = toResolvedConfigFilePath(state, resolved);
            var cfg = parseConfigFile(state, resolved, resolvedPath);
            // Watch this file
            watchConfigFile(state, resolved, resolvedPath, cfg);
            if (cfg) {
                // Update watchers for wildcard directories
                watchWildCardDirectories(state, resolved, resolvedPath, cfg);
                // Watch input files
                watchInputFiles(state, resolved, resolvedPath, cfg);
            }
        }
    }
    function stopWatching(state) {
        ts.clearMap(state.allWatchedConfigFiles, ts.closeFileWatcher);
        ts.clearMap(state.allWatchedWildcardDirectories, function (watchedWildcardDirectories) { return ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcherOf); });
        ts.clearMap(state.allWatchedInputFiles, function (watchedWildcardDirectories) { return ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcher); });
    }
    function createSolutionBuilderWorker(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions) {
        var state = createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions);
        return {
            build: function (project, cancellationToken) { return build(state, project, cancellationToken); },
            clean: function (project) { return clean(state, project); },
            buildReferences: function (project, cancellationToken) { return build(state, project, cancellationToken, /*onlyReferences*/ true); },
            cleanReferences: function (project) { return clean(state, project, /*onlyReferences*/ true); },
            getNextInvalidatedProject: function (cancellationToken) {
                setupInitialBuild(state, cancellationToken);
                return getNextInvalidatedProject(state, getBuildOrder(state), /*reportQueue*/ false);
            },
            getBuildOrder: function () { return getBuildOrder(state); },
            getUpToDateStatusOfProject: function (project) {
                var configFileName = resolveProjectName(state, project);
                var configFilePath = toResolvedConfigFilePath(state, configFileName);
                return getUpToDateStatus(state, parseConfigFile(state, configFileName, configFilePath), configFilePath);
            },
            invalidateProject: function (configFilePath, reloadLevel) { return invalidateProject(state, configFilePath, reloadLevel || ts.ConfigFileProgramReloadLevel.None); },
            buildNextInvalidatedProject: function () { return buildNextInvalidatedProject(state); },
            getAllParsedConfigs: function () { return ts.arrayFrom(ts.mapDefinedIterator(state.configFileCache.values(), function (config) { return isParsedCommandLine(config) ? config : undefined; })); },
            close: function () { return stopWatching(state); },
        };
    }
    function relName(state, path) {
        return ts.convertToRelativePath(path, state.currentDirectory, function (f) { return state.getCanonicalFileName(f); });
    }
    function reportStatus(state, message) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        state.host.reportSolutionBuilderStatus(ts.createCompilerDiagnostic.apply(void 0, __spreadArrays([message], args)));
    }
    function reportWatchStatus(state, message) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        if (state.hostWithWatch.onWatchStatusChange) {
            state.hostWithWatch.onWatchStatusChange(ts.createCompilerDiagnostic.apply(void 0, __spreadArrays([message], args)), state.host.getNewLine(), state.baseCompilerOptions);
        }
    }
    function reportErrors(_a, errors) {
        var host = _a.host;
        errors.forEach(function (err) { return host.reportDiagnostic(err); });
    }
    function reportAndStoreErrors(state, proj, errors) {
        reportErrors(state, errors);
        state.projectErrorsReported.set(proj, true);
        if (errors.length) {
            state.diagnostics.set(proj, errors);
        }
    }
    function reportParseConfigFileDiagnostic(state, proj) {
        reportAndStoreErrors(state, proj, [state.configFileCache.get(proj)]);
    }
    function reportErrorSummary(state, buildOrder) {
        if (!state.needsSummary)
            return;
        state.needsSummary = false;
        var canReportSummary = state.watch || !!state.host.reportErrorSummary;
        var diagnostics = state.diagnostics;
        var totalErrors = 0;
        if (isCircularBuildOrder(buildOrder)) {
            reportBuildQueue(state, buildOrder.buildOrder);
            reportErrors(state, buildOrder.circularDiagnostics);
            if (canReportSummary)
                totalErrors += ts.getErrorCountForSummary(buildOrder.circularDiagnostics);
        }
        else {
            // Report errors from the other projects
            buildOrder.forEach(function (project) {
                var projectPath = toResolvedConfigFilePath(state, project);
                if (!state.projectErrorsReported.has(projectPath)) {
                    reportErrors(state, diagnostics.get(projectPath) || ts.emptyArray);
                }
            });
            if (canReportSummary)
                diagnostics.forEach(function (singleProjectErrors) { return totalErrors += ts.getErrorCountForSummary(singleProjectErrors); });
        }
        if (state.watch) {
            reportWatchStatus(state, ts.getWatchErrorSummaryDiagnosticMessage(totalErrors), totalErrors);
        }
        else if (state.host.reportErrorSummary) {
            state.host.reportErrorSummary(totalErrors);
        }
    }
    /**
     * Report the build ordering inferred from the current project graph if we're in verbose mode
     */
    function reportBuildQueue(state, buildQueue) {
        if (state.options.verbose) {
            reportStatus(state, ts.Diagnostics.Projects_in_this_build_Colon_0, buildQueue.map(function (s) { return "\r\n    * " + relName(state, s); }).join(""));
        }
    }
    function reportUpToDateStatus(state, configFileName, status) {
        switch (status.type) {
            case ts.UpToDateStatusType.OutOfDateWithSelf:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relName(state, configFileName), relName(state, status.outOfDateOutputFileName), relName(state, status.newerInputFileName));
            case ts.UpToDateStatusType.OutOfDateWithUpstream:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relName(state, configFileName), relName(state, status.outOfDateOutputFileName), relName(state, status.newerProjectName));
            case ts.UpToDateStatusType.OutputMissing:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, relName(state, configFileName), relName(state, status.missingOutputFileName));
            case ts.UpToDateStatusType.UpToDate:
                if (status.newestInputFileTime !== undefined) {
                    return reportStatus(state, ts.Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relName(state, configFileName), relName(state, status.newestInputFileName || ""), relName(state, status.oldestOutputFileName || ""));
                }
                // Don't report anything for "up to date because it was already built" -- too verbose
                break;
            case ts.UpToDateStatusType.OutOfDateWithPrepend:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed, relName(state, configFileName), relName(state, status.newerProjectName));
            case ts.UpToDateStatusType.UpToDateWithUpstreamTypes:
                return reportStatus(state, ts.Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, relName(state, configFileName));
            case ts.UpToDateStatusType.UpstreamOutOfDate:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date, relName(state, configFileName), relName(state, status.upstreamProjectName));
            case ts.UpToDateStatusType.UpstreamBlocked:
                return reportStatus(state, status.upstreamProjectBlocked ?
                    ts.Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_was_not_built :
                    ts.Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, relName(state, configFileName), relName(state, status.upstreamProjectName));
            case ts.UpToDateStatusType.Unbuildable:
                return reportStatus(state, ts.Diagnostics.Failed_to_parse_file_0_Colon_1, relName(state, configFileName), status.reason);
            case ts.UpToDateStatusType.TsVersionOutputOfDate:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, relName(state, configFileName), status.version, ts.version);
            case ts.UpToDateStatusType.ContainerOnly:
            // Don't report status on "solution" projects
            // falls through
            case ts.UpToDateStatusType.ComputingUpstream:
                // Should never leak from getUptoDateStatusWorker
                break;
            default:
                ts.assertType(status);
        }
    }
    /**
     * Report the up-to-date status of a project if we're in verbose mode
     */
    function verboseReportProjectStatus(state, configFileName, status) {
        if (state.options.verbose) {
            reportUpToDateStatus(state, configFileName, status);
        }
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        /* @internal */
        server.ActionSet = "action::set";
        /* @internal */
        server.ActionInvalidate = "action::invalidate";
        /* @internal */
        server.ActionPackageInstalled = "action::packageInstalled";
        /* @internal */
        server.EventTypesRegistry = "event::typesRegistry";
        /* @internal */
        server.EventBeginInstallTypes = "event::beginInstallTypes";
        /* @internal */
        server.EventEndInstallTypes = "event::endInstallTypes";
        /* @internal */
        server.EventInitializationFailed = "event::initializationFailed";
        /* @internal */
        var Arguments;
        (function (Arguments) {
            Arguments.GlobalCacheLocation = "--globalTypingsCacheLocation";
            Arguments.LogFile = "--logFile";
            Arguments.EnableTelemetry = "--enableTelemetry";
            Arguments.TypingSafeListLocation = "--typingSafeListLocation";
            Arguments.TypesMapLocation = "--typesMapLocation";
            /**
             * This argument specifies the location of the NPM executable.
             * typingsInstaller will run the command with `${npmLocation} install ...`.
             */
            Arguments.NpmLocation = "--npmLocation";
            /**
             * Flag indicating that the typings installer should try to validate the default npm location.
             * If the default npm is not found when this flag is enabled, fallback to `npm install`
             */
            Arguments.ValidateDefaultNpmLocation = "--validateDefaultNpmLocation";
        })(Arguments = server.Arguments || (server.Arguments = {}));
        /* @internal */
        function hasArgument(argumentName) {
            return ts.sys.args.indexOf(argumentName) >= 0;
        }
        server.hasArgument = hasArgument;
        /* @internal */
        function findArgument(argumentName) {
            var index = ts.sys.args.indexOf(argumentName);
            return index >= 0 && index < ts.sys.args.length - 1
                ? ts.sys.args[index + 1]
                : undefined;
        }
        server.findArgument = findArgument;
        /* @internal */
        function nowString() {
            // E.g. "12:34:56.789"
            var d = new Date();
            return d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + "." + d.getMilliseconds();
        }
        server.nowString = nowString;
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var JsTyping;
    (function (JsTyping) {
        function isTypingUpToDate(cachedTyping, availableTypingVersions) {
            var availableVersion = new ts.Version(ts.getProperty(availableTypingVersions, "ts" + ts.versionMajorMinor) || ts.getProperty(availableTypingVersions, "latest"));
            return availableVersion.compareTo(cachedTyping.version) <= 0;
        }
        JsTyping.isTypingUpToDate = isTypingUpToDate;
        JsTyping.nodeCoreModuleList = [
            "assert",
            "async_hooks",
            "buffer",
            "child_process",
            "cluster",
            "console",
            "constants",
            "crypto",
            "dgram",
            "dns",
            "domain",
            "events",
            "fs",
            "http",
            "https",
            "http2",
            "inspector",
            "net",
            "os",
            "path",
            "perf_hooks",
            "process",
            "punycode",
            "querystring",
            "readline",
            "repl",
            "stream",
            "string_decoder",
            "timers",
            "tls",
            "tty",
            "url",
            "util",
            "v8",
            "vm",
            "zlib"
        ];
        JsTyping.nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList);
        function nonRelativeModuleNameForTypingCache(moduleName) {
            return JsTyping.nodeCoreModules.has(moduleName) ? "node" : moduleName;
        }
        JsTyping.nonRelativeModuleNameForTypingCache = nonRelativeModuleNameForTypingCache;
        function loadSafeList(host, safeListPath) {
            var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); });
            return ts.createMapFromTemplate(result.config);
        }
        JsTyping.loadSafeList = loadSafeList;
        function loadTypesMap(host, typesMapPath) {
            var result = ts.readConfigFile(typesMapPath, function (path) { return host.readFile(path); });
            if (result.config) {
                return ts.createMapFromTemplate(result.config.simpleMap);
            }
            return undefined;
        }
        JsTyping.loadTypesMap = loadTypesMap;
        /**
         * @param host is the object providing I/O related operations.
         * @param fileNames are the file names that belong to the same project
         * @param projectRootPath is the path to the project root directory
         * @param safeListPath is the path used to retrieve the safe list
         * @param packageNameToTypingLocation is the map of package names to their cached typing locations and installed versions
         * @param typeAcquisition is used to customize the typing acquisition process
         * @param compilerOptions are used as a source for typing inference
         */
        function discoverTypings(host, log, fileNames, projectRootPath, safeList, packageNameToTypingLocation, typeAcquisition, unresolvedImports, typesRegistry) {
            if (!typeAcquisition || !typeAcquisition.enable) {
                return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
            }
            // A typing name to typing file path mapping
            var inferredTypings = ts.createMap();
            // Only infer typings for .js and .jsx files
            fileNames = ts.mapDefined(fileNames, function (fileName) {
                var path = ts.normalizePath(fileName);
                if (ts.hasJSFileExtension(path)) {
                    return path;
                }
            });
            var filesToWatch = [];
            if (typeAcquisition.include)
                addInferredTypings(typeAcquisition.include, "Explicitly included types");
            var exclude = typeAcquisition.exclude || [];
            // Directories to search for package.json, bower.json and other typing information
            var possibleSearchDirs = ts.arrayToSet(fileNames, ts.getDirectoryPath);
            possibleSearchDirs.set(projectRootPath, true);
            possibleSearchDirs.forEach(function (_true, searchDir) {
                var packageJsonPath = ts.combinePaths(searchDir, "package.json");
                getTypingNamesFromJson(packageJsonPath, filesToWatch);
                var bowerJsonPath = ts.combinePaths(searchDir, "bower.json");
                getTypingNamesFromJson(bowerJsonPath, filesToWatch);
                var bowerComponentsPath = ts.combinePaths(searchDir, "bower_components");
                getTypingNamesFromPackagesFolder(bowerComponentsPath, filesToWatch);
                var nodeModulesPath = ts.combinePaths(searchDir, "node_modules");
                getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch);
            });
            getTypingNamesFromSourceFileNames(fileNames);
            // add typings for unresolved imports
            if (unresolvedImports) {
                var module_1 = ts.deduplicate(unresolvedImports.map(nonRelativeModuleNameForTypingCache), ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive);
                addInferredTypings(module_1, "Inferred typings from unresolved imports");
            }
            // Add the cached typing locations for inferred typings that are already installed
            packageNameToTypingLocation.forEach(function (typing, name) {
                var registryEntry = typesRegistry.get(name);
                if (inferredTypings.has(name) && inferredTypings.get(name) === undefined && registryEntry !== undefined && isTypingUpToDate(typing, registryEntry)) {
                    inferredTypings.set(name, typing.typingLocation);
                }
            });
            // Remove typings that the user has added to the exclude list
            for (var _i = 0, exclude_1 = exclude; _i < exclude_1.length; _i++) {
                var excludeTypingName = exclude_1[_i];
                var didDelete = inferredTypings.delete(excludeTypingName);
                if (didDelete && log)
                    log("Typing for " + excludeTypingName + " is in exclude list, will be ignored.");
            }
            var newTypingNames = [];
            var cachedTypingPaths = [];
            inferredTypings.forEach(function (inferred, typing) {
                if (inferred !== undefined) {
                    cachedTypingPaths.push(inferred);
                }
                else {
                    newTypingNames.push(typing);
                }
            });
            var result = { cachedTypingPaths: cachedTypingPaths, newTypingNames: newTypingNames, filesToWatch: filesToWatch };
            if (log)
                log("Result: " + JSON.stringify(result));
            return result;
            function addInferredTyping(typingName) {
                if (!inferredTypings.has(typingName)) {
                    inferredTypings.set(typingName, undefined); // TODO: GH#18217
                }
            }
            function addInferredTypings(typingNames, message) {
                if (log)
                    log(message + ": " + JSON.stringify(typingNames));
                ts.forEach(typingNames, addInferredTyping);
            }
            /**
             * Get the typing info from common package manager json files like package.json or bower.json
             */
            function getTypingNamesFromJson(jsonPath, filesToWatch) {
                if (!host.fileExists(jsonPath)) {
                    return;
                }
                filesToWatch.push(jsonPath);
                var jsonConfig = ts.readConfigFile(jsonPath, function (path) { return host.readFile(path); }).config;
                var jsonTypingNames = ts.flatMap([jsonConfig.dependencies, jsonConfig.devDependencies, jsonConfig.optionalDependencies, jsonConfig.peerDependencies], ts.getOwnKeys);
                addInferredTypings(jsonTypingNames, "Typing names in '" + jsonPath + "' dependencies");
            }
            /**
             * Infer typing names from given file names. For example, the file name "jquery-min.2.3.4.js"
             * should be inferred to the 'jquery' typing name; and "angular-route.1.2.3.js" should be inferred
             * to the 'angular-route' typing name.
             * @param fileNames are the names for source files in the project
             */
            function getTypingNamesFromSourceFileNames(fileNames) {
                var fromFileNames = ts.mapDefined(fileNames, function (j) {
                    if (!ts.hasJSFileExtension(j))
                        return undefined;
                    var inferredTypingName = ts.removeFileExtension(ts.getBaseFileName(j.toLowerCase()));
                    var cleanedTypingName = ts.removeMinAndVersionNumbers(inferredTypingName);
                    return safeList.get(cleanedTypingName);
                });
                if (fromFileNames.length) {
                    addInferredTypings(fromFileNames, "Inferred typings from file names");
                }
                var hasJsxFile = ts.some(fileNames, function (f) { return ts.fileExtensionIs(f, ".jsx" /* Jsx */); });
                if (hasJsxFile) {
                    if (log)
                        log("Inferred 'react' typings due to presence of '.jsx' extension");
                    addInferredTyping("react");
                }
            }
            /**
             * Infer typing names from packages folder (ex: node_module, bower_components)
             * @param packagesFolderPath is the path to the packages folder
             */
            function getTypingNamesFromPackagesFolder(packagesFolderPath, filesToWatch) {
                filesToWatch.push(packagesFolderPath);
                // Todo: add support for ModuleResolutionHost too
                if (!host.directoryExists(packagesFolderPath)) {
                    return;
                }
                // depth of 2, so we access `node_modules/foo` but not `node_modules/foo/bar`
                var fileNames = host.readDirectory(packagesFolderPath, [".json" /* Json */], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
                if (log)
                    log("Searching for typing names in " + packagesFolderPath + "; all files: " + JSON.stringify(fileNames));
                var packageNames = [];
                for (var _i = 0, fileNames_1 = fileNames; _i < fileNames_1.length; _i++) {
                    var fileName = fileNames_1[_i];
                    var normalizedFileName = ts.normalizePath(fileName);
                    var baseFileName = ts.getBaseFileName(normalizedFileName);
                    if (baseFileName !== "package.json" && baseFileName !== "bower.json") {
                        continue;
                    }
                    var result_1 = ts.readConfigFile(normalizedFileName, function (path) { return host.readFile(path); });
                    var packageJson = result_1.config;
                    // npm 3's package.json contains a "_requiredBy" field
                    // we should include all the top level module names for npm 2, and only module names whose
                    // "_requiredBy" field starts with "#" or equals "/" for npm 3.
                    if (baseFileName === "package.json" && packageJson._requiredBy &&
                        ts.filter(packageJson._requiredBy, function (r) { return r[0] === "#" || r === "/"; }).length === 0) {
                        continue;
                    }
                    // If the package has its own d.ts typings, those will take precedence. Otherwise the package name will be used
                    // to download d.ts files from DefinitelyTyped
                    if (!packageJson.name) {
                        continue;
                    }
                    var ownTypes = packageJson.types || packageJson.typings;
                    if (ownTypes) {
                        var absolutePath = ts.getNormalizedAbsolutePath(ownTypes, ts.getDirectoryPath(normalizedFileName));
                        if (log)
                            log("    Package '" + packageJson.name + "' provides its own types.");
                        inferredTypings.set(packageJson.name, absolutePath);
                    }
                    else {
                        packageNames.push(packageJson.name);
                    }
                }
                addInferredTypings(packageNames, "    Found package names");
            }
        }
        JsTyping.discoverTypings = discoverTypings;
        var NameValidationResult;
        (function (NameValidationResult) {
            NameValidationResult[NameValidationResult["Ok"] = 0] = "Ok";
            NameValidationResult[NameValidationResult["EmptyName"] = 1] = "EmptyName";
            NameValidationResult[NameValidationResult["NameTooLong"] = 2] = "NameTooLong";
            NameValidationResult[NameValidationResult["NameStartsWithDot"] = 3] = "NameStartsWithDot";
            NameValidationResult[NameValidationResult["NameStartsWithUnderscore"] = 4] = "NameStartsWithUnderscore";
            NameValidationResult[NameValidationResult["NameContainsNonURISafeCharacters"] = 5] = "NameContainsNonURISafeCharacters";
        })(NameValidationResult = JsTyping.NameValidationResult || (JsTyping.NameValidationResult = {}));
        var maxPackageNameLength = 214;
        /**
         * Validates package name using rules defined at https://docs.npmjs.com/files/package.json
         */
        function validatePackageName(packageName) {
            return validatePackageNameWorker(packageName, /*supportScopedPackage*/ true);
        }
        JsTyping.validatePackageName = validatePackageName;
        function validatePackageNameWorker(packageName, supportScopedPackage) {
            if (!packageName) {
                return 1 /* EmptyName */;
            }
            if (packageName.length > maxPackageNameLength) {
                return 2 /* NameTooLong */;
            }
            if (packageName.charCodeAt(0) === 46 /* dot */) {
                return 3 /* NameStartsWithDot */;
            }
            if (packageName.charCodeAt(0) === 95 /* _ */) {
                return 4 /* NameStartsWithUnderscore */;
            }
            // check if name is scope package like: starts with @ and has one '/' in the middle
            // scoped packages are not currently supported
            if (supportScopedPackage) {
                var matches = /^@([^/]+)\/([^/]+)$/.exec(packageName);
                if (matches) {
                    var scopeResult = validatePackageNameWorker(matches[1], /*supportScopedPackage*/ false);
                    if (scopeResult !== 0 /* Ok */) {
                        return { name: matches[1], isScopeName: true, result: scopeResult };
                    }
                    var packageResult = validatePackageNameWorker(matches[2], /*supportScopedPackage*/ false);
                    if (packageResult !== 0 /* Ok */) {
                        return { name: matches[2], isScopeName: false, result: packageResult };
                    }
                    return 0 /* Ok */;
                }
            }
            if (encodeURIComponent(packageName) !== packageName) {
                return 5 /* NameContainsNonURISafeCharacters */;
            }
            return 0 /* Ok */;
        }
        function renderPackageNameValidationFailure(result, typing) {
            return typeof result === "object" ?
                renderPackageNameValidationFailureWorker(typing, result.result, result.name, result.isScopeName) :
                renderPackageNameValidationFailureWorker(typing, result, typing, /*isScopeName*/ false);
        }
        JsTyping.renderPackageNameValidationFailure = renderPackageNameValidationFailure;
        function renderPackageNameValidationFailureWorker(typing, result, name, isScopeName) {
            var kind = isScopeName ? "Scope" : "Package";
            switch (result) {
                case 1 /* EmptyName */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' cannot be empty";
                case 2 /* NameTooLong */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' should be less than " + maxPackageNameLength + " characters";
                case 3 /* NameStartsWithDot */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' cannot start with '.'";
                case 4 /* NameStartsWithUnderscore */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' cannot start with '_'";
                case 5 /* NameContainsNonURISafeCharacters */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' contains non URI safe characters";
                case 0 /* Ok */:
                    return ts.Debug.fail(); // Shouldn't have called this.
                default:
                    throw ts.Debug.assertNever(result);
            }
        }
    })(JsTyping = ts.JsTyping || (ts.JsTyping = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var ScriptSnapshot;
    (function (ScriptSnapshot) {
        var StringScriptSnapshot = /** @class */ (function () {
            function StringScriptSnapshot(text) {
                this.text = text;
            }
            StringScriptSnapshot.prototype.getText = function (start, end) {
                return start === 0 && end === this.text.length
                    ? this.text
                    : this.text.substring(start, end);
            };
            StringScriptSnapshot.prototype.getLength = function () {
                return this.text.length;
            };
            StringScriptSnapshot.prototype.getChangeRange = function () {
                // Text-based snapshots do not support incremental parsing. Return undefined
                // to signal that to the caller.
                return undefined;
            };
            return StringScriptSnapshot;
        }());
        function fromString(text) {
            return new StringScriptSnapshot(text);
        }
        ScriptSnapshot.fromString = fromString;
    })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {}));
    /* @internal */
    var PackageJsonDependencyGroup;
    (function (PackageJsonDependencyGroup) {
        PackageJsonDependencyGroup[PackageJsonDependencyGroup["Dependencies"] = 1] = "Dependencies";
        PackageJsonDependencyGroup[PackageJsonDependencyGroup["DevDependencies"] = 2] = "DevDependencies";
        PackageJsonDependencyGroup[PackageJsonDependencyGroup["PeerDependencies"] = 4] = "PeerDependencies";
        PackageJsonDependencyGroup[PackageJsonDependencyGroup["OptionalDependencies"] = 8] = "OptionalDependencies";
        PackageJsonDependencyGroup[PackageJsonDependencyGroup["All"] = 15] = "All";
    })(PackageJsonDependencyGroup = ts.PackageJsonDependencyGroup || (ts.PackageJsonDependencyGroup = {}));
    /* @internal */
    ts.emptyOptions = {};
    var HighlightSpanKind;
    (function (HighlightSpanKind) {
        HighlightSpanKind["none"] = "none";
        HighlightSpanKind["definition"] = "definition";
        HighlightSpanKind["reference"] = "reference";
        HighlightSpanKind["writtenReference"] = "writtenReference";
    })(HighlightSpanKind = ts.HighlightSpanKind || (ts.HighlightSpanKind = {}));
    var IndentStyle;
    (function (IndentStyle) {
        IndentStyle[IndentStyle["None"] = 0] = "None";
        IndentStyle[IndentStyle["Block"] = 1] = "Block";
        IndentStyle[IndentStyle["Smart"] = 2] = "Smart";
    })(IndentStyle = ts.IndentStyle || (ts.IndentStyle = {}));
    var SemicolonPreference;
    (function (SemicolonPreference) {
        SemicolonPreference["Ignore"] = "ignore";
        SemicolonPreference["Insert"] = "insert";
        SemicolonPreference["Remove"] = "remove";
    })(SemicolonPreference = ts.SemicolonPreference || (ts.SemicolonPreference = {}));
    function getDefaultFormatCodeSettings(newLineCharacter) {
        return {
            indentSize: 4,
            tabSize: 4,
            newLineCharacter: newLineCharacter || "\n",
            convertTabsToSpaces: true,
            indentStyle: IndentStyle.Smart,
            insertSpaceAfterConstructor: false,
            insertSpaceAfterCommaDelimiter: true,
            insertSpaceAfterSemicolonInForStatements: true,
            insertSpaceBeforeAndAfterBinaryOperators: true,
            insertSpaceAfterKeywordsInControlFlowStatements: true,
            insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
            insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
            insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
            insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
            insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
            insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
            insertSpaceBeforeFunctionParenthesis: false,
            placeOpenBraceOnNewLineForFunctions: false,
            placeOpenBraceOnNewLineForControlBlocks: false,
            semicolons: SemicolonPreference.Ignore,
            trimTrailingWhitespace: true
        };
    }
    ts.getDefaultFormatCodeSettings = getDefaultFormatCodeSettings;
    /* @internal */
    ts.testFormatSettings = getDefaultFormatCodeSettings("\n");
    var SymbolDisplayPartKind;
    (function (SymbolDisplayPartKind) {
        SymbolDisplayPartKind[SymbolDisplayPartKind["aliasName"] = 0] = "aliasName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["className"] = 1] = "className";
        SymbolDisplayPartKind[SymbolDisplayPartKind["enumName"] = 2] = "enumName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["fieldName"] = 3] = "fieldName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["interfaceName"] = 4] = "interfaceName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["keyword"] = 5] = "keyword";
        SymbolDisplayPartKind[SymbolDisplayPartKind["lineBreak"] = 6] = "lineBreak";
        SymbolDisplayPartKind[SymbolDisplayPartKind["numericLiteral"] = 7] = "numericLiteral";
        SymbolDisplayPartKind[SymbolDisplayPartKind["stringLiteral"] = 8] = "stringLiteral";
        SymbolDisplayPartKind[SymbolDisplayPartKind["localName"] = 9] = "localName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["methodName"] = 10] = "methodName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["moduleName"] = 11] = "moduleName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["operator"] = 12] = "operator";
        SymbolDisplayPartKind[SymbolDisplayPartKind["parameterName"] = 13] = "parameterName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["propertyName"] = 14] = "propertyName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["punctuation"] = 15] = "punctuation";
        SymbolDisplayPartKind[SymbolDisplayPartKind["space"] = 16] = "space";
        SymbolDisplayPartKind[SymbolDisplayPartKind["text"] = 17] = "text";
        SymbolDisplayPartKind[SymbolDisplayPartKind["typeParameterName"] = 18] = "typeParameterName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["enumMemberName"] = 19] = "enumMemberName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["functionName"] = 20] = "functionName";
        SymbolDisplayPartKind[SymbolDisplayPartKind["regularExpressionLiteral"] = 21] = "regularExpressionLiteral";
    })(SymbolDisplayPartKind = ts.SymbolDisplayPartKind || (ts.SymbolDisplayPartKind = {}));
    var OutliningSpanKind;
    (function (OutliningSpanKind) {
        /** Single or multi-line comments */
        OutliningSpanKind["Comment"] = "comment";
        /** Sections marked by '// #region' and '// #endregion' comments */
        OutliningSpanKind["Region"] = "region";
        /** Declarations and expressions */
        OutliningSpanKind["Code"] = "code";
        /** Contiguous blocks of import declarations */
        OutliningSpanKind["Imports"] = "imports";
    })(OutliningSpanKind = ts.OutliningSpanKind || (ts.OutliningSpanKind = {}));
    var OutputFileType;
    (function (OutputFileType) {
        OutputFileType[OutputFileType["JavaScript"] = 0] = "JavaScript";
        OutputFileType[OutputFileType["SourceMap"] = 1] = "SourceMap";
        OutputFileType[OutputFileType["Declaration"] = 2] = "Declaration";
    })(OutputFileType = ts.OutputFileType || (ts.OutputFileType = {}));
    var EndOfLineState;
    (function (EndOfLineState) {
        EndOfLineState[EndOfLineState["None"] = 0] = "None";
        EndOfLineState[EndOfLineState["InMultiLineCommentTrivia"] = 1] = "InMultiLineCommentTrivia";
        EndOfLineState[EndOfLineState["InSingleQuoteStringLiteral"] = 2] = "InSingleQuoteStringLiteral";
        EndOfLineState[EndOfLineState["InDoubleQuoteStringLiteral"] = 3] = "InDoubleQuoteStringLiteral";
        EndOfLineState[EndOfLineState["InTemplateHeadOrNoSubstitutionTemplate"] = 4] = "InTemplateHeadOrNoSubstitutionTemplate";
        EndOfLineState[EndOfLineState["InTemplateMiddleOrTail"] = 5] = "InTemplateMiddleOrTail";
        EndOfLineState[EndOfLineState["InTemplateSubstitutionPosition"] = 6] = "InTemplateSubstitutionPosition";
    })(EndOfLineState = ts.EndOfLineState || (ts.EndOfLineState = {}));
    var TokenClass;
    (function (TokenClass) {
        TokenClass[TokenClass["Punctuation"] = 0] = "Punctuation";
        TokenClass[TokenClass["Keyword"] = 1] = "Keyword";
        TokenClass[TokenClass["Operator"] = 2] = "Operator";
        TokenClass[TokenClass["Comment"] = 3] = "Comment";
        TokenClass[TokenClass["Whitespace"] = 4] = "Whitespace";
        TokenClass[TokenClass["Identifier"] = 5] = "Identifier";
        TokenClass[TokenClass["NumberLiteral"] = 6] = "NumberLiteral";
        TokenClass[TokenClass["BigIntLiteral"] = 7] = "BigIntLiteral";
        TokenClass[TokenClass["StringLiteral"] = 8] = "StringLiteral";
        TokenClass[TokenClass["RegExpLiteral"] = 9] = "RegExpLiteral";
    })(TokenClass = ts.TokenClass || (ts.TokenClass = {}));
    var ScriptElementKind;
    (function (ScriptElementKind) {
        ScriptElementKind["unknown"] = "";
        ScriptElementKind["warning"] = "warning";
        /** predefined type (void) or keyword (class) */
        ScriptElementKind["keyword"] = "keyword";
        /** top level script node */
        ScriptElementKind["scriptElement"] = "script";
        /** module foo {} */
        ScriptElementKind["moduleElement"] = "module";
        /** class X {} */
        ScriptElementKind["classElement"] = "class";
        /** var x = class X {} */
        ScriptElementKind["localClassElement"] = "local class";
        /** interface Y {} */
        ScriptElementKind["interfaceElement"] = "interface";
        /** type T = ... */
        ScriptElementKind["typeElement"] = "type";
        /** enum E */
        ScriptElementKind["enumElement"] = "enum";
        ScriptElementKind["enumMemberElement"] = "enum member";
        /**
         * Inside module and script only
         * const v = ..
         */
        ScriptElementKind["variableElement"] = "var";
        /** Inside function */
        ScriptElementKind["localVariableElement"] = "local var";
        /**
         * Inside module and script only
         * function f() { }
         */
        ScriptElementKind["functionElement"] = "function";
        /** Inside function */
        ScriptElementKind["localFunctionElement"] = "local function";
        /** class X { [public|private]* foo() {} } */
        ScriptElementKind["memberFunctionElement"] = "method";
        /** class X { [public|private]* [get|set] foo:number; } */
        ScriptElementKind["memberGetAccessorElement"] = "getter";
        ScriptElementKind["memberSetAccessorElement"] = "setter";
        /**
         * class X { [public|private]* foo:number; }
         * interface Y { foo:number; }
         */
        ScriptElementKind["memberVariableElement"] = "property";
        /** class X { constructor() { } } */
        ScriptElementKind["constructorImplementationElement"] = "constructor";
        /** interface Y { ():number; } */
        ScriptElementKind["callSignatureElement"] = "call";
        /** interface Y { []:number; } */
        ScriptElementKind["indexSignatureElement"] = "index";
        /** interface Y { new():Y; } */
        ScriptElementKind["constructSignatureElement"] = "construct";
        /** function foo(*Y*: string) */
        ScriptElementKind["parameterElement"] = "parameter";
        ScriptElementKind["typeParameterElement"] = "type parameter";
        ScriptElementKind["primitiveType"] = "primitive type";
        ScriptElementKind["label"] = "label";
        ScriptElementKind["alias"] = "alias";
        ScriptElementKind["constElement"] = "const";
        ScriptElementKind["letElement"] = "let";
        ScriptElementKind["directory"] = "directory";
        ScriptElementKind["externalModuleName"] = "external module name";
        /**
         * <JsxTagName attribute1 attribute2={0} />
         */
        ScriptElementKind["jsxAttribute"] = "JSX attribute";
        /** String literal */
        ScriptElementKind["string"] = "string";
    })(ScriptElementKind = ts.ScriptElementKind || (ts.ScriptElementKind = {}));
    var ScriptElementKindModifier;
    (function (ScriptElementKindModifier) {
        ScriptElementKindModifier["none"] = "";
        ScriptElementKindModifier["publicMemberModifier"] = "public";
        ScriptElementKindModifier["privateMemberModifier"] = "private";
        ScriptElementKindModifier["protectedMemberModifier"] = "protected";
        ScriptElementKindModifier["exportedModifier"] = "export";
        ScriptElementKindModifier["ambientModifier"] = "declare";
        ScriptElementKindModifier["staticModifier"] = "static";
        ScriptElementKindModifier["abstractModifier"] = "abstract";
        ScriptElementKindModifier["optionalModifier"] = "optional";
        ScriptElementKindModifier["dtsModifier"] = ".d.ts";
        ScriptElementKindModifier["tsModifier"] = ".ts";
        ScriptElementKindModifier["tsxModifier"] = ".tsx";
        ScriptElementKindModifier["jsModifier"] = ".js";
        ScriptElementKindModifier["jsxModifier"] = ".jsx";
        ScriptElementKindModifier["jsonModifier"] = ".json";
    })(ScriptElementKindModifier = ts.ScriptElementKindModifier || (ts.ScriptElementKindModifier = {}));
    var ClassificationTypeNames;
    (function (ClassificationTypeNames) {
        ClassificationTypeNames["comment"] = "comment";
        ClassificationTypeNames["identifier"] = "identifier";
        ClassificationTypeNames["keyword"] = "keyword";
        ClassificationTypeNames["numericLiteral"] = "number";
        ClassificationTypeNames["bigintLiteral"] = "bigint";
        ClassificationTypeNames["operator"] = "operator";
        ClassificationTypeNames["stringLiteral"] = "string";
        ClassificationTypeNames["whiteSpace"] = "whitespace";
        ClassificationTypeNames["text"] = "text";
        ClassificationTypeNames["punctuation"] = "punctuation";
        ClassificationTypeNames["className"] = "class name";
        ClassificationTypeNames["enumName"] = "enum name";
        ClassificationTypeNames["interfaceName"] = "interface name";
        ClassificationTypeNames["moduleName"] = "module name";
        ClassificationTypeNames["typeParameterName"] = "type parameter name";
        ClassificationTypeNames["typeAliasName"] = "type alias name";
        ClassificationTypeNames["parameterName"] = "parameter name";
        ClassificationTypeNames["docCommentTagName"] = "doc comment tag name";
        ClassificationTypeNames["jsxOpenTagName"] = "jsx open tag name";
        ClassificationTypeNames["jsxCloseTagName"] = "jsx close tag name";
        ClassificationTypeNames["jsxSelfClosingTagName"] = "jsx self closing tag name";
        ClassificationTypeNames["jsxAttribute"] = "jsx attribute";
        ClassificationTypeNames["jsxText"] = "jsx text";
        ClassificationTypeNames["jsxAttributeStringLiteralValue"] = "jsx attribute string literal value";
    })(ClassificationTypeNames = ts.ClassificationTypeNames || (ts.ClassificationTypeNames = {}));
    var ClassificationType;
    (function (ClassificationType) {
        ClassificationType[ClassificationType["comment"] = 1] = "comment";
        ClassificationType[ClassificationType["identifier"] = 2] = "identifier";
        ClassificationType[ClassificationType["keyword"] = 3] = "keyword";
        ClassificationType[ClassificationType["numericLiteral"] = 4] = "numericLiteral";
        ClassificationType[ClassificationType["operator"] = 5] = "operator";
        ClassificationType[ClassificationType["stringLiteral"] = 6] = "stringLiteral";
        ClassificationType[ClassificationType["regularExpressionLiteral"] = 7] = "regularExpressionLiteral";
        ClassificationType[ClassificationType["whiteSpace"] = 8] = "whiteSpace";
        ClassificationType[ClassificationType["text"] = 9] = "text";
        ClassificationType[ClassificationType["punctuation"] = 10] = "punctuation";
        ClassificationType[ClassificationType["className"] = 11] = "className";
        ClassificationType[ClassificationType["enumName"] = 12] = "enumName";
        ClassificationType[ClassificationType["interfaceName"] = 13] = "interfaceName";
        ClassificationType[ClassificationType["moduleName"] = 14] = "moduleName";
        ClassificationType[ClassificationType["typeParameterName"] = 15] = "typeParameterName";
        ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName";
        ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName";
        ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName";
        ClassificationType[ClassificationType["jsxOpenTagName"] = 19] = "jsxOpenTagName";
        ClassificationType[ClassificationType["jsxCloseTagName"] = 20] = "jsxCloseTagName";
        ClassificationType[ClassificationType["jsxSelfClosingTagName"] = 21] = "jsxSelfClosingTagName";
        ClassificationType[ClassificationType["jsxAttribute"] = 22] = "jsxAttribute";
        ClassificationType[ClassificationType["jsxText"] = 23] = "jsxText";
        ClassificationType[ClassificationType["jsxAttributeStringLiteralValue"] = 24] = "jsxAttributeStringLiteralValue";
        ClassificationType[ClassificationType["bigintLiteral"] = 25] = "bigintLiteral";
    })(ClassificationType = ts.ClassificationType || (ts.ClassificationType = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    // These utilities are common to multiple language service features.
    //#region
    ts.scanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ true);
    var SemanticMeaning;
    (function (SemanticMeaning) {
        SemanticMeaning[SemanticMeaning["None"] = 0] = "None";
        SemanticMeaning[SemanticMeaning["Value"] = 1] = "Value";
        SemanticMeaning[SemanticMeaning["Type"] = 2] = "Type";
        SemanticMeaning[SemanticMeaning["Namespace"] = 4] = "Namespace";
        SemanticMeaning[SemanticMeaning["All"] = 7] = "All";
    })(SemanticMeaning = ts.SemanticMeaning || (ts.SemanticMeaning = {}));
    function getMeaningFromDeclaration(node) {
        switch (node.kind) {
            case 242 /* VariableDeclaration */:
                return ts.isInJSFile(node) && ts.getJSDocEnumTag(node) ? 7 /* All */ : 1 /* Value */;
            case 156 /* Parameter */:
            case 191 /* BindingElement */:
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 281 /* PropertyAssignment */:
            case 282 /* ShorthandPropertyAssignment */:
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
            case 280 /* CatchClause */:
            case 273 /* JsxAttribute */:
                return 1 /* Value */;
            case 155 /* TypeParameter */:
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 173 /* TypeLiteral */:
                return 2 /* Type */;
            case 322 /* JSDocTypedefTag */:
                // If it has no name node, it shares the name with the value declaration below it.
                return node.name === undefined ? 1 /* Value */ | 2 /* Type */ : 2 /* Type */;
            case 284 /* EnumMember */:
            case 245 /* ClassDeclaration */:
                return 1 /* Value */ | 2 /* Type */;
            case 249 /* ModuleDeclaration */:
                if (ts.isAmbientModule(node)) {
                    return 4 /* Namespace */ | 1 /* Value */;
                }
                else if (ts.getModuleInstanceState(node) === 1 /* Instantiated */) {
                    return 4 /* Namespace */ | 1 /* Value */;
                }
                else {
                    return 4 /* Namespace */;
                }
            case 248 /* EnumDeclaration */:
            case 257 /* NamedImports */:
            case 258 /* ImportSpecifier */:
            case 253 /* ImportEqualsDeclaration */:
            case 254 /* ImportDeclaration */:
            case 259 /* ExportAssignment */:
            case 260 /* ExportDeclaration */:
                return 7 /* All */;
            // An external module can be a Value
            case 290 /* SourceFile */:
                return 4 /* Namespace */ | 1 /* Value */;
        }
        return 7 /* All */;
    }
    ts.getMeaningFromDeclaration = getMeaningFromDeclaration;
    function getMeaningFromLocation(node) {
        node = getAdjustedReferenceLocation(node);
        if (node.kind === 290 /* SourceFile */) {
            return 1 /* Value */;
        }
        else if (node.parent.kind === 259 /* ExportAssignment */
            || node.parent.kind === 265 /* ExternalModuleReference */
            || node.parent.kind === 258 /* ImportSpecifier */
            || node.parent.kind === 255 /* ImportClause */
            || ts.isImportEqualsDeclaration(node.parent) && node === node.parent.name) {
            return 7 /* All */;
        }
        else if (isInRightSideOfInternalImportEqualsDeclaration(node)) {
            return getMeaningFromRightHandSideOfImportEquals(node);
        }
        else if (ts.isDeclarationName(node)) {
            return getMeaningFromDeclaration(node.parent);
        }
        else if (isTypeReference(node)) {
            return 2 /* Type */;
        }
        else if (isNamespaceReference(node)) {
            return 4 /* Namespace */;
        }
        else if (ts.isTypeParameterDeclaration(node.parent)) {
            ts.Debug.assert(ts.isJSDocTemplateTag(node.parent.parent)); // Else would be handled by isDeclarationName
            return 2 /* Type */;
        }
        else if (ts.isLiteralTypeNode(node.parent)) {
            // This might be T["name"], which is actually referencing a property and not a type. So allow both meanings.
            return 2 /* Type */ | 1 /* Value */;
        }
        else {
            return 1 /* Value */;
        }
    }
    ts.getMeaningFromLocation = getMeaningFromLocation;
    function getMeaningFromRightHandSideOfImportEquals(node) {
        //     import a = |b|; // Namespace
        //     import a = |b.c|; // Value, type, namespace
        //     import a = |b.c|.d; // Namespace
        var name = node.kind === 153 /* QualifiedName */ ? node : ts.isQualifiedName(node.parent) && node.parent.right === node ? node.parent : undefined;
        return name && name.parent.kind === 253 /* ImportEqualsDeclaration */ ? 7 /* All */ : 4 /* Namespace */;
    }
    function isInRightSideOfInternalImportEqualsDeclaration(node) {
        while (node.parent.kind === 153 /* QualifiedName */) {
            node = node.parent;
        }
        return ts.isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node;
    }
    ts.isInRightSideOfInternalImportEqualsDeclaration = isInRightSideOfInternalImportEqualsDeclaration;
    function isNamespaceReference(node) {
        return isQualifiedNameNamespaceReference(node) || isPropertyAccessNamespaceReference(node);
    }
    function isQualifiedNameNamespaceReference(node) {
        var root = node;
        var isLastClause = true;
        if (root.parent.kind === 153 /* QualifiedName */) {
            while (root.parent && root.parent.kind === 153 /* QualifiedName */) {
                root = root.parent;
            }
            isLastClause = root.right === node;
        }
        return root.parent.kind === 169 /* TypeReference */ && !isLastClause;
    }
    function isPropertyAccessNamespaceReference(node) {
        var root = node;
        var isLastClause = true;
        if (root.parent.kind === 194 /* PropertyAccessExpression */) {
            while (root.parent && root.parent.kind === 194 /* PropertyAccessExpression */) {
                root = root.parent;
            }
            isLastClause = root.name === node;
        }
        if (!isLastClause && root.parent.kind === 216 /* ExpressionWithTypeArguments */ && root.parent.parent.kind === 279 /* HeritageClause */) {
            var decl = root.parent.parent.parent;
            return (decl.kind === 245 /* ClassDeclaration */ && root.parent.parent.token === 113 /* ImplementsKeyword */) ||
                (decl.kind === 246 /* InterfaceDeclaration */ && root.parent.parent.token === 90 /* ExtendsKeyword */);
        }
        return false;
    }
    function isTypeReference(node) {
        if (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
            node = node.parent;
        }
        switch (node.kind) {
            case 104 /* ThisKeyword */:
                return !ts.isExpressionNode(node);
            case 183 /* ThisType */:
                return true;
        }
        switch (node.parent.kind) {
            case 169 /* TypeReference */:
                return true;
            case 188 /* ImportType */:
                return !node.parent.isTypeOf;
            case 216 /* ExpressionWithTypeArguments */:
                return !ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent);
        }
        return false;
    }
    function isCallExpressionTarget(node, includeElementAccess, skipPastOuterExpressions) {
        if (includeElementAccess === void 0) { includeElementAccess = false; }
        if (skipPastOuterExpressions === void 0) { skipPastOuterExpressions = false; }
        return isCalleeWorker(node, ts.isCallExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions);
    }
    ts.isCallExpressionTarget = isCallExpressionTarget;
    function isNewExpressionTarget(node, includeElementAccess, skipPastOuterExpressions) {
        if (includeElementAccess === void 0) { includeElementAccess = false; }
        if (skipPastOuterExpressions === void 0) { skipPastOuterExpressions = false; }
        return isCalleeWorker(node, ts.isNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions);
    }
    ts.isNewExpressionTarget = isNewExpressionTarget;
    function isCallOrNewExpressionTarget(node, includeElementAccess, skipPastOuterExpressions) {
        if (includeElementAccess === void 0) { includeElementAccess = false; }
        if (skipPastOuterExpressions === void 0) { skipPastOuterExpressions = false; }
        return isCalleeWorker(node, ts.isCallOrNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions);
    }
    ts.isCallOrNewExpressionTarget = isCallOrNewExpressionTarget;
    function isTaggedTemplateTag(node, includeElementAccess, skipPastOuterExpressions) {
        if (includeElementAccess === void 0) { includeElementAccess = false; }
        if (skipPastOuterExpressions === void 0) { skipPastOuterExpressions = false; }
        return isCalleeWorker(node, ts.isTaggedTemplateExpression, selectTagOfTaggedTemplateExpression, includeElementAccess, skipPastOuterExpressions);
    }
    ts.isTaggedTemplateTag = isTaggedTemplateTag;
    function isDecoratorTarget(node, includeElementAccess, skipPastOuterExpressions) {
        if (includeElementAccess === void 0) { includeElementAccess = false; }
        if (skipPastOuterExpressions === void 0) { skipPastOuterExpressions = false; }
        return isCalleeWorker(node, ts.isDecorator, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions);
    }
    ts.isDecoratorTarget = isDecoratorTarget;
    function isJsxOpeningLikeElementTagName(node, includeElementAccess, skipPastOuterExpressions) {
        if (includeElementAccess === void 0) { includeElementAccess = false; }
        if (skipPastOuterExpressions === void 0) { skipPastOuterExpressions = false; }
        return isCalleeWorker(node, ts.isJsxOpeningLikeElement, selectTagNameOfJsxOpeningLikeElement, includeElementAccess, skipPastOuterExpressions);
    }
    ts.isJsxOpeningLikeElementTagName = isJsxOpeningLikeElementTagName;
    function selectExpressionOfCallOrNewExpressionOrDecorator(node) {
        return node.expression;
    }
    function selectTagOfTaggedTemplateExpression(node) {
        return node.tag;
    }
    function selectTagNameOfJsxOpeningLikeElement(node) {
        return node.tagName;
    }
    function isCalleeWorker(node, pred, calleeSelector, includeElementAccess, skipPastOuterExpressions) {
        var target = includeElementAccess ? climbPastPropertyOrElementAccess(node) : climbPastPropertyAccess(node);
        if (skipPastOuterExpressions) {
            target = ts.skipOuterExpressions(target);
        }
        return !!target && !!target.parent && pred(target.parent) && calleeSelector(target.parent) === target;
    }
    function climbPastPropertyAccess(node) {
        return isRightSideOfPropertyAccess(node) ? node.parent : node;
    }
    ts.climbPastPropertyAccess = climbPastPropertyAccess;
    function climbPastPropertyOrElementAccess(node) {
        return isRightSideOfPropertyAccess(node) || isArgumentExpressionOfElementAccess(node) ? node.parent : node;
    }
    ts.climbPastPropertyOrElementAccess = climbPastPropertyOrElementAccess;
    function getTargetLabel(referenceNode, labelName) {
        while (referenceNode) {
            if (referenceNode.kind === 238 /* LabeledStatement */ && referenceNode.label.escapedText === labelName) {
                return referenceNode.label;
            }
            referenceNode = referenceNode.parent;
        }
        return undefined;
    }
    ts.getTargetLabel = getTargetLabel;
    function hasPropertyAccessExpressionWithName(node, funcName) {
        if (!ts.isPropertyAccessExpression(node.expression)) {
            return false;
        }
        return node.expression.name.text === funcName;
    }
    ts.hasPropertyAccessExpressionWithName = hasPropertyAccessExpressionWithName;
    function isJumpStatementTarget(node) {
        var _a;
        return ts.isIdentifier(node) && ((_a = ts.tryCast(node.parent, ts.isBreakOrContinueStatement)) === null || _a === void 0 ? void 0 : _a.label) === node;
    }
    ts.isJumpStatementTarget = isJumpStatementTarget;
    function isLabelOfLabeledStatement(node) {
        var _a;
        return ts.isIdentifier(node) && ((_a = ts.tryCast(node.parent, ts.isLabeledStatement)) === null || _a === void 0 ? void 0 : _a.label) === node;
    }
    ts.isLabelOfLabeledStatement = isLabelOfLabeledStatement;
    function isLabelName(node) {
        return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
    }
    ts.isLabelName = isLabelName;
    function isTagName(node) {
        var _a;
        return ((_a = ts.tryCast(node.parent, ts.isJSDocTag)) === null || _a === void 0 ? void 0 : _a.tagName) === node;
    }
    ts.isTagName = isTagName;
    function isRightSideOfQualifiedName(node) {
        var _a;
        return ((_a = ts.tryCast(node.parent, ts.isQualifiedName)) === null || _a === void 0 ? void 0 : _a.right) === node;
    }
    ts.isRightSideOfQualifiedName = isRightSideOfQualifiedName;
    function isRightSideOfPropertyAccess(node) {
        var _a;
        return ((_a = ts.tryCast(node.parent, ts.isPropertyAccessExpression)) === null || _a === void 0 ? void 0 : _a.name) === node;
    }
    ts.isRightSideOfPropertyAccess = isRightSideOfPropertyAccess;
    function isArgumentExpressionOfElementAccess(node) {
        var _a;
        return ((_a = ts.tryCast(node.parent, ts.isElementAccessExpression)) === null || _a === void 0 ? void 0 : _a.argumentExpression) === node;
    }
    ts.isArgumentExpressionOfElementAccess = isArgumentExpressionOfElementAccess;
    function isNameOfModuleDeclaration(node) {
        var _a;
        return ((_a = ts.tryCast(node.parent, ts.isModuleDeclaration)) === null || _a === void 0 ? void 0 : _a.name) === node;
    }
    ts.isNameOfModuleDeclaration = isNameOfModuleDeclaration;
    function isNameOfFunctionDeclaration(node) {
        var _a;
        return ts.isIdentifier(node) && ((_a = ts.tryCast(node.parent, ts.isFunctionLike)) === null || _a === void 0 ? void 0 : _a.name) === node;
    }
    ts.isNameOfFunctionDeclaration = isNameOfFunctionDeclaration;
    function isLiteralNameOfPropertyDeclarationOrIndexAccess(node) {
        switch (node.parent.kind) {
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 281 /* PropertyAssignment */:
            case 284 /* EnumMember */:
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 249 /* ModuleDeclaration */:
                return ts.getNameOfDeclaration(node.parent) === node;
            case 195 /* ElementAccessExpression */:
                return node.parent.argumentExpression === node;
            case 154 /* ComputedPropertyName */:
                return true;
            case 187 /* LiteralType */:
                return node.parent.parent.kind === 185 /* IndexedAccessType */;
            default:
                return false;
        }
    }
    ts.isLiteralNameOfPropertyDeclarationOrIndexAccess = isLiteralNameOfPropertyDeclarationOrIndexAccess;
    function isExpressionOfExternalModuleImportEqualsDeclaration(node) {
        return ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
            ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node;
    }
    ts.isExpressionOfExternalModuleImportEqualsDeclaration = isExpressionOfExternalModuleImportEqualsDeclaration;
    function getContainerNode(node) {
        if (ts.isJSDocTypeAlias(node)) {
            // This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope.
            // node.parent = the JSDoc comment, node.parent.parent = the node having the comment.
            // Then we get parent again in the loop.
            node = node.parent.parent;
        }
        while (true) {
            node = node.parent;
            if (!node) {
                return undefined;
            }
            switch (node.kind) {
                case 290 /* SourceFile */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 245 /* ClassDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 248 /* EnumDeclaration */:
                case 249 /* ModuleDeclaration */:
                    return node;
            }
        }
    }
    ts.getContainerNode = getContainerNode;
    function getNodeKind(node) {
        switch (node.kind) {
            case 290 /* SourceFile */:
                return ts.isExternalModule(node) ? "module" /* moduleElement */ : "script" /* scriptElement */;
            case 249 /* ModuleDeclaration */:
                return "module" /* moduleElement */;
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
                return "class" /* classElement */;
            case 246 /* InterfaceDeclaration */: return "interface" /* interfaceElement */;
            case 247 /* TypeAliasDeclaration */:
            case 315 /* JSDocCallbackTag */:
            case 322 /* JSDocTypedefTag */:
                return "type" /* typeElement */;
            case 248 /* EnumDeclaration */: return "enum" /* enumElement */;
            case 242 /* VariableDeclaration */:
                return getKindOfVariableDeclaration(node);
            case 191 /* BindingElement */:
                return getKindOfVariableDeclaration(ts.getRootDeclaration(node));
            case 202 /* ArrowFunction */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
                return "function" /* functionElement */;
            case 163 /* GetAccessor */: return "getter" /* memberGetAccessorElement */;
            case 164 /* SetAccessor */: return "setter" /* memberSetAccessorElement */;
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
                return "method" /* memberFunctionElement */;
            case 281 /* PropertyAssignment */:
                var initializer = node.initializer;
                return ts.isFunctionLike(initializer) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */;
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 282 /* ShorthandPropertyAssignment */:
            case 283 /* SpreadAssignment */:
                return "property" /* memberVariableElement */;
            case 167 /* IndexSignature */: return "index" /* indexSignatureElement */;
            case 166 /* ConstructSignature */: return "construct" /* constructSignatureElement */;
            case 165 /* CallSignature */: return "call" /* callSignatureElement */;
            case 162 /* Constructor */: return "constructor" /* constructorImplementationElement */;
            case 155 /* TypeParameter */: return "type parameter" /* typeParameterElement */;
            case 284 /* EnumMember */: return "enum member" /* enumMemberElement */;
            case 156 /* Parameter */: return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) ? "property" /* memberVariableElement */ : "parameter" /* parameterElement */;
            case 253 /* ImportEqualsDeclaration */:
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
            case 256 /* NamespaceImport */:
            case 262 /* NamespaceExport */:
                return "alias" /* alias */;
            case 209 /* BinaryExpression */:
                var kind = ts.getAssignmentDeclarationKind(node);
                var right = node.right;
                switch (kind) {
                    case 7 /* ObjectDefinePropertyValue */:
                    case 8 /* ObjectDefinePropertyExports */:
                    case 9 /* ObjectDefinePrototypeProperty */:
                    case 0 /* None */:
                        return "" /* unknown */;
                    case 1 /* ExportsProperty */:
                    case 2 /* ModuleExports */:
                        var rightKind = getNodeKind(right);
                        return rightKind === "" /* unknown */ ? "const" /* constElement */ : rightKind;
                    case 3 /* PrototypeProperty */:
                        return ts.isFunctionExpression(right) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */;
                    case 4 /* ThisProperty */:
                        return "property" /* memberVariableElement */; // property
                    case 5 /* Property */:
                        // static method / property
                        return ts.isFunctionExpression(right) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */;
                    case 6 /* Prototype */:
                        return "local class" /* localClassElement */;
                    default: {
                        ts.assertType(kind);
                        return "" /* unknown */;
                    }
                }
            case 75 /* Identifier */:
                return ts.isImportClause(node.parent) ? "alias" /* alias */ : "" /* unknown */;
            case 259 /* ExportAssignment */:
                var scriptKind = getNodeKind(node.expression);
                // If the expression didn't come back with something (like it does for an identifiers)
                return scriptKind === "" /* unknown */ ? "const" /* constElement */ : scriptKind;
            default:
                return "" /* unknown */;
        }
        function getKindOfVariableDeclaration(v) {
            return ts.isVarConst(v)
                ? "const" /* constElement */
                : ts.isLet(v)
                    ? "let" /* letElement */
                    : "var" /* variableElement */;
        }
    }
    ts.getNodeKind = getNodeKind;
    function isThis(node) {
        switch (node.kind) {
            case 104 /* ThisKeyword */:
                // case SyntaxKind.ThisType: TODO: GH#9267
                return true;
            case 75 /* Identifier */:
                // 'this' as a parameter
                return ts.identifierIsThisKeyword(node) && node.parent.kind === 156 /* Parameter */;
            default:
                return false;
        }
    }
    ts.isThis = isThis;
    // Matches the beginning of a triple slash directive
    var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</;
    function getLineStartPositionForPosition(position, sourceFile) {
        var lineStarts = ts.getLineStarts(sourceFile);
        var line = sourceFile.getLineAndCharacterOfPosition(position).line;
        return lineStarts[line];
    }
    ts.getLineStartPositionForPosition = getLineStartPositionForPosition;
    function rangeContainsRange(r1, r2) {
        return startEndContainsRange(r1.pos, r1.end, r2);
    }
    ts.rangeContainsRange = rangeContainsRange;
    function rangeContainsRangeExclusive(r1, r2) {
        return rangeContainsPositionExclusive(r1, r2.pos) && rangeContainsPositionExclusive(r1, r2.end);
    }
    ts.rangeContainsRangeExclusive = rangeContainsRangeExclusive;
    function rangeContainsPosition(r, pos) {
        return r.pos <= pos && pos <= r.end;
    }
    ts.rangeContainsPosition = rangeContainsPosition;
    function rangeContainsPositionExclusive(r, pos) {
        return r.pos < pos && pos < r.end;
    }
    ts.rangeContainsPositionExclusive = rangeContainsPositionExclusive;
    function startEndContainsRange(start, end, range) {
        return start <= range.pos && end >= range.end;
    }
    ts.startEndContainsRange = startEndContainsRange;
    function rangeContainsStartEnd(range, start, end) {
        return range.pos <= start && range.end >= end;
    }
    ts.rangeContainsStartEnd = rangeContainsStartEnd;
    function rangeOverlapsWithStartEnd(r1, start, end) {
        return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end);
    }
    ts.rangeOverlapsWithStartEnd = rangeOverlapsWithStartEnd;
    function nodeOverlapsWithStartEnd(node, sourceFile, start, end) {
        return startEndOverlapsWithStartEnd(node.getStart(sourceFile), node.end, start, end);
    }
    ts.nodeOverlapsWithStartEnd = nodeOverlapsWithStartEnd;
    function startEndOverlapsWithStartEnd(start1, end1, start2, end2) {
        var start = Math.max(start1, start2);
        var end = Math.min(end1, end2);
        return start < end;
    }
    ts.startEndOverlapsWithStartEnd = startEndOverlapsWithStartEnd;
    /**
     * Assumes `candidate.start <= position` holds.
     */
    function positionBelongsToNode(candidate, position, sourceFile) {
        ts.Debug.assert(candidate.pos <= position);
        return position < candidate.end || !isCompletedNode(candidate, sourceFile);
    }
    ts.positionBelongsToNode = positionBelongsToNode;
    function isCompletedNode(n, sourceFile) {
        if (n === undefined || ts.nodeIsMissing(n)) {
            return false;
        }
        switch (n.kind) {
            case 245 /* ClassDeclaration */:
            case 246 /* InterfaceDeclaration */:
            case 248 /* EnumDeclaration */:
            case 193 /* ObjectLiteralExpression */:
            case 189 /* ObjectBindingPattern */:
            case 173 /* TypeLiteral */:
            case 223 /* Block */:
            case 250 /* ModuleBlock */:
            case 251 /* CaseBlock */:
            case 257 /* NamedImports */:
            case 261 /* NamedExports */:
                return nodeEndsWith(n, 19 /* CloseBraceToken */, sourceFile);
            case 280 /* CatchClause */:
                return isCompletedNode(n.block, sourceFile);
            case 197 /* NewExpression */:
                if (!n.arguments) {
                    return true;
                }
            // falls through
            case 196 /* CallExpression */:
            case 200 /* ParenthesizedExpression */:
            case 182 /* ParenthesizedType */:
                return nodeEndsWith(n, 21 /* CloseParenToken */, sourceFile);
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
                return isCompletedNode(n.type, sourceFile);
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 166 /* ConstructSignature */:
            case 165 /* CallSignature */:
            case 202 /* ArrowFunction */:
                if (n.body) {
                    return isCompletedNode(n.body, sourceFile);
                }
                if (n.type) {
                    return isCompletedNode(n.type, sourceFile);
                }
                // Even though type parameters can be unclosed, we can get away with
                // having at least a closing paren.
                return hasChildOfKind(n, 21 /* CloseParenToken */, sourceFile);
            case 249 /* ModuleDeclaration */:
                return !!n.body && isCompletedNode(n.body, sourceFile);
            case 227 /* IfStatement */:
                if (n.elseStatement) {
                    return isCompletedNode(n.elseStatement, sourceFile);
                }
                return isCompletedNode(n.thenStatement, sourceFile);
            case 226 /* ExpressionStatement */:
                return isCompletedNode(n.expression, sourceFile) ||
                    hasChildOfKind(n, 26 /* SemicolonToken */, sourceFile);
            case 192 /* ArrayLiteralExpression */:
            case 190 /* ArrayBindingPattern */:
            case 195 /* ElementAccessExpression */:
            case 154 /* ComputedPropertyName */:
            case 175 /* TupleType */:
                return nodeEndsWith(n, 23 /* CloseBracketToken */, sourceFile);
            case 167 /* IndexSignature */:
                if (n.type) {
                    return isCompletedNode(n.type, sourceFile);
                }
                return hasChildOfKind(n, 23 /* CloseBracketToken */, sourceFile);
            case 277 /* CaseClause */:
            case 278 /* DefaultClause */:
                // there is no such thing as terminator token for CaseClause/DefaultClause so for simplicity always consider them non-completed
                return false;
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
            case 229 /* WhileStatement */:
                return isCompletedNode(n.statement, sourceFile);
            case 228 /* DoStatement */:
                // rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')';
                return hasChildOfKind(n, 111 /* WhileKeyword */, sourceFile)
                    ? nodeEndsWith(n, 21 /* CloseParenToken */, sourceFile)
                    : isCompletedNode(n.statement, sourceFile);
            case 172 /* TypeQuery */:
                return isCompletedNode(n.exprName, sourceFile);
            case 204 /* TypeOfExpression */:
            case 203 /* DeleteExpression */:
            case 205 /* VoidExpression */:
            case 212 /* YieldExpression */:
            case 213 /* SpreadElement */:
                var unaryWordExpression = n;
                return isCompletedNode(unaryWordExpression.expression, sourceFile);
            case 198 /* TaggedTemplateExpression */:
                return isCompletedNode(n.template, sourceFile);
            case 211 /* TemplateExpression */:
                var lastSpan = ts.lastOrUndefined(n.templateSpans);
                return isCompletedNode(lastSpan, sourceFile);
            case 221 /* TemplateSpan */:
                return ts.nodeIsPresent(n.literal);
            case 260 /* ExportDeclaration */:
            case 254 /* ImportDeclaration */:
                return ts.nodeIsPresent(n.moduleSpecifier);
            case 207 /* PrefixUnaryExpression */:
                return isCompletedNode(n.operand, sourceFile);
            case 209 /* BinaryExpression */:
                return isCompletedNode(n.right, sourceFile);
            case 210 /* ConditionalExpression */:
                return isCompletedNode(n.whenFalse, sourceFile);
            default:
                return true;
        }
    }
    /*
     * Checks if node ends with 'expectedLastToken'.
     * If child at position 'length - 1' is 'SemicolonToken' it is skipped and 'expectedLastToken' is compared with child at position 'length - 2'.
     */
    function nodeEndsWith(n, expectedLastToken, sourceFile) {
        var children = n.getChildren(sourceFile);
        if (children.length) {
            var lastChild = ts.last(children);
            if (lastChild.kind === expectedLastToken) {
                return true;
            }
            else if (lastChild.kind === 26 /* SemicolonToken */ && children.length !== 1) {
                return children[children.length - 2].kind === expectedLastToken;
            }
        }
        return false;
    }
    function findListItemInfo(node) {
        var list = findContainingList(node);
        // It is possible at this point for syntaxList to be undefined, either if
        // node.parent had no list child, or if none of its list children contained
        // the span of node. If this happens, return undefined. The caller should
        // handle this case.
        if (!list) {
            return undefined;
        }
        var children = list.getChildren();
        var listItemIndex = ts.indexOfNode(children, node);
        return {
            listItemIndex: listItemIndex,
            list: list
        };
    }
    ts.findListItemInfo = findListItemInfo;
    function hasChildOfKind(n, kind, sourceFile) {
        return !!findChildOfKind(n, kind, sourceFile);
    }
    ts.hasChildOfKind = hasChildOfKind;
    function findChildOfKind(n, kind, sourceFile) {
        return ts.find(n.getChildren(sourceFile), function (c) { return c.kind === kind; });
    }
    ts.findChildOfKind = findChildOfKind;
    function findContainingList(node) {
        // The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will
        // be parented by the container of the SyntaxList, not the SyntaxList itself.
        // In order to find the list item index, we first need to locate SyntaxList itself and then search
        // for the position of the relevant node (or comma).
        var syntaxList = ts.find(node.parent.getChildren(), function (c) { return ts.isSyntaxList(c) && rangeContainsRange(c, node); });
        // Either we didn't find an appropriate list, or the list must contain us.
        ts.Debug.assert(!syntaxList || ts.contains(syntaxList.getChildren(), node));
        return syntaxList;
    }
    ts.findContainingList = findContainingList;
    function isDefaultModifier(node) {
        return node.kind === 84 /* DefaultKeyword */;
    }
    function isClassKeyword(node) {
        return node.kind === 80 /* ClassKeyword */;
    }
    function isFunctionKeyword(node) {
        return node.kind === 94 /* FunctionKeyword */;
    }
    function getAdjustedLocationForClass(node) {
        if (ts.isNamedDeclaration(node)) {
            return node.name;
        }
        if (ts.isClassDeclaration(node)) {
            // for class and function declarations, use the `default` modifier
            // when the declaration is unnamed.
            var defaultModifier = ts.find(node.modifiers, isDefaultModifier);
            if (defaultModifier)
                return defaultModifier;
        }
        if (ts.isClassExpression(node)) {
            // for class expressions, use the `class` keyword when the class is unnamed
            var classKeyword = ts.find(node.getChildren(), isClassKeyword);
            if (classKeyword)
                return classKeyword;
        }
    }
    function getAdjustedLocationForFunction(node) {
        if (ts.isNamedDeclaration(node)) {
            return node.name;
        }
        if (ts.isFunctionDeclaration(node)) {
            // for class and function declarations, use the `default` modifier
            // when the declaration is unnamed.
            var defaultModifier = ts.find(node.modifiers, isDefaultModifier);
            if (defaultModifier)
                return defaultModifier;
        }
        if (ts.isFunctionExpression(node)) {
            // for function expressions, use the `function` keyword when the function is unnamed
            var functionKeyword = ts.find(node.getChildren(), isFunctionKeyword);
            if (functionKeyword)
                return functionKeyword;
        }
    }
    function getAdjustedLocationForDeclaration(node, forRename) {
        if (!forRename) {
            switch (node.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return getAdjustedLocationForClass(node);
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                    return getAdjustedLocationForFunction(node);
            }
        }
        if (ts.isNamedDeclaration(node)) {
            return node.name;
        }
    }
    function getAdjustedLocationForImportDeclaration(node, forRename) {
        if (node.importClause) {
            if (node.importClause.name && node.importClause.namedBindings) {
                // do not adjust if we have both a name and named bindings
                return;
            }
            // /**/import [|name|] from ...;
            // import /**/type [|name|] from ...;
            if (node.importClause.name) {
                return node.importClause.name;
            }
            // /**/import { [|name|] } from ...;
            // /**/import { propertyName as [|name|] } from ...;
            // /**/import * as [|name|] from ...;
            // import /**/type { [|name|] } from ...;
            // import /**/type { propertyName as [|name|] } from ...;
            // import /**/type * as [|name|] from ...;
            if (node.importClause.namedBindings) {
                if (ts.isNamedImports(node.importClause.namedBindings)) {
                    // do nothing if there is more than one binding
                    var onlyBinding = ts.singleOrUndefined(node.importClause.namedBindings.elements);
                    if (!onlyBinding) {
                        return;
                    }
                    return onlyBinding.name;
                }
                else if (ts.isNamespaceImport(node.importClause.namedBindings)) {
                    return node.importClause.namedBindings.name;
                }
            }
        }
        if (!forRename) {
            // /**/import "[|module|]";
            // /**/import ... from "[|module|]";
            // import /**/type ... from "[|module|]";
            return node.moduleSpecifier;
        }
    }
    function getAdjustedLocationForExportDeclaration(node, forRename) {
        if (node.exportClause) {
            // /**/export { [|name|] } ...
            // /**/export { propertyName as [|name|] } ...
            // /**/export * as [|name|] ...
            // export /**/type { [|name|] } from ...
            // export /**/type { propertyName as [|name|] } from ...
            // export /**/type * as [|name|] ...
            if (ts.isNamedExports(node.exportClause)) {
                // do nothing if there is more than one binding
                var onlyBinding = ts.singleOrUndefined(node.exportClause.elements);
                if (!onlyBinding) {
                    return;
                }
                return node.exportClause.elements[0].name;
            }
            else if (ts.isNamespaceExport(node.exportClause)) {
                return node.exportClause.name;
            }
        }
        if (!forRename) {
            // /**/export * from "[|module|]";
            // export /**/type * from "[|module|]";
            return node.moduleSpecifier;
        }
    }
    function getAdjustedLocationForHeritageClause(node) {
        // /**/extends [|name|]
        // /**/implements [|name|]
        if (node.types.length === 1) {
            return node.types[0].expression;
        }
        // /**/extends name1, name2 ...
        // /**/implements name1, name2 ...
    }
    function getAdjustedLocation(node, forRename) {
        var parent = node.parent;
        // /**/<modifier> [|name|] ...
        // /**/<modifier> <class|interface|type|enum|module|namespace|function|get|set> [|name|] ...
        // /**/<class|interface|type|enum|module|namespace|function|get|set> [|name|] ...
        // /**/import [|name|] = ...
        //
        // NOTE: If the node is a modifier, we don't adjust its location if it is the `default` modifier as that is handled
        // specially by `getSymbolAtLocation`.
        if (ts.isModifier(node) && (forRename || node.kind !== 84 /* DefaultKeyword */) ? ts.contains(parent.modifiers, node) :
            node.kind === 80 /* ClassKeyword */ ? ts.isClassDeclaration(parent) || ts.isClassExpression(node) :
                node.kind === 94 /* FunctionKeyword */ ? ts.isFunctionDeclaration(parent) || ts.isFunctionExpression(node) :
                    node.kind === 114 /* InterfaceKeyword */ ? ts.isInterfaceDeclaration(parent) :
                        node.kind === 88 /* EnumKeyword */ ? ts.isEnumDeclaration(parent) :
                            node.kind === 145 /* TypeKeyword */ ? ts.isTypeAliasDeclaration(parent) :
                                node.kind === 136 /* NamespaceKeyword */ || node.kind === 135 /* ModuleKeyword */ ? ts.isModuleDeclaration(parent) :
                                    node.kind === 96 /* ImportKeyword */ ? ts.isImportEqualsDeclaration(parent) :
                                        node.kind === 131 /* GetKeyword */ ? ts.isGetAccessorDeclaration(parent) :
                                            node.kind === 142 /* SetKeyword */ && ts.isSetAccessorDeclaration(parent)) {
            var location = getAdjustedLocationForDeclaration(parent, forRename);
            if (location) {
                return location;
            }
        }
        // /**/<var|let|const> [|name|] ...
        if ((node.kind === 109 /* VarKeyword */ || node.kind === 81 /* ConstKeyword */ || node.kind === 115 /* LetKeyword */) &&
            ts.isVariableDeclarationList(parent) && parent.declarations.length === 1) {
            var decl = parent.declarations[0];
            if (ts.isIdentifier(decl.name)) {
                return decl.name;
            }
        }
        if (node.kind === 145 /* TypeKeyword */) {
            // import /**/type [|name|] from ...;
            // import /**/type { [|name|] } from ...;
            // import /**/type { propertyName as [|name|] } from ...;
            // import /**/type ... from "[|module|]";
            if (ts.isImportClause(parent) && parent.isTypeOnly) {
                var location = getAdjustedLocationForImportDeclaration(parent.parent, forRename);
                if (location) {
                    return location;
                }
            }
            // export /**/type { [|name|] } from ...;
            // export /**/type { propertyName as [|name|] } from ...;
            // export /**/type * from "[|module|]";
            // export /**/type * as ... from "[|module|]";
            if (ts.isExportDeclaration(parent) && parent.isTypeOnly) {
                var location = getAdjustedLocationForExportDeclaration(parent, forRename);
                if (location) {
                    return location;
                }
            }
        }
        // import { propertyName /**/as [|name|] } ...
        // import * /**/as [|name|] ...
        // export { propertyName /**/as [|name|] } ...
        // export * /**/as [|name|] ...
        if (node.kind === 123 /* AsKeyword */) {
            if (ts.isImportSpecifier(parent) && parent.propertyName ||
                ts.isExportSpecifier(parent) && parent.propertyName ||
                ts.isNamespaceImport(parent) ||
                ts.isNamespaceExport(parent)) {
                return parent.name;
            }
            if (ts.isExportDeclaration(parent) && parent.exportClause && ts.isNamespaceExport(parent.exportClause)) {
                return parent.exportClause.name;
            }
        }
        // /**/import [|name|] from ...;
        // /**/import { [|name|] } from ...;
        // /**/import { propertyName as [|name|] } from ...;
        // /**/import ... from "[|module|]";
        // /**/import "[|module|]";
        if (node.kind === 96 /* ImportKeyword */ && ts.isImportDeclaration(parent)) {
            var location = getAdjustedLocationForImportDeclaration(parent, forRename);
            if (location) {
                return location;
            }
        }
        if (node.kind === 89 /* ExportKeyword */) {
            // /**/export { [|name|] } ...;
            // /**/export { propertyName as [|name|] } ...;
            // /**/export * from "[|module|]";
            // /**/export * as ... from "[|module|]";
            if (ts.isExportDeclaration(parent)) {
                var location = getAdjustedLocationForExportDeclaration(parent, forRename);
                if (location) {
                    return location;
                }
            }
            // NOTE: We don't adjust the location of the `default` keyword as that is handled specially by `getSymbolAtLocation`.
            // /**/export default [|name|];
            // /**/export = [|name|];
            if (ts.isExportAssignment(parent)) {
                return ts.skipOuterExpressions(parent.expression);
            }
        }
        // import name = /**/require("[|module|]");
        if (node.kind === 139 /* RequireKeyword */ && ts.isExternalModuleReference(parent)) {
            return parent.expression;
        }
        // import ... /**/from "[|module|]";
        // export ... /**/from "[|module|]";
        if (node.kind === 149 /* FromKeyword */ && (ts.isImportDeclaration(parent) || ts.isExportDeclaration(parent)) && parent.moduleSpecifier) {
            return parent.moduleSpecifier;
        }
        // class ... /**/extends [|name|] ...
        // class ... /**/implements [|name|] ...
        // class ... /**/implements name1, name2 ...
        // interface ... /**/extends [|name|] ...
        // interface ... /**/extends name1, name2 ...
        if ((node.kind === 90 /* ExtendsKeyword */ || node.kind === 113 /* ImplementsKeyword */) && ts.isHeritageClause(parent) && parent.token === node.kind) {
            var location = getAdjustedLocationForHeritageClause(parent);
            if (location) {
                return location;
            }
        }
        if (node.kind === 90 /* ExtendsKeyword */) {
            // ... <T /**/extends [|U|]> ...
            if (ts.isTypeParameterDeclaration(parent) && parent.constraint && ts.isTypeReferenceNode(parent.constraint)) {
                return parent.constraint.typeName;
            }
            // ... T /**/extends [|U|] ? ...
            if (ts.isConditionalTypeNode(parent) && ts.isTypeReferenceNode(parent.extendsType)) {
                return parent.extendsType.typeName;
            }
        }
        // ... T extends /**/infer [|U|] ? ...
        if (node.kind === 132 /* InferKeyword */ && ts.isInferTypeNode(parent)) {
            return parent.typeParameter.name;
        }
        // { [ [|K|] /**/in keyof T]: ... }
        if (node.kind === 97 /* InKeyword */ && ts.isTypeParameterDeclaration(parent) && ts.isMappedTypeNode(parent.parent)) {
            return parent.name;
        }
        // /**/keyof [|T|]
        if (node.kind === 134 /* KeyOfKeyword */ && ts.isTypeOperatorNode(parent) && parent.operator === 134 /* KeyOfKeyword */ &&
            ts.isTypeReferenceNode(parent.type)) {
            return parent.type.typeName;
        }
        // /**/readonly [|name|][]
        if (node.kind === 138 /* ReadonlyKeyword */ && ts.isTypeOperatorNode(parent) && parent.operator === 138 /* ReadonlyKeyword */ &&
            ts.isArrayTypeNode(parent.type) && ts.isTypeReferenceNode(parent.type.elementType)) {
            return parent.type.elementType.typeName;
        }
        if (!forRename) {
            // /**/new [|name|]
            // /**/void [|name|]
            // /**/void obj.[|name|]
            // /**/typeof [|name|]
            // /**/typeof obj.[|name|]
            // /**/await [|name|]
            // /**/await obj.[|name|]
            // /**/yield [|name|]
            // /**/yield obj.[|name|]
            // /**/delete obj.[|name|]
            if (node.kind === 99 /* NewKeyword */ && ts.isNewExpression(parent) ||
                node.kind === 110 /* VoidKeyword */ && ts.isVoidExpression(parent) ||
                node.kind === 108 /* TypeOfKeyword */ && ts.isTypeOfExpression(parent) ||
                node.kind === 127 /* AwaitKeyword */ && ts.isAwaitExpression(parent) ||
                node.kind === 121 /* YieldKeyword */ && ts.isYieldExpression(parent) ||
                node.kind === 85 /* DeleteKeyword */ && ts.isDeleteExpression(parent)) {
                if (parent.expression) {
                    return ts.skipOuterExpressions(parent.expression);
                }
            }
            // left /**/in [|name|]
            // left /**/instanceof [|name|]
            if ((node.kind === 97 /* InKeyword */ || node.kind === 98 /* InstanceOfKeyword */) && ts.isBinaryExpression(parent) && parent.operatorToken === node) {
                return ts.skipOuterExpressions(parent.right);
            }
            // left /**/as [|name|]
            if (node.kind === 123 /* AsKeyword */ && ts.isAsExpression(parent) && ts.isTypeReferenceNode(parent.type)) {
                return parent.type.typeName;
            }
            // for (... /**/in [|name|])
            // for (... /**/of [|name|])
            if (node.kind === 97 /* InKeyword */ && ts.isForInStatement(parent) ||
                node.kind === 152 /* OfKeyword */ && ts.isForOfStatement(parent)) {
                return ts.skipOuterExpressions(parent.expression);
            }
        }
        return node;
    }
    /**
     * Adjusts the location used for "find references" and "go to definition" when the cursor was not
     * on a property name.
     */
    function getAdjustedReferenceLocation(node) {
        return getAdjustedLocation(node, /*forRename*/ false);
    }
    ts.getAdjustedReferenceLocation = getAdjustedReferenceLocation;
    /**
     * Adjusts the location used for "rename" when the cursor was not on a property name.
     */
    function getAdjustedRenameLocation(node) {
        return getAdjustedLocation(node, /*forRename*/ true);
    }
    ts.getAdjustedRenameLocation = getAdjustedRenameLocation;
    /**
     * Gets the token whose text has range [start, end) and
     * position >= start and (position < end or (position === end && token is literal or keyword or identifier))
     */
    function getTouchingPropertyName(sourceFile, position) {
        return getTouchingToken(sourceFile, position, function (n) { return ts.isPropertyNameLiteral(n) || ts.isKeyword(n.kind) || ts.isPrivateIdentifier(n); });
    }
    ts.getTouchingPropertyName = getTouchingPropertyName;
    /**
     * Returns the token if position is in [start, end).
     * If position === end, returns the preceding token if includeItemAtEndPosition(previousToken) === true
     */
    function getTouchingToken(sourceFile, position, includePrecedingTokenAtEndPosition) {
        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includePrecedingTokenAtEndPosition, /*includeEndPosition*/ false);
    }
    ts.getTouchingToken = getTouchingToken;
    /** Returns a token if position is in [start-of-leading-trivia, end) */
    function getTokenAtPosition(sourceFile, position) {
        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, /*includeEndPosition*/ false);
    }
    ts.getTokenAtPosition = getTokenAtPosition;
    /** Get the token whose text contains the position */
    function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includePrecedingTokenAtEndPosition, includeEndPosition) {
        var current = sourceFile;
        outer: while (true) {
            // find the child that contains 'position'
            for (var _i = 0, _a = current.getChildren(sourceFile); _i < _a.length; _i++) {
                var child = _a[_i];
                var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
                if (start > position) {
                    // If this child begins after position, then all subsequent children will as well.
                    break;
                }
                var end = child.getEnd();
                if (position < end || (position === end && (child.kind === 1 /* EndOfFileToken */ || includeEndPosition))) {
                    current = child;
                    continue outer;
                }
                else if (includePrecedingTokenAtEndPosition && end === position) {
                    var previousToken = findPrecedingToken(position, sourceFile, child);
                    if (previousToken && includePrecedingTokenAtEndPosition(previousToken)) {
                        return previousToken;
                    }
                }
            }
            return current;
        }
    }
    /**
     * The token on the left of the position is the token that strictly includes the position
     * or sits to the left of the cursor if it is on a boundary. For example
     *
     *   fo|o               -> will return foo
     *   foo <comment> |bar -> will return foo
     *
     */
    function findTokenOnLeftOfPosition(file, position) {
        // Ideally, getTokenAtPosition should return a token. However, it is currently
        // broken, so we do a check to make sure the result was indeed a token.
        var tokenAtPosition = getTokenAtPosition(file, position);
        if (ts.isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) {
            return tokenAtPosition;
        }
        return findPrecedingToken(position, file);
    }
    ts.findTokenOnLeftOfPosition = findTokenOnLeftOfPosition;
    function findNextToken(previousToken, parent, sourceFile) {
        return find(parent);
        function find(n) {
            if (ts.isToken(n) && n.pos === previousToken.end) {
                // this is token that starts at the end of previous token - return it
                return n;
            }
            return ts.firstDefined(n.getChildren(sourceFile), function (child) {
                var shouldDiveInChildNode = 
                // previous token is enclosed somewhere in the child
                (child.pos <= previousToken.pos && child.end > previousToken.end) ||
                    // previous token ends exactly at the beginning of child
                    (child.pos === previousToken.end);
                return shouldDiveInChildNode && nodeHasTokens(child, sourceFile) ? find(child) : undefined;
            });
        }
    }
    ts.findNextToken = findNextToken;
    /**
     * Finds the rightmost token satisfying `token.end <= position`,
     * excluding `JsxText` tokens containing only whitespace.
     */
    function findPrecedingToken(position, sourceFile, startNode, excludeJsdoc) {
        var result = find(startNode || sourceFile);
        ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result)));
        return result;
        function find(n) {
            if (isNonWhitespaceToken(n) && n.kind !== 1 /* EndOfFileToken */) {
                return n;
            }
            var children = n.getChildren(sourceFile);
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                // Note that the span of a node's tokens is [node.getStart(...), node.end).
                // Given that `position < child.end` and child has constituent tokens, we distinguish these cases:
                // 1) `position` precedes `child`'s tokens or `child` has no tokens (ie: in a comment or whitespace preceding `child`):
                // we need to find the last token in a previous child.
                // 2) `position` is within the same span: we recurse on `child`.
                if (position < child.end) {
                    var start = child.getStart(sourceFile, /*includeJsDoc*/ !excludeJsdoc);
                    var lookInPreviousChild = (start >= position) || // cursor in the leading trivia
                        !nodeHasTokens(child, sourceFile) ||
                        isWhiteSpaceOnlyJsxText(child);
                    if (lookInPreviousChild) {
                        // actual start of the node is past the position - previous token should be at the end of previous child
                        var candidate_1 = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i, sourceFile);
                        return candidate_1 && findRightmostToken(candidate_1, sourceFile);
                    }
                    else {
                        // candidate should be in this node
                        return find(child);
                    }
                }
            }
            ts.Debug.assert(startNode !== undefined || n.kind === 290 /* SourceFile */ || n.kind === 1 /* EndOfFileToken */ || ts.isJSDocCommentContainingNode(n));
            // Here we know that none of child token nodes embrace the position,
            // the only known case is when position is at the end of the file.
            // Try to find the rightmost token in the file without filtering.
            // Namely we are skipping the check: 'position < node.end'
            var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile);
            return candidate && findRightmostToken(candidate, sourceFile);
        }
    }
    ts.findPrecedingToken = findPrecedingToken;
    function isNonWhitespaceToken(n) {
        return ts.isToken(n) && !isWhiteSpaceOnlyJsxText(n);
    }
    function findRightmostToken(n, sourceFile) {
        if (isNonWhitespaceToken(n)) {
            return n;
        }
        var children = n.getChildren(sourceFile);
        var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile);
        return candidate && findRightmostToken(candidate, sourceFile);
    }
    /**
     * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens.
     */
    function findRightmostChildNodeWithTokens(children, exclusiveStartPosition, sourceFile) {
        for (var i = exclusiveStartPosition - 1; i >= 0; i--) {
            var child = children[i];
            if (isWhiteSpaceOnlyJsxText(child)) {
                ts.Debug.assert(i > 0, "`JsxText` tokens should not be the first child of `JsxElement | JsxSelfClosingElement`");
            }
            else if (nodeHasTokens(children[i], sourceFile)) {
                return children[i];
            }
        }
    }
    function isInString(sourceFile, position, previousToken) {
        if (previousToken === void 0) { previousToken = findPrecedingToken(position, sourceFile); }
        if (previousToken && ts.isStringTextContainingNode(previousToken)) {
            var start = previousToken.getStart(sourceFile);
            var end = previousToken.getEnd();
            // To be "in" one of these literals, the position has to be:
            //   1. entirely within the token text.
            //   2. at the end position of an unterminated token.
            //   3. at the end of a regular expression (due to trailing flags like '/foo/g').
            if (start < position && position < end) {
                return true;
            }
            if (position === end) {
                return !!previousToken.isUnterminated;
            }
        }
        return false;
    }
    ts.isInString = isInString;
    /**
     * returns true if the position is in between the open and close elements of an JSX expression.
     */
    function isInsideJsxElementOrAttribute(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        if (!token) {
            return false;
        }
        if (token.kind === 11 /* JsxText */) {
            return true;
        }
        // <div>Hello |</div>
        if (token.kind === 29 /* LessThanToken */ && token.parent.kind === 11 /* JsxText */) {
            return true;
        }
        // <div> { | </div> or <div a={| </div>
        if (token.kind === 29 /* LessThanToken */ && token.parent.kind === 276 /* JsxExpression */) {
            return true;
        }
        // <div> {
        // |
        // } < /div>
        if (token && token.kind === 19 /* CloseBraceToken */ && token.parent.kind === 276 /* JsxExpression */) {
            return true;
        }
        // <div>|</div>
        if (token.kind === 29 /* LessThanToken */ && token.parent.kind === 269 /* JsxClosingElement */) {
            return true;
        }
        return false;
    }
    ts.isInsideJsxElementOrAttribute = isInsideJsxElementOrAttribute;
    function isWhiteSpaceOnlyJsxText(node) {
        return ts.isJsxText(node) && node.containsOnlyTriviaWhiteSpaces;
    }
    function isInTemplateString(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        return ts.isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile);
    }
    ts.isInTemplateString = isInTemplateString;
    function isInJSXText(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        if (ts.isJsxText(token)) {
            return true;
        }
        if (token.kind === 18 /* OpenBraceToken */ && ts.isJsxExpression(token.parent) && ts.isJsxElement(token.parent.parent)) {
            return true;
        }
        if (token.kind === 29 /* LessThanToken */ && ts.isJsxOpeningLikeElement(token.parent) && ts.isJsxElement(token.parent.parent)) {
            return true;
        }
        return false;
    }
    ts.isInJSXText = isInJSXText;
    function findPrecedingMatchingToken(token, matchingTokenKind, sourceFile) {
        var tokenKind = token.kind;
        var remainingMatchingTokens = 0;
        while (true) {
            var preceding = findPrecedingToken(token.getFullStart(), sourceFile);
            if (!preceding) {
                return undefined;
            }
            token = preceding;
            if (token.kind === matchingTokenKind) {
                if (remainingMatchingTokens === 0) {
                    return token;
                }
                remainingMatchingTokens--;
            }
            else if (token.kind === tokenKind) {
                remainingMatchingTokens++;
            }
        }
    }
    ts.findPrecedingMatchingToken = findPrecedingMatchingToken;
    function removeOptionality(type, isOptionalExpression, isOptionalChain) {
        return isOptionalExpression ? type.getNonNullableType() :
            isOptionalChain ? type.getNonOptionalType() :
                type;
    }
    ts.removeOptionality = removeOptionality;
    function isPossiblyTypeArgumentPosition(token, sourceFile, checker) {
        var info = getPossibleTypeArgumentsInfo(token, sourceFile);
        return info !== undefined && (ts.isPartOfTypeNode(info.called) ||
            getPossibleGenericSignatures(info.called, info.nTypeArguments, checker).length !== 0 ||
            isPossiblyTypeArgumentPosition(info.called, sourceFile, checker));
    }
    ts.isPossiblyTypeArgumentPosition = isPossiblyTypeArgumentPosition;
    function getPossibleGenericSignatures(called, typeArgumentCount, checker) {
        var type = checker.getTypeAtLocation(called);
        if (ts.isOptionalChain(called.parent)) {
            type = removeOptionality(type, ts.isOptionalChainRoot(called.parent), /*isOptionalChain*/ true);
        }
        var signatures = ts.isNewExpression(called.parent) ? type.getConstructSignatures() : type.getCallSignatures();
        return signatures.filter(function (candidate) { return !!candidate.typeParameters && candidate.typeParameters.length >= typeArgumentCount; });
    }
    ts.getPossibleGenericSignatures = getPossibleGenericSignatures;
    // Get info for an expression like `f <` that may be the start of type arguments.
    function getPossibleTypeArgumentsInfo(tokenIn, sourceFile) {
        var token = tokenIn;
        // This function determines if the node could be type argument position
        // Since during editing, when type argument list is not complete,
        // the tree could be of any shape depending on the tokens parsed before current node,
        // scanning of the previous identifier followed by "<" before current node would give us better result
        // Note that we also balance out the already provided type arguments, arrays, object literals while doing so
        var remainingLessThanTokens = 0;
        var nTypeArguments = 0;
        while (token) {
            switch (token.kind) {
                case 29 /* LessThanToken */:
                    // Found the beginning of the generic argument expression
                    token = findPrecedingToken(token.getFullStart(), sourceFile);
                    if (token && token.kind === 28 /* QuestionDotToken */) {
                        token = findPrecedingToken(token.getFullStart(), sourceFile);
                    }
                    if (!token || !ts.isIdentifier(token))
                        return undefined;
                    if (!remainingLessThanTokens) {
                        return ts.isDeclarationName(token) ? undefined : { called: token, nTypeArguments: nTypeArguments };
                    }
                    remainingLessThanTokens--;
                    break;
                case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                    remainingLessThanTokens = +3;
                    break;
                case 48 /* GreaterThanGreaterThanToken */:
                    remainingLessThanTokens = +2;
                    break;
                case 31 /* GreaterThanToken */:
                    remainingLessThanTokens++;
                    break;
                case 19 /* CloseBraceToken */:
                    // This can be object type, skip until we find the matching open brace token
                    // Skip until the matching open brace token
                    token = findPrecedingMatchingToken(token, 18 /* OpenBraceToken */, sourceFile);
                    if (!token)
                        return undefined;
                    break;
                case 21 /* CloseParenToken */:
                    // This can be object type, skip until we find the matching open brace token
                    // Skip until the matching open brace token
                    token = findPrecedingMatchingToken(token, 20 /* OpenParenToken */, sourceFile);
                    if (!token)
                        return undefined;
                    break;
                case 23 /* CloseBracketToken */:
                    // This can be object type, skip until we find the matching open brace token
                    // Skip until the matching open brace token
                    token = findPrecedingMatchingToken(token, 22 /* OpenBracketToken */, sourceFile);
                    if (!token)
                        return undefined;
                    break;
                // Valid tokens in a type name. Skip.
                case 27 /* CommaToken */:
                    nTypeArguments++;
                    break;
                case 38 /* EqualsGreaterThanToken */:
                // falls through
                case 75 /* Identifier */:
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                // falls through
                case 108 /* TypeOfKeyword */:
                case 90 /* ExtendsKeyword */:
                case 134 /* KeyOfKeyword */:
                case 24 /* DotToken */:
                case 51 /* BarToken */:
                case 57 /* QuestionToken */:
                case 58 /* ColonToken */:
                    break;
                default:
                    if (ts.isTypeNode(token)) {
                        break;
                    }
                    // Invalid token in type
                    return undefined;
            }
            token = findPrecedingToken(token.getFullStart(), sourceFile);
        }
        return undefined;
    }
    ts.getPossibleTypeArgumentsInfo = getPossibleTypeArgumentsInfo;
    /**
     * Returns true if the cursor at position in sourceFile is within a comment.
     *
     * @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
     * @param predicate Additional predicate to test on the comment range.
     */
    function isInComment(sourceFile, position, tokenAtPosition) {
        return ts.formatting.getRangeOfEnclosingComment(sourceFile, position, /*precedingToken*/ undefined, tokenAtPosition);
    }
    ts.isInComment = isInComment;
    function hasDocComment(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        return !!ts.findAncestor(token, ts.isJSDoc);
    }
    ts.hasDocComment = hasDocComment;
    function nodeHasTokens(n, sourceFile) {
        // If we have a token or node that has a non-zero width, it must have tokens.
        // Note: getWidth() does not take trivia into account.
        return n.kind === 1 /* EndOfFileToken */ ? !!n.jsDoc : n.getWidth(sourceFile) !== 0;
    }
    function getNodeModifiers(node) {
        var flags = ts.isDeclaration(node) ? ts.getCombinedModifierFlags(node) : 0 /* None */;
        var result = [];
        if (flags & 8 /* Private */)
            result.push("private" /* privateMemberModifier */);
        if (flags & 16 /* Protected */)
            result.push("protected" /* protectedMemberModifier */);
        if (flags & 4 /* Public */)
            result.push("public" /* publicMemberModifier */);
        if (flags & 32 /* Static */)
            result.push("static" /* staticModifier */);
        if (flags & 128 /* Abstract */)
            result.push("abstract" /* abstractModifier */);
        if (flags & 1 /* Export */)
            result.push("export" /* exportedModifier */);
        if (node.flags & 8388608 /* Ambient */)
            result.push("declare" /* ambientModifier */);
        if (node.kind === 259 /* ExportAssignment */)
            result.push("export" /* exportedModifier */);
        return result.length > 0 ? result.join(",") : "" /* none */;
    }
    ts.getNodeModifiers = getNodeModifiers;
    function getTypeArgumentOrTypeParameterList(node) {
        if (node.kind === 169 /* TypeReference */ || node.kind === 196 /* CallExpression */) {
            return node.typeArguments;
        }
        if (ts.isFunctionLike(node) || node.kind === 245 /* ClassDeclaration */ || node.kind === 246 /* InterfaceDeclaration */) {
            return node.typeParameters;
        }
        return undefined;
    }
    ts.getTypeArgumentOrTypeParameterList = getTypeArgumentOrTypeParameterList;
    function isComment(kind) {
        return kind === 2 /* SingleLineCommentTrivia */ || kind === 3 /* MultiLineCommentTrivia */;
    }
    ts.isComment = isComment;
    function isStringOrRegularExpressionOrTemplateLiteral(kind) {
        if (kind === 10 /* StringLiteral */
            || kind === 13 /* RegularExpressionLiteral */
            || ts.isTemplateLiteralKind(kind)) {
            return true;
        }
        return false;
    }
    ts.isStringOrRegularExpressionOrTemplateLiteral = isStringOrRegularExpressionOrTemplateLiteral;
    function isPunctuation(kind) {
        return 18 /* FirstPunctuation */ <= kind && kind <= 74 /* LastPunctuation */;
    }
    ts.isPunctuation = isPunctuation;
    function isInsideTemplateLiteral(node, position, sourceFile) {
        return ts.isTemplateLiteralKind(node.kind)
            && (node.getStart(sourceFile) < position && position < node.end) || (!!node.isUnterminated && position === node.end);
    }
    ts.isInsideTemplateLiteral = isInsideTemplateLiteral;
    function isAccessibilityModifier(kind) {
        switch (kind) {
            case 119 /* PublicKeyword */:
            case 117 /* PrivateKeyword */:
            case 118 /* ProtectedKeyword */:
                return true;
        }
        return false;
    }
    ts.isAccessibilityModifier = isAccessibilityModifier;
    function cloneCompilerOptions(options) {
        var result = ts.clone(options);
        ts.setConfigFileInOptions(result, options && options.configFile);
        return result;
    }
    ts.cloneCompilerOptions = cloneCompilerOptions;
    function isArrayLiteralOrObjectLiteralDestructuringPattern(node) {
        if (node.kind === 192 /* ArrayLiteralExpression */ ||
            node.kind === 193 /* ObjectLiteralExpression */) {
            // [a,b,c] from:
            // [a, b, c] = someExpression;
            if (node.parent.kind === 209 /* BinaryExpression */ &&
                node.parent.left === node &&
                node.parent.operatorToken.kind === 62 /* EqualsToken */) {
                return true;
            }
            // [a, b, c] from:
            // for([a, b, c] of expression)
            if (node.parent.kind === 232 /* ForOfStatement */ &&
                node.parent.initializer === node) {
                return true;
            }
            // [a, b, c] of
            // [x, [a, b, c] ] = someExpression
            // or
            // {x, a: {a, b, c} } = someExpression
            if (isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.kind === 281 /* PropertyAssignment */ ? node.parent.parent : node.parent)) {
                return true;
            }
        }
        return false;
    }
    ts.isArrayLiteralOrObjectLiteralDestructuringPattern = isArrayLiteralOrObjectLiteralDestructuringPattern;
    function isInReferenceComment(sourceFile, position) {
        return isInReferenceCommentWorker(sourceFile, position, /*shouldBeReference*/ true);
    }
    ts.isInReferenceComment = isInReferenceComment;
    function isInNonReferenceComment(sourceFile, position) {
        return isInReferenceCommentWorker(sourceFile, position, /*shouldBeReference*/ false);
    }
    ts.isInNonReferenceComment = isInNonReferenceComment;
    function isInReferenceCommentWorker(sourceFile, position, shouldBeReference) {
        var range = isInComment(sourceFile, position, /*tokenAtPosition*/ undefined);
        return !!range && shouldBeReference === tripleSlashDirectivePrefixRegex.test(sourceFile.text.substring(range.pos, range.end));
    }
    function getReplacementSpanForContextToken(contextToken) {
        if (!contextToken)
            return undefined;
        switch (contextToken.kind) {
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
                return createTextSpanFromStringLiteralLikeContent(contextToken);
            default:
                return createTextSpanFromNode(contextToken);
        }
    }
    ts.getReplacementSpanForContextToken = getReplacementSpanForContextToken;
    function createTextSpanFromNode(node, sourceFile, endNode) {
        return ts.createTextSpanFromBounds(node.getStart(sourceFile), (endNode || node).getEnd());
    }
    ts.createTextSpanFromNode = createTextSpanFromNode;
    function createTextSpanFromStringLiteralLikeContent(node) {
        if (node.isUnterminated)
            return undefined;
        return ts.createTextSpanFromBounds(node.getStart() + 1, node.getEnd() - 1);
    }
    ts.createTextSpanFromStringLiteralLikeContent = createTextSpanFromStringLiteralLikeContent;
    function createTextRangeFromNode(node, sourceFile) {
        return ts.createRange(node.getStart(sourceFile), node.end);
    }
    ts.createTextRangeFromNode = createTextRangeFromNode;
    function createTextSpanFromRange(range) {
        return ts.createTextSpanFromBounds(range.pos, range.end);
    }
    ts.createTextSpanFromRange = createTextSpanFromRange;
    function createTextRangeFromSpan(span) {
        return ts.createRange(span.start, span.start + span.length);
    }
    ts.createTextRangeFromSpan = createTextRangeFromSpan;
    function createTextChangeFromStartLength(start, length, newText) {
        return createTextChange(ts.createTextSpan(start, length), newText);
    }
    ts.createTextChangeFromStartLength = createTextChangeFromStartLength;
    function createTextChange(span, newText) {
        return { span: span, newText: newText };
    }
    ts.createTextChange = createTextChange;
    ts.typeKeywords = [
        125 /* AnyKeyword */,
        124 /* AssertsKeyword */,
        151 /* BigIntKeyword */,
        128 /* BooleanKeyword */,
        91 /* FalseKeyword */,
        134 /* KeyOfKeyword */,
        137 /* NeverKeyword */,
        100 /* NullKeyword */,
        140 /* NumberKeyword */,
        141 /* ObjectKeyword */,
        138 /* ReadonlyKeyword */,
        143 /* StringKeyword */,
        144 /* SymbolKeyword */,
        106 /* TrueKeyword */,
        110 /* VoidKeyword */,
        146 /* UndefinedKeyword */,
        147 /* UniqueKeyword */,
        148 /* UnknownKeyword */,
    ];
    function isTypeKeyword(kind) {
        return ts.contains(ts.typeKeywords, kind);
    }
    ts.isTypeKeyword = isTypeKeyword;
    function isTypeKeywordToken(node) {
        return node.kind === 145 /* TypeKeyword */;
    }
    ts.isTypeKeywordToken = isTypeKeywordToken;
    /** True if the symbol is for an external module, as opposed to a namespace. */
    function isExternalModuleSymbol(moduleSymbol) {
        return !!(moduleSymbol.flags & 1536 /* Module */) && moduleSymbol.name.charCodeAt(0) === 34 /* doubleQuote */;
    }
    ts.isExternalModuleSymbol = isExternalModuleSymbol;
    function nodeSeenTracker() {
        var seen = [];
        return function (node) {
            var id = ts.getNodeId(node);
            return !seen[id] && (seen[id] = true);
        };
    }
    ts.nodeSeenTracker = nodeSeenTracker;
    function getSnapshotText(snap) {
        return snap.getText(0, snap.getLength());
    }
    ts.getSnapshotText = getSnapshotText;
    function repeatString(str, count) {
        var result = "";
        for (var i = 0; i < count; i++) {
            result += str;
        }
        return result;
    }
    ts.repeatString = repeatString;
    function skipConstraint(type) {
        return type.isTypeParameter() ? type.getConstraint() || type : type;
    }
    ts.skipConstraint = skipConstraint;
    function getNameFromPropertyName(name) {
        return name.kind === 154 /* ComputedPropertyName */
            // treat computed property names where expression is string/numeric literal as just string/numeric literal
            ? ts.isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined
            : ts.isPrivateIdentifier(name) ? ts.idText(name) : ts.getTextOfIdentifierOrLiteral(name);
    }
    ts.getNameFromPropertyName = getNameFromPropertyName;
    function programContainsModules(program) {
        return program.getSourceFiles().some(function (s) { return !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!(s.externalModuleIndicator || s.commonJsModuleIndicator); });
    }
    ts.programContainsModules = programContainsModules;
    function programContainsEs6Modules(program) {
        return program.getSourceFiles().some(function (s) { return !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator; });
    }
    ts.programContainsEs6Modules = programContainsEs6Modules;
    function compilerOptionsIndicateEs6Modules(compilerOptions) {
        return !!compilerOptions.module || compilerOptions.target >= 2 /* ES2015 */ || !!compilerOptions.noEmit;
    }
    ts.compilerOptionsIndicateEs6Modules = compilerOptionsIndicateEs6Modules;
    function createModuleSpecifierResolutionHost(program, host) {
        // Mix in `getProbableSymlinks` from Program when host doesn't have it
        // in order for non-Project hosts to have a symlinks cache.
        return {
            fileExists: function (fileName) { return program.fileExists(fileName); },
            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
            readFile: ts.maybeBind(host, host.readFile),
            useCaseSensitiveFileNames: ts.maybeBind(host, host.useCaseSensitiveFileNames),
            getProbableSymlinks: ts.maybeBind(host, host.getProbableSymlinks) || (function () { return program.getProbableSymlinks(); }),
            getGlobalTypingsCacheLocation: ts.maybeBind(host, host.getGlobalTypingsCacheLocation),
            getSourceFiles: function () { return program.getSourceFiles(); },
            redirectTargetsMap: program.redirectTargetsMap,
            getProjectReferenceRedirect: function (fileName) { return program.getProjectReferenceRedirect(fileName); },
            isSourceOfProjectReferenceRedirect: function (fileName) { return program.isSourceOfProjectReferenceRedirect(fileName); },
        };
    }
    ts.createModuleSpecifierResolutionHost = createModuleSpecifierResolutionHost;
    function getModuleSpecifierResolverHost(program, host) {
        return __assign(__assign({}, createModuleSpecifierResolutionHost(program, host)), { getCommonSourceDirectory: function () { return program.getCommonSourceDirectory(); } });
    }
    ts.getModuleSpecifierResolverHost = getModuleSpecifierResolverHost;
    function makeImportIfNecessary(defaultImport, namedImports, moduleSpecifier, quotePreference) {
        return defaultImport || namedImports && namedImports.length ? makeImport(defaultImport, namedImports, moduleSpecifier, quotePreference) : undefined;
    }
    ts.makeImportIfNecessary = makeImportIfNecessary;
    function makeImport(defaultImport, namedImports, moduleSpecifier, quotePreference, isTypeOnly) {
        return ts.createImportDeclaration(
        /*decorators*/ undefined, 
        /*modifiers*/ undefined, defaultImport || namedImports
            ? ts.createImportClause(defaultImport, namedImports && namedImports.length ? ts.createNamedImports(namedImports) : undefined, isTypeOnly)
            : undefined, typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier);
    }
    ts.makeImport = makeImport;
    function makeStringLiteral(text, quotePreference) {
        return ts.createLiteral(text, quotePreference === 0 /* Single */);
    }
    ts.makeStringLiteral = makeStringLiteral;
    var QuotePreference;
    (function (QuotePreference) {
        QuotePreference[QuotePreference["Single"] = 0] = "Single";
        QuotePreference[QuotePreference["Double"] = 1] = "Double";
    })(QuotePreference = ts.QuotePreference || (ts.QuotePreference = {}));
    function quotePreferenceFromString(str, sourceFile) {
        return ts.isStringDoubleQuoted(str, sourceFile) ? 1 /* Double */ : 0 /* Single */;
    }
    ts.quotePreferenceFromString = quotePreferenceFromString;
    function getQuotePreference(sourceFile, preferences) {
        if (preferences.quotePreference && preferences.quotePreference !== "auto") {
            return preferences.quotePreference === "single" ? 0 /* Single */ : 1 /* Double */;
        }
        else {
            var firstModuleSpecifier = sourceFile.imports && ts.find(sourceFile.imports, ts.isStringLiteral);
            return firstModuleSpecifier ? quotePreferenceFromString(firstModuleSpecifier, sourceFile) : 1 /* Double */;
        }
    }
    ts.getQuotePreference = getQuotePreference;
    function getQuoteFromPreference(qp) {
        switch (qp) {
            case 0 /* Single */: return "'";
            case 1 /* Double */: return '"';
            default: return ts.Debug.assertNever(qp);
        }
    }
    ts.getQuoteFromPreference = getQuoteFromPreference;
    function symbolNameNoDefault(symbol) {
        var escaped = symbolEscapedNameNoDefault(symbol);
        return escaped === undefined ? undefined : ts.unescapeLeadingUnderscores(escaped);
    }
    ts.symbolNameNoDefault = symbolNameNoDefault;
    function symbolEscapedNameNoDefault(symbol) {
        if (symbol.escapedName !== "default" /* Default */) {
            return symbol.escapedName;
        }
        return ts.firstDefined(symbol.declarations, function (decl) {
            var name = ts.getNameOfDeclaration(decl);
            return name && name.kind === 75 /* Identifier */ ? name.escapedText : undefined;
        });
    }
    ts.symbolEscapedNameNoDefault = symbolEscapedNameNoDefault;
    function isObjectBindingElementWithoutPropertyName(bindingElement) {
        return ts.isBindingElement(bindingElement) &&
            ts.isObjectBindingPattern(bindingElement.parent) &&
            ts.isIdentifier(bindingElement.name) &&
            !bindingElement.propertyName;
    }
    ts.isObjectBindingElementWithoutPropertyName = isObjectBindingElementWithoutPropertyName;
    function getPropertySymbolFromBindingElement(checker, bindingElement) {
        var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
        return typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
    }
    ts.getPropertySymbolFromBindingElement = getPropertySymbolFromBindingElement;
    /**
     * Find symbol of the given property-name and add the symbol to the given result array
     * @param symbol a symbol to start searching for the given propertyName
     * @param propertyName a name of property to search for
     * @param result an array of symbol of found property symbols
     * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol.
     *                                The value of previousIterationSymbol is undefined when the function is first called.
     */
    function getPropertySymbolsFromBaseTypes(symbol, propertyName, checker, cb) {
        var seen = ts.createMap();
        return recur(symbol);
        function recur(symbol) {
            // Use `addToSeen` to ensure we don't infinitely recurse in this situation:
            //      interface C extends C {
            //          /*findRef*/propName: string;
            //      }
            if (!(symbol.flags & (32 /* Class */ | 64 /* Interface */)) || !ts.addToSeen(seen, ts.getSymbolId(symbol)))
                return;
            return ts.firstDefined(symbol.declarations, function (declaration) { return ts.firstDefined(ts.getAllSuperTypeNodes(declaration), function (typeReference) {
                var type = checker.getTypeAtLocation(typeReference);
                var propertySymbol = type && type.symbol && checker.getPropertyOfType(type, propertyName);
                // Visit the typeReference as well to see if it directly or indirectly uses that property
                return type && propertySymbol && (ts.firstDefined(checker.getRootSymbols(propertySymbol), cb) || recur(type.symbol));
            }); });
        }
    }
    ts.getPropertySymbolsFromBaseTypes = getPropertySymbolsFromBaseTypes;
    function isMemberSymbolInBaseType(memberSymbol, checker) {
        return getPropertySymbolsFromBaseTypes(memberSymbol.parent, memberSymbol.name, checker, function (_) { return true; }) || false;
    }
    ts.isMemberSymbolInBaseType = isMemberSymbolInBaseType;
    function getParentNodeInSpan(node, file, span) {
        if (!node)
            return undefined;
        while (node.parent) {
            if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) {
                return node;
            }
            node = node.parent;
        }
    }
    ts.getParentNodeInSpan = getParentNodeInSpan;
    function spanContainsNode(span, node, file) {
        return ts.textSpanContainsPosition(span, node.getStart(file)) &&
            node.getEnd() <= ts.textSpanEnd(span);
    }
    function findModifier(node, kind) {
        return node.modifiers && ts.find(node.modifiers, function (m) { return m.kind === kind; });
    }
    ts.findModifier = findModifier;
    function insertImports(changes, sourceFile, imports, blankLineBetween) {
        var decl = ts.isArray(imports) ? imports[0] : imports;
        var importKindPredicate = decl.kind === 225 /* VariableStatement */ ? ts.isRequireVariableDeclarationStatement : ts.isAnyImportSyntax;
        var lastImportDeclaration = ts.findLast(sourceFile.statements, function (statement) { return importKindPredicate(statement); });
        if (lastImportDeclaration) {
            if (ts.isArray(imports)) {
                changes.insertNodesAfter(sourceFile, lastImportDeclaration, imports);
            }
            else {
                changes.insertNodeAfter(sourceFile, lastImportDeclaration, imports);
            }
        }
        else if (ts.isArray(imports)) {
            changes.insertNodesAtTopOfFile(sourceFile, imports, blankLineBetween);
        }
        else {
            changes.insertNodeAtTopOfFile(sourceFile, imports, blankLineBetween);
        }
    }
    ts.insertImports = insertImports;
    function getTypeKeywordOfTypeOnlyImport(importClause, sourceFile) {
        ts.Debug.assert(importClause.isTypeOnly);
        return ts.cast(importClause.getChildAt(0, sourceFile), isTypeKeywordToken);
    }
    ts.getTypeKeywordOfTypeOnlyImport = getTypeKeywordOfTypeOnlyImport;
    function textSpansEqual(a, b) {
        return !!a && !!b && a.start === b.start && a.length === b.length;
    }
    ts.textSpansEqual = textSpansEqual;
    function documentSpansEqual(a, b) {
        return a.fileName === b.fileName && textSpansEqual(a.textSpan, b.textSpan);
    }
    ts.documentSpansEqual = documentSpansEqual;
    /**
     * Iterates through 'array' by index and performs the callback on each element of array until the callback
     * returns a truthy value, then returns that value.
     * If no such value is found, the callback is applied to each element of array and undefined is returned.
     */
    function forEachUnique(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                if (array.indexOf(array[i]) === i) {
                    var result = callback(array[i], i);
                    if (result) {
                        return result;
                    }
                }
            }
        }
        return undefined;
    }
    ts.forEachUnique = forEachUnique;
    // #endregion
    // Display-part writer helpers
    // #region
    function isFirstDeclarationOfSymbolParameter(symbol) {
        return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === 156 /* Parameter */;
    }
    ts.isFirstDeclarationOfSymbolParameter = isFirstDeclarationOfSymbolParameter;
    var displayPartWriter = getDisplayPartWriter();
    function getDisplayPartWriter() {
        var absoluteMaximumLength = ts.defaultMaximumTruncationLength * 10; // A hard cutoff to avoid overloading the messaging channel in worst-case scenarios
        var displayParts;
        var lineStart;
        var indent;
        var length;
        resetWriter();
        var unknownWrite = function (text) { return writeKind(text, ts.SymbolDisplayPartKind.text); };
        return {
            displayParts: function () {
                var finalText = displayParts.length && displayParts[displayParts.length - 1].text;
                if (length > absoluteMaximumLength && finalText && finalText !== "...") {
                    if (!ts.isWhiteSpaceLike(finalText.charCodeAt(finalText.length - 1))) {
                        displayParts.push(displayPart(" ", ts.SymbolDisplayPartKind.space));
                    }
                    displayParts.push(displayPart("...", ts.SymbolDisplayPartKind.punctuation));
                }
                return displayParts;
            },
            writeKeyword: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.keyword); },
            writeOperator: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.operator); },
            writePunctuation: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.punctuation); },
            writeTrailingSemicolon: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.punctuation); },
            writeSpace: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.space); },
            writeStringLiteral: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.stringLiteral); },
            writeParameter: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.parameterName); },
            writeProperty: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.propertyName); },
            writeLiteral: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.stringLiteral); },
            writeSymbol: writeSymbol,
            writeLine: writeLine,
            write: unknownWrite,
            writeComment: unknownWrite,
            getText: function () { return ""; },
            getTextPos: function () { return 0; },
            getColumn: function () { return 0; },
            getLine: function () { return 0; },
            isAtStartOfLine: function () { return false; },
            hasTrailingWhitespace: function () { return false; },
            hasTrailingComment: function () { return false; },
            rawWrite: ts.notImplemented,
            getIndent: function () { return indent; },
            increaseIndent: function () { indent++; },
            decreaseIndent: function () { indent--; },
            clear: resetWriter,
            trackSymbol: ts.noop,
            reportInaccessibleThisError: ts.noop,
            reportInaccessibleUniqueSymbolError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
        };
        function writeIndent() {
            if (length > absoluteMaximumLength)
                return;
            if (lineStart) {
                var indentString = ts.getIndentString(indent);
                if (indentString) {
                    length += indentString.length;
                    displayParts.push(displayPart(indentString, ts.SymbolDisplayPartKind.space));
                }
                lineStart = false;
            }
        }
        function writeKind(text, kind) {
            if (length > absoluteMaximumLength)
                return;
            writeIndent();
            length += text.length;
            displayParts.push(displayPart(text, kind));
        }
        function writeSymbol(text, symbol) {
            if (length > absoluteMaximumLength)
                return;
            writeIndent();
            length += text.length;
            displayParts.push(symbolPart(text, symbol));
        }
        function writeLine() {
            if (length > absoluteMaximumLength)
                return;
            length += 1;
            displayParts.push(lineBreakPart());
            lineStart = true;
        }
        function resetWriter() {
            displayParts = [];
            lineStart = true;
            indent = 0;
            length = 0;
        }
    }
    function symbolPart(text, symbol) {
        return displayPart(text, displayPartKind(symbol));
        function displayPartKind(symbol) {
            var flags = symbol.flags;
            if (flags & 3 /* Variable */) {
                return isFirstDeclarationOfSymbolParameter(symbol) ? ts.SymbolDisplayPartKind.parameterName : ts.SymbolDisplayPartKind.localName;
            }
            else if (flags & 4 /* Property */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 32768 /* GetAccessor */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 65536 /* SetAccessor */) {
                return ts.SymbolDisplayPartKind.propertyName;
            }
            else if (flags & 8 /* EnumMember */) {
                return ts.SymbolDisplayPartKind.enumMemberName;
            }
            else if (flags & 16 /* Function */) {
                return ts.SymbolDisplayPartKind.functionName;
            }
            else if (flags & 32 /* Class */) {
                return ts.SymbolDisplayPartKind.className;
            }
            else if (flags & 64 /* Interface */) {
                return ts.SymbolDisplayPartKind.interfaceName;
            }
            else if (flags & 384 /* Enum */) {
                return ts.SymbolDisplayPartKind.enumName;
            }
            else if (flags & 1536 /* Module */) {
                return ts.SymbolDisplayPartKind.moduleName;
            }
            else if (flags & 8192 /* Method */) {
                return ts.SymbolDisplayPartKind.methodName;
            }
            else if (flags & 262144 /* TypeParameter */) {
                return ts.SymbolDisplayPartKind.typeParameterName;
            }
            else if (flags & 524288 /* TypeAlias */) {
                return ts.SymbolDisplayPartKind.aliasName;
            }
            else if (flags & 2097152 /* Alias */) {
                return ts.SymbolDisplayPartKind.aliasName;
            }
            return ts.SymbolDisplayPartKind.text;
        }
    }
    ts.symbolPart = symbolPart;
    function displayPart(text, kind) {
        return { text: text, kind: ts.SymbolDisplayPartKind[kind] };
    }
    ts.displayPart = displayPart;
    function spacePart() {
        return displayPart(" ", ts.SymbolDisplayPartKind.space);
    }
    ts.spacePart = spacePart;
    function keywordPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.keyword);
    }
    ts.keywordPart = keywordPart;
    function punctuationPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.punctuation);
    }
    ts.punctuationPart = punctuationPart;
    function operatorPart(kind) {
        return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.operator);
    }
    ts.operatorPart = operatorPart;
    function textOrKeywordPart(text) {
        var kind = ts.stringToToken(text);
        return kind === undefined
            ? textPart(text)
            : keywordPart(kind);
    }
    ts.textOrKeywordPart = textOrKeywordPart;
    function textPart(text) {
        return displayPart(text, ts.SymbolDisplayPartKind.text);
    }
    ts.textPart = textPart;
    var carriageReturnLineFeed = "\r\n";
    /**
     * The default is CRLF.
     */
    function getNewLineOrDefaultFromHost(host, formatSettings) {
        var _a;
        return (formatSettings === null || formatSettings === void 0 ? void 0 : formatSettings.newLineCharacter) || ((_a = host.getNewLine) === null || _a === void 0 ? void 0 : _a.call(host)) ||
            carriageReturnLineFeed;
    }
    ts.getNewLineOrDefaultFromHost = getNewLineOrDefaultFromHost;
    function lineBreakPart() {
        return displayPart("\n", ts.SymbolDisplayPartKind.lineBreak);
    }
    ts.lineBreakPart = lineBreakPart;
    function mapToDisplayParts(writeDisplayParts) {
        try {
            writeDisplayParts(displayPartWriter);
            return displayPartWriter.displayParts();
        }
        finally {
            displayPartWriter.clear();
        }
    }
    ts.mapToDisplayParts = mapToDisplayParts;
    function typeToDisplayParts(typechecker, type, enclosingDeclaration, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        return mapToDisplayParts(function (writer) {
            typechecker.writeType(type, enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */ | 16384 /* UseAliasDefinedOutsideCurrentScope */, writer);
        });
    }
    ts.typeToDisplayParts = typeToDisplayParts;
    function symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration, meaning, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        return mapToDisplayParts(function (writer) {
            typeChecker.writeSymbol(symbol, enclosingDeclaration, meaning, flags | 8 /* UseAliasDefinedOutsideCurrentScope */, writer);
        });
    }
    ts.symbolToDisplayParts = symbolToDisplayParts;
    function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        flags |= 16384 /* UseAliasDefinedOutsideCurrentScope */ | 1024 /* MultilineObjectLiterals */ | 32 /* WriteTypeArgumentsOfSignature */ | 8192 /* OmitParameterModifiers */;
        return mapToDisplayParts(function (writer) {
            typechecker.writeSignature(signature, enclosingDeclaration, flags, /*signatureKind*/ undefined, writer);
        });
    }
    ts.signatureToDisplayParts = signatureToDisplayParts;
    function isImportOrExportSpecifierName(location) {
        return !!location.parent && ts.isImportOrExportSpecifier(location.parent) && location.parent.propertyName === location;
    }
    ts.isImportOrExportSpecifierName = isImportOrExportSpecifierName;
    function scriptKindIs(fileName, host) {
        var scriptKinds = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            scriptKinds[_i - 2] = arguments[_i];
        }
        var scriptKind = getScriptKind(fileName, host);
        return ts.some(scriptKinds, function (k) { return k === scriptKind; });
    }
    ts.scriptKindIs = scriptKindIs;
    function getScriptKind(fileName, host) {
        // First check to see if the script kind was specified by the host. Chances are the host
        // may override the default script kind for the file extension.
        return ts.ensureScriptKind(fileName, host && host.getScriptKind && host.getScriptKind(fileName));
    }
    ts.getScriptKind = getScriptKind;
    function getSymbolTarget(symbol, checker) {
        var next = symbol;
        while (isAliasSymbol(next) || (isTransientSymbol(next) && next.target)) {
            if (isTransientSymbol(next) && next.target) {
                next = next.target;
            }
            else {
                next = ts.skipAlias(next, checker);
            }
        }
        return next;
    }
    ts.getSymbolTarget = getSymbolTarget;
    function isTransientSymbol(symbol) {
        return (symbol.flags & 33554432 /* Transient */) !== 0;
    }
    function isAliasSymbol(symbol) {
        return (symbol.flags & 2097152 /* Alias */) !== 0;
    }
    function getUniqueSymbolId(symbol, checker) {
        return ts.getSymbolId(ts.skipAlias(symbol, checker));
    }
    ts.getUniqueSymbolId = getUniqueSymbolId;
    function getFirstNonSpaceCharacterPosition(text, position) {
        while (ts.isWhiteSpaceLike(text.charCodeAt(position))) {
            position += 1;
        }
        return position;
    }
    ts.getFirstNonSpaceCharacterPosition = getFirstNonSpaceCharacterPosition;
    function getPrecedingNonSpaceCharacterPosition(text, position) {
        while (position > -1 && ts.isWhiteSpaceSingleLine(text.charCodeAt(position))) {
            position -= 1;
        }
        return position + 1;
    }
    ts.getPrecedingNonSpaceCharacterPosition = getPrecedingNonSpaceCharacterPosition;
    /**
     * Creates a deep, memberwise clone of a node with no source map location.
     *
     * WARNING: This is an expensive operation and is only intended to be used in refactorings
     * and code fixes (because those are triggered by explicit user actions).
     */
    function getSynthesizedDeepClone(node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = true; }
        var clone = node && getSynthesizedDeepCloneWorker(node);
        if (clone && !includeTrivia)
            suppressLeadingAndTrailingTrivia(clone);
        return clone;
    }
    ts.getSynthesizedDeepClone = getSynthesizedDeepClone;
    function getSynthesizedDeepCloneWithRenames(node, includeTrivia, renameMap, checker, callback) {
        if (includeTrivia === void 0) { includeTrivia = true; }
        var clone;
        if (renameMap && checker && ts.isBindingElement(node) && ts.isIdentifier(node.name) && ts.isObjectBindingPattern(node.parent)) {
            var symbol = checker.getSymbolAtLocation(node.name);
            var renameInfo = symbol && renameMap.get(String(ts.getSymbolId(symbol)));
            if (renameInfo && renameInfo.text !== (node.name || node.propertyName).getText()) {
                clone = ts.setOriginalNode(ts.createBindingElement(node.dotDotDotToken, node.propertyName || node.name, renameInfo, node.initializer), node);
            }
        }
        else if (renameMap && checker && ts.isIdentifier(node)) {
            var symbol = checker.getSymbolAtLocation(node);
            var renameInfo = symbol && renameMap.get(String(ts.getSymbolId(symbol)));
            if (renameInfo) {
                clone = ts.setOriginalNode(ts.createIdentifier(renameInfo.text), node);
            }
        }
        if (!clone) {
            clone = getSynthesizedDeepCloneWorker(node, renameMap, checker, callback);
        }
        if (clone && !includeTrivia)
            suppressLeadingAndTrailingTrivia(clone);
        if (callback && clone)
            callback(node, clone);
        return clone;
    }
    ts.getSynthesizedDeepCloneWithRenames = getSynthesizedDeepCloneWithRenames;
    function getSynthesizedDeepCloneWorker(node, renameMap, checker, callback) {
        var visited = (renameMap || checker || callback) ?
            ts.visitEachChild(node, wrapper, ts.nullTransformationContext) :
            ts.visitEachChild(node, getSynthesizedDeepClone, ts.nullTransformationContext);
        if (visited === node) {
            // This only happens for leaf nodes - internal nodes always see their children change.
            var clone_1 = ts.getSynthesizedClone(node);
            if (ts.isStringLiteral(clone_1)) {
                clone_1.textSourceNode = node;
            }
            else if (ts.isNumericLiteral(clone_1)) {
                clone_1.numericLiteralFlags = node.numericLiteralFlags;
            }
            return ts.setTextRange(clone_1, node);
        }
        // PERF: As an optimization, rather than calling getSynthesizedClone, we'll update
        // the new node created by visitEachChild with the extra changes getSynthesizedClone
        // would have made.
        visited.parent = undefined;
        return visited;
        function wrapper(node) {
            return getSynthesizedDeepCloneWithRenames(node, /*includeTrivia*/ true, renameMap, checker, callback);
        }
    }
    function getSynthesizedDeepClones(nodes, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = true; }
        return nodes && ts.createNodeArray(nodes.map(function (n) { return getSynthesizedDeepClone(n, includeTrivia); }), nodes.hasTrailingComma);
    }
    ts.getSynthesizedDeepClones = getSynthesizedDeepClones;
    /**
     * Sets EmitFlags to suppress leading and trailing trivia on the node.
     */
    function suppressLeadingAndTrailingTrivia(node) {
        suppressLeadingTrivia(node);
        suppressTrailingTrivia(node);
    }
    ts.suppressLeadingAndTrailingTrivia = suppressLeadingAndTrailingTrivia;
    /**
     * Sets EmitFlags to suppress leading trivia on the node.
     */
    function suppressLeadingTrivia(node) {
        addEmitFlagsRecursively(node, 512 /* NoLeadingComments */, getFirstChild);
    }
    ts.suppressLeadingTrivia = suppressLeadingTrivia;
    /**
     * Sets EmitFlags to suppress trailing trivia on the node.
     */
    function suppressTrailingTrivia(node) {
        addEmitFlagsRecursively(node, 1024 /* NoTrailingComments */, ts.getLastChild);
    }
    ts.suppressTrailingTrivia = suppressTrailingTrivia;
    function copyComments(sourceNode, targetNode) {
        var sourceFile = sourceNode.getSourceFile();
        var text = sourceFile.text;
        if (hasLeadingLineBreak(sourceNode, text)) {
            copyLeadingComments(sourceNode, targetNode, sourceFile);
        }
        else {
            copyTrailingAsLeadingComments(sourceNode, targetNode, sourceFile);
        }
        copyTrailingComments(sourceNode, targetNode, sourceFile);
    }
    ts.copyComments = copyComments;
    function hasLeadingLineBreak(node, text) {
        var start = node.getFullStart();
        var end = node.getStart();
        for (var i = start; i < end; i++) {
            if (text.charCodeAt(i) === 10 /* lineFeed */)
                return true;
        }
        return false;
    }
    function addEmitFlagsRecursively(node, flag, getChild) {
        ts.addEmitFlags(node, flag);
        var child = getChild(node);
        if (child)
            addEmitFlagsRecursively(child, flag, getChild);
    }
    function getFirstChild(node) {
        return node.forEachChild(function (child) { return child; });
    }
    function getUniqueName(baseName, sourceFile) {
        var nameText = baseName;
        for (var i = 1; !ts.isFileLevelUniqueName(sourceFile, nameText); i++) {
            nameText = baseName + "_" + i;
        }
        return nameText;
    }
    ts.getUniqueName = getUniqueName;
    /**
     * @return The index of the (only) reference to the extracted symbol.  We want the cursor
     * to be on the reference, rather than the declaration, because it's closer to where the
     * user was before extracting it.
     */
    function getRenameLocation(edits, renameFilename, name, preferLastLocation) {
        var delta = 0;
        var lastPos = -1;
        for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) {
            var _a = edits_1[_i], fileName = _a.fileName, textChanges_2 = _a.textChanges;
            ts.Debug.assert(fileName === renameFilename);
            for (var _b = 0, textChanges_1 = textChanges_2; _b < textChanges_1.length; _b++) {
                var change = textChanges_1[_b];
                var span = change.span, newText = change.newText;
                var index = indexInTextChange(newText, name);
                if (index !== -1) {
                    lastPos = span.start + delta + index;
                    // If the reference comes first, return immediately.
                    if (!preferLastLocation) {
                        return lastPos;
                    }
                }
                delta += newText.length - span.length;
            }
        }
        // If the declaration comes first, return the position of the last occurrence.
        ts.Debug.assert(preferLastLocation);
        ts.Debug.assert(lastPos >= 0);
        return lastPos;
    }
    ts.getRenameLocation = getRenameLocation;
    function copyLeadingComments(sourceNode, targetNode, sourceFile, commentKind, hasTrailingNewLine) {
        ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticLeadingComment));
    }
    ts.copyLeadingComments = copyLeadingComments;
    function copyTrailingComments(sourceNode, targetNode, sourceFile, commentKind, hasTrailingNewLine) {
        ts.forEachTrailingCommentRange(sourceFile.text, sourceNode.end, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticTrailingComment));
    }
    ts.copyTrailingComments = copyTrailingComments;
    /**
     * This function copies the trailing comments for the token that comes before `sourceNode`, as leading comments of `targetNode`.
     * This is useful because sometimes a comment that refers to `sourceNode` will be a leading comment for `sourceNode`, according to the
     * notion of trivia ownership, and instead will be a trailing comment for the token before `sourceNode`, e.g.:
     * `function foo(\* not leading comment for a *\ a: string) {}`
     * The comment refers to `a` but belongs to the `(` token, but we might want to copy it.
     */
    function copyTrailingAsLeadingComments(sourceNode, targetNode, sourceFile, commentKind, hasTrailingNewLine) {
        ts.forEachTrailingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticLeadingComment));
    }
    ts.copyTrailingAsLeadingComments = copyTrailingAsLeadingComments;
    function getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, cb) {
        return function (pos, end, kind, htnl) {
            if (kind === 3 /* MultiLineCommentTrivia */) {
                // Remove leading /*
                pos += 2;
                // Remove trailing */
                end -= 2;
            }
            else {
                // Remove leading //
                pos += 2;
            }
            cb(targetNode, commentKind || kind, sourceFile.text.slice(pos, end), hasTrailingNewLine !== undefined ? hasTrailingNewLine : htnl);
        };
    }
    function indexInTextChange(change, name) {
        if (ts.startsWith(change, name))
            return 0;
        // Add a " " to avoid references inside words
        var idx = change.indexOf(" " + name);
        if (idx === -1)
            idx = change.indexOf("." + name);
        if (idx === -1)
            idx = change.indexOf('"' + name);
        return idx === -1 ? -1 : idx + 1;
    }
    /* @internal */
    function needsParentheses(expression) {
        return ts.isBinaryExpression(expression) && expression.operatorToken.kind === 27 /* CommaToken */ || ts.isObjectLiteralExpression(expression);
    }
    ts.needsParentheses = needsParentheses;
    function getContextualTypeFromParent(node, checker) {
        var parent = node.parent;
        switch (parent.kind) {
            case 197 /* NewExpression */:
                return checker.getContextualType(parent);
            case 209 /* BinaryExpression */: {
                var _a = parent, left = _a.left, operatorToken = _a.operatorToken, right = _a.right;
                return isEqualityOperatorKind(operatorToken.kind)
                    ? checker.getTypeAtLocation(node === right ? left : right)
                    : checker.getContextualType(node);
            }
            case 277 /* CaseClause */:
                return parent.expression === node ? getSwitchedType(parent, checker) : undefined;
            default:
                return checker.getContextualType(node);
        }
    }
    ts.getContextualTypeFromParent = getContextualTypeFromParent;
    function quote(text, preferences) {
        // Editors can pass in undefined or empty string - we want to infer the preference in those cases.
        var quotePreference = preferences.quotePreference || "auto";
        var quoted = JSON.stringify(text);
        switch (quotePreference) {
            // TODO use getQuotePreference to infer the actual quote style.
            case "auto":
            case "double":
                return quoted;
            case "single":
                return "'" + ts.stripQuotes(quoted).replace("'", "\\'").replace('\\"', '"') + "'";
            default:
                return ts.Debug.assertNever(quotePreference);
        }
    }
    ts.quote = quote;
    function isEqualityOperatorKind(kind) {
        switch (kind) {
            case 36 /* EqualsEqualsEqualsToken */:
            case 34 /* EqualsEqualsToken */:
            case 37 /* ExclamationEqualsEqualsToken */:
            case 35 /* ExclamationEqualsToken */:
                return true;
            default:
                return false;
        }
    }
    ts.isEqualityOperatorKind = isEqualityOperatorKind;
    function isStringLiteralOrTemplate(node) {
        switch (node.kind) {
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 211 /* TemplateExpression */:
            case 198 /* TaggedTemplateExpression */:
                return true;
            default:
                return false;
        }
    }
    ts.isStringLiteralOrTemplate = isStringLiteralOrTemplate;
    function hasIndexSignature(type) {
        return !!type.getStringIndexType() || !!type.getNumberIndexType();
    }
    ts.hasIndexSignature = hasIndexSignature;
    function getSwitchedType(caseClause, checker) {
        return checker.getTypeAtLocation(caseClause.parent.parent.expression);
    }
    ts.getSwitchedType = getSwitchedType;
    ts.ANONYMOUS = "anonymous function";
    function getTypeNodeIfAccessible(type, enclosingScope, program, host) {
        var checker = program.getTypeChecker();
        var typeIsAccessible = true;
        var notAccessible = function () { typeIsAccessible = false; };
        var res = checker.typeToTypeNode(type, enclosingScope, /*flags*/ undefined, {
            trackSymbol: function (symbol, declaration, meaning) {
                typeIsAccessible = typeIsAccessible && checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility === 0 /* Accessible */;
            },
            reportInaccessibleThisError: notAccessible,
            reportPrivateInBaseOfClassExpression: notAccessible,
            reportInaccessibleUniqueSymbolError: notAccessible,
            moduleResolverHost: getModuleSpecifierResolverHost(program, host)
        });
        return typeIsAccessible ? res : undefined;
    }
    ts.getTypeNodeIfAccessible = getTypeNodeIfAccessible;
    function syntaxRequiresTrailingCommaOrSemicolonOrASI(kind) {
        return kind === 165 /* CallSignature */
            || kind === 166 /* ConstructSignature */
            || kind === 167 /* IndexSignature */
            || kind === 158 /* PropertySignature */
            || kind === 160 /* MethodSignature */;
    }
    ts.syntaxRequiresTrailingCommaOrSemicolonOrASI = syntaxRequiresTrailingCommaOrSemicolonOrASI;
    function syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI(kind) {
        return kind === 244 /* FunctionDeclaration */
            || kind === 162 /* Constructor */
            || kind === 161 /* MethodDeclaration */
            || kind === 163 /* GetAccessor */
            || kind === 164 /* SetAccessor */;
    }
    ts.syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI = syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI;
    function syntaxRequiresTrailingModuleBlockOrSemicolonOrASI(kind) {
        return kind === 249 /* ModuleDeclaration */;
    }
    ts.syntaxRequiresTrailingModuleBlockOrSemicolonOrASI = syntaxRequiresTrailingModuleBlockOrSemicolonOrASI;
    function syntaxRequiresTrailingSemicolonOrASI(kind) {
        return kind === 225 /* VariableStatement */
            || kind === 226 /* ExpressionStatement */
            || kind === 228 /* DoStatement */
            || kind === 233 /* ContinueStatement */
            || kind === 234 /* BreakStatement */
            || kind === 235 /* ReturnStatement */
            || kind === 239 /* ThrowStatement */
            || kind === 241 /* DebuggerStatement */
            || kind === 159 /* PropertyDeclaration */
            || kind === 247 /* TypeAliasDeclaration */
            || kind === 254 /* ImportDeclaration */
            || kind === 253 /* ImportEqualsDeclaration */
            || kind === 260 /* ExportDeclaration */
            || kind === 252 /* NamespaceExportDeclaration */
            || kind === 259 /* ExportAssignment */;
    }
    ts.syntaxRequiresTrailingSemicolonOrASI = syntaxRequiresTrailingSemicolonOrASI;
    ts.syntaxMayBeASICandidate = ts.or(syntaxRequiresTrailingCommaOrSemicolonOrASI, syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI, syntaxRequiresTrailingModuleBlockOrSemicolonOrASI, syntaxRequiresTrailingSemicolonOrASI);
    function nodeIsASICandidate(node, sourceFile) {
        var lastToken = node.getLastToken(sourceFile);
        if (lastToken && lastToken.kind === 26 /* SemicolonToken */) {
            return false;
        }
        if (syntaxRequiresTrailingCommaOrSemicolonOrASI(node.kind)) {
            if (lastToken && lastToken.kind === 27 /* CommaToken */) {
                return false;
            }
        }
        else if (syntaxRequiresTrailingModuleBlockOrSemicolonOrASI(node.kind)) {
            var lastChild = ts.last(node.getChildren(sourceFile));
            if (lastChild && ts.isModuleBlock(lastChild)) {
                return false;
            }
        }
        else if (syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI(node.kind)) {
            var lastChild = ts.last(node.getChildren(sourceFile));
            if (lastChild && ts.isFunctionBlock(lastChild)) {
                return false;
            }
        }
        else if (!syntaxRequiresTrailingSemicolonOrASI(node.kind)) {
            return false;
        }
        // See comment in parser’s `parseDoStatement`
        if (node.kind === 228 /* DoStatement */) {
            return true;
        }
        var topNode = ts.findAncestor(node, function (ancestor) { return !ancestor.parent; });
        var nextToken = findNextToken(node, topNode, sourceFile);
        if (!nextToken || nextToken.kind === 19 /* CloseBraceToken */) {
            return true;
        }
        var startLine = sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
        var endLine = sourceFile.getLineAndCharacterOfPosition(nextToken.getStart(sourceFile)).line;
        return startLine !== endLine;
    }
    function positionIsASICandidate(pos, context, sourceFile) {
        var contextAncestor = ts.findAncestor(context, function (ancestor) {
            if (ancestor.end !== pos) {
                return "quit";
            }
            return ts.syntaxMayBeASICandidate(ancestor.kind);
        });
        return !!contextAncestor && nodeIsASICandidate(contextAncestor, sourceFile);
    }
    ts.positionIsASICandidate = positionIsASICandidate;
    function probablyUsesSemicolons(sourceFile) {
        var withSemicolon = 0;
        var withoutSemicolon = 0;
        var nStatementsToObserve = 5;
        ts.forEachChild(sourceFile, function visit(node) {
            if (syntaxRequiresTrailingSemicolonOrASI(node.kind)) {
                var lastToken = node.getLastToken(sourceFile);
                if (lastToken && lastToken.kind === 26 /* SemicolonToken */) {
                    withSemicolon++;
                }
                else {
                    withoutSemicolon++;
                }
            }
            if (withSemicolon + withoutSemicolon >= nStatementsToObserve) {
                return true;
            }
            return ts.forEachChild(node, visit);
        });
        // One statement missing a semicolon isn’t sufficient evidence to say the user
        // doesn’t want semicolons, because they may not even be done writing that statement.
        if (withSemicolon === 0 && withoutSemicolon <= 1) {
            return true;
        }
        // If even 2/5 places have a semicolon, the user probably wants semicolons
        return withSemicolon / withoutSemicolon > 1 / nStatementsToObserve;
    }
    ts.probablyUsesSemicolons = probablyUsesSemicolons;
    function tryGetDirectories(host, directoryName) {
        return tryIOAndConsumeErrors(host, host.getDirectories, directoryName) || [];
    }
    ts.tryGetDirectories = tryGetDirectories;
    function tryReadDirectory(host, path, extensions, exclude, include) {
        return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include) || ts.emptyArray;
    }
    ts.tryReadDirectory = tryReadDirectory;
    function tryFileExists(host, path) {
        return tryIOAndConsumeErrors(host, host.fileExists, path);
    }
    ts.tryFileExists = tryFileExists;
    function tryDirectoryExists(host, path) {
        return tryAndIgnoreErrors(function () { return ts.directoryProbablyExists(path, host); }) || false;
    }
    ts.tryDirectoryExists = tryDirectoryExists;
    function tryAndIgnoreErrors(cb) {
        try {
            return cb();
        }
        catch (_a) {
            return undefined;
        }
    }
    ts.tryAndIgnoreErrors = tryAndIgnoreErrors;
    function tryIOAndConsumeErrors(host, toApply) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        return tryAndIgnoreErrors(function () { return toApply && toApply.apply(host, args); });
    }
    ts.tryIOAndConsumeErrors = tryIOAndConsumeErrors;
    function findPackageJsons(startDirectory, host, stopDirectory) {
        var paths = [];
        ts.forEachAncestorDirectory(startDirectory, function (ancestor) {
            if (ancestor === stopDirectory) {
                return true;
            }
            var currentConfigPath = ts.combinePaths(ancestor, "package.json");
            if (tryFileExists(host, currentConfigPath)) {
                paths.push(currentConfigPath);
            }
        });
        return paths;
    }
    ts.findPackageJsons = findPackageJsons;
    function findPackageJson(directory, host) {
        var packageJson;
        ts.forEachAncestorDirectory(directory, function (ancestor) {
            if (ancestor === "node_modules")
                return true;
            packageJson = ts.findConfigFile(ancestor, function (f) { return tryFileExists(host, f); }, "package.json");
            if (packageJson) {
                return true; // break out
            }
        });
        return packageJson;
    }
    ts.findPackageJson = findPackageJson;
    function getPackageJsonsVisibleToFile(fileName, host) {
        if (!host.fileExists) {
            return [];
        }
        var packageJsons = [];
        ts.forEachAncestorDirectory(ts.getDirectoryPath(fileName), function (ancestor) {
            var packageJsonFileName = ts.combinePaths(ancestor, "package.json");
            if (host.fileExists(packageJsonFileName)) {
                var info = createPackageJsonInfo(packageJsonFileName, host);
                if (info) {
                    packageJsons.push(info);
                }
            }
        });
        return packageJsons;
    }
    ts.getPackageJsonsVisibleToFile = getPackageJsonsVisibleToFile;
    function createPackageJsonInfo(fileName, host) {
        if (!host.readFile) {
            return undefined;
        }
        var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
        var stringContent = host.readFile(fileName);
        if (!stringContent)
            return undefined;
        var content = tryParseJson(stringContent);
        if (!content)
            return false;
        var info = {};
        for (var _i = 0, dependencyKeys_1 = dependencyKeys; _i < dependencyKeys_1.length; _i++) {
            var key = dependencyKeys_1[_i];
            var dependencies = content[key];
            if (!dependencies) {
                continue;
            }
            var dependencyMap = ts.createMap();
            for (var packageName in dependencies) {
                dependencyMap.set(packageName, dependencies[packageName]);
            }
            info[key] = dependencyMap;
        }
        var dependencyGroups = [
            [1 /* Dependencies */, info.dependencies],
            [2 /* DevDependencies */, info.devDependencies],
            [8 /* OptionalDependencies */, info.optionalDependencies],
            [4 /* PeerDependencies */, info.peerDependencies],
        ];
        return __assign(__assign({}, info), { fileName: fileName,
            get: get,
            has: function (dependencyName, inGroups) {
                return !!get(dependencyName, inGroups);
            } });
        function get(dependencyName, inGroups) {
            if (inGroups === void 0) { inGroups = 15 /* All */; }
            for (var _i = 0, dependencyGroups_1 = dependencyGroups; _i < dependencyGroups_1.length; _i++) {
                var _a = dependencyGroups_1[_i], group_1 = _a[0], deps = _a[1];
                if (deps && (inGroups & group_1)) {
                    var dep = deps.get(dependencyName);
                    if (dep !== undefined) {
                        return dep;
                    }
                }
            }
        }
    }
    ts.createPackageJsonInfo = createPackageJsonInfo;
    function tryParseJson(text) {
        try {
            return JSON.parse(text);
        }
        catch (_a) {
            return undefined;
        }
    }
    function consumesNodeCoreModules(sourceFile) {
        return ts.some(sourceFile.imports, function (_a) {
            var text = _a.text;
            return ts.JsTyping.nodeCoreModules.has(text);
        });
    }
    ts.consumesNodeCoreModules = consumesNodeCoreModules;
    function isInsideNodeModules(fileOrDirectory) {
        return ts.contains(ts.getPathComponents(fileOrDirectory), "node_modules");
    }
    ts.isInsideNodeModules = isInsideNodeModules;
    function isDiagnosticWithLocation(diagnostic) {
        return diagnostic.file !== undefined && diagnostic.start !== undefined && diagnostic.length !== undefined;
    }
    ts.isDiagnosticWithLocation = isDiagnosticWithLocation;
    function findDiagnosticForNode(node, sortedFileDiagnostics) {
        var span = createTextSpanFromNode(node);
        var index = ts.binarySearchKey(sortedFileDiagnostics, span, ts.identity, ts.compareTextSpans);
        if (index >= 0) {
            var diagnostic = sortedFileDiagnostics[index];
            ts.Debug.assertEqual(diagnostic.file, node.getSourceFile(), "Diagnostics proided to 'findDiagnosticForNode' must be from a single SourceFile");
            return ts.cast(diagnostic, isDiagnosticWithLocation);
        }
    }
    ts.findDiagnosticForNode = findDiagnosticForNode;
    function getDiagnosticsWithinSpan(span, sortedFileDiagnostics) {
        var _a;
        var index = ts.binarySearchKey(sortedFileDiagnostics, span.start, function (diag) { return diag.start; }, ts.compareValues);
        if (index < 0) {
            index = ~index;
        }
        while (((_a = sortedFileDiagnostics[index - 1]) === null || _a === void 0 ? void 0 : _a.start) === span.start) {
            index--;
        }
        var result = [];
        var end = ts.textSpanEnd(span);
        while (true) {
            var diagnostic = ts.tryCast(sortedFileDiagnostics[index], isDiagnosticWithLocation);
            if (!diagnostic || diagnostic.start > end) {
                break;
            }
            if (ts.textSpanContainsTextSpan(span, diagnostic)) {
                result.push(diagnostic);
            }
            index++;
        }
        return result;
    }
    ts.getDiagnosticsWithinSpan = getDiagnosticsWithinSpan;
    /* @internal */
    function getRefactorContextSpan(_a) {
        var startPosition = _a.startPosition, endPosition = _a.endPosition;
        return ts.createTextSpanFromBounds(startPosition, endPosition === undefined ? startPosition : endPosition);
    }
    ts.getRefactorContextSpan = getRefactorContextSpan;
    function mapOneOrMany(valueOrArray, f, resultSelector) {
        if (resultSelector === void 0) { resultSelector = ts.identity; }
        return valueOrArray ? ts.isArray(valueOrArray) ? resultSelector(ts.map(valueOrArray, f)) : f(valueOrArray, 0) : undefined;
    }
    ts.mapOneOrMany = mapOneOrMany;
    /**
     * If the provided value is an array, the first element of the array is returned; otherwise, the provided value is returned instead.
     */
    function firstOrOnly(valueOrArray) {
        return ts.isArray(valueOrArray) ? ts.first(valueOrArray) : valueOrArray;
    }
    ts.firstOrOnly = firstOrOnly;
    function getNameForExportedSymbol(symbol, scriptTarget) {
        if (symbol.escapedName === "export=" /* ExportEquals */ || symbol.escapedName === "default" /* Default */) {
            // Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase.
            return ts.firstDefined(symbol.declarations, function (d) { return ts.isExportAssignment(d) && ts.isIdentifier(d.expression) ? d.expression.text : undefined; })
                || ts.codefix.moduleSymbolToValidIdentifier(ts.Debug.checkDefined(symbol.parent), scriptTarget);
        }
        return symbol.name;
    }
    ts.getNameForExportedSymbol = getNameForExportedSymbol;
    /**
     * Useful to check whether a string contains another string at a specific index
     * without allocating another string or traversing the entire contents of the outer string.
     *
     * This function is useful in place of either of the following:
     *
     * ```ts
     * // Allocates
     * haystack.substr(startIndex, needle.length) === needle
     *
     * // Full traversal
     * haystack.indexOf(needle, startIndex) === startIndex
     * ```
     *
     * @param haystack The string that potentially contains `needle`.
     * @param needle The string whose content might sit within `haystack`.
     * @param startIndex The index within `haystack` to start searching for `needle`.
     */
    function stringContainsAt(haystack, needle, startIndex) {
        var needleLength = needle.length;
        if (needleLength + startIndex > haystack.length) {
            return false;
        }
        for (var i = 0; i < needleLength; i++) {
            if (needle.charCodeAt(i) !== haystack.charCodeAt(i + startIndex))
                return false;
        }
        return true;
    }
    ts.stringContainsAt = stringContainsAt;
    function startsWithUnderscore(name) {
        return name.charCodeAt(0) === 95 /* _ */;
    }
    ts.startsWithUnderscore = startsWithUnderscore;
    function isGlobalDeclaration(declaration) {
        return !isNonGlobalDeclaration(declaration);
    }
    ts.isGlobalDeclaration = isGlobalDeclaration;
    function isNonGlobalDeclaration(declaration) {
        var sourceFile = declaration.getSourceFile();
        // If the file is not a module, the declaration is global
        if (!sourceFile.externalModuleIndicator && !sourceFile.commonJsModuleIndicator) {
            return false;
        }
        // If the file is a module written in TypeScript, it still might be in a `declare global` augmentation
        return ts.isInJSFile(declaration) || !ts.findAncestor(declaration, ts.isGlobalScopeAugmentation);
    }
    ts.isNonGlobalDeclaration = isNonGlobalDeclaration;
    // #endregion
})(ts || (ts = {}));
var ts;
(function (ts) {
    /** The classifier is used for syntactic highlighting in editors via the TSServer */
    function createClassifier() {
        var scanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ false);
        function getClassificationsForLine(text, lexState, syntacticClassifierAbsent) {
            return convertClassificationsToResult(getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent), text);
        }
        // If there is a syntactic classifier ('syntacticClassifierAbsent' is false),
        // we will be more conservative in order to avoid conflicting with the syntactic classifier.
        function getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent) {
            var token = 0 /* Unknown */;
            var lastNonTriviaToken = 0 /* Unknown */;
            // Just a stack of TemplateHeads and OpenCurlyBraces, used to perform rudimentary (inexact)
            // classification on template strings. Because of the context free nature of templates,
            // the only precise way to classify a template portion would be by propagating the stack across
            // lines, just as we do with the end-of-line state. However, this is a burden for implementers,
            // and the behavior is entirely subsumed by the syntactic classifier anyway, so we instead
            // flatten any nesting when the template stack is non-empty and encode it in the end-of-line state.
            // Situations in which this fails are
            //  1) When template strings are nested across different lines:
            //          `hello ${ `world
            //          ` }`
            //
            //     Where on the second line, you will get the closing of a template,
            //     a closing curly, and a new template.
            //
            //  2) When substitution expressions have curly braces and the curly brace falls on the next line:
            //          `hello ${ () => {
            //          return "world" } } `
            //
            //     Where on the second line, you will get the 'return' keyword,
            //     a string literal, and a template end consisting of '} } `'.
            var templateStack = [];
            var _a = getPrefixFromLexState(lexState), prefix = _a.prefix, pushTemplate = _a.pushTemplate;
            text = prefix + text;
            var offset = prefix.length;
            if (pushTemplate) {
                templateStack.push(15 /* TemplateHead */);
            }
            scanner.setText(text);
            var endOfLineState = 0 /* None */;
            var spans = [];
            // We can run into an unfortunate interaction between the lexical and syntactic classifier
            // when the user is typing something generic.  Consider the case where the user types:
            //
            //      Foo<number
            //
            // From the lexical classifier's perspective, 'number' is a keyword, and so the word will
            // be classified as such.  However, from the syntactic classifier's tree-based perspective
            // this is simply an expression with the identifier 'number' on the RHS of the less than
            // token.  So the classification will go back to being an identifier.  The moment the user
            // types again, number will become a keyword, then an identifier, etc. etc.
            //
            // To try to avoid this problem, we avoid classifying contextual keywords as keywords
            // when the user is potentially typing something generic.  We just can't do a good enough
            // job at the lexical level, and so well leave it up to the syntactic classifier to make
            // the determination.
            //
            // In order to determine if the user is potentially typing something generic, we use a
            // weak heuristic where we track < and > tokens.  It's a weak heuristic, but should
            // work well enough in practice.
            var angleBracketStack = 0;
            do {
                token = scanner.scan();
                if (!ts.isTrivia(token)) {
                    handleToken();
                    lastNonTriviaToken = token;
                }
                var end = scanner.getTextPos();
                pushEncodedClassification(scanner.getTokenPos(), end, offset, classFromKind(token), spans);
                if (end >= text.length) {
                    var end_1 = getNewEndOfLineState(scanner, token, ts.lastOrUndefined(templateStack));
                    if (end_1 !== undefined) {
                        endOfLineState = end_1;
                    }
                }
            } while (token !== 1 /* EndOfFileToken */);
            function handleToken() {
                switch (token) {
                    case 43 /* SlashToken */:
                    case 67 /* SlashEqualsToken */:
                        if (!noRegexTable[lastNonTriviaToken] && scanner.reScanSlashToken() === 13 /* RegularExpressionLiteral */) {
                            token = 13 /* RegularExpressionLiteral */;
                        }
                        break;
                    case 29 /* LessThanToken */:
                        if (lastNonTriviaToken === 75 /* Identifier */) {
                            // Could be the start of something generic.  Keep track of that by bumping
                            // up the current count of generic contexts we may be in.
                            angleBracketStack++;
                        }
                        break;
                    case 31 /* GreaterThanToken */:
                        if (angleBracketStack > 0) {
                            // If we think we're currently in something generic, then mark that that
                            // generic entity is complete.
                            angleBracketStack--;
                        }
                        break;
                    case 125 /* AnyKeyword */:
                    case 143 /* StringKeyword */:
                    case 140 /* NumberKeyword */:
                    case 128 /* BooleanKeyword */:
                    case 144 /* SymbolKeyword */:
                        if (angleBracketStack > 0 && !syntacticClassifierAbsent) {
                            // If it looks like we're could be in something generic, don't classify this
                            // as a keyword.  We may just get overwritten by the syntactic classifier,
                            // causing a noisy experience for the user.
                            token = 75 /* Identifier */;
                        }
                        break;
                    case 15 /* TemplateHead */:
                        templateStack.push(token);
                        break;
                    case 18 /* OpenBraceToken */:
                        // If we don't have anything on the template stack,
                        // then we aren't trying to keep track of a previously scanned template head.
                        if (templateStack.length > 0) {
                            templateStack.push(token);
                        }
                        break;
                    case 19 /* CloseBraceToken */:
                        // If we don't have anything on the template stack,
                        // then we aren't trying to keep track of a previously scanned template head.
                        if (templateStack.length > 0) {
                            var lastTemplateStackToken = ts.lastOrUndefined(templateStack);
                            if (lastTemplateStackToken === 15 /* TemplateHead */) {
                                token = scanner.reScanTemplateToken(/* isTaggedTemplate */ false);
                                // Only pop on a TemplateTail; a TemplateMiddle indicates there is more for us.
                                if (token === 17 /* TemplateTail */) {
                                    templateStack.pop();
                                }
                                else {
                                    ts.Debug.assertEqual(token, 16 /* TemplateMiddle */, "Should have been a template middle.");
                                }
                            }
                            else {
                                ts.Debug.assertEqual(lastTemplateStackToken, 18 /* OpenBraceToken */, "Should have been an open brace");
                                templateStack.pop();
                            }
                        }
                        break;
                    default:
                        if (!ts.isKeyword(token)) {
                            break;
                        }
                        if (lastNonTriviaToken === 24 /* DotToken */) {
                            token = 75 /* Identifier */;
                        }
                        else if (ts.isKeyword(lastNonTriviaToken) && ts.isKeyword(token) && !canFollow(lastNonTriviaToken, token)) {
                            // We have two keywords in a row.  Only treat the second as a keyword if
                            // it's a sequence that could legally occur in the language.  Otherwise
                            // treat it as an identifier.  This way, if someone writes "private var"
                            // we recognize that 'var' is actually an identifier here.
                            token = 75 /* Identifier */;
                        }
                }
            }
            return { endOfLineState: endOfLineState, spans: spans };
        }
        return { getClassificationsForLine: getClassificationsForLine, getEncodedLexicalClassifications: getEncodedLexicalClassifications };
    }
    ts.createClassifier = createClassifier;
    /// We do not have a full parser support to know when we should parse a regex or not
    /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where
    /// we have a series of divide operator. this list allows us to be more accurate by ruling out
    /// locations where a regexp cannot exist.
    var noRegexTable = ts.arrayToNumericMap([
        75 /* Identifier */,
        10 /* StringLiteral */,
        8 /* NumericLiteral */,
        9 /* BigIntLiteral */,
        13 /* RegularExpressionLiteral */,
        104 /* ThisKeyword */,
        45 /* PlusPlusToken */,
        46 /* MinusMinusToken */,
        21 /* CloseParenToken */,
        23 /* CloseBracketToken */,
        19 /* CloseBraceToken */,
        106 /* TrueKeyword */,
        91 /* FalseKeyword */,
    ], function (token) { return token; }, function () { return true; });
    function getNewEndOfLineState(scanner, token, lastOnTemplateStack) {
        switch (token) {
            case 10 /* StringLiteral */: {
                // Check to see if we finished up on a multiline string literal.
                if (!scanner.isUnterminated())
                    return undefined;
                var tokenText = scanner.getTokenText();
                var lastCharIndex = tokenText.length - 1;
                var numBackslashes = 0;
                while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === 92 /* backslash */) {
                    numBackslashes++;
                }
                // If we have an odd number of backslashes, then the multiline string is unclosed
                if ((numBackslashes & 1) === 0)
                    return undefined;
                return tokenText.charCodeAt(0) === 34 /* doubleQuote */ ? 3 /* InDoubleQuoteStringLiteral */ : 2 /* InSingleQuoteStringLiteral */;
            }
            case 3 /* MultiLineCommentTrivia */:
                // Check to see if the multiline comment was unclosed.
                return scanner.isUnterminated() ? 1 /* InMultiLineCommentTrivia */ : undefined;
            default:
                if (ts.isTemplateLiteralKind(token)) {
                    if (!scanner.isUnterminated()) {
                        return undefined;
                    }
                    switch (token) {
                        case 17 /* TemplateTail */:
                            return 5 /* InTemplateMiddleOrTail */;
                        case 14 /* NoSubstitutionTemplateLiteral */:
                            return 4 /* InTemplateHeadOrNoSubstitutionTemplate */;
                        default:
                            return ts.Debug.fail("Only 'NoSubstitutionTemplateLiteral's and 'TemplateTail's can be unterminated; got SyntaxKind #" + token);
                    }
                }
                return lastOnTemplateStack === 15 /* TemplateHead */ ? 6 /* InTemplateSubstitutionPosition */ : undefined;
        }
    }
    function pushEncodedClassification(start, end, offset, classification, result) {
        if (classification === 8 /* whiteSpace */) {
            // Don't bother with whitespace classifications.  They're not needed.
            return;
        }
        if (start === 0 && offset > 0) {
            // We're classifying the first token, and this was a case where we prepended text.
            // We should consider the start of this token to be at the start of the original text.
            start += offset;
        }
        var length = end - start;
        if (length > 0) {
            // All our tokens are in relation to the augmented text.  Move them back to be
            // relative to the original text.
            result.push(start - offset, length, classification);
        }
    }
    function convertClassificationsToResult(classifications, text) {
        var entries = [];
        var dense = classifications.spans;
        var lastEnd = 0;
        for (var i = 0; i < dense.length; i += 3) {
            var start = dense[i];
            var length_1 = dense[i + 1];
            var type = dense[i + 2];
            // Make a whitespace entry between the last item and this one.
            if (lastEnd >= 0) {
                var whitespaceLength_1 = start - lastEnd;
                if (whitespaceLength_1 > 0) {
                    entries.push({ length: whitespaceLength_1, classification: ts.TokenClass.Whitespace });
                }
            }
            entries.push({ length: length_1, classification: convertClassification(type) });
            lastEnd = start + length_1;
        }
        var whitespaceLength = text.length - lastEnd;
        if (whitespaceLength > 0) {
            entries.push({ length: whitespaceLength, classification: ts.TokenClass.Whitespace });
        }
        return { entries: entries, finalLexState: classifications.endOfLineState };
    }
    function convertClassification(type) {
        switch (type) {
            case 1 /* comment */: return ts.TokenClass.Comment;
            case 3 /* keyword */: return ts.TokenClass.Keyword;
            case 4 /* numericLiteral */: return ts.TokenClass.NumberLiteral;
            case 25 /* bigintLiteral */: return ts.TokenClass.BigIntLiteral;
            case 5 /* operator */: return ts.TokenClass.Operator;
            case 6 /* stringLiteral */: return ts.TokenClass.StringLiteral;
            case 8 /* whiteSpace */: return ts.TokenClass.Whitespace;
            case 10 /* punctuation */: return ts.TokenClass.Punctuation;
            case 2 /* identifier */:
            case 11 /* className */:
            case 12 /* enumName */:
            case 13 /* interfaceName */:
            case 14 /* moduleName */:
            case 15 /* typeParameterName */:
            case 16 /* typeAliasName */:
            case 9 /* text */:
            case 17 /* parameterName */:
                return ts.TokenClass.Identifier;
            default:
                return undefined; // TODO: GH#18217 Debug.assertNever(type);
        }
    }
    /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */
    function canFollow(keyword1, keyword2) {
        if (!ts.isAccessibilityModifier(keyword1)) {
            // Assume any other keyword combination is legal.
            // This can be refined in the future if there are more cases we want the classifier to be better at.
            return true;
        }
        switch (keyword2) {
            case 131 /* GetKeyword */:
            case 142 /* SetKeyword */:
            case 129 /* ConstructorKeyword */:
            case 120 /* StaticKeyword */:
                return true; // Allow things like "public get", "public constructor" and "public static".
            default:
                return false; // Any other keyword following "public" is actually an identifier, not a real keyword.
        }
    }
    function getPrefixFromLexState(lexState) {
        // If we're in a string literal, then prepend: "\
        // (and a newline).  That way when we lex we'll think we're still in a string literal.
        //
        // If we're in a multiline comment, then prepend: /*
        // (and a newline).  That way when we lex we'll think we're still in a multiline comment.
        switch (lexState) {
            case 3 /* InDoubleQuoteStringLiteral */:
                return { prefix: "\"\\\n" };
            case 2 /* InSingleQuoteStringLiteral */:
                return { prefix: "'\\\n" };
            case 1 /* InMultiLineCommentTrivia */:
                return { prefix: "/*\n" };
            case 4 /* InTemplateHeadOrNoSubstitutionTemplate */:
                return { prefix: "`\n" };
            case 5 /* InTemplateMiddleOrTail */:
                return { prefix: "}\n", pushTemplate: true };
            case 6 /* InTemplateSubstitutionPosition */:
                return { prefix: "", pushTemplate: true };
            case 0 /* None */:
                return { prefix: "" };
            default:
                return ts.Debug.assertNever(lexState);
        }
    }
    function isBinaryExpressionOperatorToken(token) {
        switch (token) {
            case 41 /* AsteriskToken */:
            case 43 /* SlashToken */:
            case 44 /* PercentToken */:
            case 39 /* PlusToken */:
            case 40 /* MinusToken */:
            case 47 /* LessThanLessThanToken */:
            case 48 /* GreaterThanGreaterThanToken */:
            case 49 /* GreaterThanGreaterThanGreaterThanToken */:
            case 29 /* LessThanToken */:
            case 31 /* GreaterThanToken */:
            case 32 /* LessThanEqualsToken */:
            case 33 /* GreaterThanEqualsToken */:
            case 98 /* InstanceOfKeyword */:
            case 97 /* InKeyword */:
            case 123 /* AsKeyword */:
            case 34 /* EqualsEqualsToken */:
            case 35 /* ExclamationEqualsToken */:
            case 36 /* EqualsEqualsEqualsToken */:
            case 37 /* ExclamationEqualsEqualsToken */:
            case 50 /* AmpersandToken */:
            case 52 /* CaretToken */:
            case 51 /* BarToken */:
            case 55 /* AmpersandAmpersandToken */:
            case 56 /* BarBarToken */:
            case 73 /* BarEqualsToken */:
            case 72 /* AmpersandEqualsToken */:
            case 74 /* CaretEqualsToken */:
            case 69 /* LessThanLessThanEqualsToken */:
            case 70 /* GreaterThanGreaterThanEqualsToken */:
            case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
            case 63 /* PlusEqualsToken */:
            case 64 /* MinusEqualsToken */:
            case 65 /* AsteriskEqualsToken */:
            case 67 /* SlashEqualsToken */:
            case 68 /* PercentEqualsToken */:
            case 62 /* EqualsToken */:
            case 27 /* CommaToken */:
            case 60 /* QuestionQuestionToken */:
                return true;
            default:
                return false;
        }
    }
    function isPrefixUnaryExpressionOperatorToken(token) {
        switch (token) {
            case 39 /* PlusToken */:
            case 40 /* MinusToken */:
            case 54 /* TildeToken */:
            case 53 /* ExclamationToken */:
            case 45 /* PlusPlusToken */:
            case 46 /* MinusMinusToken */:
                return true;
            default:
                return false;
        }
    }
    function classFromKind(token) {
        if (ts.isKeyword(token)) {
            return 3 /* keyword */;
        }
        else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) {
            return 5 /* operator */;
        }
        else if (token >= 18 /* FirstPunctuation */ && token <= 74 /* LastPunctuation */) {
            return 10 /* punctuation */;
        }
        switch (token) {
            case 8 /* NumericLiteral */:
                return 4 /* numericLiteral */;
            case 9 /* BigIntLiteral */:
                return 25 /* bigintLiteral */;
            case 10 /* StringLiteral */:
                return 6 /* stringLiteral */;
            case 13 /* RegularExpressionLiteral */:
                return 7 /* regularExpressionLiteral */;
            case 7 /* ConflictMarkerTrivia */:
            case 3 /* MultiLineCommentTrivia */:
            case 2 /* SingleLineCommentTrivia */:
                return 1 /* comment */;
            case 5 /* WhitespaceTrivia */:
            case 4 /* NewLineTrivia */:
                return 8 /* whiteSpace */;
            case 75 /* Identifier */:
            default:
                if (ts.isTemplateLiteralKind(token)) {
                    return 6 /* stringLiteral */;
                }
                return 2 /* identifier */;
        }
    }
    /* @internal */
    function getSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) {
        return convertClassificationsToSpans(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span));
    }
    ts.getSemanticClassifications = getSemanticClassifications;
    function checkForClassificationCancellation(cancellationToken, kind) {
        // We don't want to actually call back into our host on every node to find out if we've
        // been canceled.  That would be an enormous amount of chattyness, along with the all
        // the overhead of marshalling the data to/from the host.  So instead we pick a few
        // reasonable node kinds to bother checking on.  These node kinds represent high level
        // constructs that we would expect to see commonly, but just at a far less frequent
        // interval.
        //
        // For example, in checker.ts (around 750k) we only have around 600 of these constructs.
        // That means we're calling back into the host around every 1.2k of the file we process.
        // Lib.d.ts has similar numbers.
        switch (kind) {
            case 249 /* ModuleDeclaration */:
            case 245 /* ClassDeclaration */:
            case 246 /* InterfaceDeclaration */:
            case 244 /* FunctionDeclaration */:
                cancellationToken.throwIfCancellationRequested();
        }
    }
    /* @internal */
    function getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) {
        var spans = [];
        sourceFile.forEachChild(function cb(node) {
            // Only walk into nodes that intersect the requested span.
            if (!node || !ts.textSpanIntersectsWith(span, node.pos, node.getFullWidth())) {
                return;
            }
            checkForClassificationCancellation(cancellationToken, node.kind);
            // Only bother calling into the typechecker if this is an identifier that
            // could possibly resolve to a type name.  This makes classification run
            // in a third of the time it would normally take.
            if (ts.isIdentifier(node) && !ts.nodeIsMissing(node) && classifiableNames.has(node.escapedText)) {
                var symbol = typeChecker.getSymbolAtLocation(node);
                var type = symbol && classifySymbol(symbol, ts.getMeaningFromLocation(node), typeChecker);
                if (type) {
                    pushClassification(node.getStart(sourceFile), node.getEnd(), type);
                }
            }
            node.forEachChild(cb);
        });
        return { spans: spans, endOfLineState: 0 /* None */ };
        function pushClassification(start, end, type) {
            var length = end - start;
            ts.Debug.assert(length > 0, "Classification had non-positive length of " + length);
            spans.push(start);
            spans.push(length);
            spans.push(type);
        }
    }
    ts.getEncodedSemanticClassifications = getEncodedSemanticClassifications;
    function classifySymbol(symbol, meaningAtPosition, checker) {
        var flags = symbol.getFlags();
        if ((flags & 2885600 /* Classifiable */) === 0 /* None */) {
            return undefined;
        }
        else if (flags & 32 /* Class */) {
            return 11 /* className */;
        }
        else if (flags & 384 /* Enum */) {
            return 12 /* enumName */;
        }
        else if (flags & 524288 /* TypeAlias */) {
            return 16 /* typeAliasName */;
        }
        else if (flags & 1536 /* Module */) {
            // Only classify a module as such if
            //  - It appears in a namespace context.
            //  - There exists a module declaration which actually impacts the value side.
            return meaningAtPosition & 4 /* Namespace */ || meaningAtPosition & 1 /* Value */ && hasValueSideModule(symbol) ? 14 /* moduleName */ : undefined;
        }
        else if (flags & 2097152 /* Alias */) {
            return classifySymbol(checker.getAliasedSymbol(symbol), meaningAtPosition, checker);
        }
        else if (meaningAtPosition & 2 /* Type */) {
            return flags & 64 /* Interface */ ? 13 /* interfaceName */ : flags & 262144 /* TypeParameter */ ? 15 /* typeParameterName */ : undefined;
        }
        else {
            return undefined;
        }
    }
    /** Returns true if there exists a module that introduces entities on the value side. */
    function hasValueSideModule(symbol) {
        return ts.some(symbol.declarations, function (declaration) {
            return ts.isModuleDeclaration(declaration) && ts.getModuleInstanceState(declaration) === 1 /* Instantiated */;
        });
    }
    function getClassificationTypeName(type) {
        switch (type) {
            case 1 /* comment */: return "comment" /* comment */;
            case 2 /* identifier */: return "identifier" /* identifier */;
            case 3 /* keyword */: return "keyword" /* keyword */;
            case 4 /* numericLiteral */: return "number" /* numericLiteral */;
            case 25 /* bigintLiteral */: return "bigint" /* bigintLiteral */;
            case 5 /* operator */: return "operator" /* operator */;
            case 6 /* stringLiteral */: return "string" /* stringLiteral */;
            case 8 /* whiteSpace */: return "whitespace" /* whiteSpace */;
            case 9 /* text */: return "text" /* text */;
            case 10 /* punctuation */: return "punctuation" /* punctuation */;
            case 11 /* className */: return "class name" /* className */;
            case 12 /* enumName */: return "enum name" /* enumName */;
            case 13 /* interfaceName */: return "interface name" /* interfaceName */;
            case 14 /* moduleName */: return "module name" /* moduleName */;
            case 15 /* typeParameterName */: return "type parameter name" /* typeParameterName */;
            case 16 /* typeAliasName */: return "type alias name" /* typeAliasName */;
            case 17 /* parameterName */: return "parameter name" /* parameterName */;
            case 18 /* docCommentTagName */: return "doc comment tag name" /* docCommentTagName */;
            case 19 /* jsxOpenTagName */: return "jsx open tag name" /* jsxOpenTagName */;
            case 20 /* jsxCloseTagName */: return "jsx close tag name" /* jsxCloseTagName */;
            case 21 /* jsxSelfClosingTagName */: return "jsx self closing tag name" /* jsxSelfClosingTagName */;
            case 22 /* jsxAttribute */: return "jsx attribute" /* jsxAttribute */;
            case 23 /* jsxText */: return "jsx text" /* jsxText */;
            case 24 /* jsxAttributeStringLiteralValue */: return "jsx attribute string literal value" /* jsxAttributeStringLiteralValue */;
            default: return undefined; // TODO: GH#18217 throw Debug.assertNever(type);
        }
    }
    function convertClassificationsToSpans(classifications) {
        ts.Debug.assert(classifications.spans.length % 3 === 0);
        var dense = classifications.spans;
        var result = [];
        for (var i = 0; i < dense.length; i += 3) {
            result.push({
                textSpan: ts.createTextSpan(dense[i], dense[i + 1]),
                classificationType: getClassificationTypeName(dense[i + 2])
            });
        }
        return result;
    }
    /* @internal */
    function getSyntacticClassifications(cancellationToken, sourceFile, span) {
        return convertClassificationsToSpans(getEncodedSyntacticClassifications(cancellationToken, sourceFile, span));
    }
    ts.getSyntacticClassifications = getSyntacticClassifications;
    /* @internal */
    function getEncodedSyntacticClassifications(cancellationToken, sourceFile, span) {
        var spanStart = span.start;
        var spanLength = span.length;
        // Make a scanner we can get trivia from.
        var triviaScanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
        var mergeConflictScanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
        var result = [];
        processElement(sourceFile);
        return { spans: result, endOfLineState: 0 /* None */ };
        function pushClassification(start, length, type) {
            result.push(start);
            result.push(length);
            result.push(type);
        }
        function classifyLeadingTriviaAndGetTokenStart(token) {
            triviaScanner.setTextPos(token.pos);
            while (true) {
                var start = triviaScanner.getTextPos();
                // only bother scanning if we have something that could be trivia.
                if (!ts.couldStartTrivia(sourceFile.text, start)) {
                    return start;
                }
                var kind = triviaScanner.scan();
                var end = triviaScanner.getTextPos();
                var width = end - start;
                // The moment we get something that isn't trivia, then stop processing.
                if (!ts.isTrivia(kind)) {
                    return start;
                }
                switch (kind) {
                    case 4 /* NewLineTrivia */:
                    case 5 /* WhitespaceTrivia */:
                        // Don't bother with newlines/whitespace.
                        continue;
                    case 2 /* SingleLineCommentTrivia */:
                    case 3 /* MultiLineCommentTrivia */:
                        // Only bother with the trivia if it at least intersects the span of interest.
                        classifyComment(token, kind, start, width);
                        // Classifying a comment might cause us to reuse the trivia scanner
                        // (because of jsdoc comments).  So after we classify the comment make
                        // sure we set the scanner position back to where it needs to be.
                        triviaScanner.setTextPos(end);
                        continue;
                    case 7 /* ConflictMarkerTrivia */:
                        var text = sourceFile.text;
                        var ch = text.charCodeAt(start);
                        // for the <<<<<<< and >>>>>>> markers, we just add them in as comments
                        // in the classification stream.
                        if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
                            pushClassification(start, width, 1 /* comment */);
                            continue;
                        }
                        // for the ||||||| and ======== markers, add a comment for the first line,
                        // and then lex all subsequent lines up until the end of the conflict marker.
                        ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
                        classifyDisabledMergeCode(text, start, end);
                        break;
                    case 6 /* ShebangTrivia */:
                        // TODO: Maybe we should classify these.
                        break;
                    default:
                        ts.Debug.assertNever(kind);
                }
            }
        }
        function classifyComment(token, kind, start, width) {
            if (kind === 3 /* MultiLineCommentTrivia */) {
                // See if this is a doc comment.  If so, we'll classify certain portions of it
                // specially.
                var docCommentAndDiagnostics = ts.parseIsolatedJSDocComment(sourceFile.text, start, width);
                if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) {
                    // TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]`
                    docCommentAndDiagnostics.jsDoc.parent = token;
                    classifyJSDocComment(docCommentAndDiagnostics.jsDoc);
                    return;
                }
            }
            else if (kind === 2 /* SingleLineCommentTrivia */) {
                if (tryClassifyTripleSlashComment(start, width)) {
                    return;
                }
            }
            // Simple comment.  Just add as is.
            pushCommentRange(start, width);
        }
        function pushCommentRange(start, width) {
            pushClassification(start, width, 1 /* comment */);
        }
        function classifyJSDocComment(docComment) {
            var pos = docComment.pos;
            if (docComment.tags) {
                for (var _i = 0, _a = docComment.tags; _i < _a.length; _i++) {
                    var tag = _a[_i];
                    // As we walk through each tag, classify the portion of text from the end of
                    // the last tag (or the start of the entire doc comment) as 'comment'.
                    if (tag.pos !== pos) {
                        pushCommentRange(pos, tag.pos - pos);
                    }
                    pushClassification(tag.pos, 1, 10 /* punctuation */); // "@"
                    pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, 18 /* docCommentTagName */); // e.g. "param"
                    pos = tag.tagName.end;
                    switch (tag.kind) {
                        case 317 /* JSDocParameterTag */:
                            processJSDocParameterTag(tag);
                            break;
                        case 321 /* JSDocTemplateTag */:
                            processJSDocTemplateTag(tag);
                            pos = tag.end;
                            break;
                        case 320 /* JSDocTypeTag */:
                            processElement(tag.typeExpression);
                            pos = tag.end;
                            break;
                        case 318 /* JSDocReturnTag */:
                            processElement(tag.typeExpression);
                            pos = tag.end;
                            break;
                    }
                }
            }
            if (pos !== docComment.end) {
                pushCommentRange(pos, docComment.end - pos);
            }
            return;
            function processJSDocParameterTag(tag) {
                if (tag.isNameFirst) {
                    pushCommentRange(pos, tag.name.pos - pos);
                    pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */);
                    pos = tag.name.end;
                }
                if (tag.typeExpression) {
                    pushCommentRange(pos, tag.typeExpression.pos - pos);
                    processElement(tag.typeExpression);
                    pos = tag.typeExpression.end;
                }
                if (!tag.isNameFirst) {
                    pushCommentRange(pos, tag.name.pos - pos);
                    pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */);
                    pos = tag.name.end;
                }
            }
        }
        function tryClassifyTripleSlashComment(start, width) {
            var tripleSlashXMLCommentRegEx = /^(\/\/\/\s*)(<)(?:(\S+)((?:[^/]|\/[^>])*)(\/>)?)?/im;
            var attributeRegex = /(\S+)(\s*)(=)(\s*)('[^']+'|"[^"]+")/img;
            var text = sourceFile.text.substr(start, width);
            var match = tripleSlashXMLCommentRegEx.exec(text);
            if (!match) {
                return false;
            }
            // Limiting classification to exactly the elements and attributes
            // defined in `ts.commentPragmas` would be excessive, but we can avoid
            // some obvious false positives (e.g. in XML-like doc comments) by
            // checking the element name.
            // eslint-disable-next-line no-in-operator
            if (!match[3] || !(match[3] in ts.commentPragmas)) {
                return false;
            }
            var pos = start;
            pushCommentRange(pos, match[1].length); // ///
            pos += match[1].length;
            pushClassification(pos, match[2].length, 10 /* punctuation */); // <
            pos += match[2].length;
            pushClassification(pos, match[3].length, 21 /* jsxSelfClosingTagName */); // element name
            pos += match[3].length;
            var attrText = match[4];
            var attrPos = pos;
            while (true) {
                var attrMatch = attributeRegex.exec(attrText);
                if (!attrMatch) {
                    break;
                }
                var newAttrPos = pos + attrMatch.index;
                if (newAttrPos > attrPos) {
                    pushCommentRange(attrPos, newAttrPos - attrPos);
                    attrPos = newAttrPos;
                }
                pushClassification(attrPos, attrMatch[1].length, 22 /* jsxAttribute */); // attribute name
                attrPos += attrMatch[1].length;
                if (attrMatch[2].length) {
                    pushCommentRange(attrPos, attrMatch[2].length); // whitespace
                    attrPos += attrMatch[2].length;
                }
                pushClassification(attrPos, attrMatch[3].length, 5 /* operator */); // =
                attrPos += attrMatch[3].length;
                if (attrMatch[4].length) {
                    pushCommentRange(attrPos, attrMatch[4].length); // whitespace
                    attrPos += attrMatch[4].length;
                }
                pushClassification(attrPos, attrMatch[5].length, 24 /* jsxAttributeStringLiteralValue */); // attribute value
                attrPos += attrMatch[5].length;
            }
            pos += match[4].length;
            if (pos > attrPos) {
                pushCommentRange(attrPos, pos - attrPos);
            }
            if (match[5]) {
                pushClassification(pos, match[5].length, 10 /* punctuation */); // />
                pos += match[5].length;
            }
            var end = start + width;
            if (pos < end) {
                pushCommentRange(pos, end - pos);
            }
            return true;
        }
        function processJSDocTemplateTag(tag) {
            for (var _i = 0, _a = tag.getChildren(); _i < _a.length; _i++) {
                var child = _a[_i];
                processElement(child);
            }
        }
        function classifyDisabledMergeCode(text, start, end) {
            // Classify the line that the ||||||| or ======= marker is on as a comment.
            // Then just lex all further tokens and add them to the result.
            var i;
            for (i = start; i < end; i++) {
                if (ts.isLineBreak(text.charCodeAt(i))) {
                    break;
                }
            }
            pushClassification(start, i - start, 1 /* comment */);
            mergeConflictScanner.setTextPos(i);
            while (mergeConflictScanner.getTextPos() < end) {
                classifyDisabledCodeToken();
            }
        }
        function classifyDisabledCodeToken() {
            var start = mergeConflictScanner.getTextPos();
            var tokenKind = mergeConflictScanner.scan();
            var end = mergeConflictScanner.getTextPos();
            var type = classifyTokenType(tokenKind);
            if (type) {
                pushClassification(start, end - start, type);
            }
        }
        /**
         * Returns true if node should be treated as classified and no further processing is required.
         * False will mean that node is not classified and traverse routine should recurse into node contents.
         */
        function tryClassifyNode(node) {
            if (ts.isJSDoc(node)) {
                return true;
            }
            if (ts.nodeIsMissing(node)) {
                return true;
            }
            var classifiedElementName = tryClassifyJsxElementName(node);
            if (!ts.isToken(node) && node.kind !== 11 /* JsxText */ && classifiedElementName === undefined) {
                return false;
            }
            var tokenStart = node.kind === 11 /* JsxText */ ? node.pos : classifyLeadingTriviaAndGetTokenStart(node);
            var tokenWidth = node.end - tokenStart;
            ts.Debug.assert(tokenWidth >= 0);
            if (tokenWidth > 0) {
                var type = classifiedElementName || classifyTokenType(node.kind, node);
                if (type) {
                    pushClassification(tokenStart, tokenWidth, type);
                }
            }
            return true;
        }
        function tryClassifyJsxElementName(token) {
            switch (token.parent && token.parent.kind) {
                case 268 /* JsxOpeningElement */:
                    if (token.parent.tagName === token) {
                        return 19 /* jsxOpenTagName */;
                    }
                    break;
                case 269 /* JsxClosingElement */:
                    if (token.parent.tagName === token) {
                        return 20 /* jsxCloseTagName */;
                    }
                    break;
                case 267 /* JsxSelfClosingElement */:
                    if (token.parent.tagName === token) {
                        return 21 /* jsxSelfClosingTagName */;
                    }
                    break;
                case 273 /* JsxAttribute */:
                    if (token.parent.name === token) {
                        return 22 /* jsxAttribute */;
                    }
                    break;
            }
            return undefined;
        }
        // for accurate classification, the actual token should be passed in.  however, for
        // cases like 'disabled merge code' classification, we just get the token kind and
        // classify based on that instead.
        function classifyTokenType(tokenKind, token) {
            if (ts.isKeyword(tokenKind)) {
                return 3 /* keyword */;
            }
            // Special case `<` and `>`: If they appear in a generic context they are punctuation,
            // not operators.
            if (tokenKind === 29 /* LessThanToken */ || tokenKind === 31 /* GreaterThanToken */) {
                // If the node owning the token has a type argument list or type parameter list, then
                // we can effectively assume that a '<' and '>' belong to those lists.
                if (token && ts.getTypeArgumentOrTypeParameterList(token.parent)) {
                    return 10 /* punctuation */;
                }
            }
            if (ts.isPunctuation(tokenKind)) {
                if (token) {
                    var parent = token.parent;
                    if (tokenKind === 62 /* EqualsToken */) {
                        // the '=' in a variable declaration is special cased here.
                        if (parent.kind === 242 /* VariableDeclaration */ ||
                            parent.kind === 159 /* PropertyDeclaration */ ||
                            parent.kind === 156 /* Parameter */ ||
                            parent.kind === 273 /* JsxAttribute */) {
                            return 5 /* operator */;
                        }
                    }
                    if (parent.kind === 209 /* BinaryExpression */ ||
                        parent.kind === 207 /* PrefixUnaryExpression */ ||
                        parent.kind === 208 /* PostfixUnaryExpression */ ||
                        parent.kind === 210 /* ConditionalExpression */) {
                        return 5 /* operator */;
                    }
                }
                return 10 /* punctuation */;
            }
            else if (tokenKind === 8 /* NumericLiteral */) {
                return 4 /* numericLiteral */;
            }
            else if (tokenKind === 9 /* BigIntLiteral */) {
                return 25 /* bigintLiteral */;
            }
            else if (tokenKind === 10 /* StringLiteral */) {
                return token && token.parent.kind === 273 /* JsxAttribute */ ? 24 /* jsxAttributeStringLiteralValue */ : 6 /* stringLiteral */;
            }
            else if (tokenKind === 13 /* RegularExpressionLiteral */) {
                // TODO: we should get another classification type for these literals.
                return 6 /* stringLiteral */;
            }
            else if (ts.isTemplateLiteralKind(tokenKind)) {
                // TODO (drosen): we should *also* get another classification type for these literals.
                return 6 /* stringLiteral */;
            }
            else if (tokenKind === 11 /* JsxText */) {
                return 23 /* jsxText */;
            }
            else if (tokenKind === 75 /* Identifier */) {
                if (token) {
                    switch (token.parent.kind) {
                        case 245 /* ClassDeclaration */:
                            if (token.parent.name === token) {
                                return 11 /* className */;
                            }
                            return;
                        case 155 /* TypeParameter */:
                            if (token.parent.name === token) {
                                return 15 /* typeParameterName */;
                            }
                            return;
                        case 246 /* InterfaceDeclaration */:
                            if (token.parent.name === token) {
                                return 13 /* interfaceName */;
                            }
                            return;
                        case 248 /* EnumDeclaration */:
                            if (token.parent.name === token) {
                                return 12 /* enumName */;
                            }
                            return;
                        case 249 /* ModuleDeclaration */:
                            if (token.parent.name === token) {
                                return 14 /* moduleName */;
                            }
                            return;
                        case 156 /* Parameter */:
                            if (token.parent.name === token) {
                                return ts.isThisIdentifier(token) ? 3 /* keyword */ : 17 /* parameterName */;
                            }
                            return;
                    }
                }
                return 2 /* identifier */;
            }
        }
        function processElement(element) {
            if (!element) {
                return;
            }
            // Ignore nodes that don't intersect the original span to classify.
            if (ts.decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) {
                checkForClassificationCancellation(cancellationToken, element.kind);
                for (var _i = 0, _a = element.getChildren(sourceFile); _i < _a.length; _i++) {
                    var child = _a[_i];
                    if (!tryClassifyNode(child)) {
                        // Recurse into our child nodes.
                        processElement(child);
                    }
                }
            }
        }
    }
    ts.getEncodedSyntacticClassifications = getEncodedSyntacticClassifications;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Completions;
    (function (Completions) {
        var StringCompletions;
        (function (StringCompletions) {
            function getStringLiteralCompletions(sourceFile, position, contextToken, checker, options, host, log, preferences) {
                if (ts.isInReferenceComment(sourceFile, position)) {
                    var entries = getTripleSlashReferenceCompletion(sourceFile, position, options, host);
                    return entries && convertPathCompletions(entries);
                }
                if (ts.isInString(sourceFile, position, contextToken)) {
                    if (!contextToken || !ts.isStringLiteralLike(contextToken))
                        return undefined;
                    var entries = getStringLiteralCompletionEntries(sourceFile, contextToken, position, checker, options, host);
                    return convertStringLiteralCompletions(entries, contextToken, sourceFile, checker, log, preferences);
                }
            }
            StringCompletions.getStringLiteralCompletions = getStringLiteralCompletions;
            function convertStringLiteralCompletions(completion, contextToken, sourceFile, checker, log, preferences) {
                if (completion === undefined) {
                    return undefined;
                }
                switch (completion.kind) {
                    case 0 /* Paths */:
                        return convertPathCompletions(completion.paths);
                    case 1 /* Properties */: {
                        var entries = [];
                        Completions.getCompletionEntriesFromSymbols(completion.symbols, entries, contextToken, sourceFile, sourceFile, checker, 99 /* ESNext */, log, 4 /* String */, preferences); // Target will not be used, so arbitrary
                        return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: completion.hasIndexSignature, entries: entries };
                    }
                    case 2 /* Types */: {
                        var entries = completion.types.map(function (type) { return ({
                            name: type.value,
                            kindModifiers: "" /* none */,
                            kind: "string" /* string */,
                            sortText: "0",
                            replacementSpan: ts.getReplacementSpanForContextToken(contextToken)
                        }); });
                        return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: completion.isNewIdentifier, entries: entries };
                    }
                    default:
                        return ts.Debug.assertNever(completion);
                }
            }
            function getStringLiteralCompletionDetails(name, sourceFile, position, contextToken, checker, options, host, cancellationToken) {
                if (!contextToken || !ts.isStringLiteralLike(contextToken))
                    return undefined;
                var completions = getStringLiteralCompletionEntries(sourceFile, contextToken, position, checker, options, host);
                return completions && stringLiteralCompletionDetails(name, contextToken, completions, sourceFile, checker, cancellationToken);
            }
            StringCompletions.getStringLiteralCompletionDetails = getStringLiteralCompletionDetails;
            function stringLiteralCompletionDetails(name, location, completion, sourceFile, checker, cancellationToken) {
                switch (completion.kind) {
                    case 0 /* Paths */: {
                        var match = ts.find(completion.paths, function (p) { return p.name === name; });
                        return match && Completions.createCompletionDetails(name, kindModifiersFromExtension(match.extension), match.kind, [ts.textPart(name)]);
                    }
                    case 1 /* Properties */: {
                        var match = ts.find(completion.symbols, function (s) { return s.name === name; });
                        return match && Completions.createCompletionDetailsForSymbol(match, checker, sourceFile, location, cancellationToken);
                    }
                    case 2 /* Types */:
                        return ts.find(completion.types, function (t) { return t.value === name; }) ? Completions.createCompletionDetails(name, "" /* none */, "type" /* typeElement */, [ts.textPart(name)]) : undefined;
                    default:
                        return ts.Debug.assertNever(completion);
                }
            }
            function convertPathCompletions(pathCompletions) {
                var isGlobalCompletion = false; // We don't want the editor to offer any other completions, such as snippets, inside a comment.
                var isNewIdentifierLocation = true; // The user may type in a path that doesn't yet exist, creating a "new identifier" with respect to the collection of identifiers the server is aware of.
                var entries = pathCompletions.map(function (_a) {
                    var name = _a.name, kind = _a.kind, span = _a.span, extension = _a.extension;
                    return ({ name: name, kind: kind, kindModifiers: kindModifiersFromExtension(extension), sortText: Completions.SortText.LocationPriority, replacementSpan: span });
                });
                return { isGlobalCompletion: isGlobalCompletion, isMemberCompletion: false, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
            }
            function kindModifiersFromExtension(extension) {
                switch (extension) {
                    case ".d.ts" /* Dts */: return ".d.ts" /* dtsModifier */;
                    case ".js" /* Js */: return ".js" /* jsModifier */;
                    case ".json" /* Json */: return ".json" /* jsonModifier */;
                    case ".jsx" /* Jsx */: return ".jsx" /* jsxModifier */;
                    case ".ts" /* Ts */: return ".ts" /* tsModifier */;
                    case ".tsx" /* Tsx */: return ".tsx" /* tsxModifier */;
                    case ".tsbuildinfo" /* TsBuildInfo */: return ts.Debug.fail("Extension " + ".tsbuildinfo" /* TsBuildInfo */ + " is unsupported.");
                    case undefined: return "" /* none */;
                    default:
                        return ts.Debug.assertNever(extension);
                }
            }
            var StringLiteralCompletionKind;
            (function (StringLiteralCompletionKind) {
                StringLiteralCompletionKind[StringLiteralCompletionKind["Paths"] = 0] = "Paths";
                StringLiteralCompletionKind[StringLiteralCompletionKind["Properties"] = 1] = "Properties";
                StringLiteralCompletionKind[StringLiteralCompletionKind["Types"] = 2] = "Types";
            })(StringLiteralCompletionKind || (StringLiteralCompletionKind = {}));
            function getStringLiteralCompletionEntries(sourceFile, node, position, typeChecker, compilerOptions, host) {
                var parent = node.parent;
                switch (parent.kind) {
                    case 187 /* LiteralType */:
                        switch (parent.parent.kind) {
                            case 169 /* TypeReference */:
                                return { kind: 2 /* Types */, types: getStringLiteralTypes(typeChecker.getTypeArgumentConstraint(parent)), isNewIdentifier: false };
                            case 185 /* IndexedAccessType */:
                                // Get all apparent property names
                                // i.e. interface Foo {
                                //          foo: string;
                                //          bar: string;
                                //      }
                                //      let x: Foo["/*completion position*/"]
                                return stringLiteralCompletionsFromProperties(typeChecker.getTypeFromTypeNode(parent.parent.objectType));
                            case 188 /* ImportType */:
                                return { kind: 0 /* Paths */, paths: getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker) };
                            case 178 /* UnionType */: {
                                if (!ts.isTypeReferenceNode(parent.parent.parent))
                                    return undefined;
                                var alreadyUsedTypes_1 = getAlreadyUsedTypesInStringLiteralUnion(parent.parent, parent);
                                var types = getStringLiteralTypes(typeChecker.getTypeArgumentConstraint(parent.parent)).filter(function (t) { return !ts.contains(alreadyUsedTypes_1, t.value); });
                                return { kind: 2 /* Types */, types: types, isNewIdentifier: false };
                            }
                            default:
                                return undefined;
                        }
                    case 281 /* PropertyAssignment */:
                        if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
                            // Get quoted name of properties of the object literal expression
                            // i.e. interface ConfigFiles {
                            //          'jspm:dev': string
                            //      }
                            //      let files: ConfigFiles = {
                            //          '/*completion position*/'
                            //      }
                            //
                            //      function foo(c: ConfigFiles) {}
                            //      foo({
                            //          '/*completion position*/'
                            //      });
                            return stringLiteralCompletionsFromProperties(typeChecker.getContextualType(parent.parent));
                        }
                        return fromContextualType();
                    case 195 /* ElementAccessExpression */: {
                        var _a = parent, expression = _a.expression, argumentExpression = _a.argumentExpression;
                        if (node === argumentExpression) {
                            // Get all names of properties on the expression
                            // i.e. interface A {
                            //      'prop1': string
                            // }
                            // let a: A;
                            // a['/*completion position*/']
                            return stringLiteralCompletionsFromProperties(typeChecker.getTypeAtLocation(expression));
                        }
                        return undefined;
                    }
                    case 196 /* CallExpression */:
                    case 197 /* NewExpression */:
                        if (!ts.isRequireCall(parent, /*checkArgumentIsStringLiteralLike*/ false) && !ts.isImportCall(parent)) {
                            var argumentInfo = ts.SignatureHelp.getArgumentInfoForCompletions(node, position, sourceFile);
                            // Get string literal completions from specialized signatures of the target
                            // i.e. declare function f(a: 'A');
                            // f("/*completion position*/")
                            return argumentInfo ? getStringLiteralCompletionsFromSignature(argumentInfo, typeChecker) : fromContextualType();
                        }
                    // falls through (is `require("")` or `import("")`)
                    case 254 /* ImportDeclaration */:
                    case 260 /* ExportDeclaration */:
                    case 265 /* ExternalModuleReference */:
                        // Get all known external module names or complete a path to a module
                        // i.e. import * as ns from "/*completion position*/";
                        //      var y = import("/*completion position*/");
                        //      import x = require("/*completion position*/");
                        //      var y = require("/*completion position*/");
                        //      export * from "/*completion position*/";
                        return { kind: 0 /* Paths */, paths: getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker) };
                    default:
                        return fromContextualType();
                }
                function fromContextualType() {
                    // Get completion for string literal from string literal type
                    // i.e. var x: "hi" | "hello" = "/*completion position*/"
                    return { kind: 2 /* Types */, types: getStringLiteralTypes(ts.getContextualTypeFromParent(node, typeChecker)), isNewIdentifier: false };
                }
            }
            function getAlreadyUsedTypesInStringLiteralUnion(union, current) {
                return ts.mapDefined(union.types, function (type) {
                    return type !== current && ts.isLiteralTypeNode(type) && ts.isStringLiteral(type.literal) ? type.literal.text : undefined;
                });
            }
            function getStringLiteralCompletionsFromSignature(argumentInfo, checker) {
                var isNewIdentifier = false;
                var uniques = ts.createMap();
                var candidates = [];
                checker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount);
                var types = ts.flatMap(candidates, function (candidate) {
                    if (!ts.signatureHasRestParameter(candidate) && argumentInfo.argumentCount > candidate.parameters.length)
                        return;
                    var type = checker.getParameterType(candidate, argumentInfo.argumentIndex);
                    isNewIdentifier = isNewIdentifier || !!(type.flags & 4 /* String */);
                    return getStringLiteralTypes(type, uniques);
                });
                return { kind: 2 /* Types */, types: types, isNewIdentifier: isNewIdentifier };
            }
            function stringLiteralCompletionsFromProperties(type) {
                return type && {
                    kind: 1 /* Properties */,
                    symbols: type.getApparentProperties().filter(function (prop) {
                        return !ts.isPrivateIdentifierPropertyDeclaration(ts.isTransientSymbol(prop) && prop.syntheticOrigin ? prop.syntheticOrigin.valueDeclaration : prop.valueDeclaration);
                    }),
                    hasIndexSignature: ts.hasIndexSignature(type)
                };
            }
            function getStringLiteralTypes(type, uniques) {
                if (uniques === void 0) { uniques = ts.createMap(); }
                if (!type)
                    return ts.emptyArray;
                type = ts.skipConstraint(type);
                return type.isUnion() ? ts.flatMap(type.types, function (t) { return getStringLiteralTypes(t, uniques); }) :
                    type.isStringLiteral() && !(type.flags & 1024 /* EnumLiteral */) && ts.addToSeen(uniques, type.value) ? [type] : ts.emptyArray;
            }
            function nameAndKind(name, kind, extension) {
                return { name: name, kind: kind, extension: extension };
            }
            function directoryResult(name) {
                return nameAndKind(name, "directory" /* directory */, /*extension*/ undefined);
            }
            function addReplacementSpans(text, textStart, names) {
                var span = getDirectoryFragmentTextSpan(text, textStart);
                return names.map(function (_a) {
                    var name = _a.name, kind = _a.kind, extension = _a.extension;
                    return ({ name: name, kind: kind, extension: extension, span: span });
                });
            }
            function getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker) {
                return addReplacementSpans(node.text, node.getStart(sourceFile) + 1, getStringLiteralCompletionsFromModuleNamesWorker(sourceFile, node, compilerOptions, host, typeChecker));
            }
            function getStringLiteralCompletionsFromModuleNamesWorker(sourceFile, node, compilerOptions, host, typeChecker) {
                var literalValue = ts.normalizeSlashes(node.text);
                var scriptPath = sourceFile.path;
                var scriptDirectory = ts.getDirectoryPath(scriptPath);
                return isPathRelativeToScript(literalValue) || !compilerOptions.baseUrl && (ts.isRootedDiskPath(literalValue) || ts.isUrl(literalValue))
                    ? getCompletionEntriesForRelativeModules(literalValue, scriptDirectory, compilerOptions, host, scriptPath)
                    : getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, compilerOptions, host, typeChecker);
            }
            function getExtensionOptions(compilerOptions, includeExtensions) {
                if (includeExtensions === void 0) { includeExtensions = false; }
                return { extensions: getSupportedExtensionsForModuleResolution(compilerOptions), includeExtensions: includeExtensions };
            }
            function getCompletionEntriesForRelativeModules(literalValue, scriptDirectory, compilerOptions, host, scriptPath) {
                var extensionOptions = getExtensionOptions(compilerOptions);
                if (compilerOptions.rootDirs) {
                    return getCompletionEntriesForDirectoryFragmentWithRootDirs(compilerOptions.rootDirs, literalValue, scriptDirectory, extensionOptions, compilerOptions, host, scriptPath);
                }
                else {
                    return getCompletionEntriesForDirectoryFragment(literalValue, scriptDirectory, extensionOptions, host, scriptPath);
                }
            }
            function getSupportedExtensionsForModuleResolution(compilerOptions) {
                var extensions = ts.getSupportedExtensions(compilerOptions);
                return compilerOptions.resolveJsonModule && ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs ?
                    extensions.concat(".json" /* Json */) :
                    extensions;
            }
            /**
             * Takes a script path and returns paths for all potential folders that could be merged with its
             * containing folder via the "rootDirs" compiler option
             */
            function getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase) {
                // Make all paths absolute/normalized if they are not already
                rootDirs = rootDirs.map(function (rootDirectory) { return ts.normalizePath(ts.isRootedDiskPath(rootDirectory) ? rootDirectory : ts.combinePaths(basePath, rootDirectory)); });
                // Determine the path to the directory containing the script relative to the root directory it is contained within
                var relativeDirectory = ts.firstDefined(rootDirs, function (rootDirectory) {
                    return ts.containsPath(rootDirectory, scriptDirectory, basePath, ignoreCase) ? scriptDirectory.substr(rootDirectory.length) : undefined;
                }); // TODO: GH#18217
                // Now find a path for each potential directory that is to be merged with the one containing the script
                return ts.deduplicate(__spreadArrays(rootDirs.map(function (rootDirectory) { return ts.combinePaths(rootDirectory, relativeDirectory); }), [scriptDirectory]), ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive);
            }
            function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs, fragment, scriptDirectory, extensionOptions, compilerOptions, host, exclude) {
                var basePath = compilerOptions.project || host.getCurrentDirectory();
                var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
                var baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase);
                return ts.flatMap(baseDirectories, function (baseDirectory) { return getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude); });
            }
            /**
             * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename.
             */
            function getCompletionEntriesForDirectoryFragment(fragment, scriptPath, _a, host, exclude, result) {
                var extensions = _a.extensions, includeExtensions = _a.includeExtensions;
                if (result === void 0) { result = []; }
                if (fragment === undefined) {
                    fragment = "";
                }
                fragment = ts.normalizeSlashes(fragment);
                /**
                 * Remove the basename from the path. Note that we don't use the basename to filter completions;
                 * the client is responsible for refining completions.
                 */
                if (!ts.hasTrailingDirectorySeparator(fragment)) {
                    fragment = ts.getDirectoryPath(fragment);
                }
                if (fragment === "") {
                    fragment = "." + ts.directorySeparator;
                }
                fragment = ts.ensureTrailingDirectorySeparator(fragment);
                // const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); // TODO(rbuckton): should use resolvePaths
                var absolutePath = ts.resolvePath(scriptPath, fragment);
                var baseDirectory = ts.hasTrailingDirectorySeparator(absolutePath) ? absolutePath : ts.getDirectoryPath(absolutePath);
                var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
                if (!ts.tryDirectoryExists(host, baseDirectory))
                    return result;
                // Enumerate the available files if possible
                var files = ts.tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]);
                if (files) {
                    /**
                     * Multiple file entries might map to the same truncated name once we remove extensions
                     * (happens iff includeExtensions === false)so we use a set-like data structure. Eg:
                     *
                     * both foo.ts and foo.tsx become foo
                     */
                    var foundFiles = ts.createMap(); // maps file to its extension
                    for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
                        var filePath = files_1[_i];
                        filePath = ts.normalizePath(filePath);
                        if (exclude && ts.comparePaths(filePath, exclude, scriptPath, ignoreCase) === 0 /* EqualTo */) {
                            continue;
                        }
                        var foundFileName = includeExtensions || ts.fileExtensionIs(filePath, ".json" /* Json */) ? ts.getBaseFileName(filePath) : ts.removeFileExtension(ts.getBaseFileName(filePath));
                        foundFiles.set(foundFileName, ts.tryGetExtensionFromPath(filePath));
                    }
                    foundFiles.forEach(function (ext, foundFile) {
                        result.push(nameAndKind(foundFile, "script" /* scriptElement */, ext));
                    });
                }
                // If possible, get folder completion as well
                var directories = ts.tryGetDirectories(host, baseDirectory);
                if (directories) {
                    for (var _b = 0, directories_1 = directories; _b < directories_1.length; _b++) {
                        var directory = directories_1[_b];
                        var directoryName = ts.getBaseFileName(ts.normalizePath(directory));
                        if (directoryName !== "@types") {
                            result.push(directoryResult(directoryName));
                        }
                    }
                }
                // check for a version redirect
                var packageJsonPath = ts.findPackageJson(baseDirectory, host);
                if (packageJsonPath) {
                    var packageJson = ts.readJson(packageJsonPath, host);
                    var typesVersions = packageJson.typesVersions;
                    if (typeof typesVersions === "object") {
                        var versionResult = ts.getPackageJsonTypesVersionsPaths(typesVersions);
                        var versionPaths = versionResult && versionResult.paths;
                        var rest = absolutePath.slice(ts.ensureTrailingDirectorySeparator(baseDirectory).length);
                        if (versionPaths) {
                            addCompletionEntriesFromPaths(result, rest, baseDirectory, extensions, versionPaths, host);
                        }
                    }
                }
                return result;
            }
            function addCompletionEntriesFromPaths(result, fragment, baseDirectory, fileExtensions, paths, host) {
                for (var path in paths) {
                    if (!ts.hasProperty(paths, path))
                        continue;
                    var patterns = paths[path];
                    if (patterns) {
                        var _loop_1 = function (name, kind, extension) {
                            // Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
                            if (!result.some(function (entry) { return entry.name === name; })) {
                                result.push(nameAndKind(name, kind, extension));
                            }
                        };
                        for (var _i = 0, _a = getCompletionsForPathMapping(path, patterns, fragment, baseDirectory, fileExtensions, host); _i < _a.length; _i++) {
                            var _b = _a[_i], name = _b.name, kind = _b.kind, extension = _b.extension;
                            _loop_1(name, kind, extension);
                        }
                    }
                }
            }
            /**
             * Check all of the declared modules and those in node modules. Possible sources of modules:
             *      Modules that are found by the type checker
             *      Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option)
             *      Modules from node_modules (i.e. those listed in package.json)
             *          This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
             */
            function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, compilerOptions, host, typeChecker) {
                var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths;
                var result = [];
                var extensionOptions = getExtensionOptions(compilerOptions);
                if (baseUrl) {
                    var projectDir = compilerOptions.project || host.getCurrentDirectory();
                    var absolute = ts.normalizePath(ts.combinePaths(projectDir, baseUrl));
                    getCompletionEntriesForDirectoryFragment(fragment, absolute, extensionOptions, host, /*exclude*/ undefined, result);
                    if (paths) {
                        addCompletionEntriesFromPaths(result, fragment, absolute, extensionOptions.extensions, paths, host);
                    }
                }
                var fragmentDirectory = getFragmentDirectory(fragment);
                for (var _i = 0, _a = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _a.length; _i++) {
                    var ambientName = _a[_i];
                    result.push(nameAndKind(ambientName, "external module name" /* externalModuleName */, /*extension*/ undefined));
                }
                getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result);
                if (ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs) {
                    // If looking for a global package name, don't just include everything in `node_modules` because that includes dependencies' own dependencies.
                    // (But do if we didn't find anything, e.g. 'package.json' missing.)
                    var foundGlobal = false;
                    if (fragmentDirectory === undefined) {
                        var _loop_2 = function (moduleName) {
                            if (!result.some(function (entry) { return entry.name === moduleName; })) {
                                foundGlobal = true;
                                result.push(nameAndKind(moduleName, "external module name" /* externalModuleName */, /*extension*/ undefined));
                            }
                        };
                        for (var _b = 0, _c = enumerateNodeModulesVisibleToScript(host, scriptPath); _b < _c.length; _b++) {
                            var moduleName = _c[_b];
                            _loop_2(moduleName);
                        }
                    }
                    if (!foundGlobal) {
                        ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
                            var nodeModules = ts.combinePaths(ancestor, "node_modules");
                            if (ts.tryDirectoryExists(host, nodeModules)) {
                                getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
                            }
                        });
                    }
                }
                return result;
            }
            function getFragmentDirectory(fragment) {
                return containsSlash(fragment) ? ts.hasTrailingDirectorySeparator(fragment) ? fragment : ts.getDirectoryPath(fragment) : undefined;
            }
            function getCompletionsForPathMapping(path, patterns, fragment, baseUrl, fileExtensions, host) {
                if (!ts.endsWith(path, "*")) {
                    // For a path mapping "foo": ["/x/y/z.ts"], add "foo" itself as a completion.
                    return !ts.stringContains(path, "*") ? justPathMappingName(path) : ts.emptyArray;
                }
                var pathPrefix = path.slice(0, path.length - 1);
                var remainingFragment = ts.tryRemovePrefix(fragment, pathPrefix);
                return remainingFragment === undefined ? justPathMappingName(pathPrefix) : ts.flatMap(patterns, function (pattern) {
                    return getModulesForPathsPattern(remainingFragment, baseUrl, pattern, fileExtensions, host);
                });
                function justPathMappingName(name) {
                    return ts.startsWith(name, fragment) ? [directoryResult(name)] : ts.emptyArray;
                }
            }
            function getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host) {
                if (!host.readDirectory) {
                    return undefined;
                }
                var parsed = ts.hasZeroOrOneAsteriskCharacter(pattern) ? ts.tryParsePattern(pattern) : undefined;
                if (!parsed) {
                    return undefined;
                }
                // The prefix has two effective parts: the directory path and the base component after the filepath that is not a
                // full directory component. For example: directory/path/of/prefix/base*
                var normalizedPrefix = ts.resolvePath(parsed.prefix);
                var normalizedPrefixDirectory = ts.hasTrailingDirectorySeparator(parsed.prefix) ? normalizedPrefix : ts.getDirectoryPath(normalizedPrefix);
                var normalizedPrefixBase = ts.hasTrailingDirectorySeparator(parsed.prefix) ? "" : ts.getBaseFileName(normalizedPrefix);
                var fragmentHasPath = containsSlash(fragment);
                var fragmentDirectory = fragmentHasPath ? ts.hasTrailingDirectorySeparator(fragment) ? fragment : ts.getDirectoryPath(fragment) : undefined;
                // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call
                var expandedPrefixDirectory = fragmentHasPath ? ts.combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + fragmentDirectory) : normalizedPrefixDirectory;
                var normalizedSuffix = ts.normalizePath(parsed.suffix);
                // Need to normalize after combining: If we combinePaths("a", "../b"), we want "b" and not "a/../b".
                var baseDirectory = ts.normalizePath(ts.combinePaths(baseUrl, expandedPrefixDirectory));
                var completePrefix = fragmentHasPath ? baseDirectory : ts.ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase;
                // If we have a suffix, then we need to read the directory all the way down. We could create a glob
                // that encodes the suffix, but we would have to escape the character "?" which readDirectory
                // doesn't support. For now, this is safer but slower
                var includeGlob = normalizedSuffix ? "**/*" : "./*";
                var matches = ts.mapDefined(ts.tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]), function (match) {
                    var extension = ts.tryGetExtensionFromPath(match);
                    var name = trimPrefixAndSuffix(match);
                    return name === undefined ? undefined : nameAndKind(ts.removeFileExtension(name), "script" /* scriptElement */, extension);
                });
                var directories = ts.mapDefined(ts.tryGetDirectories(host, baseDirectory).map(function (d) { return ts.combinePaths(baseDirectory, d); }), function (dir) {
                    var name = trimPrefixAndSuffix(dir);
                    return name === undefined ? undefined : directoryResult(name);
                });
                return __spreadArrays(matches, directories);
                function trimPrefixAndSuffix(path) {
                    var inner = withoutStartAndEnd(ts.normalizePath(path), completePrefix, normalizedSuffix);
                    return inner === undefined ? undefined : removeLeadingDirectorySeparator(inner);
                }
            }
            function withoutStartAndEnd(s, start, end) {
                return ts.startsWith(s, start) && ts.endsWith(s, end) ? s.slice(start.length, s.length - end.length) : undefined;
            }
            function removeLeadingDirectorySeparator(path) {
                return path[0] === ts.directorySeparator ? path.slice(1) : path;
            }
            function getAmbientModuleCompletions(fragment, fragmentDirectory, checker) {
                // Get modules that the type checker picked up
                var ambientModules = checker.getAmbientModules().map(function (sym) { return ts.stripQuotes(sym.name); });
                var nonRelativeModuleNames = ambientModules.filter(function (moduleName) { return ts.startsWith(moduleName, fragment); });
                // Nested modules of the form "module-name/sub" need to be adjusted to only return the string
                // after the last '/' that appears in the fragment because that's where the replacement span
                // starts
                if (fragmentDirectory !== undefined) {
                    var moduleNameWithSeparator_1 = ts.ensureTrailingDirectorySeparator(fragmentDirectory);
                    return nonRelativeModuleNames.map(function (nonRelativeModuleName) { return ts.removePrefix(nonRelativeModuleName, moduleNameWithSeparator_1); });
                }
                return nonRelativeModuleNames;
            }
            function getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host) {
                var token = ts.getTokenAtPosition(sourceFile, position);
                var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos);
                var range = commentRanges && ts.find(commentRanges, function (commentRange) { return position >= commentRange.pos && position <= commentRange.end; });
                if (!range) {
                    return undefined;
                }
                var text = sourceFile.text.slice(range.pos, position);
                var match = tripleSlashDirectiveFragmentRegex.exec(text);
                if (!match) {
                    return undefined;
                }
                var prefix = match[1], kind = match[2], toComplete = match[3];
                var scriptPath = ts.getDirectoryPath(sourceFile.path);
                var names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, /*includeExtensions*/ true), host, sourceFile.path)
                    : kind === "types" ? getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, getFragmentDirectory(toComplete), getExtensionOptions(compilerOptions))
                        : ts.Debug.fail();
                return addReplacementSpans(toComplete, range.pos + prefix.length, names);
            }
            function getCompletionEntriesFromTypings(host, options, scriptPath, fragmentDirectory, extensionOptions, result) {
                if (result === void 0) { result = []; }
                // Check for typings specified in compiler options
                var seen = ts.createMap();
                var typeRoots = ts.tryAndIgnoreErrors(function () { return ts.getEffectiveTypeRoots(options, host); }) || ts.emptyArray;
                for (var _i = 0, typeRoots_1 = typeRoots; _i < typeRoots_1.length; _i++) {
                    var root = typeRoots_1[_i];
                    getCompletionEntriesFromDirectories(root);
                }
                // Also get all @types typings installed in visible node_modules directories
                for (var _a = 0, _b = ts.findPackageJsons(scriptPath, host); _a < _b.length; _a++) {
                    var packageJson = _b[_a];
                    var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
                    getCompletionEntriesFromDirectories(typesDir);
                }
                return result;
                function getCompletionEntriesFromDirectories(directory) {
                    if (!ts.tryDirectoryExists(host, directory))
                        return;
                    for (var _i = 0, _a = ts.tryGetDirectories(host, directory); _i < _a.length; _i++) {
                        var typeDirectoryName = _a[_i];
                        var packageName = ts.unmangleScopedPackageName(typeDirectoryName);
                        if (options.types && !ts.contains(options.types, packageName))
                            continue;
                        if (fragmentDirectory === undefined) {
                            if (!seen.has(packageName)) {
                                result.push(nameAndKind(packageName, "external module name" /* externalModuleName */, /*extension*/ undefined));
                                seen.set(packageName, true);
                            }
                        }
                        else {
                            var baseDirectory = ts.combinePaths(directory, typeDirectoryName);
                            var remainingFragment = ts.tryRemoveDirectoryPrefix(fragmentDirectory, packageName, ts.hostGetCanonicalFileName(host));
                            if (remainingFragment !== undefined) {
                                getCompletionEntriesForDirectoryFragment(remainingFragment, baseDirectory, extensionOptions, host, /*exclude*/ undefined, result);
                            }
                        }
                    }
                }
            }
            function enumerateNodeModulesVisibleToScript(host, scriptPath) {
                if (!host.readFile || !host.fileExists)
                    return ts.emptyArray;
                var result = [];
                for (var _i = 0, _a = ts.findPackageJsons(scriptPath, host); _i < _a.length; _i++) {
                    var packageJson = _a[_i];
                    var contents = ts.readJson(packageJson, host); // Cast to assert that readFile is defined
                    // Provide completions for all non @types dependencies
                    for (var _b = 0, nodeModulesDependencyKeys_1 = nodeModulesDependencyKeys; _b < nodeModulesDependencyKeys_1.length; _b++) {
                        var key = nodeModulesDependencyKeys_1[_b];
                        var dependencies = contents[key];
                        if (!dependencies)
                            continue;
                        for (var dep in dependencies) {
                            if (dependencies.hasOwnProperty(dep) && !ts.startsWith(dep, "@types/")) {
                                result.push(dep);
                            }
                        }
                    }
                }
                return result;
            }
            // Replace everything after the last directory separator that appears
            function getDirectoryFragmentTextSpan(text, textStart) {
                var index = Math.max(text.lastIndexOf(ts.directorySeparator), text.lastIndexOf("\\"));
                var offset = index !== -1 ? index + 1 : 0;
                // If the range is an identifier, span is unnecessary.
                var length = text.length - offset;
                return length === 0 || ts.isIdentifierText(text.substr(offset, length), 99 /* ESNext */) ? undefined : ts.createTextSpan(textStart + offset, length);
            }
            // Returns true if the path is explicitly relative to the script (i.e. relative to . or ..)
            function isPathRelativeToScript(path) {
                if (path && path.length >= 2 && path.charCodeAt(0) === 46 /* dot */) {
                    var slashIndex = path.length >= 3 && path.charCodeAt(1) === 46 /* dot */ ? 2 : 1;
                    var slashCharCode = path.charCodeAt(slashIndex);
                    return slashCharCode === 47 /* slash */ || slashCharCode === 92 /* backslash */;
                }
                return false;
            }
            /**
             * Matches a triple slash reference directive with an incomplete string literal for its path. Used
             * to determine if the caret is currently within the string literal and capture the literal fragment
             * for completions.
             * For example, this matches
             *
             * /// <reference path="fragment
             *
             * but not
             *
             * /// <reference path="fragment"
             */
            var tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3"]*)$/;
            var nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
            function containsSlash(fragment) {
                return ts.stringContains(fragment, ts.directorySeparator);
            }
        })(StringCompletions = Completions.StringCompletions || (Completions.StringCompletions = {}));
    })(Completions = ts.Completions || (ts.Completions = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Completions;
    (function (Completions) {
        var SortText;
        (function (SortText) {
            SortText["LocationPriority"] = "0";
            SortText["OptionalMember"] = "1";
            SortText["MemberDeclaredBySpreadAssignment"] = "2";
            SortText["SuggestedClassMembers"] = "3";
            SortText["GlobalsOrKeywords"] = "4";
            SortText["AutoImportSuggestions"] = "5";
            SortText["JavascriptIdentifiers"] = "6";
        })(SortText = Completions.SortText || (Completions.SortText = {}));
        /**
         * Special values for `CompletionInfo['source']` used to disambiguate
         * completion items with the same `name`. (Each completion item must
         * have a unique name/source combination, because those two fields
         * comprise `CompletionEntryIdentifier` in `getCompletionEntryDetails`.
         *
         * When the completion item is an auto-import suggestion, the source
         * is the module specifier of the suggestion. To avoid collisions,
         * the values here should not be a module specifier we would ever
         * generate for an auto-import.
         */
        var CompletionSource;
        (function (CompletionSource) {
            /** Completions that require `this.` insertion text */
            CompletionSource["ThisProperty"] = "ThisProperty/";
        })(CompletionSource = Completions.CompletionSource || (Completions.CompletionSource = {}));
        var SymbolOriginInfoKind;
        (function (SymbolOriginInfoKind) {
            SymbolOriginInfoKind[SymbolOriginInfoKind["ThisType"] = 1] = "ThisType";
            SymbolOriginInfoKind[SymbolOriginInfoKind["SymbolMember"] = 2] = "SymbolMember";
            SymbolOriginInfoKind[SymbolOriginInfoKind["Export"] = 4] = "Export";
            SymbolOriginInfoKind[SymbolOriginInfoKind["Promise"] = 8] = "Promise";
            SymbolOriginInfoKind[SymbolOriginInfoKind["Nullable"] = 16] = "Nullable";
            SymbolOriginInfoKind[SymbolOriginInfoKind["SymbolMemberNoExport"] = 2] = "SymbolMemberNoExport";
            SymbolOriginInfoKind[SymbolOriginInfoKind["SymbolMemberExport"] = 6] = "SymbolMemberExport";
        })(SymbolOriginInfoKind || (SymbolOriginInfoKind = {}));
        function originIsThisType(origin) {
            return !!(origin.kind & 1 /* ThisType */);
        }
        function originIsSymbolMember(origin) {
            return !!(origin.kind & 2 /* SymbolMember */);
        }
        function originIsExport(origin) {
            return !!(origin && origin.kind & 4 /* Export */);
        }
        function originIsPromise(origin) {
            return !!(origin.kind & 8 /* Promise */);
        }
        function originIsNullableMember(origin) {
            return !!(origin.kind & 16 /* Nullable */);
        }
        var KeywordCompletionFilters;
        (function (KeywordCompletionFilters) {
            KeywordCompletionFilters[KeywordCompletionFilters["None"] = 0] = "None";
            KeywordCompletionFilters[KeywordCompletionFilters["All"] = 1] = "All";
            KeywordCompletionFilters[KeywordCompletionFilters["ClassElementKeywords"] = 2] = "ClassElementKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["InterfaceElementKeywords"] = 3] = "InterfaceElementKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["ConstructorParameterKeywords"] = 4] = "ConstructorParameterKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["FunctionLikeBodyKeywords"] = 5] = "FunctionLikeBodyKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["TypeAssertionKeywords"] = 6] = "TypeAssertionKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["TypeKeywords"] = 7] = "TypeKeywords";
            KeywordCompletionFilters[KeywordCompletionFilters["Last"] = 7] = "Last";
        })(KeywordCompletionFilters || (KeywordCompletionFilters = {}));
        var GlobalsSearch;
        (function (GlobalsSearch) {
            GlobalsSearch[GlobalsSearch["Continue"] = 0] = "Continue";
            GlobalsSearch[GlobalsSearch["Success"] = 1] = "Success";
            GlobalsSearch[GlobalsSearch["Fail"] = 2] = "Fail";
        })(GlobalsSearch || (GlobalsSearch = {}));
        function createImportSuggestionsForFileCache() {
            var cache;
            var projectVersion;
            var fileName;
            return {
                isEmpty: function () {
                    return !cache;
                },
                clear: function () {
                    cache = undefined;
                    fileName = undefined;
                    projectVersion = undefined;
                },
                set: function (file, suggestions, version) {
                    cache = suggestions;
                    fileName = file;
                    if (version) {
                        projectVersion = version;
                    }
                },
                get: function (file, checker, version) {
                    if (file !== fileName) {
                        return undefined;
                    }
                    if (version) {
                        return projectVersion === version ? cache : undefined;
                    }
                    ts.forEach(cache, function (suggestion) {
                        var _a, _b, _c;
                        // If the symbol/moduleSymbol was a merged symbol, it will have a new identity
                        // in the checker, even though the symbols to merge are the same (guaranteed by
                        // cache invalidation in synchronizeHostData).
                        if ((_a = suggestion.symbol.declarations) === null || _a === void 0 ? void 0 : _a.length) {
                            suggestion.symbol = checker.getMergedSymbol(suggestion.origin.isDefaultExport
                                ? (_b = suggestion.symbol.declarations[0].localSymbol) !== null && _b !== void 0 ? _b : suggestion.symbol.declarations[0].symbol : suggestion.symbol.declarations[0].symbol);
                        }
                        if ((_c = suggestion.origin.moduleSymbol.declarations) === null || _c === void 0 ? void 0 : _c.length) {
                            suggestion.origin.moduleSymbol = checker.getMergedSymbol(suggestion.origin.moduleSymbol.declarations[0].symbol);
                        }
                    });
                    return cache;
                },
            };
        }
        Completions.createImportSuggestionsForFileCache = createImportSuggestionsForFileCache;
        function getCompletionsAtPosition(host, program, log, sourceFile, position, preferences, triggerCharacter) {
            var typeChecker = program.getTypeChecker();
            var compilerOptions = program.getCompilerOptions();
            var contextToken = ts.findPrecedingToken(position, sourceFile);
            if (triggerCharacter && !ts.isInString(sourceFile, position, contextToken) && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) {
                return undefined;
            }
            var stringCompletions = Completions.StringCompletions.getStringLiteralCompletions(sourceFile, position, contextToken, typeChecker, compilerOptions, host, log, preferences);
            if (stringCompletions) {
                return stringCompletions;
            }
            if (contextToken && ts.isBreakOrContinueStatement(contextToken.parent)
                && (contextToken.kind === 77 /* BreakKeyword */ || contextToken.kind === 82 /* ContinueKeyword */ || contextToken.kind === 75 /* Identifier */)) {
                return getLabelCompletionAtPosition(contextToken.parent);
            }
            var completionData = getCompletionData(program, log, sourceFile, isUncheckedFile(sourceFile, compilerOptions), position, preferences, /*detailsEntryId*/ undefined, host);
            if (!completionData) {
                return undefined;
            }
            switch (completionData.kind) {
                case 0 /* Data */:
                    return completionInfoFromData(sourceFile, typeChecker, compilerOptions, log, completionData, preferences);
                case 1 /* JsDocTagName */:
                    // If the current position is a jsDoc tag name, only tag names should be provided for completion
                    return jsdocCompletionInfo(ts.JsDoc.getJSDocTagNameCompletions());
                case 2 /* JsDocTag */:
                    // If the current position is a jsDoc tag, only tags should be provided for completion
                    return jsdocCompletionInfo(ts.JsDoc.getJSDocTagCompletions());
                case 3 /* JsDocParameterName */:
                    return jsdocCompletionInfo(ts.JsDoc.getJSDocParameterNameCompletions(completionData.tag));
                default:
                    return ts.Debug.assertNever(completionData);
            }
        }
        Completions.getCompletionsAtPosition = getCompletionsAtPosition;
        function jsdocCompletionInfo(entries) {
            return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries };
        }
        function completionInfoFromData(sourceFile, typeChecker, compilerOptions, log, completionData, preferences) {
            var symbols = completionData.symbols, completionKind = completionData.completionKind, isInSnippetScope = completionData.isInSnippetScope, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, propertyAccessToConvert = completionData.propertyAccessToConvert, keywordFilters = completionData.keywordFilters, literals = completionData.literals, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap, recommendedCompletion = completionData.recommendedCompletion, isJsxInitializer = completionData.isJsxInitializer, insideJsDocTagTypeExpression = completionData.insideJsDocTagTypeExpression, symbolToSortTextMap = completionData.symbolToSortTextMap;
            if (location && location.parent && ts.isJsxClosingElement(location.parent)) {
                // In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag,
                // instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element.
                // For example:
                //     var x = <div> </ /*1*/
                // The completion list at "1" will contain "div>" with type any
                // And at `<div> </ /*1*/ >` (with a closing `>`), the completion list will contain "div".
                var tagName = location.parent.parent.openingElement.tagName;
                var hasClosingAngleBracket = !!ts.findChildOfKind(location.parent, 31 /* GreaterThanToken */, sourceFile);
                var entry = {
                    name: tagName.getFullText(sourceFile) + (hasClosingAngleBracket ? "" : ">"),
                    kind: "class" /* classElement */,
                    kindModifiers: undefined,
                    sortText: SortText.LocationPriority,
                };
                return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [entry] };
            }
            var entries = [];
            if (isUncheckedFile(sourceFile, compilerOptions)) {
                var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, 
                /* contextToken */ undefined, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, preferences, propertyAccessToConvert, completionData.isJsxIdentifierExpected, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap, symbolToSortTextMap);
                getJSCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries); // TODO: GH#18217
            }
            else {
                if (!isNewIdentifierLocation && (!symbols || symbols.length === 0) && keywordFilters === 0 /* None */) {
                    return undefined;
                }
                getCompletionEntriesFromSymbols(symbols, entries, 
                /* contextToken */ undefined, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, preferences, propertyAccessToConvert, completionData.isJsxIdentifierExpected, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap, symbolToSortTextMap);
            }
            if (keywordFilters !== 0 /* None */) {
                var entryNames = ts.arrayToSet(entries, function (e) { return e.name; });
                for (var _i = 0, _a = getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && ts.isSourceFileJS(sourceFile)); _i < _a.length; _i++) {
                    var keywordEntry = _a[_i];
                    if (!entryNames.has(keywordEntry.name)) {
                        entries.push(keywordEntry);
                    }
                }
            }
            for (var _b = 0, literals_1 = literals; _b < literals_1.length; _b++) {
                var literal = literals_1[_b];
                entries.push(createCompletionEntryForLiteral(literal, preferences));
            }
            return { isGlobalCompletion: isInSnippetScope, isMemberCompletion: isMemberCompletionKind(completionKind), isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
        }
        function isUncheckedFile(sourceFile, compilerOptions) {
            return ts.isSourceFileJS(sourceFile) && !ts.isCheckJsEnabledForFile(sourceFile, compilerOptions);
        }
        function isMemberCompletionKind(kind) {
            switch (kind) {
                case 0 /* ObjectPropertyDeclaration */:
                case 3 /* MemberLike */:
                case 2 /* PropertyAccess */:
                    return true;
                default:
                    return false;
            }
        }
        function getJSCompletionEntries(sourceFile, position, uniqueNames, target, entries) {
            ts.getNameTable(sourceFile).forEach(function (pos, name) {
                // Skip identifiers produced only from the current location
                if (pos === position) {
                    return;
                }
                var realName = ts.unescapeLeadingUnderscores(name);
                if (!uniqueNames.has(realName) && ts.isIdentifierText(realName, target)) {
                    uniqueNames.add(realName);
                    entries.push({
                        name: realName,
                        kind: "warning" /* warning */,
                        kindModifiers: "",
                        sortText: SortText.JavascriptIdentifiers,
                        isFromUncheckedFile: true
                    });
                }
            });
        }
        function completionNameForLiteral(literal, preferences) {
            return typeof literal === "object" ? ts.pseudoBigIntToString(literal) + "n" :
                ts.isString(literal) ? ts.quote(literal, preferences) : JSON.stringify(literal);
        }
        function createCompletionEntryForLiteral(literal, preferences) {
            return { name: completionNameForLiteral(literal, preferences), kind: "string" /* string */, kindModifiers: "" /* none */, sortText: SortText.LocationPriority };
        }
        function createCompletionEntry(symbol, sortText, contextToken, location, sourceFile, typeChecker, name, needsConvertPropertyAccess, origin, recommendedCompletion, propertyAccessToConvert, isJsxInitializer, preferences) {
            var insertText;
            var replacementSpan = ts.getReplacementSpanForContextToken(contextToken);
            var insertQuestionDot = origin && originIsNullableMember(origin);
            var useBraces = origin && originIsSymbolMember(origin) || needsConvertPropertyAccess;
            if (origin && originIsThisType(origin)) {
                insertText = needsConvertPropertyAccess
                    ? "this" + (insertQuestionDot ? "?." : "") + "[" + quotePropertyName(name, preferences) + "]"
                    : "this" + (insertQuestionDot ? "?." : ".") + name;
            }
            // We should only have needsConvertPropertyAccess if there's a property access to convert. But see #21790.
            // Somehow there was a global with a non-identifier name. Hopefully someone will complain about getting a "foo bar" global completion and provide a repro.
            else if ((useBraces || insertQuestionDot) && propertyAccessToConvert) {
                insertText = useBraces ? needsConvertPropertyAccess ? "[" + quotePropertyName(name, preferences) + "]" : "[" + name + "]" : name;
                if (insertQuestionDot || propertyAccessToConvert.questionDotToken) {
                    insertText = "?." + insertText;
                }
                var dot = ts.findChildOfKind(propertyAccessToConvert, 24 /* DotToken */, sourceFile) ||
                    ts.findChildOfKind(propertyAccessToConvert, 28 /* QuestionDotToken */, sourceFile);
                if (!dot) {
                    return undefined;
                }
                // If the text after the '.' starts with this name, write over it. Else, add new text.
                var end = ts.startsWith(name, propertyAccessToConvert.name.text) ? propertyAccessToConvert.name.end : dot.end;
                replacementSpan = ts.createTextSpanFromBounds(dot.getStart(sourceFile), end);
            }
            if (isJsxInitializer) {
                if (insertText === undefined)
                    insertText = name;
                insertText = "{" + insertText + "}";
                if (typeof isJsxInitializer !== "boolean") {
                    replacementSpan = ts.createTextSpanFromNode(isJsxInitializer, sourceFile);
                }
            }
            if (origin && originIsPromise(origin) && propertyAccessToConvert) {
                if (insertText === undefined)
                    insertText = name;
                var precedingToken = ts.findPrecedingToken(propertyAccessToConvert.pos, sourceFile);
                var awaitText = "";
                if (precedingToken && ts.positionIsASICandidate(precedingToken.end, precedingToken.parent, sourceFile)) {
                    awaitText = ";";
                }
                awaitText += "(await " + propertyAccessToConvert.expression.getText() + ")";
                insertText = needsConvertPropertyAccess ? "" + awaitText + insertText : "" + awaitText + (insertQuestionDot ? "?." : ".") + insertText;
                replacementSpan = ts.createTextSpanFromBounds(propertyAccessToConvert.getStart(sourceFile), propertyAccessToConvert.end);
            }
            if (insertText !== undefined && !preferences.includeCompletionsWithInsertText) {
                return undefined;
            }
            // TODO(drosen): Right now we just permit *all* semantic meanings when calling
            // 'getSymbolKind' which is permissible given that it is backwards compatible; but
            // really we should consider passing the meaning for the node so that we don't report
            // that a suggestion for a value is an interface.  We COULD also just do what
            // 'getSymbolModifiers' does, which is to use the first declaration.
            // Use a 'sortText' of 0' so that all symbol completion entries come before any other
            // entries (like JavaScript identifier entries).
            return {
                name: name,
                kind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, location),
                kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol),
                sortText: sortText,
                source: getSourceFromOrigin(origin),
                hasAction: origin && originIsExport(origin) || undefined,
                isRecommended: isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker) || undefined,
                insertText: insertText,
                replacementSpan: replacementSpan,
            };
        }
        function quotePropertyName(name, preferences) {
            if (/^\d+$/.test(name)) {
                return name;
            }
            return ts.quote(name, preferences);
        }
        function isRecommendedCompletionMatch(localSymbol, recommendedCompletion, checker) {
            return localSymbol === recommendedCompletion ||
                !!(localSymbol.flags & 1048576 /* ExportValue */) && checker.getExportSymbolOfSymbol(localSymbol) === recommendedCompletion;
        }
        function getSourceFromOrigin(origin) {
            if (originIsExport(origin)) {
                return ts.stripQuotes(origin.moduleSymbol.name);
            }
            if ((origin === null || origin === void 0 ? void 0 : origin.kind) === 1 /* ThisType */) {
                return CompletionSource.ThisProperty;
            }
        }
        function getCompletionEntriesFromSymbols(symbols, entries, contextToken, location, sourceFile, typeChecker, target, log, kind, preferences, propertyAccessToConvert, jsxIdentifierExpected, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap, symbolToSortTextMap) {
            var start = ts.timestamp();
            // Tracks unique names.
            // Value is set to false for global variables or completions from external module exports, because we can have multiple of those;
            // true otherwise. Based on the order we add things we will always see locals first, then globals, then module exports.
            // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name.
            var uniques = ts.createMap();
            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
                var symbol = symbols_1[_i];
                var origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[ts.getSymbolId(symbol)] : undefined;
                var info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind, !!jsxIdentifierExpected);
                if (!info) {
                    continue;
                }
                var name = info.name, needsConvertPropertyAccess = info.needsConvertPropertyAccess;
                if (uniques.get(name)) {
                    continue;
                }
                var entry = createCompletionEntry(symbol, symbolToSortTextMap && symbolToSortTextMap[ts.getSymbolId(symbol)] || SortText.LocationPriority, contextToken, location, sourceFile, typeChecker, name, needsConvertPropertyAccess, origin, recommendedCompletion, propertyAccessToConvert, isJsxInitializer, preferences);
                if (!entry) {
                    continue;
                }
                /** True for locals; false for globals, module exports from other files, `this.` completions. */
                var shouldShadowLaterSymbols = !origin && !(symbol.parent === undefined && !ts.some(symbol.declarations, function (d) { return d.getSourceFile() === location.getSourceFile(); }));
                uniques.set(name, shouldShadowLaterSymbols);
                entries.push(entry);
            }
            log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (ts.timestamp() - start));
            // Prevent consumers of this map from having to worry about
            // the boolean value. Externally, it should be seen as the
            // set of all names.
            return {
                has: function (name) { return uniques.has(name); },
                add: function (name) { return uniques.set(name, true); },
            };
        }
        Completions.getCompletionEntriesFromSymbols = getCompletionEntriesFromSymbols;
        function getLabelCompletionAtPosition(node) {
            var entries = getLabelStatementCompletions(node);
            if (entries.length) {
                return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries };
            }
        }
        function getLabelStatementCompletions(node) {
            var entries = [];
            var uniques = ts.createMap();
            var current = node;
            while (current) {
                if (ts.isFunctionLike(current)) {
                    break;
                }
                if (ts.isLabeledStatement(current)) {
                    var name = current.label.text;
                    if (!uniques.has(name)) {
                        uniques.set(name, true);
                        entries.push({
                            name: name,
                            kindModifiers: "" /* none */,
                            kind: "label" /* label */,
                            sortText: SortText.LocationPriority
                        });
                    }
                }
                current = current.parent;
            }
            return entries;
        }
        function getSymbolCompletionFromEntryId(program, log, sourceFile, position, entryId, host, preferences) {
            var compilerOptions = program.getCompilerOptions();
            var completionData = getCompletionData(program, log, sourceFile, isUncheckedFile(sourceFile, compilerOptions), position, { includeCompletionsForModuleExports: true, includeCompletionsWithInsertText: true }, entryId, host);
            if (!completionData) {
                return { type: "none" };
            }
            if (completionData.kind !== 0 /* Data */) {
                return { type: "request", request: completionData };
            }
            var symbols = completionData.symbols, literals = completionData.literals, location = completionData.location, completionKind = completionData.completionKind, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap, previousToken = completionData.previousToken, isJsxInitializer = completionData.isJsxInitializer, isTypeOnlyLocation = completionData.isTypeOnlyLocation;
            var literal = ts.find(literals, function (l) { return completionNameForLiteral(l, preferences) === entryId.name; });
            if (literal !== undefined)
                return { type: "literal", literal: literal };
            // Find the symbol with the matching entry name.
            // We don't need to perform character checks here because we're only comparing the
            // name against 'entryName' (which is known to be good), not building a new
            // completion entry.
            return ts.firstDefined(symbols, function (symbol) {
                var origin = symbolToOriginInfoMap[ts.getSymbolId(symbol)];
                var info = getCompletionEntryDisplayNameForSymbol(symbol, compilerOptions.target, origin, completionKind, completionData.isJsxIdentifierExpected);
                return info && info.name === entryId.name && getSourceFromOrigin(origin) === entryId.source
                    ? { type: "symbol", symbol: symbol, location: location, symbolToOriginInfoMap: symbolToOriginInfoMap, previousToken: previousToken, isJsxInitializer: isJsxInitializer, isTypeOnlyLocation: isTypeOnlyLocation }
                    : undefined;
            }) || { type: "none" };
        }
        function getCompletionEntryDetails(program, log, sourceFile, position, entryId, host, formatContext, preferences, cancellationToken) {
            var typeChecker = program.getTypeChecker();
            var compilerOptions = program.getCompilerOptions();
            var name = entryId.name;
            var contextToken = ts.findPrecedingToken(position, sourceFile);
            if (ts.isInString(sourceFile, position, contextToken)) {
                return Completions.StringCompletions.getStringLiteralCompletionDetails(name, sourceFile, position, contextToken, typeChecker, compilerOptions, host, cancellationToken);
            }
            // Compute all the completion symbols again.
            var symbolCompletion = getSymbolCompletionFromEntryId(program, log, sourceFile, position, entryId, host, preferences);
            switch (symbolCompletion.type) {
                case "request": {
                    var request = symbolCompletion.request;
                    switch (request.kind) {
                        case 1 /* JsDocTagName */:
                            return ts.JsDoc.getJSDocTagNameCompletionDetails(name);
                        case 2 /* JsDocTag */:
                            return ts.JsDoc.getJSDocTagCompletionDetails(name);
                        case 3 /* JsDocParameterName */:
                            return ts.JsDoc.getJSDocParameterNameCompletionDetails(name);
                        default:
                            return ts.Debug.assertNever(request);
                    }
                }
                case "symbol": {
                    var symbol = symbolCompletion.symbol, location = symbolCompletion.location, symbolToOriginInfoMap = symbolCompletion.symbolToOriginInfoMap, previousToken = symbolCompletion.previousToken;
                    var _a = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, typeChecker, host, compilerOptions, sourceFile, position, previousToken, formatContext, preferences), codeActions = _a.codeActions, sourceDisplay = _a.sourceDisplay;
                    return createCompletionDetailsForSymbol(symbol, typeChecker, sourceFile, location, cancellationToken, codeActions, sourceDisplay); // TODO: GH#18217
                }
                case "literal": {
                    var literal = symbolCompletion.literal;
                    return createSimpleDetails(completionNameForLiteral(literal, preferences), "string" /* string */, typeof literal === "string" ? ts.SymbolDisplayPartKind.stringLiteral : ts.SymbolDisplayPartKind.numericLiteral);
                }
                case "none":
                    // Didn't find a symbol with this name.  See if we can find a keyword instead.
                    return allKeywordsCompletions().some(function (c) { return c.name === name; }) ? createSimpleDetails(name, "keyword" /* keyword */, ts.SymbolDisplayPartKind.keyword) : undefined;
                default:
                    ts.Debug.assertNever(symbolCompletion);
            }
        }
        Completions.getCompletionEntryDetails = getCompletionEntryDetails;
        function createSimpleDetails(name, kind, kind2) {
            return createCompletionDetails(name, "" /* none */, kind, [ts.displayPart(name, kind2)]);
        }
        function createCompletionDetailsForSymbol(symbol, checker, sourceFile, location, cancellationToken, codeActions, sourceDisplay) {
            var _a = checker.runWithCancellationToken(cancellationToken, function (checker) {
                return ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, 7 /* All */);
            }), displayParts = _a.displayParts, documentation = _a.documentation, symbolKind = _a.symbolKind, tags = _a.tags;
            return createCompletionDetails(symbol.name, ts.SymbolDisplay.getSymbolModifiers(symbol), symbolKind, displayParts, documentation, tags, codeActions, sourceDisplay);
        }
        Completions.createCompletionDetailsForSymbol = createCompletionDetailsForSymbol;
        function createCompletionDetails(name, kindModifiers, kind, displayParts, documentation, tags, codeActions, source) {
            return { name: name, kindModifiers: kindModifiers, kind: kind, displayParts: displayParts, documentation: documentation, tags: tags, codeActions: codeActions, source: source };
        }
        Completions.createCompletionDetails = createCompletionDetails;
        function getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, checker, host, compilerOptions, sourceFile, position, previousToken, formatContext, preferences) {
            var symbolOriginInfo = symbolToOriginInfoMap[ts.getSymbolId(symbol)];
            if (!symbolOriginInfo || !originIsExport(symbolOriginInfo)) {
                return { codeActions: undefined, sourceDisplay: undefined };
            }
            var moduleSymbol = symbolOriginInfo.moduleSymbol;
            var exportedSymbol = checker.getMergedSymbol(ts.skipAlias(symbol.exportSymbol || symbol, checker));
            var _a = ts.codefix.getImportCompletionAction(exportedSymbol, moduleSymbol, sourceFile, ts.getNameForExportedSymbol(symbol, compilerOptions.target), host, program, formatContext, previousToken && ts.isIdentifier(previousToken) ? previousToken.getStart(sourceFile) : position, preferences), moduleSpecifier = _a.moduleSpecifier, codeAction = _a.codeAction;
            return { sourceDisplay: [ts.textPart(moduleSpecifier)], codeActions: [codeAction] };
        }
        function getCompletionEntrySymbol(program, log, sourceFile, position, entryId, host, preferences) {
            var completion = getSymbolCompletionFromEntryId(program, log, sourceFile, position, entryId, host, preferences);
            return completion.type === "symbol" ? completion.symbol : undefined;
        }
        Completions.getCompletionEntrySymbol = getCompletionEntrySymbol;
        var CompletionDataKind;
        (function (CompletionDataKind) {
            CompletionDataKind[CompletionDataKind["Data"] = 0] = "Data";
            CompletionDataKind[CompletionDataKind["JsDocTagName"] = 1] = "JsDocTagName";
            CompletionDataKind[CompletionDataKind["JsDocTag"] = 2] = "JsDocTag";
            CompletionDataKind[CompletionDataKind["JsDocParameterName"] = 3] = "JsDocParameterName";
        })(CompletionDataKind || (CompletionDataKind = {}));
        var CompletionKind;
        (function (CompletionKind) {
            CompletionKind[CompletionKind["ObjectPropertyDeclaration"] = 0] = "ObjectPropertyDeclaration";
            CompletionKind[CompletionKind["Global"] = 1] = "Global";
            CompletionKind[CompletionKind["PropertyAccess"] = 2] = "PropertyAccess";
            CompletionKind[CompletionKind["MemberLike"] = 3] = "MemberLike";
            CompletionKind[CompletionKind["String"] = 4] = "String";
            CompletionKind[CompletionKind["None"] = 5] = "None";
        })(CompletionKind = Completions.CompletionKind || (Completions.CompletionKind = {}));
        function getRecommendedCompletion(previousToken, contextualType, checker) {
            // For a union, return the first one with a recommended completion.
            return ts.firstDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), function (type) {
                var symbol = type && type.symbol;
                // Don't include make a recommended completion for an abstract class
                return symbol && (symbol.flags & (8 /* EnumMember */ | 384 /* Enum */ | 32 /* Class */) && !ts.isAbstractConstructorSymbol(symbol))
                    ? getFirstSymbolInChain(symbol, previousToken, checker)
                    : undefined;
            });
        }
        function getContextualType(previousToken, position, sourceFile, checker) {
            var parent = previousToken.parent;
            switch (previousToken.kind) {
                case 75 /* Identifier */:
                    return ts.getContextualTypeFromParent(previousToken, checker);
                case 62 /* EqualsToken */:
                    switch (parent.kind) {
                        case 242 /* VariableDeclaration */:
                            return checker.getContextualType(parent.initializer); // TODO: GH#18217
                        case 209 /* BinaryExpression */:
                            return checker.getTypeAtLocation(parent.left);
                        case 273 /* JsxAttribute */:
                            return checker.getContextualTypeForJsxAttribute(parent);
                        default:
                            return undefined;
                    }
                case 99 /* NewKeyword */:
                    return checker.getContextualType(parent);
                case 78 /* CaseKeyword */:
                    return ts.getSwitchedType(ts.cast(parent, ts.isCaseClause), checker);
                case 18 /* OpenBraceToken */:
                    return ts.isJsxExpression(parent) && parent.parent.kind !== 266 /* JsxElement */ ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined;
                default:
                    var argInfo = ts.SignatureHelp.getArgumentInfoForCompletions(previousToken, position, sourceFile);
                    return argInfo ?
                        // At `,`, treat this as the next argument after the comma.
                        checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (previousToken.kind === 27 /* CommaToken */ ? 1 : 0)) :
                        ts.isEqualityOperatorKind(previousToken.kind) && ts.isBinaryExpression(parent) && ts.isEqualityOperatorKind(parent.operatorToken.kind) ?
                            // completion at `x ===/**/` should be for the right side
                            checker.getTypeAtLocation(parent.left) :
                            checker.getContextualType(previousToken);
            }
        }
        function getFirstSymbolInChain(symbol, enclosingDeclaration, checker) {
            var chain = checker.getAccessibleSymbolChain(symbol, enclosingDeclaration, /*meaning*/ 67108863 /* All */, /*useOnlyExternalAliasing*/ false);
            if (chain)
                return ts.first(chain);
            return symbol.parent && (isModuleSymbol(symbol.parent) ? symbol : getFirstSymbolInChain(symbol.parent, enclosingDeclaration, checker));
        }
        function isModuleSymbol(symbol) {
            return symbol.declarations.some(function (d) { return d.kind === 290 /* SourceFile */; });
        }
        function getCompletionData(program, log, sourceFile, isUncheckedFile, position, preferences, detailsEntryId, host) {
            var typeChecker = program.getTypeChecker();
            var start = ts.timestamp();
            var currentToken = ts.getTokenAtPosition(sourceFile, position); // TODO: GH#15853
            // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.)
            log("getCompletionData: Get current token: " + (ts.timestamp() - start));
            start = ts.timestamp();
            var insideComment = ts.isInComment(sourceFile, position, currentToken);
            log("getCompletionData: Is inside comment: " + (ts.timestamp() - start));
            var insideJsDocTagTypeExpression = false;
            var isInSnippetScope = false;
            if (insideComment) {
                if (ts.hasDocComment(sourceFile, position)) {
                    if (sourceFile.text.charCodeAt(position - 1) === 64 /* at */) {
                        // The current position is next to the '@' sign, when no tag name being provided yet.
                        // Provide a full list of tag names
                        return { kind: 1 /* JsDocTagName */ };
                    }
                    else {
                        // When completion is requested without "@", we will have check to make sure that
                        // there are no comments prefix the request position. We will only allow "*" and space.
                        // e.g
                        //   /** |c| /*
                        //
                        //   /**
                        //     |c|
                        //    */
                        //
                        //   /**
                        //    * |c|
                        //    */
                        //
                        //   /**
                        //    *         |c|
                        //    */
                        var lineStart = ts.getLineStartPositionForPosition(position, sourceFile);
                        if (!(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/))) {
                            return { kind: 2 /* JsDocTag */ };
                        }
                    }
                }
                // Completion should work inside certain JsDoc tags. For example:
                //     /** @type {number | string} */
                // Completion should work in the brackets
                var tag = getJsDocTagAtPosition(currentToken, position);
                if (tag) {
                    if (tag.tagName.pos <= position && position <= tag.tagName.end) {
                        return { kind: 1 /* JsDocTagName */ };
                    }
                    if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === 294 /* JSDocTypeExpression */) {
                        currentToken = ts.getTokenAtPosition(sourceFile, position);
                        if (!currentToken ||
                            (!ts.isDeclarationName(currentToken) &&
                                (currentToken.parent.kind !== 323 /* JSDocPropertyTag */ ||
                                    currentToken.parent.name !== currentToken))) {
                            // Use as type location if inside tag's type expression
                            insideJsDocTagTypeExpression = isCurrentlyEditingNode(tag.typeExpression);
                        }
                    }
                    if (!insideJsDocTagTypeExpression && ts.isJSDocParameterTag(tag) && (ts.nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) {
                        return { kind: 3 /* JsDocParameterName */, tag: tag };
                    }
                }
                if (!insideJsDocTagTypeExpression) {
                    // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
                    // comment or the plain text part of a jsDoc comment, so no completion should be available
                    log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment.");
                    return undefined;
                }
            }
            start = ts.timestamp();
            var previousToken = ts.findPrecedingToken(position, sourceFile, /*startNode*/ undefined); // TODO: GH#18217
            log("getCompletionData: Get previous token 1: " + (ts.timestamp() - start));
            // The decision to provide completion depends on the contextToken, which is determined through the previousToken.
            // Note: 'previousToken' (and thus 'contextToken') can be undefined if we are the beginning of the file
            var contextToken = previousToken;
            // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS|
            // Skip this partial identifier and adjust the contextToken to the token that precedes it.
            if (contextToken && position <= contextToken.end && (ts.isIdentifierOrPrivateIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) {
                var start_1 = ts.timestamp();
                contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined); // TODO: GH#18217
                log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_1));
            }
            // Find the node where completion is requested on.
            // Also determine whether we are trying to complete with members of that node
            // or attributes of a JSX tag.
            var node = currentToken;
            var propertyAccessToConvert;
            var isRightOfDot = false;
            var isRightOfQuestionDot = false;
            var isRightOfOpenTag = false;
            var isStartingCloseTag = false;
            var isJsxInitializer = false;
            var isJsxIdentifierExpected = false;
            var location = ts.getTouchingPropertyName(sourceFile, position);
            if (contextToken) {
                // Bail out if this is a known invalid completion location
                if (isCompletionListBlocker(contextToken)) {
                    log("Returning an empty list because completion was requested in an invalid position.");
                    return undefined;
                }
                var parent = contextToken.parent;
                if (contextToken.kind === 24 /* DotToken */ || contextToken.kind === 28 /* QuestionDotToken */) {
                    isRightOfDot = contextToken.kind === 24 /* DotToken */;
                    isRightOfQuestionDot = contextToken.kind === 28 /* QuestionDotToken */;
                    switch (parent.kind) {
                        case 194 /* PropertyAccessExpression */:
                            propertyAccessToConvert = parent;
                            node = propertyAccessToConvert.expression;
                            if (node.end === contextToken.pos &&
                                ts.isCallExpression(node) &&
                                node.getChildCount(sourceFile) &&
                                ts.last(node.getChildren(sourceFile)).kind !== 21 /* CloseParenToken */) {
                                // This is likely dot from incorrectly parsed call expression and user is starting to write spread
                                // eg: Math.min(./**/)
                                return undefined;
                            }
                            break;
                        case 153 /* QualifiedName */:
                            node = parent.left;
                            break;
                        case 249 /* ModuleDeclaration */:
                            node = parent.name;
                            break;
                        case 188 /* ImportType */:
                        case 219 /* MetaProperty */:
                            node = parent;
                            break;
                        default:
                            // There is nothing that precedes the dot, so this likely just a stray character
                            // or leading into a '...' token. Just bail out instead.
                            return undefined;
                    }
                }
                else if (sourceFile.languageVariant === 1 /* JSX */) {
                    // <UI.Test /* completion position */ />
                    // If the tagname is a property access expression, we will then walk up to the top most of property access expression.
                    // Then, try to get a JSX container and its associated attributes type.
                    if (parent && parent.kind === 194 /* PropertyAccessExpression */) {
                        contextToken = parent;
                        parent = parent.parent;
                    }
                    // Fix location
                    if (currentToken.parent === location) {
                        switch (currentToken.kind) {
                            case 31 /* GreaterThanToken */:
                                if (currentToken.parent.kind === 266 /* JsxElement */ || currentToken.parent.kind === 268 /* JsxOpeningElement */) {
                                    location = currentToken;
                                }
                                break;
                            case 43 /* SlashToken */:
                                if (currentToken.parent.kind === 267 /* JsxSelfClosingElement */) {
                                    location = currentToken;
                                }
                                break;
                        }
                    }
                    switch (parent.kind) {
                        case 269 /* JsxClosingElement */:
                            if (contextToken.kind === 43 /* SlashToken */) {
                                isStartingCloseTag = true;
                                location = contextToken;
                            }
                            break;
                        case 209 /* BinaryExpression */:
                            if (!binaryExpressionMayBeOpenTag(parent)) {
                                break;
                            }
                        // falls through
                        case 267 /* JsxSelfClosingElement */:
                        case 266 /* JsxElement */:
                        case 268 /* JsxOpeningElement */:
                            isJsxIdentifierExpected = true;
                            if (contextToken.kind === 29 /* LessThanToken */) {
                                isRightOfOpenTag = true;
                                location = contextToken;
                            }
                            break;
                        case 273 /* JsxAttribute */:
                            switch (previousToken.kind) {
                                case 62 /* EqualsToken */:
                                    isJsxInitializer = true;
                                    break;
                                case 75 /* Identifier */:
                                    isJsxIdentifierExpected = true;
                                    // For `<div x=[|f/**/|]`, `parent` will be `x` and `previousToken.parent` will be `f` (which is its own JsxAttribute)
                                    // Note for `<div someBool f>` we don't want to treat this as a jsx inializer, instead it's the attribute name.
                                    if (parent !== previousToken.parent &&
                                        !parent.initializer &&
                                        ts.findChildOfKind(parent, 62 /* EqualsToken */, sourceFile)) {
                                        isJsxInitializer = previousToken;
                                    }
                            }
                            break;
                    }
                }
            }
            var semanticStart = ts.timestamp();
            var completionKind = 5 /* None */;
            var isNewIdentifierLocation = false;
            var keywordFilters = 0 /* None */;
            // This also gets mutated in nested-functions after the return
            var symbols = [];
            var symbolToOriginInfoMap = [];
            var symbolToSortTextMap = [];
            var importSuggestionsCache = host.getImportSuggestionsCache && host.getImportSuggestionsCache();
            var isTypeOnly = isTypeOnlyCompletion();
            if (isRightOfDot || isRightOfQuestionDot) {
                getTypeScriptMemberSymbols();
            }
            else if (isRightOfOpenTag) {
                var tagSymbols = typeChecker.getJsxIntrinsicTagNamesAt(location);
                ts.Debug.assertEachIsDefined(tagSymbols, "getJsxIntrinsicTagNames() should all be defined");
                tryGetGlobalSymbols();
                symbols = tagSymbols.concat(symbols);
                completionKind = 3 /* MemberLike */;
                keywordFilters = 0 /* None */;
            }
            else if (isStartingCloseTag) {
                var tagName = contextToken.parent.parent.openingElement.tagName;
                var tagSymbol = typeChecker.getSymbolAtLocation(tagName);
                if (tagSymbol) {
                    symbols = [tagSymbol];
                }
                completionKind = 3 /* MemberLike */;
                keywordFilters = 0 /* None */;
            }
            else {
                // For JavaScript or TypeScript, if we're not after a dot, then just try to get the
                // global symbols in scope.  These results should be valid for either language as
                // the set of symbols that can be referenced from this location.
                if (!tryGetGlobalSymbols()) {
                    return undefined;
                }
            }
            log("getCompletionData: Semantic work: " + (ts.timestamp() - semanticStart));
            var contextualType = previousToken && getContextualType(previousToken, position, sourceFile, typeChecker);
            var literals = ts.mapDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), function (t) { return t.isLiteral() ? t.value : undefined; });
            var recommendedCompletion = previousToken && contextualType && getRecommendedCompletion(previousToken, contextualType, typeChecker);
            return {
                kind: 0 /* Data */,
                symbols: symbols,
                completionKind: completionKind,
                isInSnippetScope: isInSnippetScope,
                propertyAccessToConvert: propertyAccessToConvert,
                isNewIdentifierLocation: isNewIdentifierLocation,
                location: location,
                keywordFilters: keywordFilters,
                literals: literals,
                symbolToOriginInfoMap: symbolToOriginInfoMap,
                recommendedCompletion: recommendedCompletion,
                previousToken: previousToken,
                isJsxInitializer: isJsxInitializer,
                insideJsDocTagTypeExpression: insideJsDocTagTypeExpression,
                symbolToSortTextMap: symbolToSortTextMap,
                isTypeOnlyLocation: isTypeOnly,
                isJsxIdentifierExpected: isJsxIdentifierExpected,
            };
            function isTagWithTypeExpression(tag) {
                switch (tag.kind) {
                    case 317 /* JSDocParameterTag */:
                    case 323 /* JSDocPropertyTag */:
                    case 318 /* JSDocReturnTag */:
                    case 320 /* JSDocTypeTag */:
                    case 322 /* JSDocTypedefTag */:
                        return true;
                    default:
                        return false;
                }
            }
            function getTypeScriptMemberSymbols() {
                // Right of dot member completion list
                completionKind = 2 /* PropertyAccess */;
                // Since this is qualified name check it's a type node location
                var isImportType = ts.isLiteralImportTypeNode(node);
                var isTypeLocation = insideJsDocTagTypeExpression
                    || (isImportType && !node.isTypeOf)
                    || ts.isPartOfTypeNode(node.parent)
                    || ts.isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker);
                var isRhsOfImportDeclaration = ts.isInRightSideOfInternalImportEqualsDeclaration(node);
                if (ts.isEntityName(node) || isImportType) {
                    var isNamespaceName = ts.isModuleDeclaration(node.parent);
                    if (isNamespaceName)
                        isNewIdentifierLocation = true;
                    var symbol = typeChecker.getSymbolAtLocation(node);
                    if (symbol) {
                        symbol = ts.skipAlias(symbol, typeChecker);
                        if (symbol.flags & (1536 /* Module */ | 384 /* Enum */)) {
                            // Extract module or enum members
                            var exportedSymbols = typeChecker.getExportsOfModule(symbol);
                            ts.Debug.assertEachIsDefined(exportedSymbols, "getExportsOfModule() should all be defined");
                            var isValidValueAccess_1 = function (symbol) { return typeChecker.isValidPropertyAccess(isImportType ? node : (node.parent), symbol.name); };
                            var isValidTypeAccess_1 = function (symbol) { return symbolCanBeReferencedAtTypeLocation(symbol); };
                            var isValidAccess = isNamespaceName
                                // At `namespace N.M/**/`, if this is the only declaration of `M`, don't include `M` as a completion.
                                ? function (symbol) { return !!(symbol.flags & 1920 /* Namespace */) && !symbol.declarations.every(function (d) { return d.parent === node.parent; }); }
                                : isRhsOfImportDeclaration ?
                                    // Any kind is allowed when dotting off namespace in internal import equals declaration
                                    function (symbol) { return isValidTypeAccess_1(symbol) || isValidValueAccess_1(symbol); } :
                                    isTypeLocation ? isValidTypeAccess_1 : isValidValueAccess_1;
                            for (var _i = 0, exportedSymbols_1 = exportedSymbols; _i < exportedSymbols_1.length; _i++) {
                                var exportedSymbol = exportedSymbols_1[_i];
                                if (isValidAccess(exportedSymbol)) {
                                    symbols.push(exportedSymbol);
                                }
                            }
                            // If the module is merged with a value, we must get the type of the class and add its propertes (for inherited static methods).
                            if (!isTypeLocation &&
                                symbol.declarations &&
                                symbol.declarations.some(function (d) { return d.kind !== 290 /* SourceFile */ && d.kind !== 249 /* ModuleDeclaration */ && d.kind !== 248 /* EnumDeclaration */; })) {
                                var type = typeChecker.getTypeOfSymbolAtLocation(symbol, node).getNonOptionalType();
                                var insertQuestionDot = false;
                                if (type.isNullableType()) {
                                    var canCorrectToQuestionDot = isRightOfDot &&
                                        !isRightOfQuestionDot &&
                                        preferences.includeAutomaticOptionalChainCompletions !== false;
                                    if (canCorrectToQuestionDot || isRightOfQuestionDot) {
                                        type = type.getNonNullableType();
                                        if (canCorrectToQuestionDot) {
                                            insertQuestionDot = true;
                                        }
                                    }
                                }
                                addTypeProperties(type, !!(node.flags & 32768 /* AwaitContext */), insertQuestionDot);
                            }
                            return;
                        }
                    }
                }
                if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */) && contextToken === node.getChildAt(1)) {
                    var completion = (node.keywordToken === 99 /* NewKeyword */) ? "target" : "meta";
                    symbols.push(typeChecker.createSymbol(4 /* Property */, ts.escapeLeadingUnderscores(completion)));
                    return;
                }
                if (!isTypeLocation) {
                    var type = typeChecker.getTypeAtLocation(node).getNonOptionalType();
                    var insertQuestionDot = false;
                    if (type.isNullableType()) {
                        var canCorrectToQuestionDot = isRightOfDot &&
                            !isRightOfQuestionDot &&
                            preferences.includeAutomaticOptionalChainCompletions !== false;
                        if (canCorrectToQuestionDot || isRightOfQuestionDot) {
                            type = type.getNonNullableType();
                            if (canCorrectToQuestionDot) {
                                insertQuestionDot = true;
                            }
                        }
                    }
                    addTypeProperties(type, !!(node.flags & 32768 /* AwaitContext */), insertQuestionDot);
                }
            }
            function addTypeProperties(type, insertAwait, insertQuestionDot) {
                isNewIdentifierLocation = !!type.getStringIndexType();
                if (isRightOfQuestionDot && ts.some(type.getCallSignatures())) {
                    isNewIdentifierLocation = true;
                }
                var propertyAccess = node.kind === 188 /* ImportType */ ? node : node.parent;
                if (isUncheckedFile) {
                    // In javascript files, for union types, we don't just get the members that
                    // the individual types have in common, we also include all the members that
                    // each individual type has. This is because we're going to add all identifiers
                    // anyways. So we might as well elevate the members that were at least part
                    // of the individual types to a higher status since we know what they are.
                    symbols.push.apply(symbols, getPropertiesForCompletion(type, typeChecker));
                }
                else {
                    for (var _i = 0, _a = type.getApparentProperties(); _i < _a.length; _i++) {
                        var symbol = _a[_i];
                        if (typeChecker.isValidPropertyAccessForCompletions(propertyAccess, type, symbol)) {
                            addPropertySymbol(symbol, /*insertAwait*/ false, insertQuestionDot);
                        }
                    }
                }
                if (insertAwait && preferences.includeCompletionsWithInsertText) {
                    var promiseType = typeChecker.getPromisedTypeOfPromise(type);
                    if (promiseType) {
                        for (var _b = 0, _c = promiseType.getApparentProperties(); _b < _c.length; _b++) {
                            var symbol = _c[_b];
                            if (typeChecker.isValidPropertyAccessForCompletions(propertyAccess, promiseType, symbol)) {
                                addPropertySymbol(symbol, /* insertAwait */ true, insertQuestionDot);
                            }
                        }
                    }
                }
            }
            function addPropertySymbol(symbol, insertAwait, insertQuestionDot) {
                // For a computed property with an accessible name like `Symbol.iterator`,
                // we'll add a completion for the *name* `Symbol` instead of for the property.
                // If this is e.g. [Symbol.iterator], add a completion for `Symbol`.
                var computedPropertyName = ts.firstDefined(symbol.declarations, function (decl) { return ts.tryCast(ts.getNameOfDeclaration(decl), ts.isComputedPropertyName); });
                if (computedPropertyName) {
                    var leftMostName = getLeftMostName(computedPropertyName.expression); // The completion is for `Symbol`, not `iterator`.
                    var nameSymbol = leftMostName && typeChecker.getSymbolAtLocation(leftMostName);
                    // If this is nested like for `namespace N { export const sym = Symbol(); }`, we'll add the completion for `N`.
                    var firstAccessibleSymbol = nameSymbol && getFirstSymbolInChain(nameSymbol, contextToken, typeChecker);
                    if (firstAccessibleSymbol && !symbolToOriginInfoMap[ts.getSymbolId(firstAccessibleSymbol)]) {
                        symbols.push(firstAccessibleSymbol);
                        var moduleSymbol = firstAccessibleSymbol.parent;
                        symbolToOriginInfoMap[ts.getSymbolId(firstAccessibleSymbol)] =
                            !moduleSymbol || !ts.isExternalModuleSymbol(moduleSymbol)
                                ? { kind: getNullableSymbolOriginInfoKind(2 /* SymbolMemberNoExport */) }
                                : { kind: getNullableSymbolOriginInfoKind(6 /* SymbolMemberExport */), moduleSymbol: moduleSymbol, isDefaultExport: false };
                    }
                    else if (preferences.includeCompletionsWithInsertText) {
                        addSymbolOriginInfo(symbol);
                        symbols.push(symbol);
                    }
                }
                else {
                    addSymbolOriginInfo(symbol);
                    symbols.push(symbol);
                }
                function addSymbolOriginInfo(symbol) {
                    if (preferences.includeCompletionsWithInsertText) {
                        if (insertAwait && !symbolToOriginInfoMap[ts.getSymbolId(symbol)]) {
                            symbolToOriginInfoMap[ts.getSymbolId(symbol)] = { kind: getNullableSymbolOriginInfoKind(8 /* Promise */) };
                        }
                        else if (insertQuestionDot) {
                            symbolToOriginInfoMap[ts.getSymbolId(symbol)] = { kind: 16 /* Nullable */ };
                        }
                    }
                }
                function getNullableSymbolOriginInfoKind(kind) {
                    return insertQuestionDot ? kind | 16 /* Nullable */ : kind;
                }
            }
            /** Given 'a.b.c', returns 'a'. */
            function getLeftMostName(e) {
                return ts.isIdentifier(e) ? e : ts.isPropertyAccessExpression(e) ? getLeftMostName(e.expression) : undefined;
            }
            function tryGetGlobalSymbols() {
                var result = tryGetObjectLikeCompletionSymbols()
                    || tryGetImportOrExportClauseCompletionSymbols()
                    || tryGetLocalNamedExportCompletionSymbols()
                    || tryGetConstructorCompletion()
                    || tryGetClassLikeCompletionSymbols()
                    || tryGetJsxCompletionSymbols()
                    || (getGlobalCompletions(), 1 /* Success */);
                return result === 1 /* Success */;
            }
            function tryGetConstructorCompletion() {
                if (!tryGetConstructorLikeCompletionContainer(contextToken))
                    return 0 /* Continue */;
                // no members, only keywords
                completionKind = 5 /* None */;
                // Declaring new property/method/accessor
                isNewIdentifierLocation = true;
                // Has keywords for constructor parameter
                keywordFilters = 4 /* ConstructorParameterKeywords */;
                return 1 /* Success */;
            }
            function tryGetJsxCompletionSymbols() {
                var jsxContainer = tryGetContainingJsxElement(contextToken);
                // Cursor is inside a JSX self-closing element or opening element
                var attrsType = jsxContainer && typeChecker.getContextualType(jsxContainer.attributes);
                if (!attrsType)
                    return 0 /* Continue */;
                var completionsType = jsxContainer && typeChecker.getContextualType(jsxContainer.attributes, 4 /* Completions */);
                symbols = filterJsxAttributes(getPropertiesForObjectExpression(attrsType, completionsType, jsxContainer.attributes, typeChecker), jsxContainer.attributes.properties);
                setSortTextToOptionalMember();
                completionKind = 3 /* MemberLike */;
                isNewIdentifierLocation = false;
                return 1 /* Success */;
            }
            function getGlobalCompletions() {
                keywordFilters = tryGetFunctionLikeBodyCompletionContainer(contextToken) ? 5 /* FunctionLikeBodyKeywords */ : 1 /* All */;
                // Get all entities in the current scope.
                completionKind = 1 /* Global */;
                isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken);
                if (previousToken !== contextToken) {
                    ts.Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'.");
                }
                // We need to find the node that will give us an appropriate scope to begin
                // aggregating completion candidates. This is achieved in 'getScopeNode'
                // by finding the first node that encompasses a position, accounting for whether a node
                // is "complete" to decide whether a position belongs to the node.
                //
                // However, at the end of an identifier, we are interested in the scope of the identifier
                // itself, but fall outside of the identifier. For instance:
                //
                //      xyz => x$
                //
                // the cursor is outside of both the 'x' and the arrow function 'xyz => x',
                // so 'xyz' is not returned in our results.
                //
                // We define 'adjustedPosition' so that we may appropriately account for
                // being at the end of an identifier. The intention is that if requesting completion
                // at the end of an identifier, it should be effectively equivalent to requesting completion
                // anywhere inside/at the beginning of the identifier. So in the previous case, the
                // 'adjustedPosition' will work as if requesting completion in the following:
                //
                //      xyz => $x
                //
                // If previousToken !== contextToken, then
                //   - 'contextToken' was adjusted to the token prior to 'previousToken'
                //      because we were at the end of an identifier.
                //   - 'previousToken' is defined.
                var adjustedPosition = previousToken !== contextToken ?
                    previousToken.getStart() :
                    position;
                var scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
                isInSnippetScope = isSnippetScope(scopeNode);
                var symbolMeanings = (isTypeOnly ? 0 /* None */ : 111551 /* Value */) | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */;
                symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
                ts.Debug.assertEachIsDefined(symbols, "getSymbolsInScope() should all be defined");
                for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
                    var symbol = symbols_2[_i];
                    if (!typeChecker.isArgumentsSymbol(symbol) &&
                        !ts.some(symbol.declarations, function (d) { return d.getSourceFile() === sourceFile; })) {
                        symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.GlobalsOrKeywords;
                    }
                }
                // Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions`
                if (preferences.includeCompletionsWithInsertText && scopeNode.kind !== 290 /* SourceFile */) {
                    var thisType = typeChecker.tryGetThisTypeAt(scopeNode, /*includeGlobalThis*/ false);
                    if (thisType && !isProbablyGlobalType(thisType, sourceFile, typeChecker)) {
                        for (var _a = 0, _b = getPropertiesForCompletion(thisType, typeChecker); _a < _b.length; _a++) {
                            var symbol = _b[_a];
                            symbolToOriginInfoMap[ts.getSymbolId(symbol)] = { kind: 1 /* ThisType */ };
                            symbols.push(symbol);
                            symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.SuggestedClassMembers;
                        }
                    }
                }
                if (shouldOfferImportCompletions()) {
                    var lowerCaseTokenText_1 = previousToken && ts.isIdentifier(previousToken) ? previousToken.text.toLowerCase() : "";
                    var autoImportSuggestions = getSymbolsFromOtherSourceFileExports(program.getCompilerOptions().target, host);
                    if (!detailsEntryId && importSuggestionsCache) {
                        importSuggestionsCache.set(sourceFile.fileName, autoImportSuggestions, host.getProjectVersion && host.getProjectVersion());
                    }
                    autoImportSuggestions.forEach(function (_a) {
                        var symbol = _a.symbol, symbolName = _a.symbolName, skipFilter = _a.skipFilter, origin = _a.origin;
                        if (detailsEntryId) {
                            if (detailsEntryId.source && ts.stripQuotes(origin.moduleSymbol.name) !== detailsEntryId.source) {
                                return;
                            }
                        }
                        else if (!skipFilter && !stringContainsCharactersInOrder(symbolName.toLowerCase(), lowerCaseTokenText_1)) {
                            return;
                        }
                        var symbolId = ts.getSymbolId(symbol);
                        symbols.push(symbol);
                        symbolToOriginInfoMap[symbolId] = origin;
                        symbolToSortTextMap[symbolId] = SortText.AutoImportSuggestions;
                    });
                }
                filterGlobalCompletion(symbols);
            }
            function shouldOfferImportCompletions() {
                // If not already a module, must have modules enabled.
                if (!preferences.includeCompletionsForModuleExports)
                    return false;
                // If already using ES6 modules, OK to continue using them.
                if (sourceFile.externalModuleIndicator || sourceFile.commonJsModuleIndicator)
                    return true;
                // If module transpilation is enabled or we're targeting es6 or above, or not emitting, OK.
                if (ts.compilerOptionsIndicateEs6Modules(program.getCompilerOptions()))
                    return true;
                // If some file is using ES6 modules, assume that it's OK to add more.
                return ts.programContainsModules(program);
            }
            function isSnippetScope(scopeNode) {
                switch (scopeNode.kind) {
                    case 290 /* SourceFile */:
                    case 211 /* TemplateExpression */:
                    case 276 /* JsxExpression */:
                    case 223 /* Block */:
                        return true;
                    default:
                        return ts.isStatement(scopeNode);
                }
            }
            function filterGlobalCompletion(symbols) {
                var isTypeOnly = isTypeOnlyCompletion();
                if (isTypeOnly) {
                    keywordFilters = isTypeAssertion()
                        ? 6 /* TypeAssertionKeywords */
                        : 7 /* TypeKeywords */;
                }
                ts.filterMutate(symbols, function (symbol) {
                    if (!ts.isSourceFile(location)) {
                        // export = /**/ here we want to get all meanings, so any symbol is ok
                        if (ts.isExportAssignment(location.parent)) {
                            return true;
                        }
                        symbol = ts.skipAlias(symbol, typeChecker);
                        // import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
                        if (ts.isInRightSideOfInternalImportEqualsDeclaration(location)) {
                            return !!(symbol.flags & 1920 /* Namespace */);
                        }
                        if (isTypeOnly) {
                            // It's a type, but you can reach it by namespace.type as well
                            return symbolCanBeReferencedAtTypeLocation(symbol);
                        }
                    }
                    // expressions are value space (which includes the value namespaces)
                    return !!(ts.getCombinedLocalAndExportSymbolFlags(symbol) & 111551 /* Value */);
                });
            }
            function isTypeAssertion() {
                return ts.isAssertionExpression(contextToken.parent);
            }
            function isTypeOnlyCompletion() {
                return insideJsDocTagTypeExpression
                    || !isContextTokenValueLocation(contextToken) &&
                        (ts.isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker)
                            || ts.isPartOfTypeNode(location)
                            || isContextTokenTypeLocation(contextToken));
            }
            function isContextTokenValueLocation(contextToken) {
                return contextToken &&
                    contextToken.kind === 108 /* TypeOfKeyword */ &&
                    (contextToken.parent.kind === 172 /* TypeQuery */ || ts.isTypeOfExpression(contextToken.parent));
            }
            function isContextTokenTypeLocation(contextToken) {
                if (contextToken) {
                    var parentKind = contextToken.parent.kind;
                    switch (contextToken.kind) {
                        case 58 /* ColonToken */:
                            return parentKind === 159 /* PropertyDeclaration */ ||
                                parentKind === 158 /* PropertySignature */ ||
                                parentKind === 156 /* Parameter */ ||
                                parentKind === 242 /* VariableDeclaration */ ||
                                ts.isFunctionLikeKind(parentKind);
                        case 62 /* EqualsToken */:
                            return parentKind === 247 /* TypeAliasDeclaration */;
                        case 123 /* AsKeyword */:
                            return parentKind === 217 /* AsExpression */;
                        case 29 /* LessThanToken */:
                            return parentKind === 169 /* TypeReference */ ||
                                parentKind === 199 /* TypeAssertionExpression */;
                        case 90 /* ExtendsKeyword */:
                            return parentKind === 155 /* TypeParameter */;
                    }
                }
                return false;
            }
            /** True if symbol is a type or a module containing at least one type. */
            function symbolCanBeReferencedAtTypeLocation(symbol, seenModules) {
                if (seenModules === void 0) { seenModules = ts.createMap(); }
                var sym = ts.skipAlias(symbol.exportSymbol || symbol, typeChecker);
                return !!(sym.flags & 788968 /* Type */) ||
                    !!(sym.flags & 1536 /* Module */) &&
                        ts.addToSeen(seenModules, ts.getSymbolId(sym)) &&
                        typeChecker.getExportsOfModule(sym).some(function (e) { return symbolCanBeReferencedAtTypeLocation(e, seenModules); });
            }
            /**
             * Gathers symbols that can be imported from other files, de-duplicating along the way. Symbols can be "duplicates"
             * if re-exported from another module, e.g. `export { foo } from "./a"`. That syntax creates a fresh symbol, but
             * it’s just an alias to the first, and both have the same name, so we generally want to filter those aliases out,
             * if and only if the the first can be imported (it may be excluded due to package.json filtering in
             * `codefix.forEachExternalModuleToImportFrom`).
             *
             * Example. Imagine a chain of node_modules re-exporting one original symbol:
             *
             * ```js
             *  node_modules/x/index.js         node_modules/y/index.js           node_modules/z/index.js
             * +-----------------------+      +--------------------------+      +--------------------------+
             * |                       |      |                          |      |                          |
             * | export const foo = 0; | <--- | export { foo } from 'x'; | <--- | export { foo } from 'y'; |
             * |                       |      |                          |      |                          |
             * +-----------------------+      +--------------------------+      +--------------------------+
             * ```
             *
             * Also imagine three buckets, which we’ll reference soon:
             *
             * ```md
             * |                  |      |                      |      |                   |
             * |   **Bucket A**   |      |    **Bucket B**      |      |    **Bucket C**   |
             * |    Symbols to    |      | Aliases to symbols   |      | Symbols to return |
             * |    definitely    |      | in Buckets A or C    |      | if nothing better |
             * |      return      |      | (don’t return these) |      |    comes along    |
             * |__________________|      |______________________|      |___________________|
             * ```
             *
             * We _probably_ want to show `foo` from 'x', but not from 'y' or 'z'. However, if 'x' is not in a package.json, it
             * will not appear in a `forEachExternalModuleToImportFrom` iteration. Furthermore, the order of iterations is not
             * guaranteed, as it is host-dependent. Therefore, when presented with the symbol `foo` from module 'y' alone, we
             * may not be sure whether or not it should go in the list. So, we’ll take the following steps:
             *
             * 1. Resolve alias `foo` from 'y' to the export declaration in 'x', get the symbol there, and see if that symbol is
             *    already in Bucket A (symbols we already know will be returned). If it is, put `foo` from 'y' in Bucket B
             *    (symbols that are aliases to symbols in Bucket A). If it’s not, put it in Bucket C.
             * 2. Next, imagine we see `foo` from module 'z'. Again, we resolve the alias to the nearest export, which is in 'y'.
             *    At this point, if that nearest export from 'y' is in _any_ of the three buckets, we know the symbol in 'z'
             *    should never be returned in the final list, so put it in Bucket B.
             * 3. Next, imagine we see `foo` from module 'x', the original. Syntactically, it doesn’t look like a re-export, so
             *    we can just check Bucket C to see if we put any aliases to the original in there. If they exist, throw them out.
             *    Put this symbol in Bucket A.
             * 4. After we’ve iterated through every symbol of every module, any symbol left in Bucket C means that step 3 didn’t
             *    occur for that symbol---that is, the original symbol is not in Bucket A, so we should include the alias. Move
             *    everything from Bucket C to Bucket A.
             */
            function getSymbolsFromOtherSourceFileExports(target, host) {
                var cached = importSuggestionsCache && importSuggestionsCache.get(sourceFile.fileName, typeChecker, detailsEntryId && host.getProjectVersion ? host.getProjectVersion() : undefined);
                if (cached) {
                    log("getSymbolsFromOtherSourceFileExports: Using cached list");
                    return cached;
                }
                var startTime = ts.timestamp();
                log("getSymbolsFromOtherSourceFileExports: Recomputing list" + (detailsEntryId ? " for details entry" : ""));
                var seenResolvedModules = ts.createMap();
                var seenExports = ts.createMap();
                /** Bucket B */
                var aliasesToAlreadyIncludedSymbols = ts.createMap();
                /** Bucket C */
                var aliasesToReturnIfOriginalsAreMissing = ts.createMap();
                /** Bucket A */
                var results = [];
                /** Ids present in `results` for faster lookup */
                var resultSymbolIds = ts.createMap();
                ts.codefix.forEachExternalModuleToImportFrom(program, host, sourceFile, !detailsEntryId, function (moduleSymbol) {
                    // Perf -- ignore other modules if this is a request for details
                    if (detailsEntryId && detailsEntryId.source && ts.stripQuotes(moduleSymbol.name) !== detailsEntryId.source) {
                        return;
                    }
                    var resolvedModuleSymbol = typeChecker.resolveExternalModuleSymbol(moduleSymbol);
                    // resolvedModuleSymbol may be a namespace. A namespace may be `export =` by multiple module declarations, but only keep the first one.
                    if (!ts.addToSeen(seenResolvedModules, ts.getSymbolId(resolvedModuleSymbol))) {
                        return;
                    }
                    // Don't add another completion for `export =` of a symbol that's already global.
                    // So in `declare namespace foo {} declare module "foo" { export = foo; }`, there will just be the global completion for `foo`.
                    if (resolvedModuleSymbol !== moduleSymbol && ts.every(resolvedModuleSymbol.declarations, ts.isNonGlobalDeclaration)) {
                        pushSymbol(resolvedModuleSymbol, moduleSymbol, /*skipFilter*/ true);
                    }
                    for (var _i = 0, _a = typeChecker.getExportsAndPropertiesOfModule(moduleSymbol); _i < _a.length; _i++) {
                        var symbol = _a[_i];
                        var symbolId = ts.getSymbolId(symbol).toString();
                        // `getExportsAndPropertiesOfModule` can include duplicates
                        if (!ts.addToSeen(seenExports, symbolId)) {
                            continue;
                        }
                        // If this is `export { _break as break };` (a keyword) -- skip this and prefer the keyword completion.
                        if (ts.some(symbol.declarations, function (d) { return ts.isExportSpecifier(d) && !!d.propertyName && ts.isIdentifierANonContextualKeyword(d.name); })) {
                            continue;
                        }
                        // If `symbol.parent !== moduleSymbol`, this is an `export * from "foo"` re-export. Those don't create new symbols.
                        var isExportStarFromReExport = typeChecker.getMergedSymbol(symbol.parent) !== resolvedModuleSymbol;
                        // If `!!d.parent.parent.moduleSpecifier`, this is `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check).
                        if (isExportStarFromReExport || ts.some(symbol.declarations, function (d) { return ts.isExportSpecifier(d) && !d.propertyName && !!d.parent.parent.moduleSpecifier; })) {
                            // Walk the export chain back one module (step 1 or 2 in diagrammed example).
                            // Or, in the case of `export * from "foo"`, `symbol` already points to the original export, so just use that.
                            var nearestExportSymbol = isExportStarFromReExport ? symbol : getNearestExportSymbol(symbol);
                            if (!nearestExportSymbol)
                                continue;
                            var nearestExportSymbolId = ts.getSymbolId(nearestExportSymbol).toString();
                            var symbolHasBeenSeen = resultSymbolIds.has(nearestExportSymbolId) || aliasesToAlreadyIncludedSymbols.has(nearestExportSymbolId);
                            if (!symbolHasBeenSeen) {
                                aliasesToReturnIfOriginalsAreMissing.set(nearestExportSymbolId, { alias: symbol, moduleSymbol: moduleSymbol });
                                aliasesToAlreadyIncludedSymbols.set(symbolId, true);
                            }
                            else {
                                // Perf - we know this symbol is an alias to one that’s already covered in `symbols`, so store it here
                                // in case another symbol re-exports this one; that way we can short-circuit as soon as we see this symbol id.
                                ts.addToSeen(aliasesToAlreadyIncludedSymbols, symbolId);
                            }
                        }
                        else {
                            // This is not a re-export, so see if we have any aliases pending and remove them (step 3 in diagrammed example)
                            aliasesToReturnIfOriginalsAreMissing.delete(symbolId);
                            pushSymbol(symbol, moduleSymbol);
                        }
                    }
                });
                // By this point, any potential duplicates that were actually duplicates have been
                // removed, so the rest need to be added. (Step 4 in diagrammed example)
                aliasesToReturnIfOriginalsAreMissing.forEach(function (_a) {
                    var alias = _a.alias, moduleSymbol = _a.moduleSymbol;
                    return pushSymbol(alias, moduleSymbol);
                });
                log("getSymbolsFromOtherSourceFileExports: " + (ts.timestamp() - startTime));
                return results;
                function pushSymbol(symbol, moduleSymbol, skipFilter) {
                    if (skipFilter === void 0) { skipFilter = false; }
                    var isDefaultExport = symbol.escapedName === "default" /* Default */;
                    if (isDefaultExport) {
                        symbol = ts.getLocalSymbolForExportDefault(symbol) || symbol;
                    }
                    if (typeChecker.isUndefinedSymbol(symbol)) {
                        return;
                    }
                    ts.addToSeen(resultSymbolIds, ts.getSymbolId(symbol));
                    var origin = { kind: 4 /* Export */, moduleSymbol: moduleSymbol, isDefaultExport: isDefaultExport };
                    results.push({
                        symbol: symbol,
                        symbolName: ts.getNameForExportedSymbol(symbol, target),
                        origin: origin,
                        skipFilter: skipFilter,
                    });
                }
            }
            function getNearestExportSymbol(fromSymbol) {
                return findAlias(typeChecker, fromSymbol, function (alias) {
                    return ts.some(alias.declarations, function (d) { return ts.isExportSpecifier(d) || !!d.localSymbol; });
                });
            }
            /**
             * True if you could remove some characters in `a` to get `b`.
             * E.g., true for "abcdef" and "bdf".
             * But not true for "abcdef" and "dbf".
             */
            function stringContainsCharactersInOrder(str, characters) {
                if (characters.length === 0) {
                    return true;
                }
                var characterIndex = 0;
                for (var strIndex = 0; strIndex < str.length; strIndex++) {
                    if (str.charCodeAt(strIndex) === characters.charCodeAt(characterIndex)) {
                        characterIndex++;
                        if (characterIndex === characters.length) {
                            return true;
                        }
                    }
                }
                // Did not find all characters
                return false;
            }
            /**
             * Finds the first node that "embraces" the position, so that one may
             * accurately aggregate locals from the closest containing scope.
             */
            function getScopeNode(initialToken, position, sourceFile) {
                var scope = initialToken;
                while (scope && !ts.positionBelongsToNode(scope, position, sourceFile)) {
                    scope = scope.parent;
                }
                return scope;
            }
            function isCompletionListBlocker(contextToken) {
                var start = ts.timestamp();
                var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) ||
                    isSolelyIdentifierDefinitionLocation(contextToken) ||
                    isDotOfNumericLiteral(contextToken) ||
                    isInJsxText(contextToken);
                log("getCompletionsAtPosition: isCompletionListBlocker: " + (ts.timestamp() - start));
                return result;
            }
            function isInJsxText(contextToken) {
                if (contextToken.kind === 11 /* JsxText */) {
                    return true;
                }
                if (contextToken.kind === 31 /* GreaterThanToken */ && contextToken.parent) {
                    if (contextToken.parent.kind === 268 /* JsxOpeningElement */) {
                        // Two possibilities:
                        //   1. <div>/**/
                        //      - contextToken: GreaterThanToken (before cursor)
                        //      - location: JSXElement
                        //      - different parents (JSXOpeningElement, JSXElement)
                        //   2. <Component<string> /**/>
                        //      - contextToken: GreaterThanToken (before cursor)
                        //      - location: GreaterThanToken (after cursor)
                        //      - same parent (JSXOpeningElement)
                        return location.parent.kind !== 268 /* JsxOpeningElement */;
                    }
                    if (contextToken.parent.kind === 269 /* JsxClosingElement */ || contextToken.parent.kind === 267 /* JsxSelfClosingElement */) {
                        return !!contextToken.parent.parent && contextToken.parent.parent.kind === 266 /* JsxElement */;
                    }
                }
                return false;
            }
            function isNewIdentifierDefinitionLocation(previousToken) {
                if (previousToken) {
                    var containingNodeKind = previousToken.parent.kind;
                    // Previous token may have been a keyword that was converted to an identifier.
                    switch (keywordForNode(previousToken)) {
                        case 27 /* CommaToken */:
                            return containingNodeKind === 196 /* CallExpression */ // func( a, |
                                || containingNodeKind === 162 /* Constructor */ // constructor( a, |   /* public, protected, private keywords are allowed here, so show completion */
                                || containingNodeKind === 197 /* NewExpression */ // new C(a, |
                                || containingNodeKind === 192 /* ArrayLiteralExpression */ // [a, |
                                || containingNodeKind === 209 /* BinaryExpression */ // const x = (a, |
                                || containingNodeKind === 170 /* FunctionType */; // var x: (s: string, list|
                        case 20 /* OpenParenToken */:
                            return containingNodeKind === 196 /* CallExpression */ // func( |
                                || containingNodeKind === 162 /* Constructor */ // constructor( |
                                || containingNodeKind === 197 /* NewExpression */ // new C(a|
                                || containingNodeKind === 200 /* ParenthesizedExpression */ // const x = (a|
                                || containingNodeKind === 182 /* ParenthesizedType */; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */
                        case 22 /* OpenBracketToken */:
                            return containingNodeKind === 192 /* ArrayLiteralExpression */ // [ |
                                || containingNodeKind === 167 /* IndexSignature */ // [ | : string ]
                                || containingNodeKind === 154 /* ComputedPropertyName */; // [ |    /* this can become an index signature */
                        case 135 /* ModuleKeyword */: // module |
                        case 136 /* NamespaceKeyword */: // namespace |
                            return true;
                        case 24 /* DotToken */:
                            return containingNodeKind === 249 /* ModuleDeclaration */; // module A.|
                        case 18 /* OpenBraceToken */:
                            return containingNodeKind === 245 /* ClassDeclaration */; // class A{ |
                        case 62 /* EqualsToken */:
                            return containingNodeKind === 242 /* VariableDeclaration */ // const x = a|
                                || containingNodeKind === 209 /* BinaryExpression */; // x = a|
                        case 15 /* TemplateHead */:
                            return containingNodeKind === 211 /* TemplateExpression */; // `aa ${|
                        case 16 /* TemplateMiddle */:
                            return containingNodeKind === 221 /* TemplateSpan */; // `aa ${10} dd ${|
                        case 119 /* PublicKeyword */:
                        case 117 /* PrivateKeyword */:
                        case 118 /* ProtectedKeyword */:
                            return containingNodeKind === 159 /* PropertyDeclaration */; // class A{ public |
                    }
                }
                return false;
            }
            function isInStringOrRegularExpressionOrTemplateLiteral(contextToken) {
                // To be "in" one of these literals, the position has to be:
                //   1. entirely within the token text.
                //   2. at the end position of an unterminated token.
                //   3. at the end of a regular expression (due to trailing flags like '/foo/g').
                return (ts.isRegularExpressionLiteral(contextToken) || ts.isStringTextContainingNode(contextToken)) && (ts.rangeContainsPositionExclusive(ts.createTextRangeFromSpan(ts.createTextSpanFromNode(contextToken)), position) ||
                    position === contextToken.end && (!!contextToken.isUnterminated || ts.isRegularExpressionLiteral(contextToken)));
            }
            /**
             * Aggregates relevant symbols for completion in object literals and object binding patterns.
             * Relevant symbols are stored in the captured 'symbols' variable.
             *
             * @returns true if 'symbols' was successfully populated; false otherwise.
             */
            function tryGetObjectLikeCompletionSymbols() {
                var objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken);
                if (!objectLikeContainer)
                    return 0 /* Continue */;
                // We're looking up possible property names from contextual/inferred/declared type.
                completionKind = 0 /* ObjectPropertyDeclaration */;
                var typeMembers;
                var existingMembers;
                if (objectLikeContainer.kind === 193 /* ObjectLiteralExpression */) {
                    var instantiatedType = typeChecker.getContextualType(objectLikeContainer);
                    var completionsType = instantiatedType && typeChecker.getContextualType(objectLikeContainer, 4 /* Completions */);
                    if (!instantiatedType || !completionsType)
                        return 2 /* Fail */;
                    isNewIdentifierLocation = ts.hasIndexSignature(instantiatedType || completionsType);
                    typeMembers = getPropertiesForObjectExpression(instantiatedType, completionsType, objectLikeContainer, typeChecker);
                    existingMembers = objectLikeContainer.properties;
                }
                else {
                    ts.Debug.assert(objectLikeContainer.kind === 189 /* ObjectBindingPattern */);
                    // We are *only* completing on properties from the type being destructured.
                    isNewIdentifierLocation = false;
                    var rootDeclaration = ts.getRootDeclaration(objectLikeContainer.parent);
                    if (!ts.isVariableLike(rootDeclaration))
                        return ts.Debug.fail("Root declaration is not variable-like.");
                    // We don't want to complete using the type acquired by the shape
                    // of the binding pattern; we are only interested in types acquired
                    // through type declaration or inference.
                    // Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed -
                    // type of parameter will flow in from the contextual type of the function
                    var canGetType = ts.hasInitializer(rootDeclaration) || ts.hasType(rootDeclaration) || rootDeclaration.parent.parent.kind === 232 /* ForOfStatement */;
                    if (!canGetType && rootDeclaration.kind === 156 /* Parameter */) {
                        if (ts.isExpression(rootDeclaration.parent)) {
                            canGetType = !!typeChecker.getContextualType(rootDeclaration.parent);
                        }
                        else if (rootDeclaration.parent.kind === 161 /* MethodDeclaration */ || rootDeclaration.parent.kind === 164 /* SetAccessor */) {
                            canGetType = ts.isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent);
                        }
                    }
                    if (canGetType) {
                        var typeForObject_1 = typeChecker.getTypeAtLocation(objectLikeContainer);
                        if (!typeForObject_1)
                            return 2 /* Fail */;
                        // In a binding pattern, get only known properties (unless in the same scope).
                        // Everywhere else we will get all possible properties.
                        var containerClass_1 = ts.getContainingClass(objectLikeContainer);
                        typeMembers = typeChecker.getPropertiesOfType(typeForObject_1).filter(function (symbol) {
                            // either public
                            return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24 /* NonPublicAccessibilityModifier */)
                                // or we're in it
                                || containerClass_1 && ts.contains(typeForObject_1.symbol.declarations, containerClass_1);
                        });
                        existingMembers = objectLikeContainer.elements;
                    }
                }
                if (typeMembers && typeMembers.length > 0) {
                    // Add filtered items to the completion list
                    symbols = filterObjectMembersList(typeMembers, ts.Debug.checkDefined(existingMembers));
                }
                setSortTextToOptionalMember();
                return 1 /* Success */;
            }
            /**
             * Aggregates relevant symbols for completion in import clauses and export clauses
             * whose declarations have a module specifier; for instance, symbols will be aggregated for
             *
             *      import { | } from "moduleName";
             *      export { a as foo, | } from "moduleName";
             *
             * but not for
             *
             *      export { | };
             *
             * Relevant symbols are stored in the captured 'symbols' variable.
             */
            function tryGetImportOrExportClauseCompletionSymbols() {
                // `import { |` or `import { a as 0, | }`
                var namedImportsOrExports = contextToken && (contextToken.kind === 18 /* OpenBraceToken */ || contextToken.kind === 27 /* CommaToken */)
                    ? ts.tryCast(contextToken.parent, ts.isNamedImportsOrExports) : undefined;
                if (!namedImportsOrExports)
                    return 0 /* Continue */;
                // try to show exported member for imported/re-exported module
                var moduleSpecifier = (namedImportsOrExports.kind === 257 /* NamedImports */ ? namedImportsOrExports.parent.parent : namedImportsOrExports.parent).moduleSpecifier;
                if (!moduleSpecifier)
                    return namedImportsOrExports.kind === 257 /* NamedImports */ ? 2 /* Fail */ : 0 /* Continue */;
                var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier); // TODO: GH#18217
                if (!moduleSpecifierSymbol)
                    return 2 /* Fail */;
                completionKind = 3 /* MemberLike */;
                isNewIdentifierLocation = false;
                var exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol);
                var existing = ts.arrayToSet(namedImportsOrExports.elements, function (n) { return isCurrentlyEditingNode(n) ? undefined : (n.propertyName || n.name).escapedText; });
                symbols = exports.filter(function (e) { return e.escapedName !== "default" /* Default */ && !existing.get(e.escapedName); });
                return 1 /* Success */;
            }
            /**
             * Adds local declarations for completions in named exports:
             *
             *   export { | };
             *
             * Does not check for the absence of a module specifier (`export {} from "./other"`)
             * because `tryGetImportOrExportClauseCompletionSymbols` runs first and handles that,
             * preventing this function from running.
             */
            function tryGetLocalNamedExportCompletionSymbols() {
                var _a;
                var namedExports = contextToken && (contextToken.kind === 18 /* OpenBraceToken */ || contextToken.kind === 27 /* CommaToken */)
                    ? ts.tryCast(contextToken.parent, ts.isNamedExports)
                    : undefined;
                if (!namedExports) {
                    return 0 /* Continue */;
                }
                var localsContainer = ts.findAncestor(namedExports, ts.or(ts.isSourceFile, ts.isModuleDeclaration));
                completionKind = 5 /* None */;
                isNewIdentifierLocation = false;
                (_a = localsContainer.locals) === null || _a === void 0 ? void 0 : _a.forEach(function (symbol, name) {
                    var _a, _b;
                    symbols.push(symbol);
                    if ((_b = (_a = localsContainer.symbol) === null || _a === void 0 ? void 0 : _a.exports) === null || _b === void 0 ? void 0 : _b.has(name)) {
                        symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.OptionalMember;
                    }
                });
                return 1 /* Success */;
            }
            /**
             * Aggregates relevant symbols for completion in class declaration
             * Relevant symbols are stored in the captured 'symbols' variable.
             */
            function tryGetClassLikeCompletionSymbols() {
                var decl = tryGetObjectTypeDeclarationCompletionContainer(sourceFile, contextToken, location, position);
                if (!decl)
                    return 0 /* Continue */;
                // We're looking up possible property names from parent type.
                completionKind = 3 /* MemberLike */;
                // Declaring new property/method/accessor
                isNewIdentifierLocation = true;
                keywordFilters = contextToken.kind === 41 /* AsteriskToken */ ? 0 /* None */ :
                    ts.isClassLike(decl) ? 2 /* ClassElementKeywords */ : 3 /* InterfaceElementKeywords */;
                // If you're in an interface you don't want to repeat things from super-interface. So just stop here.
                if (!ts.isClassLike(decl))
                    return 1 /* Success */;
                var classElement = contextToken.kind === 26 /* SemicolonToken */ ? contextToken.parent.parent : contextToken.parent;
                var classElementModifierFlags = ts.isClassElement(classElement) ? ts.getModifierFlags(classElement) : 0 /* None */;
                // If this is context token is not something we are editing now, consider if this would lead to be modifier
                if (contextToken.kind === 75 /* Identifier */ && !isCurrentlyEditingNode(contextToken)) {
                    switch (contextToken.getText()) {
                        case "private":
                            classElementModifierFlags = classElementModifierFlags | 8 /* Private */;
                            break;
                        case "static":
                            classElementModifierFlags = classElementModifierFlags | 32 /* Static */;
                            break;
                    }
                }
                // No member list for private methods
                if (!(classElementModifierFlags & 8 /* Private */)) {
                    // List of property symbols of base type that are not private and already implemented
                    var baseSymbols = ts.flatMap(ts.getAllSuperTypeNodes(decl), function (baseTypeNode) {
                        var type = typeChecker.getTypeAtLocation(baseTypeNode);
                        return type && typeChecker.getPropertiesOfType(classElementModifierFlags & 32 /* Static */ ? typeChecker.getTypeOfSymbolAtLocation(type.symbol, decl) : type);
                    });
                    symbols = filterClassMembersList(baseSymbols, decl.members, classElementModifierFlags);
                }
                return 1 /* Success */;
            }
            /**
             * Returns the immediate owning object literal or binding pattern of a context token,
             * on the condition that one exists and that the context implies completion should be given.
             */
            function tryGetObjectLikeCompletionContainer(contextToken) {
                if (contextToken) {
                    var parent = contextToken.parent;
                    switch (contextToken.kind) {
                        case 18 /* OpenBraceToken */: // const x = { |
                        case 27 /* CommaToken */: // const x = { a: 0, |
                            if (ts.isObjectLiteralExpression(parent) || ts.isObjectBindingPattern(parent)) {
                                return parent;
                            }
                            break;
                        case 41 /* AsteriskToken */:
                            return ts.isMethodDeclaration(parent) ? ts.tryCast(parent.parent, ts.isObjectLiteralExpression) : undefined;
                        case 75 /* Identifier */:
                            return contextToken.text === "async" && ts.isShorthandPropertyAssignment(contextToken.parent)
                                ? contextToken.parent.parent : undefined;
                    }
                }
                return undefined;
            }
            function isConstructorParameterCompletion(node) {
                return !!node.parent && ts.isParameter(node.parent) && ts.isConstructorDeclaration(node.parent.parent)
                    && (ts.isParameterPropertyModifier(node.kind) || ts.isDeclarationName(node));
            }
            /**
             * Returns the immediate owning class declaration of a context token,
             * on the condition that one exists and that the context implies completion should be given.
             */
            function tryGetConstructorLikeCompletionContainer(contextToken) {
                if (contextToken) {
                    var parent = contextToken.parent;
                    switch (contextToken.kind) {
                        case 20 /* OpenParenToken */:
                        case 27 /* CommaToken */:
                            return ts.isConstructorDeclaration(contextToken.parent) ? contextToken.parent : undefined;
                        default:
                            if (isConstructorParameterCompletion(contextToken)) {
                                return parent.parent;
                            }
                    }
                }
                return undefined;
            }
            function tryGetFunctionLikeBodyCompletionContainer(contextToken) {
                if (contextToken) {
                    var prev_1;
                    var container = ts.findAncestor(contextToken.parent, function (node) {
                        if (ts.isClassLike(node)) {
                            return "quit";
                        }
                        if (ts.isFunctionLikeDeclaration(node) && prev_1 === node.body) {
                            return true;
                        }
                        prev_1 = node;
                        return false;
                    });
                    return container && container;
                }
            }
            function tryGetContainingJsxElement(contextToken) {
                if (contextToken) {
                    var parent = contextToken.parent;
                    switch (contextToken.kind) {
                        case 31 /* GreaterThanToken */: // End of a type argument list
                        case 30 /* LessThanSlashToken */:
                        case 43 /* SlashToken */:
                        case 75 /* Identifier */:
                        case 194 /* PropertyAccessExpression */:
                        case 274 /* JsxAttributes */:
                        case 273 /* JsxAttribute */:
                        case 275 /* JsxSpreadAttribute */:
                            if (parent && (parent.kind === 267 /* JsxSelfClosingElement */ || parent.kind === 268 /* JsxOpeningElement */)) {
                                if (contextToken.kind === 31 /* GreaterThanToken */) {
                                    var precedingToken = ts.findPrecedingToken(contextToken.pos, sourceFile, /*startNode*/ undefined);
                                    if (!parent.typeArguments || (precedingToken && precedingToken.kind === 43 /* SlashToken */))
                                        break;
                                }
                                return parent;
                            }
                            else if (parent.kind === 273 /* JsxAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                        // The context token is the closing } or " of an attribute, which means
                        // its parent is a JsxExpression, whose parent is a JsxAttribute,
                        // whose parent is a JsxOpeningLikeElement
                        case 10 /* StringLiteral */:
                            if (parent && ((parent.kind === 273 /* JsxAttribute */) || (parent.kind === 275 /* JsxSpreadAttribute */))) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                        case 19 /* CloseBraceToken */:
                            if (parent &&
                                parent.kind === 276 /* JsxExpression */ &&
                                parent.parent && parent.parent.kind === 273 /* JsxAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                //                  each JsxAttribute can have initializer as JsxExpression
                                return parent.parent.parent.parent;
                            }
                            if (parent && parent.kind === 275 /* JsxSpreadAttribute */) {
                                // Currently we parse JsxOpeningLikeElement as:
                                //      JsxOpeningLikeElement
                                //          attributes: JsxAttributes
                                //             properties: NodeArray<JsxAttributeLike>
                                return parent.parent.parent;
                            }
                            break;
                    }
                }
                return undefined;
            }
            /**
             * @returns true if we are certain that the currently edited location must define a new location; false otherwise.
             */
            function isSolelyIdentifierDefinitionLocation(contextToken) {
                var parent = contextToken.parent;
                var containingNodeKind = parent.kind;
                switch (contextToken.kind) {
                    case 27 /* CommaToken */:
                        return containingNodeKind === 242 /* VariableDeclaration */ ||
                            isVariableDeclarationListButNotTypeArgument(contextToken) ||
                            containingNodeKind === 225 /* VariableStatement */ ||
                            containingNodeKind === 248 /* EnumDeclaration */ || // enum a { foo, |
                            isFunctionLikeButNotConstructor(containingNodeKind) ||
                            containingNodeKind === 246 /* InterfaceDeclaration */ || // interface A<T, |
                            containingNodeKind === 190 /* ArrayBindingPattern */ || // var [x, y|
                            containingNodeKind === 247 /* TypeAliasDeclaration */ || // type Map, K, |
                            // class A<T, |
                            // var C = class D<T, |
                            (ts.isClassLike(parent) &&
                                !!parent.typeParameters &&
                                parent.typeParameters.end >= contextToken.pos);
                    case 24 /* DotToken */:
                        return containingNodeKind === 190 /* ArrayBindingPattern */; // var [.|
                    case 58 /* ColonToken */:
                        return containingNodeKind === 191 /* BindingElement */; // var {x :html|
                    case 22 /* OpenBracketToken */:
                        return containingNodeKind === 190 /* ArrayBindingPattern */; // var [x|
                    case 20 /* OpenParenToken */:
                        return containingNodeKind === 280 /* CatchClause */ ||
                            isFunctionLikeButNotConstructor(containingNodeKind);
                    case 18 /* OpenBraceToken */:
                        return containingNodeKind === 248 /* EnumDeclaration */; // enum a { |
                    case 29 /* LessThanToken */:
                        return containingNodeKind === 245 /* ClassDeclaration */ || // class A< |
                            containingNodeKind === 214 /* ClassExpression */ || // var C = class D< |
                            containingNodeKind === 246 /* InterfaceDeclaration */ || // interface A< |
                            containingNodeKind === 247 /* TypeAliasDeclaration */ || // type List< |
                            ts.isFunctionLikeKind(containingNodeKind);
                    case 120 /* StaticKeyword */:
                        return containingNodeKind === 159 /* PropertyDeclaration */ && !ts.isClassLike(parent.parent);
                    case 25 /* DotDotDotToken */:
                        return containingNodeKind === 156 /* Parameter */ ||
                            (!!parent.parent && parent.parent.kind === 190 /* ArrayBindingPattern */); // var [...z|
                    case 119 /* PublicKeyword */:
                    case 117 /* PrivateKeyword */:
                    case 118 /* ProtectedKeyword */:
                        return containingNodeKind === 156 /* Parameter */ && !ts.isConstructorDeclaration(parent.parent);
                    case 123 /* AsKeyword */:
                        return containingNodeKind === 258 /* ImportSpecifier */ ||
                            containingNodeKind === 263 /* ExportSpecifier */ ||
                            containingNodeKind === 256 /* NamespaceImport */;
                    case 131 /* GetKeyword */:
                    case 142 /* SetKeyword */:
                        return !isFromObjectTypeDeclaration(contextToken);
                    case 80 /* ClassKeyword */:
                    case 88 /* EnumKeyword */:
                    case 114 /* InterfaceKeyword */:
                    case 94 /* FunctionKeyword */:
                    case 109 /* VarKeyword */:
                    case 96 /* ImportKeyword */:
                    case 115 /* LetKeyword */:
                    case 81 /* ConstKeyword */:
                    case 145 /* TypeKeyword */: // type htm|
                        return true;
                    case 41 /* AsteriskToken */:
                        return ts.isFunctionLike(contextToken.parent) && !ts.isMethodDeclaration(contextToken.parent);
                }
                // If the previous token is keyword correspoding to class member completion keyword
                // there will be completion available here
                if (isClassMemberCompletionKeyword(keywordForNode(contextToken)) && isFromObjectTypeDeclaration(contextToken)) {
                    return false;
                }
                if (isConstructorParameterCompletion(contextToken)) {
                    // constructor parameter completion is available only if
                    // - its modifier of the constructor parameter or
                    // - its name of the parameter and not being edited
                    // eg. constructor(a |<- this shouldnt show completion
                    if (!ts.isIdentifier(contextToken) ||
                        ts.isParameterPropertyModifier(keywordForNode(contextToken)) ||
                        isCurrentlyEditingNode(contextToken)) {
                        return false;
                    }
                }
                // Previous token may have been a keyword that was converted to an identifier.
                switch (keywordForNode(contextToken)) {
                    case 122 /* AbstractKeyword */:
                    case 80 /* ClassKeyword */:
                    case 81 /* ConstKeyword */:
                    case 130 /* DeclareKeyword */:
                    case 88 /* EnumKeyword */:
                    case 94 /* FunctionKeyword */:
                    case 114 /* InterfaceKeyword */:
                    case 115 /* LetKeyword */:
                    case 117 /* PrivateKeyword */:
                    case 118 /* ProtectedKeyword */:
                    case 119 /* PublicKeyword */:
                    case 120 /* StaticKeyword */:
                    case 109 /* VarKeyword */:
                        return true;
                    case 126 /* AsyncKeyword */:
                        return ts.isPropertyDeclaration(contextToken.parent);
                }
                return ts.isDeclarationName(contextToken)
                    && !ts.isJsxAttribute(contextToken.parent)
                    // Don't block completions if we're in `class C /**/`, because we're *past* the end of the identifier and might want to complete `extends`.
                    // If `contextToken !== previousToken`, this is `class C ex/**/`.
                    && !(ts.isClassLike(contextToken.parent) && (contextToken !== previousToken || position > previousToken.end));
            }
            function isFunctionLikeButNotConstructor(kind) {
                return ts.isFunctionLikeKind(kind) && kind !== 162 /* Constructor */;
            }
            function isDotOfNumericLiteral(contextToken) {
                if (contextToken.kind === 8 /* NumericLiteral */) {
                    var text = contextToken.getFullText();
                    return text.charAt(text.length - 1) === ".";
                }
                return false;
            }
            function isVariableDeclarationListButNotTypeArgument(node) {
                return node.parent.kind === 243 /* VariableDeclarationList */
                    && !ts.isPossiblyTypeArgumentPosition(node, sourceFile, typeChecker);
            }
            /**
             * Filters out completion suggestions for named imports or exports.
             *
             * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations
             *          do not occur at the current position and have not otherwise been typed.
             */
            function filterObjectMembersList(contextualMemberSymbols, existingMembers) {
                if (existingMembers.length === 0) {
                    return contextualMemberSymbols;
                }
                var membersDeclaredBySpreadAssignment = ts.createMap();
                var existingMemberNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, existingMembers_1 = existingMembers; _i < existingMembers_1.length; _i++) {
                    var m = existingMembers_1[_i];
                    // Ignore omitted expressions for missing members
                    if (m.kind !== 281 /* PropertyAssignment */ &&
                        m.kind !== 282 /* ShorthandPropertyAssignment */ &&
                        m.kind !== 191 /* BindingElement */ &&
                        m.kind !== 161 /* MethodDeclaration */ &&
                        m.kind !== 163 /* GetAccessor */ &&
                        m.kind !== 164 /* SetAccessor */ &&
                        m.kind !== 283 /* SpreadAssignment */) {
                        continue;
                    }
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(m)) {
                        continue;
                    }
                    var existingName = void 0;
                    if (ts.isSpreadAssignment(m)) {
                        setMembersDeclaredBySpreadAssignment(m, membersDeclaredBySpreadAssignment);
                    }
                    else if (ts.isBindingElement(m) && m.propertyName) {
                        // include only identifiers in completion list
                        if (m.propertyName.kind === 75 /* Identifier */) {
                            existingName = m.propertyName.escapedText;
                        }
                    }
                    else {
                        // TODO: Account for computed property name
                        // NOTE: if one only performs this step when m.name is an identifier,
                        // things like '__proto__' are not filtered out.
                        var name = ts.getNameOfDeclaration(m);
                        existingName = name && ts.isPropertyNameLiteral(name) ? ts.getEscapedTextOfIdentifierOrLiteral(name) : undefined;
                    }
                    existingMemberNames.set(existingName, true); // TODO: GH#18217
                }
                var filteredSymbols = contextualMemberSymbols.filter(function (m) { return !existingMemberNames.get(m.escapedName); });
                setSortTextToMemberDeclaredBySpreadAssignment(membersDeclaredBySpreadAssignment, filteredSymbols);
                return filteredSymbols;
            }
            function setMembersDeclaredBySpreadAssignment(declaration, membersDeclaredBySpreadAssignment) {
                var expression = declaration.expression;
                var symbol = typeChecker.getSymbolAtLocation(expression);
                var type = symbol && typeChecker.getTypeOfSymbolAtLocation(symbol, expression);
                var properties = type && type.properties;
                if (properties) {
                    properties.forEach(function (property) {
                        membersDeclaredBySpreadAssignment.set(property.name, true);
                    });
                }
            }
            // Set SortText to OptionalMember if it is an optional member
            function setSortTextToOptionalMember() {
                symbols.forEach(function (m) {
                    if (m.flags & 16777216 /* Optional */) {
                        symbolToSortTextMap[ts.getSymbolId(m)] = symbolToSortTextMap[ts.getSymbolId(m)] || SortText.OptionalMember;
                    }
                });
            }
            // Set SortText to MemberDeclaredBySpreadAssignment if it is fulfilled by spread assignment
            function setSortTextToMemberDeclaredBySpreadAssignment(membersDeclaredBySpreadAssignment, contextualMemberSymbols) {
                if (membersDeclaredBySpreadAssignment.size === 0) {
                    return;
                }
                for (var _i = 0, contextualMemberSymbols_1 = contextualMemberSymbols; _i < contextualMemberSymbols_1.length; _i++) {
                    var contextualMemberSymbol = contextualMemberSymbols_1[_i];
                    if (membersDeclaredBySpreadAssignment.has(contextualMemberSymbol.name)) {
                        symbolToSortTextMap[ts.getSymbolId(contextualMemberSymbol)] = SortText.MemberDeclaredBySpreadAssignment;
                    }
                }
            }
            /**
             * Filters out completion suggestions for class elements.
             *
             * @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
             */
            function filterClassMembersList(baseSymbols, existingMembers, currentClassElementModifierFlags) {
                var existingMemberNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, existingMembers_2 = existingMembers; _i < existingMembers_2.length; _i++) {
                    var m = existingMembers_2[_i];
                    // Ignore omitted expressions for missing members
                    if (m.kind !== 159 /* PropertyDeclaration */ &&
                        m.kind !== 161 /* MethodDeclaration */ &&
                        m.kind !== 163 /* GetAccessor */ &&
                        m.kind !== 164 /* SetAccessor */) {
                        continue;
                    }
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(m)) {
                        continue;
                    }
                    // Dont filter member even if the name matches if it is declared private in the list
                    if (ts.hasModifier(m, 8 /* Private */)) {
                        continue;
                    }
                    // do not filter it out if the static presence doesnt match
                    if (ts.hasModifier(m, 32 /* Static */) !== !!(currentClassElementModifierFlags & 32 /* Static */)) {
                        continue;
                    }
                    var existingName = ts.getPropertyNameForPropertyNameNode(m.name);
                    if (existingName) {
                        existingMemberNames.set(existingName, true);
                    }
                }
                return baseSymbols.filter(function (propertySymbol) {
                    return !existingMemberNames.has(propertySymbol.escapedName) &&
                        !!propertySymbol.declarations &&
                        !(ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & 8 /* Private */) &&
                        !ts.isPrivateIdentifierPropertyDeclaration(propertySymbol.valueDeclaration);
                });
            }
            /**
             * Filters out completion suggestions from 'symbols' according to existing JSX attributes.
             *
             * @returns Symbols to be suggested in a JSX element, barring those whose attributes
             *          do not occur at the current position and have not otherwise been typed.
             */
            function filterJsxAttributes(symbols, attributes) {
                var seenNames = ts.createUnderscoreEscapedMap();
                var membersDeclaredBySpreadAssignment = ts.createMap();
                for (var _i = 0, attributes_1 = attributes; _i < attributes_1.length; _i++) {
                    var attr = attributes_1[_i];
                    // If this is the current item we are editing right now, do not filter it out
                    if (isCurrentlyEditingNode(attr)) {
                        continue;
                    }
                    if (attr.kind === 273 /* JsxAttribute */) {
                        seenNames.set(attr.name.escapedText, true);
                    }
                    else if (ts.isJsxSpreadAttribute(attr)) {
                        setMembersDeclaredBySpreadAssignment(attr, membersDeclaredBySpreadAssignment);
                    }
                }
                var filteredSymbols = symbols.filter(function (a) { return !seenNames.get(a.escapedName); });
                setSortTextToMemberDeclaredBySpreadAssignment(membersDeclaredBySpreadAssignment, filteredSymbols);
                return filteredSymbols;
            }
            function isCurrentlyEditingNode(node) {
                return node.getStart(sourceFile) <= position && position <= node.getEnd();
            }
        }
        function getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind, jsxIdentifierExpected) {
            var name = originIsExport(origin) ? ts.getNameForExportedSymbol(symbol, target) : symbol.name;
            if (name === undefined
                // If the symbol is external module, don't show it in the completion list
                // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there)
                || symbol.flags & 1536 /* Module */ && ts.isSingleOrDoubleQuote(name.charCodeAt(0))
                // If the symbol is the internal name of an ES symbol, it is not a valid entry. Internal names for ES symbols start with "__@"
                || ts.isKnownSymbol(symbol)) {
                return undefined;
            }
            var validNameResult = { name: name, needsConvertPropertyAccess: false };
            if (ts.isIdentifierText(name, target, jsxIdentifierExpected ? 1 /* JSX */ : 0 /* Standard */) || symbol.valueDeclaration && ts.isPrivateIdentifierPropertyDeclaration(symbol.valueDeclaration)) {
                return validNameResult;
            }
            switch (kind) {
                case 3 /* MemberLike */:
                    return undefined;
                case 0 /* ObjectPropertyDeclaration */:
                    // TODO: GH#18169
                    return { name: JSON.stringify(name), needsConvertPropertyAccess: false };
                case 2 /* PropertyAccess */:
                case 1 /* Global */: // For a 'this.' completion it will be in a global context, but may have a non-identifier name.
                    // Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547
                    return name.charCodeAt(0) === 32 /* space */ ? undefined : { name: name, needsConvertPropertyAccess: true };
                case 5 /* None */:
                case 4 /* String */:
                    return validNameResult;
                default:
                    ts.Debug.assertNever(kind);
            }
        }
        // A cache of completion entries for keywords, these do not change between sessions
        var _keywordCompletions = [];
        var allKeywordsCompletions = ts.memoize(function () {
            var res = [];
            for (var i = 77 /* FirstKeyword */; i <= 152 /* LastKeyword */; i++) {
                res.push({
                    name: ts.tokenToString(i),
                    kind: "keyword" /* keyword */,
                    kindModifiers: "" /* none */,
                    sortText: SortText.GlobalsOrKeywords
                });
            }
            return res;
        });
        function getKeywordCompletions(keywordFilter, filterOutTsOnlyKeywords) {
            if (!filterOutTsOnlyKeywords)
                return getTypescriptKeywordCompletions(keywordFilter);
            var index = keywordFilter + 7 /* Last */ + 1;
            return _keywordCompletions[index] ||
                (_keywordCompletions[index] = getTypescriptKeywordCompletions(keywordFilter)
                    .filter(function (entry) { return !isTypeScriptOnlyKeyword(ts.stringToToken(entry.name)); }));
        }
        function getTypescriptKeywordCompletions(keywordFilter) {
            return _keywordCompletions[keywordFilter] || (_keywordCompletions[keywordFilter] = allKeywordsCompletions().filter(function (entry) {
                var kind = ts.stringToToken(entry.name);
                switch (keywordFilter) {
                    case 0 /* None */:
                        return false;
                    case 1 /* All */:
                        return isFunctionLikeBodyKeyword(kind)
                            || kind === 130 /* DeclareKeyword */
                            || kind === 135 /* ModuleKeyword */
                            || kind === 145 /* TypeKeyword */
                            || kind === 136 /* NamespaceKeyword */
                            || kind === 123 /* AsKeyword */
                            || ts.isTypeKeyword(kind) && kind !== 146 /* UndefinedKeyword */;
                    case 5 /* FunctionLikeBodyKeywords */:
                        return isFunctionLikeBodyKeyword(kind);
                    case 2 /* ClassElementKeywords */:
                        return isClassMemberCompletionKeyword(kind);
                    case 3 /* InterfaceElementKeywords */:
                        return isInterfaceOrTypeLiteralCompletionKeyword(kind);
                    case 4 /* ConstructorParameterKeywords */:
                        return ts.isParameterPropertyModifier(kind);
                    case 6 /* TypeAssertionKeywords */:
                        return ts.isTypeKeyword(kind) || kind === 81 /* ConstKeyword */;
                    case 7 /* TypeKeywords */:
                        return ts.isTypeKeyword(kind);
                    default:
                        return ts.Debug.assertNever(keywordFilter);
                }
            }));
        }
        function isTypeScriptOnlyKeyword(kind) {
            switch (kind) {
                case 122 /* AbstractKeyword */:
                case 125 /* AnyKeyword */:
                case 151 /* BigIntKeyword */:
                case 128 /* BooleanKeyword */:
                case 130 /* DeclareKeyword */:
                case 88 /* EnumKeyword */:
                case 150 /* GlobalKeyword */:
                case 113 /* ImplementsKeyword */:
                case 132 /* InferKeyword */:
                case 114 /* InterfaceKeyword */:
                case 133 /* IsKeyword */:
                case 134 /* KeyOfKeyword */:
                case 135 /* ModuleKeyword */:
                case 136 /* NamespaceKeyword */:
                case 137 /* NeverKeyword */:
                case 140 /* NumberKeyword */:
                case 141 /* ObjectKeyword */:
                case 117 /* PrivateKeyword */:
                case 118 /* ProtectedKeyword */:
                case 119 /* PublicKeyword */:
                case 138 /* ReadonlyKeyword */:
                case 143 /* StringKeyword */:
                case 144 /* SymbolKeyword */:
                case 145 /* TypeKeyword */:
                case 147 /* UniqueKeyword */:
                case 148 /* UnknownKeyword */:
                    return true;
                default:
                    return false;
            }
        }
        function isInterfaceOrTypeLiteralCompletionKeyword(kind) {
            return kind === 138 /* ReadonlyKeyword */;
        }
        function isClassMemberCompletionKeyword(kind) {
            switch (kind) {
                case 122 /* AbstractKeyword */:
                case 129 /* ConstructorKeyword */:
                case 131 /* GetKeyword */:
                case 142 /* SetKeyword */:
                case 126 /* AsyncKeyword */:
                case 130 /* DeclareKeyword */:
                    return true;
                default:
                    return ts.isClassMemberModifier(kind);
            }
        }
        function isFunctionLikeBodyKeyword(kind) {
            return kind === 126 /* AsyncKeyword */
                || kind === 127 /* AwaitKeyword */
                || !ts.isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind);
        }
        function keywordForNode(node) {
            return ts.isIdentifier(node) ? node.originalKeywordKind || 0 /* Unknown */ : node.kind;
        }
        /** Get the corresponding JSDocTag node if the position is in a jsDoc comment */
        function getJsDocTagAtPosition(node, position) {
            var jsdoc = ts.findAncestor(node, ts.isJSDoc);
            return jsdoc && jsdoc.tags && (ts.rangeContainsPosition(jsdoc, position) ? ts.findLast(jsdoc.tags, function (tag) { return tag.pos < position; }) : undefined);
        }
        function getPropertiesForObjectExpression(contextualType, completionsType, obj, checker) {
            var hasCompletionsType = completionsType && completionsType !== contextualType;
            var type = hasCompletionsType && !(completionsType.flags & 3 /* AnyOrUnknown */)
                ? checker.getUnionType([contextualType, completionsType])
                : contextualType;
            var properties = type.isUnion()
                ? checker.getAllPossiblePropertiesOfTypes(type.types.filter(function (memberType) {
                    // If we're providing completions for an object literal, skip primitive, array-like, or callable types since those shouldn't be implemented by object literals.
                    return !(memberType.flags & 131068 /* Primitive */ ||
                        checker.isArrayLikeType(memberType) ||
                        ts.typeHasCallOrConstructSignatures(memberType, checker) ||
                        checker.isTypeInvalidDueToUnionDiscriminant(memberType, obj));
                }))
                : type.getApparentProperties();
            return hasCompletionsType ? properties.filter(hasDeclarationOtherThanSelf) : properties;
            // Filter out members whose only declaration is the object literal itself to avoid
            // self-fulfilling completions like:
            //
            // function f<T>(x: T) {}
            // f({ abc/**/: "" }) // `abc` is a member of `T` but only because it declares itself
            function hasDeclarationOtherThanSelf(member) {
                return ts.some(member.declarations, function (decl) { return decl.parent !== obj; });
            }
        }
        /**
         * Gets all properties on a type, but if that type is a union of several types,
         * excludes array-like types or callable/constructable types.
         */
        function getPropertiesForCompletion(type, checker) {
            return type.isUnion()
                ? ts.Debug.checkEachDefined(checker.getAllPossiblePropertiesOfTypes(type.types), "getAllPossiblePropertiesOfTypes() should all be defined")
                : ts.Debug.checkEachDefined(type.getApparentProperties(), "getApparentProperties() should all be defined");
        }
        /**
         * Returns the immediate owning class declaration of a context token,
         * on the condition that one exists and that the context implies completion should be given.
         */
        function tryGetObjectTypeDeclarationCompletionContainer(sourceFile, contextToken, location, position) {
            // class c { method() { } | method2() { } }
            switch (location.kind) {
                case 324 /* SyntaxList */:
                    return ts.tryCast(location.parent, ts.isObjectTypeDeclaration);
                case 1 /* EndOfFileToken */:
                    var cls = ts.tryCast(ts.lastOrUndefined(ts.cast(location.parent, ts.isSourceFile).statements), ts.isObjectTypeDeclaration);
                    if (cls && !ts.findChildOfKind(cls, 19 /* CloseBraceToken */, sourceFile)) {
                        return cls;
                    }
                    break;
                case 75 /* Identifier */: {
                    // class c { public prop = c| }
                    if (ts.isPropertyDeclaration(location.parent) && location.parent.initializer === location) {
                        return undefined;
                    }
                    // class c extends React.Component { a: () => 1\n compon| }
                    if (isFromObjectTypeDeclaration(location)) {
                        return ts.findAncestor(location, ts.isObjectTypeDeclaration);
                    }
                }
            }
            if (!contextToken)
                return undefined;
            switch (contextToken.kind) {
                case 62 /* EqualsToken */: // class c { public prop = | /* global completions */ }
                    return undefined;
                case 26 /* SemicolonToken */: // class c {getValue(): number; | }
                case 19 /* CloseBraceToken */: // class c { method() { } | }
                    // class c { method() { } b| }
                    return isFromObjectTypeDeclaration(location) && location.parent.name === location
                        ? location.parent.parent
                        : ts.tryCast(location, ts.isObjectTypeDeclaration);
                case 18 /* OpenBraceToken */: // class c { |
                case 27 /* CommaToken */: // class c {getValue(): number, | }
                    return ts.tryCast(contextToken.parent, ts.isObjectTypeDeclaration);
                default:
                    if (!isFromObjectTypeDeclaration(contextToken)) {
                        // class c extends React.Component { a: () => 1\n| }
                        if (ts.getLineAndCharacterOfPosition(sourceFile, contextToken.getEnd()).line !== ts.getLineAndCharacterOfPosition(sourceFile, position).line && ts.isObjectTypeDeclaration(location)) {
                            return location;
                        }
                        return undefined;
                    }
                    var isValidKeyword = ts.isClassLike(contextToken.parent.parent) ? isClassMemberCompletionKeyword : isInterfaceOrTypeLiteralCompletionKeyword;
                    return (isValidKeyword(contextToken.kind) || contextToken.kind === 41 /* AsteriskToken */ || ts.isIdentifier(contextToken) && isValidKeyword(ts.stringToToken(contextToken.text))) // TODO: GH#18217
                        ? contextToken.parent.parent : undefined;
            }
        }
        // TODO: GH#19856 Would like to return `node is Node & { parent: (ClassElement | TypeElement) & { parent: ObjectTypeDeclaration } }` but then compilation takes > 10 minutes
        function isFromObjectTypeDeclaration(node) {
            return node.parent && ts.isClassOrTypeElement(node.parent) && ts.isObjectTypeDeclaration(node.parent.parent);
        }
        function isValidTrigger(sourceFile, triggerCharacter, contextToken, position) {
            switch (triggerCharacter) {
                case ".":
                case "@":
                    return true;
                case '"':
                case "'":
                case "`":
                    // Only automatically bring up completions if this is an opening quote.
                    return !!contextToken && ts.isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1;
                case "#":
                    return !!contextToken && ts.isPrivateIdentifier(contextToken) && !!ts.getContainingClass(contextToken);
                case "<":
                    // Opening JSX tag
                    return !!contextToken && contextToken.kind === 29 /* LessThanToken */ && (!ts.isBinaryExpression(contextToken.parent) || binaryExpressionMayBeOpenTag(contextToken.parent));
                case "/":
                    return !!contextToken && (ts.isStringLiteralLike(contextToken)
                        ? !!ts.tryGetImportFromModuleSpecifier(contextToken)
                        : contextToken.kind === 43 /* SlashToken */ && ts.isJsxClosingElement(contextToken.parent));
                default:
                    return ts.Debug.assertNever(triggerCharacter);
            }
        }
        function binaryExpressionMayBeOpenTag(_a) {
            var left = _a.left;
            return ts.nodeIsMissing(left);
        }
        function findAlias(typeChecker, symbol, predicate) {
            var currentAlias = symbol;
            while (currentAlias.flags & 2097152 /* Alias */ && (currentAlias = typeChecker.getImmediateAliasedSymbol(currentAlias))) {
                if (predicate(currentAlias)) {
                    return currentAlias;
                }
            }
        }
        /** Determines if a type is exactly the same type resolved by the global 'self', 'global', or 'globalThis'. */
        function isProbablyGlobalType(type, sourceFile, checker) {
            // The type of `self` and `window` is the same in lib.dom.d.ts, but `window` does not exist in
            // lib.webworker.d.ts, so checking against `self` is also a check against `window` when it exists.
            var selfSymbol = checker.resolveName("self", /*location*/ undefined, 111551 /* Value */, /*excludeGlobals*/ false);
            if (selfSymbol && checker.getTypeOfSymbolAtLocation(selfSymbol, sourceFile) === type) {
                return true;
            }
            var globalSymbol = checker.resolveName("global", /*location*/ undefined, 111551 /* Value */, /*excludeGlobals*/ false);
            if (globalSymbol && checker.getTypeOfSymbolAtLocation(globalSymbol, sourceFile) === type) {
                return true;
            }
            var globalThisSymbol = checker.resolveName("globalThis", /*location*/ undefined, 111551 /* Value */, /*excludeGlobals*/ false);
            if (globalThisSymbol && checker.getTypeOfSymbolAtLocation(globalThisSymbol, sourceFile) === type) {
                return true;
            }
            return false;
        }
    })(Completions = ts.Completions || (ts.Completions = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    /* @internal */
    var DocumentHighlights;
    (function (DocumentHighlights) {
        function getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node.parent && (ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node || ts.isJsxClosingElement(node.parent))) {
                // For a JSX element, just highlight the matching tag, not all references.
                var _a = node.parent.parent, openingElement = _a.openingElement, closingElement = _a.closingElement;
                var highlightSpans = [openingElement, closingElement].map(function (_a) {
                    var tagName = _a.tagName;
                    return getHighlightSpanForNode(tagName, sourceFile);
                });
                return [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }];
            }
            return getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile);
        }
        DocumentHighlights.getDocumentHighlights = getDocumentHighlights;
        function getHighlightSpanForNode(node, sourceFile) {
            return {
                fileName: sourceFile.fileName,
                textSpan: ts.createTextSpanFromNode(node, sourceFile),
                kind: "none" /* none */
            };
        }
        function getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) {
            var sourceFilesSet = ts.arrayToSet(sourceFilesToSearch, function (f) { return f.fileName; });
            var referenceEntries = ts.FindAllReferences.getReferenceEntriesForNode(position, node, program, sourceFilesToSearch, cancellationToken, /*options*/ undefined, sourceFilesSet);
            if (!referenceEntries)
                return undefined;
            var map = ts.arrayToMultiMap(referenceEntries.map(ts.FindAllReferences.toHighlightSpan), function (e) { return e.fileName; }, function (e) { return e.span; });
            return ts.arrayFrom(map.entries(), function (_a) {
                var fileName = _a[0], highlightSpans = _a[1];
                if (!sourceFilesSet.has(fileName)) {
                    ts.Debug.assert(program.redirectTargetsMap.has(fileName));
                    var redirectTarget_1 = program.getSourceFile(fileName);
                    var redirect = ts.find(sourceFilesToSearch, function (f) { return !!f.redirectInfo && f.redirectInfo.redirectTarget === redirectTarget_1; });
                    fileName = redirect.fileName;
                    ts.Debug.assert(sourceFilesSet.has(fileName));
                }
                return { fileName: fileName, highlightSpans: highlightSpans };
            });
        }
        function getSyntacticDocumentHighlights(node, sourceFile) {
            var highlightSpans = getHighlightSpans(node, sourceFile);
            return highlightSpans && [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }];
        }
        function getHighlightSpans(node, sourceFile) {
            switch (node.kind) {
                case 95 /* IfKeyword */:
                case 87 /* ElseKeyword */:
                    return ts.isIfStatement(node.parent) ? getIfElseOccurrences(node.parent, sourceFile) : undefined;
                case 101 /* ReturnKeyword */:
                    return useParent(node.parent, ts.isReturnStatement, getReturnOccurrences);
                case 105 /* ThrowKeyword */:
                    return useParent(node.parent, ts.isThrowStatement, getThrowOccurrences);
                case 107 /* TryKeyword */:
                case 79 /* CatchKeyword */:
                case 92 /* FinallyKeyword */:
                    var tryStatement = node.kind === 79 /* CatchKeyword */ ? node.parent.parent : node.parent;
                    return useParent(tryStatement, ts.isTryStatement, getTryCatchFinallyOccurrences);
                case 103 /* SwitchKeyword */:
                    return useParent(node.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences);
                case 78 /* CaseKeyword */:
                case 84 /* DefaultKeyword */: {
                    if (ts.isDefaultClause(node.parent) || ts.isCaseClause(node.parent)) {
                        return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences);
                    }
                    return undefined;
                }
                case 77 /* BreakKeyword */:
                case 82 /* ContinueKeyword */:
                    return useParent(node.parent, ts.isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences);
                case 93 /* ForKeyword */:
                case 111 /* WhileKeyword */:
                case 86 /* DoKeyword */:
                    return useParent(node.parent, function (n) { return ts.isIterationStatement(n, /*lookInLabeledStatements*/ true); }, getLoopBreakContinueOccurrences);
                case 129 /* ConstructorKeyword */:
                    return getFromAllDeclarations(ts.isConstructorDeclaration, [129 /* ConstructorKeyword */]);
                case 131 /* GetKeyword */:
                case 142 /* SetKeyword */:
                    return getFromAllDeclarations(ts.isAccessor, [131 /* GetKeyword */, 142 /* SetKeyword */]);
                case 127 /* AwaitKeyword */:
                    return useParent(node.parent, ts.isAwaitExpression, getAsyncAndAwaitOccurrences);
                case 126 /* AsyncKeyword */:
                    return highlightSpans(getAsyncAndAwaitOccurrences(node));
                case 121 /* YieldKeyword */:
                    return highlightSpans(getYieldOccurrences(node));
                default:
                    return ts.isModifierKind(node.kind) && (ts.isDeclaration(node.parent) || ts.isVariableStatement(node.parent))
                        ? highlightSpans(getModifierOccurrences(node.kind, node.parent))
                        : undefined;
            }
            function getFromAllDeclarations(nodeTest, keywords) {
                return useParent(node.parent, nodeTest, function (decl) { return ts.mapDefined(decl.symbol.declarations, function (d) {
                    return nodeTest(d) ? ts.find(d.getChildren(sourceFile), function (c) { return ts.contains(keywords, c.kind); }) : undefined;
                }); });
            }
            function useParent(node, nodeTest, getNodes) {
                return nodeTest(node) ? highlightSpans(getNodes(node, sourceFile)) : undefined;
            }
            function highlightSpans(nodes) {
                return nodes && nodes.map(function (node) { return getHighlightSpanForNode(node, sourceFile); });
            }
        }
        /**
         * Aggregates all throw-statements within this node *without* crossing
         * into function boundaries and try-blocks with catch-clauses.
         */
        function aggregateOwnedThrowStatements(node) {
            if (ts.isThrowStatement(node)) {
                return [node];
            }
            else if (ts.isTryStatement(node)) {
                // Exceptions thrown within a try block lacking a catch clause are "owned" in the current context.
                return ts.concatenate(node.catchClause ? aggregateOwnedThrowStatements(node.catchClause) : node.tryBlock && aggregateOwnedThrowStatements(node.tryBlock), node.finallyBlock && aggregateOwnedThrowStatements(node.finallyBlock));
            }
            // Do not cross function boundaries.
            return ts.isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateOwnedThrowStatements);
        }
        /**
         * For lack of a better name, this function takes a throw statement and returns the
         * nearest ancestor that is a try-block (whose try statement has a catch clause),
         * function-block, or source file.
         */
        function getThrowStatementOwner(throwStatement) {
            var child = throwStatement;
            while (child.parent) {
                var parent = child.parent;
                if (ts.isFunctionBlock(parent) || parent.kind === 290 /* SourceFile */) {
                    return parent;
                }
                // A throw-statement is only owned by a try-statement if the try-statement has
                // a catch clause, and if the throw-statement occurs within the try block.
                if (ts.isTryStatement(parent) && parent.tryBlock === child && parent.catchClause) {
                    return child;
                }
                child = parent;
            }
            return undefined;
        }
        function aggregateAllBreakAndContinueStatements(node) {
            return ts.isBreakOrContinueStatement(node) ? [node] : ts.isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateAllBreakAndContinueStatements);
        }
        function flatMapChildren(node, cb) {
            var result = [];
            node.forEachChild(function (child) {
                var value = cb(child);
                if (value !== undefined) {
                    result.push.apply(result, ts.toArray(value));
                }
            });
            return result;
        }
        function ownsBreakOrContinueStatement(owner, statement) {
            var actualOwner = getBreakOrContinueOwner(statement);
            return !!actualOwner && actualOwner === owner;
        }
        function getBreakOrContinueOwner(statement) {
            return ts.findAncestor(statement, function (node) {
                switch (node.kind) {
                    case 237 /* SwitchStatement */:
                        if (statement.kind === 233 /* ContinueStatement */) {
                            return false;
                        }
                    // falls through
                    case 230 /* ForStatement */:
                    case 231 /* ForInStatement */:
                    case 232 /* ForOfStatement */:
                    case 229 /* WhileStatement */:
                    case 228 /* DoStatement */:
                        return !statement.label || isLabeledBy(node, statement.label.escapedText);
                    default:
                        // Don't cross function boundaries.
                        // TODO: GH#20090
                        return ts.isFunctionLike(node) && "quit";
                }
            });
        }
        function getModifierOccurrences(modifier, declaration) {
            return ts.mapDefined(getNodesToSearchForModifier(declaration, ts.modifierToFlag(modifier)), function (node) { return ts.findModifier(node, modifier); });
        }
        function getNodesToSearchForModifier(declaration, modifierFlag) {
            // Types of node whose children might have modifiers.
            var container = declaration.parent;
            switch (container.kind) {
                case 250 /* ModuleBlock */:
                case 290 /* SourceFile */:
                case 223 /* Block */:
                case 277 /* CaseClause */:
                case 278 /* DefaultClause */:
                    // Container is either a class declaration or the declaration is a classDeclaration
                    if (modifierFlag & 128 /* Abstract */ && ts.isClassDeclaration(declaration)) {
                        return __spreadArrays(declaration.members, [declaration]);
                    }
                    else {
                        return container.statements;
                    }
                case 162 /* Constructor */:
                case 161 /* MethodDeclaration */:
                case 244 /* FunctionDeclaration */:
                    return __spreadArrays(container.parameters, (ts.isClassLike(container.parent) ? container.parent.members : []));
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                case 246 /* InterfaceDeclaration */:
                case 173 /* TypeLiteral */:
                    var nodes = container.members;
                    // If we're an accessibility modifier, we're in an instance member and should search
                    // the constructor's parameter list for instance members as well.
                    if (modifierFlag & (28 /* AccessibilityModifier */ | 64 /* Readonly */)) {
                        var constructor = ts.find(container.members, ts.isConstructorDeclaration);
                        if (constructor) {
                            return __spreadArrays(nodes, constructor.parameters);
                        }
                    }
                    else if (modifierFlag & 128 /* Abstract */) {
                        return __spreadArrays(nodes, [container]);
                    }
                    return nodes;
                default:
                    ts.Debug.assertNever(container, "Invalid container kind.");
            }
        }
        function pushKeywordIf(keywordList, token) {
            var expected = [];
            for (var _i = 2; _i < arguments.length; _i++) {
                expected[_i - 2] = arguments[_i];
            }
            if (token && ts.contains(expected, token.kind)) {
                keywordList.push(token);
                return true;
            }
            return false;
        }
        function getLoopBreakContinueOccurrences(loopNode) {
            var keywords = [];
            if (pushKeywordIf(keywords, loopNode.getFirstToken(), 93 /* ForKeyword */, 111 /* WhileKeyword */, 86 /* DoKeyword */)) {
                // If we succeeded and got a do-while loop, then start looking for a 'while' keyword.
                if (loopNode.kind === 228 /* DoStatement */) {
                    var loopTokens = loopNode.getChildren();
                    for (var i = loopTokens.length - 1; i >= 0; i--) {
                        if (pushKeywordIf(keywords, loopTokens[i], 111 /* WhileKeyword */)) {
                            break;
                        }
                    }
                }
            }
            ts.forEach(aggregateAllBreakAndContinueStatements(loopNode.statement), function (statement) {
                if (ownsBreakOrContinueStatement(loopNode, statement)) {
                    pushKeywordIf(keywords, statement.getFirstToken(), 77 /* BreakKeyword */, 82 /* ContinueKeyword */);
                }
            });
            return keywords;
        }
        function getBreakOrContinueStatementOccurrences(breakOrContinueStatement) {
            var owner = getBreakOrContinueOwner(breakOrContinueStatement);
            if (owner) {
                switch (owner.kind) {
                    case 230 /* ForStatement */:
                    case 231 /* ForInStatement */:
                    case 232 /* ForOfStatement */:
                    case 228 /* DoStatement */:
                    case 229 /* WhileStatement */:
                        return getLoopBreakContinueOccurrences(owner);
                    case 237 /* SwitchStatement */:
                        return getSwitchCaseDefaultOccurrences(owner);
                }
            }
            return undefined;
        }
        function getSwitchCaseDefaultOccurrences(switchStatement) {
            var keywords = [];
            pushKeywordIf(keywords, switchStatement.getFirstToken(), 103 /* SwitchKeyword */);
            // Go through each clause in the switch statement, collecting the 'case'/'default' keywords.
            ts.forEach(switchStatement.caseBlock.clauses, function (clause) {
                pushKeywordIf(keywords, clause.getFirstToken(), 78 /* CaseKeyword */, 84 /* DefaultKeyword */);
                ts.forEach(aggregateAllBreakAndContinueStatements(clause), function (statement) {
                    if (ownsBreakOrContinueStatement(switchStatement, statement)) {
                        pushKeywordIf(keywords, statement.getFirstToken(), 77 /* BreakKeyword */);
                    }
                });
            });
            return keywords;
        }
        function getTryCatchFinallyOccurrences(tryStatement, sourceFile) {
            var keywords = [];
            pushKeywordIf(keywords, tryStatement.getFirstToken(), 107 /* TryKeyword */);
            if (tryStatement.catchClause) {
                pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), 79 /* CatchKeyword */);
            }
            if (tryStatement.finallyBlock) {
                var finallyKeyword = ts.findChildOfKind(tryStatement, 92 /* FinallyKeyword */, sourceFile);
                pushKeywordIf(keywords, finallyKeyword, 92 /* FinallyKeyword */);
            }
            return keywords;
        }
        function getThrowOccurrences(throwStatement, sourceFile) {
            var owner = getThrowStatementOwner(throwStatement);
            if (!owner) {
                return undefined;
            }
            var keywords = [];
            ts.forEach(aggregateOwnedThrowStatements(owner), function (throwStatement) {
                keywords.push(ts.findChildOfKind(throwStatement, 105 /* ThrowKeyword */, sourceFile));
            });
            // If the "owner" is a function, then we equate 'return' and 'throw' statements in their
            // ability to "jump out" of the function, and include occurrences for both.
            if (ts.isFunctionBlock(owner)) {
                ts.forEachReturnStatement(owner, function (returnStatement) {
                    keywords.push(ts.findChildOfKind(returnStatement, 101 /* ReturnKeyword */, sourceFile));
                });
            }
            return keywords;
        }
        function getReturnOccurrences(returnStatement, sourceFile) {
            var func = ts.getContainingFunction(returnStatement);
            if (!func) {
                return undefined;
            }
            var keywords = [];
            ts.forEachReturnStatement(ts.cast(func.body, ts.isBlock), function (returnStatement) {
                keywords.push(ts.findChildOfKind(returnStatement, 101 /* ReturnKeyword */, sourceFile));
            });
            // Include 'throw' statements that do not occur within a try block.
            ts.forEach(aggregateOwnedThrowStatements(func.body), function (throwStatement) {
                keywords.push(ts.findChildOfKind(throwStatement, 105 /* ThrowKeyword */, sourceFile));
            });
            return keywords;
        }
        function getAsyncAndAwaitOccurrences(node) {
            var func = ts.getContainingFunction(node);
            if (!func) {
                return undefined;
            }
            var keywords = [];
            if (func.modifiers) {
                func.modifiers.forEach(function (modifier) {
                    pushKeywordIf(keywords, modifier, 126 /* AsyncKeyword */);
                });
            }
            ts.forEachChild(func, function (child) {
                traverseWithoutCrossingFunction(child, function (node) {
                    if (ts.isAwaitExpression(node)) {
                        pushKeywordIf(keywords, node.getFirstToken(), 127 /* AwaitKeyword */);
                    }
                });
            });
            return keywords;
        }
        function getYieldOccurrences(node) {
            var func = ts.getContainingFunction(node);
            if (!func) {
                return undefined;
            }
            var keywords = [];
            ts.forEachChild(func, function (child) {
                traverseWithoutCrossingFunction(child, function (node) {
                    if (ts.isYieldExpression(node)) {
                        pushKeywordIf(keywords, node.getFirstToken(), 121 /* YieldKeyword */);
                    }
                });
            });
            return keywords;
        }
        // Do not cross function/class/interface/module/type boundaries.
        function traverseWithoutCrossingFunction(node, cb) {
            cb(node);
            if (!ts.isFunctionLike(node) && !ts.isClassLike(node) && !ts.isInterfaceDeclaration(node) && !ts.isModuleDeclaration(node) && !ts.isTypeAliasDeclaration(node) && !ts.isTypeNode(node)) {
                ts.forEachChild(node, function (child) { return traverseWithoutCrossingFunction(child, cb); });
            }
        }
        function getIfElseOccurrences(ifStatement, sourceFile) {
            var keywords = getIfElseKeywords(ifStatement, sourceFile);
            var result = [];
            // We'd like to highlight else/ifs together if they are only separated by whitespace
            // (i.e. the keywords are separated by no comments, no newlines).
            for (var i = 0; i < keywords.length; i++) {
                if (keywords[i].kind === 87 /* ElseKeyword */ && i < keywords.length - 1) {
                    var elseKeyword = keywords[i];
                    var ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword.
                    var shouldCombineElseAndIf = true;
                    // Avoid recalculating getStart() by iterating backwards.
                    for (var j = ifKeyword.getStart(sourceFile) - 1; j >= elseKeyword.end; j--) {
                        if (!ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) {
                            shouldCombineElseAndIf = false;
                            break;
                        }
                    }
                    if (shouldCombineElseAndIf) {
                        result.push({
                            fileName: sourceFile.fileName,
                            textSpan: ts.createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end),
                            kind: "reference" /* reference */
                        });
                        i++; // skip the next keyword
                        continue;
                    }
                }
                // Ordinary case: just highlight the keyword.
                result.push(getHighlightSpanForNode(keywords[i], sourceFile));
            }
            return result;
        }
        function getIfElseKeywords(ifStatement, sourceFile) {
            var keywords = [];
            // Traverse upwards through all parent if-statements linked by their else-branches.
            while (ts.isIfStatement(ifStatement.parent) && ifStatement.parent.elseStatement === ifStatement) {
                ifStatement = ifStatement.parent;
            }
            // Now traverse back down through the else branches, aggregating if/else keywords of if-statements.
            while (true) {
                var children = ifStatement.getChildren(sourceFile);
                pushKeywordIf(keywords, children[0], 95 /* IfKeyword */);
                // Generally the 'else' keyword is second-to-last, so we traverse backwards.
                for (var i = children.length - 1; i >= 0; i--) {
                    if (pushKeywordIf(keywords, children[i], 87 /* ElseKeyword */)) {
                        break;
                    }
                }
                if (!ifStatement.elseStatement || !ts.isIfStatement(ifStatement.elseStatement)) {
                    break;
                }
                ifStatement = ifStatement.elseStatement;
            }
            return keywords;
        }
        /**
         * Whether or not a 'node' is preceded by a label of the given string.
         * Note: 'node' cannot be a SourceFile.
         */
        function isLabeledBy(node, labelName) {
            return !!ts.findAncestor(node.parent, function (owner) { return !ts.isLabeledStatement(owner) ? "quit" : owner.label.escapedText === labelName; });
        }
    })(DocumentHighlights = ts.DocumentHighlights || (ts.DocumentHighlights = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory) {
        return createDocumentRegistryInternal(useCaseSensitiveFileNames, currentDirectory);
    }
    ts.createDocumentRegistry = createDocumentRegistry;
    /*@internal*/
    function createDocumentRegistryInternal(useCaseSensitiveFileNames, currentDirectory, externalCache) {
        if (currentDirectory === void 0) { currentDirectory = ""; }
        // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
        // for those settings.
        var buckets = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(!!useCaseSensitiveFileNames);
        function reportStats() {
            var bucketInfoArray = ts.arrayFrom(buckets.keys()).filter(function (name) { return name && name.charAt(0) === "_"; }).map(function (name) {
                var entries = buckets.get(name);
                var sourceFiles = [];
                entries.forEach(function (entry, name) {
                    sourceFiles.push({
                        name: name,
                        refCount: entry.languageServiceRefCount
                    });
                });
                sourceFiles.sort(function (x, y) { return y.refCount - x.refCount; });
                return {
                    bucket: name,
                    sourceFiles: sourceFiles
                };
            });
            return JSON.stringify(bucketInfoArray, undefined, 2);
        }
        function acquireDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind);
        }
        function acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) {
            return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ true, scriptKind);
        }
        function updateDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind);
        }
        function updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) {
            return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ false, scriptKind);
        }
        function acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, acquiring, scriptKind) {
            var bucket = ts.getOrUpdate(buckets, key, ts.createMap);
            var entry = bucket.get(path);
            var scriptTarget = scriptKind === 6 /* JSON */ ? 100 /* JSON */ : compilationSettings.target || 1 /* ES5 */;
            if (!entry && externalCache) {
                var sourceFile = externalCache.getDocument(key, path);
                if (sourceFile) {
                    ts.Debug.assert(acquiring);
                    entry = {
                        sourceFile: sourceFile,
                        languageServiceRefCount: 0
                    };
                    bucket.set(path, entry);
                }
            }
            if (!entry) {
                // Have never seen this file with these settings.  Create a new source file for it.
                var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, /*setNodeParents*/ false, scriptKind);
                if (externalCache) {
                    externalCache.setDocument(key, path, sourceFile);
                }
                entry = {
                    sourceFile: sourceFile,
                    languageServiceRefCount: 1,
                };
                bucket.set(path, entry);
            }
            else {
                // We have an entry for this file.  However, it may be for a different version of
                // the script snapshot.  If so, update it appropriately.  Otherwise, we can just
                // return it as is.
                if (entry.sourceFile.version !== version) {
                    entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); // TODO: GH#18217
                    if (externalCache) {
                        externalCache.setDocument(key, path, entry.sourceFile);
                    }
                }
                // If we're acquiring, then this is the first time this LS is asking for this document.
                // Increase our ref count so we know there's another LS using the document.  If we're
                // not acquiring, then that means the LS is 'updating' the file instead, and that means
                // it has already acquired the document previously.  As such, we do not need to increase
                // the ref count.
                if (acquiring) {
                    entry.languageServiceRefCount++;
                }
            }
            ts.Debug.assert(entry.languageServiceRefCount !== 0);
            return entry.sourceFile;
        }
        function releaseDocument(fileName, compilationSettings) {
            var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
            var key = getKeyForCompilationSettings(compilationSettings);
            return releaseDocumentWithKey(path, key);
        }
        function releaseDocumentWithKey(path, key) {
            var bucket = ts.Debug.checkDefined(buckets.get(key));
            var entry = bucket.get(path);
            entry.languageServiceRefCount--;
            ts.Debug.assert(entry.languageServiceRefCount >= 0);
            if (entry.languageServiceRefCount === 0) {
                bucket.delete(path);
            }
        }
        function getLanguageServiceRefCounts(path) {
            return ts.arrayFrom(buckets.entries(), function (_a) {
                var key = _a[0], bucket = _a[1];
                var entry = bucket.get(path);
                return [key, entry && entry.languageServiceRefCount];
            });
        }
        return {
            acquireDocument: acquireDocument,
            acquireDocumentWithKey: acquireDocumentWithKey,
            updateDocument: updateDocument,
            updateDocumentWithKey: updateDocumentWithKey,
            releaseDocument: releaseDocument,
            releaseDocumentWithKey: releaseDocumentWithKey,
            getLanguageServiceRefCounts: getLanguageServiceRefCounts,
            reportStats: reportStats,
            getKeyForCompilationSettings: getKeyForCompilationSettings
        };
    }
    ts.createDocumentRegistryInternal = createDocumentRegistryInternal;
    function getKeyForCompilationSettings(settings) {
        return ts.sourceFileAffectingCompilerOptions.map(function (option) { return ts.getCompilerOptionValue(settings, option); }).join("|");
    }
})(ts || (ts = {}));
/* Code for finding imports of an exported symbol. Used only by FindAllReferences. */
/* @internal */
var ts;
(function (ts) {
    var FindAllReferences;
    (function (FindAllReferences) {
        /** Creates the imports map and returns an ImportTracker that uses it. Call this lazily to avoid calling `getDirectImportsMap` unnecessarily.  */
        function createImportTracker(sourceFiles, sourceFilesSet, checker, cancellationToken) {
            var allDirectImports = getDirectImportsMap(sourceFiles, checker, cancellationToken);
            return function (exportSymbol, exportInfo, isForRename) {
                var _a = getImportersForExport(sourceFiles, sourceFilesSet, allDirectImports, exportInfo, checker, cancellationToken), directImports = _a.directImports, indirectUsers = _a.indirectUsers;
                return __assign({ indirectUsers: indirectUsers }, getSearchesFromDirectImports(directImports, exportSymbol, exportInfo.exportKind, checker, isForRename));
            };
        }
        FindAllReferences.createImportTracker = createImportTracker;
        var ExportKind;
        (function (ExportKind) {
            ExportKind[ExportKind["Named"] = 0] = "Named";
            ExportKind[ExportKind["Default"] = 1] = "Default";
            ExportKind[ExportKind["ExportEquals"] = 2] = "ExportEquals";
        })(ExportKind = FindAllReferences.ExportKind || (FindAllReferences.ExportKind = {}));
        var ImportExport;
        (function (ImportExport) {
            ImportExport[ImportExport["Import"] = 0] = "Import";
            ImportExport[ImportExport["Export"] = 1] = "Export";
        })(ImportExport = FindAllReferences.ImportExport || (FindAllReferences.ImportExport = {}));
        /** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */
        function getImportersForExport(sourceFiles, sourceFilesSet, allDirectImports, _a, checker, cancellationToken) {
            var exportingModuleSymbol = _a.exportingModuleSymbol, exportKind = _a.exportKind;
            var markSeenDirectImport = ts.nodeSeenTracker();
            var markSeenIndirectUser = ts.nodeSeenTracker();
            var directImports = [];
            var isAvailableThroughGlobal = !!exportingModuleSymbol.globalExports;
            var indirectUserDeclarations = isAvailableThroughGlobal ? undefined : [];
            handleDirectImports(exportingModuleSymbol);
            return { directImports: directImports, indirectUsers: getIndirectUsers() };
            function getIndirectUsers() {
                if (isAvailableThroughGlobal) {
                    // It has `export as namespace`, so anything could potentially use it.
                    return sourceFiles;
                }
                // Module augmentations may use this module's exports without importing it.
                for (var _i = 0, _a = exportingModuleSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    if (ts.isExternalModuleAugmentation(decl) && sourceFilesSet.has(decl.getSourceFile().fileName)) {
                        addIndirectUser(decl);
                    }
                }
                // This may return duplicates (if there are multiple module declarations in a single source file, all importing the same thing as a namespace), but `State.markSearchedSymbol` will handle that.
                return indirectUserDeclarations.map(ts.getSourceFileOfNode);
            }
            function handleDirectImports(exportingModuleSymbol) {
                var theseDirectImports = getDirectImports(exportingModuleSymbol);
                if (theseDirectImports) {
                    for (var _i = 0, theseDirectImports_1 = theseDirectImports; _i < theseDirectImports_1.length; _i++) {
                        var direct = theseDirectImports_1[_i];
                        if (!markSeenDirectImport(direct)) {
                            continue;
                        }
                        if (cancellationToken)
                            cancellationToken.throwIfCancellationRequested();
                        switch (direct.kind) {
                            case 196 /* CallExpression */:
                                if (!isAvailableThroughGlobal) {
                                    var parent = direct.parent;
                                    if (exportKind === 2 /* ExportEquals */ && parent.kind === 242 /* VariableDeclaration */) {
                                        var name = parent.name;
                                        if (name.kind === 75 /* Identifier */) {
                                            directImports.push(name);
                                            break;
                                        }
                                    }
                                    // Don't support re-exporting 'require()' calls, so just add a single indirect user.
                                    addIndirectUser(direct.getSourceFile());
                                }
                                break;
                            case 75 /* Identifier */: // for 'const x = require("y");
                                break; // TODO: GH#23879
                            case 253 /* ImportEqualsDeclaration */:
                                handleNamespaceImport(direct, direct.name, ts.hasModifier(direct, 1 /* Export */), /*alreadyAddedDirect*/ false);
                                break;
                            case 254 /* ImportDeclaration */:
                                directImports.push(direct);
                                var namedBindings = direct.importClause && direct.importClause.namedBindings;
                                if (namedBindings && namedBindings.kind === 256 /* NamespaceImport */) {
                                    handleNamespaceImport(direct, namedBindings.name, /*isReExport*/ false, /*alreadyAddedDirect*/ true);
                                }
                                else if (!isAvailableThroughGlobal && ts.isDefaultImport(direct)) {
                                    addIndirectUser(getSourceFileLikeForImportDeclaration(direct)); // Add a check for indirect uses to handle synthetic default imports
                                }
                                break;
                            case 260 /* ExportDeclaration */:
                                if (!direct.exportClause) {
                                    // This is `export * from "foo"`, so imports of this module may import the export too.
                                    handleDirectImports(getContainingModuleSymbol(direct, checker));
                                }
                                else {
                                    // This is `export { foo } from "foo"` and creates an alias symbol, so recursive search will get handle re-exports.
                                    directImports.push(direct);
                                }
                                break;
                            case 188 /* ImportType */:
                                directImports.push(direct);
                                break;
                            default:
                                ts.Debug.failBadSyntaxKind(direct, "Unexpected import kind.");
                        }
                    }
                }
            }
            function handleNamespaceImport(importDeclaration, name, isReExport, alreadyAddedDirect) {
                if (exportKind === 2 /* ExportEquals */) {
                    // This is a direct import, not import-as-namespace.
                    if (!alreadyAddedDirect)
                        directImports.push(importDeclaration);
                }
                else if (!isAvailableThroughGlobal) {
                    var sourceFileLike = getSourceFileLikeForImportDeclaration(importDeclaration);
                    ts.Debug.assert(sourceFileLike.kind === 290 /* SourceFile */ || sourceFileLike.kind === 249 /* ModuleDeclaration */);
                    if (isReExport || findNamespaceReExports(sourceFileLike, name, checker)) {
                        addIndirectUsers(sourceFileLike);
                    }
                    else {
                        addIndirectUser(sourceFileLike);
                    }
                }
            }
            function addIndirectUser(sourceFileLike) {
                ts.Debug.assert(!isAvailableThroughGlobal);
                var isNew = markSeenIndirectUser(sourceFileLike);
                if (isNew) {
                    indirectUserDeclarations.push(sourceFileLike); // TODO: GH#18217
                }
                return isNew;
            }
            /** Adds a module and all of its transitive dependencies as possible indirect users. */
            function addIndirectUsers(sourceFileLike) {
                if (!addIndirectUser(sourceFileLike)) {
                    return;
                }
                var moduleSymbol = checker.getMergedSymbol(sourceFileLike.symbol);
                ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */));
                var directImports = getDirectImports(moduleSymbol);
                if (directImports) {
                    for (var _i = 0, directImports_1 = directImports; _i < directImports_1.length; _i++) {
                        var directImport = directImports_1[_i];
                        if (!ts.isImportTypeNode(directImport)) {
                            addIndirectUsers(getSourceFileLikeForImportDeclaration(directImport));
                        }
                    }
                }
            }
            function getDirectImports(moduleSymbol) {
                return allDirectImports.get(ts.getSymbolId(moduleSymbol).toString());
            }
        }
        /**
         * Given the set of direct imports of a module, we need to find which ones import the particular exported symbol.
         * The returned `importSearches` will result in the entire source file being searched.
         * But re-exports will be placed in 'singleReferences' since they cannot be locally referenced.
         */
        function getSearchesFromDirectImports(directImports, exportSymbol, exportKind, checker, isForRename) {
            var importSearches = [];
            var singleReferences = [];
            function addSearch(location, symbol) {
                importSearches.push([location, symbol]);
            }
            if (directImports) {
                for (var _i = 0, directImports_2 = directImports; _i < directImports_2.length; _i++) {
                    var decl = directImports_2[_i];
                    handleImport(decl);
                }
            }
            return { importSearches: importSearches, singleReferences: singleReferences };
            function handleImport(decl) {
                if (decl.kind === 253 /* ImportEqualsDeclaration */) {
                    if (isExternalModuleImportEquals(decl)) {
                        handleNamespaceImportLike(decl.name);
                    }
                    return;
                }
                if (decl.kind === 75 /* Identifier */) {
                    handleNamespaceImportLike(decl);
                    return;
                }
                if (decl.kind === 188 /* ImportType */) {
                    if (decl.qualifier) {
                        var firstIdentifier = ts.getFirstIdentifier(decl.qualifier);
                        if (firstIdentifier.escapedText === ts.symbolName(exportSymbol)) {
                            singleReferences.push(firstIdentifier);
                        }
                    }
                    else if (exportKind === 2 /* ExportEquals */) {
                        singleReferences.push(decl.argument.literal);
                    }
                    return;
                }
                // Ignore if there's a grammar error
                if (decl.moduleSpecifier.kind !== 10 /* StringLiteral */) {
                    return;
                }
                if (decl.kind === 260 /* ExportDeclaration */) {
                    if (decl.exportClause && ts.isNamedExports(decl.exportClause)) {
                        searchForNamedImport(decl.exportClause);
                    }
                    return;
                }
                var _a = decl.importClause || { name: undefined, namedBindings: undefined }, name = _a.name, namedBindings = _a.namedBindings;
                if (namedBindings) {
                    switch (namedBindings.kind) {
                        case 256 /* NamespaceImport */:
                            handleNamespaceImportLike(namedBindings.name);
                            break;
                        case 257 /* NamedImports */:
                            // 'default' might be accessed as a named import `{ default as foo }`.
                            if (exportKind === 0 /* Named */ || exportKind === 1 /* Default */) {
                                searchForNamedImport(namedBindings);
                            }
                            break;
                        default:
                            ts.Debug.assertNever(namedBindings);
                    }
                }
                // `export =` might be imported by a default import if `--allowSyntheticDefaultImports` is on, so this handles both ExportKind.Default and ExportKind.ExportEquals.
                // If a default import has the same name as the default export, allow to rename it.
                // Given `import f` and `export default function f`, we will rename both, but for `import g` we will rename just that.
                if (name && (exportKind === 1 /* Default */ || exportKind === 2 /* ExportEquals */) && (!isForRename || name.escapedText === ts.symbolEscapedNameNoDefault(exportSymbol))) {
                    var defaultImportAlias = checker.getSymbolAtLocation(name);
                    addSearch(name, defaultImportAlias);
                }
            }
            /**
             * `import x = require("./x")` or `import * as x from "./x"`.
             * An `export =` may be imported by this syntax, so it may be a direct import.
             * If it's not a direct import, it will be in `indirectUsers`, so we don't have to do anything here.
             */
            function handleNamespaceImportLike(importName) {
                // Don't rename an import that already has a different name than the export.
                if (exportKind === 2 /* ExportEquals */ && (!isForRename || isNameMatch(importName.escapedText))) {
                    addSearch(importName, checker.getSymbolAtLocation(importName));
                }
            }
            function searchForNamedImport(namedBindings) {
                if (!namedBindings) {
                    return;
                }
                for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    var name = element.name, propertyName = element.propertyName;
                    if (!isNameMatch((propertyName || name).escapedText)) {
                        continue;
                    }
                    if (propertyName) {
                        // This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference.
                        singleReferences.push(propertyName);
                        // If renaming `{ foo as bar }`, don't touch `bar`, just `foo`.
                        // But do rename `foo` in ` { default as foo }` if that's the original export name.
                        if (!isForRename || name.escapedText === exportSymbol.escapedName) {
                            // Search locally for `bar`.
                            addSearch(name, checker.getSymbolAtLocation(name));
                        }
                    }
                    else {
                        var localSymbol = element.kind === 263 /* ExportSpecifier */ && element.propertyName
                            ? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol.
                            : checker.getSymbolAtLocation(name);
                        addSearch(name, localSymbol);
                    }
                }
            }
            function isNameMatch(name) {
                // Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports
                return name === exportSymbol.escapedName || exportKind !== 0 /* Named */ && name === "default" /* Default */;
            }
        }
        /** Returns 'true' is the namespace 'name' is re-exported from this module, and 'false' if it is only used locally. */
        function findNamespaceReExports(sourceFileLike, name, checker) {
            var namespaceImportSymbol = checker.getSymbolAtLocation(name);
            return !!forEachPossibleImportOrExportStatement(sourceFileLike, function (statement) {
                if (!ts.isExportDeclaration(statement))
                    return;
                var exportClause = statement.exportClause, moduleSpecifier = statement.moduleSpecifier;
                return !moduleSpecifier && exportClause && ts.isNamedExports(exportClause) &&
                    exportClause.elements.some(function (element) { return checker.getExportSpecifierLocalTargetSymbol(element) === namespaceImportSymbol; });
            });
        }
        function findModuleReferences(program, sourceFiles, searchModuleSymbol) {
            var refs = [];
            var checker = program.getTypeChecker();
            for (var _i = 0, sourceFiles_1 = sourceFiles; _i < sourceFiles_1.length; _i++) {
                var referencingFile = sourceFiles_1[_i];
                var searchSourceFile = searchModuleSymbol.valueDeclaration;
                if (searchSourceFile.kind === 290 /* SourceFile */) {
                    for (var _a = 0, _b = referencingFile.referencedFiles; _a < _b.length; _a++) {
                        var ref = _b[_a];
                        if (program.getSourceFileFromReference(referencingFile, ref) === searchSourceFile) {
                            refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref });
                        }
                    }
                    for (var _c = 0, _d = referencingFile.typeReferenceDirectives; _c < _d.length; _c++) {
                        var ref = _d[_c];
                        var referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName);
                        if (referenced !== undefined && referenced.resolvedFileName === searchSourceFile.fileName) {
                            refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref });
                        }
                    }
                }
                forEachImport(referencingFile, function (_importDecl, moduleSpecifier) {
                    var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier);
                    if (moduleSymbol === searchModuleSymbol) {
                        refs.push({ kind: "import", literal: moduleSpecifier });
                    }
                });
            }
            return refs;
        }
        FindAllReferences.findModuleReferences = findModuleReferences;
        /** Returns a map from a module symbol Id to all import statements that directly reference the module. */
        function getDirectImportsMap(sourceFiles, checker, cancellationToken) {
            var map = ts.createMap();
            for (var _i = 0, sourceFiles_2 = sourceFiles; _i < sourceFiles_2.length; _i++) {
                var sourceFile = sourceFiles_2[_i];
                if (cancellationToken)
                    cancellationToken.throwIfCancellationRequested();
                forEachImport(sourceFile, function (importDecl, moduleSpecifier) {
                    var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier);
                    if (moduleSymbol) {
                        var id = ts.getSymbolId(moduleSymbol).toString();
                        var imports = map.get(id);
                        if (!imports) {
                            map.set(id, imports = []);
                        }
                        imports.push(importDecl);
                    }
                });
            }
            return map;
        }
        /** Iterates over all statements at the top level or in module declarations. Returns the first truthy result. */
        function forEachPossibleImportOrExportStatement(sourceFileLike, action) {
            return ts.forEach(sourceFileLike.kind === 290 /* SourceFile */ ? sourceFileLike.statements : sourceFileLike.body.statements, function (statement) {
                return action(statement) || (isAmbientModuleDeclaration(statement) && ts.forEach(statement.body && statement.body.statements, action));
            });
        }
        /** Calls `action` for each import, re-export, or require() in a file. */
        function forEachImport(sourceFile, action) {
            if (sourceFile.externalModuleIndicator || sourceFile.imports !== undefined) {
                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                    var i = _a[_i];
                    action(ts.importFromModuleSpecifier(i), i);
                }
            }
            else {
                forEachPossibleImportOrExportStatement(sourceFile, function (statement) {
                    switch (statement.kind) {
                        case 260 /* ExportDeclaration */:
                        case 254 /* ImportDeclaration */: {
                            var decl = statement;
                            if (decl.moduleSpecifier && ts.isStringLiteral(decl.moduleSpecifier)) {
                                action(decl, decl.moduleSpecifier);
                            }
                            break;
                        }
                        case 253 /* ImportEqualsDeclaration */: {
                            var decl = statement;
                            if (isExternalModuleImportEquals(decl)) {
                                action(decl, decl.moduleReference.expression);
                            }
                            break;
                        }
                    }
                });
            }
        }
        /**
         * Given a local reference, we might notice that it's an import/export and recursively search for references of that.
         * If at an import, look locally for the symbol it imports.
         * If at an export, look for all imports of it.
         * This doesn't handle export specifiers; that is done in `getReferencesAtExportSpecifier`.
         * @param comingFromExport If we are doing a search for all exports, don't bother looking backwards for the imported symbol, since that's the reason we're here.
         */
        function getImportOrExportSymbol(node, symbol, checker, comingFromExport) {
            return comingFromExport ? getExport() : getExport() || getImport();
            function getExport() {
                var parent = node.parent;
                var grandParent = parent.parent;
                if (symbol.exportSymbol) {
                    if (parent.kind === 194 /* PropertyAccessExpression */) {
                        // When accessing an export of a JS module, there's no alias. The symbol will still be flagged as an export even though we're at the use.
                        // So check that we are at the declaration.
                        return symbol.declarations.some(function (d) { return d === parent; }) && ts.isBinaryExpression(grandParent)
                            ? getSpecialPropertyExport(grandParent, /*useLhsSymbol*/ false)
                            : undefined;
                    }
                    else {
                        return exportInfo(symbol.exportSymbol, getExportKindForDeclaration(parent));
                    }
                }
                else {
                    var exportNode = getExportNode(parent, node);
                    if (exportNode && ts.hasModifier(exportNode, 1 /* Export */)) {
                        if (ts.isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) {
                            // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement.
                            if (comingFromExport) {
                                return undefined;
                            }
                            var lhsSymbol = checker.getSymbolAtLocation(exportNode.name);
                            return { kind: 0 /* Import */, symbol: lhsSymbol };
                        }
                        else {
                            return exportInfo(symbol, getExportKindForDeclaration(exportNode));
                        }
                    }
                    // If we are in `export = a;` or `export default a;`, `parent` is the export assignment.
                    else if (ts.isExportAssignment(parent)) {
                        return getExportAssignmentExport(parent);
                    }
                    // If we are in `export = class A {};` (or `export = class A {};`) at `A`, `parent.parent` is the export assignment.
                    else if (ts.isExportAssignment(grandParent)) {
                        return getExportAssignmentExport(grandParent);
                    }
                    // Similar for `module.exports =` and `exports.A =`.
                    else if (ts.isBinaryExpression(parent)) {
                        return getSpecialPropertyExport(parent, /*useLhsSymbol*/ true);
                    }
                    else if (ts.isBinaryExpression(grandParent)) {
                        return getSpecialPropertyExport(grandParent, /*useLhsSymbol*/ true);
                    }
                    else if (ts.isJSDocTypedefTag(parent)) {
                        return exportInfo(symbol, 0 /* Named */);
                    }
                }
                function getExportAssignmentExport(ex) {
                    // Get the symbol for the `export =` node; its parent is the module it's the export of.
                    var exportingModuleSymbol = ts.Debug.checkDefined(ex.symbol.parent, "Expected export symbol to have a parent");
                    var exportKind = ex.isExportEquals ? 2 /* ExportEquals */ : 1 /* Default */;
                    return { kind: 1 /* Export */, symbol: symbol, exportInfo: { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } };
                }
                function getSpecialPropertyExport(node, useLhsSymbol) {
                    var kind;
                    switch (ts.getAssignmentDeclarationKind(node)) {
                        case 1 /* ExportsProperty */:
                            kind = 0 /* Named */;
                            break;
                        case 2 /* ModuleExports */:
                            kind = 2 /* ExportEquals */;
                            break;
                        default:
                            return undefined;
                    }
                    var sym = useLhsSymbol ? checker.getSymbolAtLocation(ts.getNameOfAccessExpression(ts.cast(node.left, ts.isAccessExpression))) : symbol;
                    return sym && exportInfo(sym, kind);
                }
            }
            function getImport() {
                var isImport = isNodeImport(node);
                if (!isImport)
                    return undefined;
                // A symbol being imported is always an alias. So get what that aliases to find the local symbol.
                var importedSymbol = checker.getImmediateAliasedSymbol(symbol);
                if (!importedSymbol)
                    return undefined;
                // Search on the local symbol in the exporting module, not the exported symbol.
                importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker);
                // Similarly, skip past the symbol for 'export ='
                if (importedSymbol.escapedName === "export=") {
                    importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker);
                }
                // If the import has a different name than the export, do not continue searching.
                // If `importedName` is undefined, do continue searching as the export is anonymous.
                // (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
                var importedName = ts.symbolEscapedNameNoDefault(importedSymbol);
                if (importedName === undefined || importedName === "default" /* Default */ || importedName === symbol.escapedName) {
                    return { kind: 0 /* Import */, symbol: importedSymbol };
                }
            }
            function exportInfo(symbol, kind) {
                var exportInfo = getExportInfo(symbol, kind, checker);
                return exportInfo && { kind: 1 /* Export */, symbol: symbol, exportInfo: exportInfo };
            }
            // Not meant for use with export specifiers or export assignment.
            function getExportKindForDeclaration(node) {
                return ts.hasModifier(node, 512 /* Default */) ? 1 /* Default */ : 0 /* Named */;
            }
        }
        FindAllReferences.getImportOrExportSymbol = getImportOrExportSymbol;
        function getExportEqualsLocalSymbol(importedSymbol, checker) {
            if (importedSymbol.flags & 2097152 /* Alias */) {
                return ts.Debug.checkDefined(checker.getImmediateAliasedSymbol(importedSymbol));
            }
            var decl = importedSymbol.valueDeclaration;
            if (ts.isExportAssignment(decl)) { // `export = class {}`
                return ts.Debug.checkDefined(decl.expression.symbol);
            }
            else if (ts.isBinaryExpression(decl)) { // `module.exports = class {}`
                return ts.Debug.checkDefined(decl.right.symbol);
            }
            else if (ts.isSourceFile(decl)) { // json module
                return ts.Debug.checkDefined(decl.symbol);
            }
            return ts.Debug.fail();
        }
        // If a reference is a class expression, the exported node would be its parent.
        // If a reference is a variable declaration, the exported node would be the variable statement.
        function getExportNode(parent, node) {
            var declaration = ts.isVariableDeclaration(parent) ? parent : ts.isBindingElement(parent) ? ts.walkUpBindingElementsAndPatterns(parent) : undefined;
            if (declaration) {
                return parent.name !== node ? undefined :
                    ts.isCatchClause(declaration.parent) ? undefined : ts.isVariableStatement(declaration.parent.parent) ? declaration.parent.parent : undefined;
            }
            else {
                return parent;
            }
        }
        function isNodeImport(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    return parent.name === node && isExternalModuleImportEquals(parent);
                case 258 /* ImportSpecifier */:
                    // For a rename import `{ foo as bar }`, don't search for the imported symbol. Just find local uses of `bar`.
                    return !parent.propertyName;
                case 255 /* ImportClause */:
                case 256 /* NamespaceImport */:
                    ts.Debug.assert(parent.name === node);
                    return true;
                default:
                    return false;
            }
        }
        function getExportInfo(exportSymbol, exportKind, checker) {
            var moduleSymbol = exportSymbol.parent;
            if (!moduleSymbol)
                return undefined; // This can happen if an `export` is not at the top-level (which is a compile error).
            var exportingModuleSymbol = checker.getMergedSymbol(moduleSymbol); // Need to get merged symbol in case there's an augmentation.
            // `export` may appear in a namespace. In that case, just rely on global search.
            return ts.isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } : undefined;
        }
        FindAllReferences.getExportInfo = getExportInfo;
        /** If at an export specifier, go to the symbol it refers to. */
        function skipExportSpecifierSymbol(symbol, checker) {
            // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does.
            if (symbol.declarations) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (ts.isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) {
                        return checker.getExportSpecifierLocalTargetSymbol(declaration);
                    }
                }
            }
            return symbol;
        }
        function getContainingModuleSymbol(importer, checker) {
            return checker.getMergedSymbol(getSourceFileLikeForImportDeclaration(importer).symbol);
        }
        function getSourceFileLikeForImportDeclaration(node) {
            if (node.kind === 196 /* CallExpression */) {
                return node.getSourceFile();
            }
            var parent = node.parent;
            if (parent.kind === 290 /* SourceFile */) {
                return parent;
            }
            ts.Debug.assert(parent.kind === 250 /* ModuleBlock */);
            return ts.cast(parent.parent, isAmbientModuleDeclaration);
        }
        function isAmbientModuleDeclaration(node) {
            return node.kind === 249 /* ModuleDeclaration */ && node.name.kind === 10 /* StringLiteral */;
        }
        function isExternalModuleImportEquals(eq) {
            return eq.moduleReference.kind === 265 /* ExternalModuleReference */ && eq.moduleReference.expression.kind === 10 /* StringLiteral */;
        }
    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var FindAllReferences;
    (function (FindAllReferences) {
        var DefinitionKind;
        (function (DefinitionKind) {
            DefinitionKind[DefinitionKind["Symbol"] = 0] = "Symbol";
            DefinitionKind[DefinitionKind["Label"] = 1] = "Label";
            DefinitionKind[DefinitionKind["Keyword"] = 2] = "Keyword";
            DefinitionKind[DefinitionKind["This"] = 3] = "This";
            DefinitionKind[DefinitionKind["String"] = 4] = "String";
        })(DefinitionKind = FindAllReferences.DefinitionKind || (FindAllReferences.DefinitionKind = {}));
        var EntryKind;
        (function (EntryKind) {
            EntryKind[EntryKind["Span"] = 0] = "Span";
            EntryKind[EntryKind["Node"] = 1] = "Node";
            EntryKind[EntryKind["StringLiteral"] = 2] = "StringLiteral";
            EntryKind[EntryKind["SearchedLocalFoundProperty"] = 3] = "SearchedLocalFoundProperty";
            EntryKind[EntryKind["SearchedPropertyFoundLocal"] = 4] = "SearchedPropertyFoundLocal";
        })(EntryKind = FindAllReferences.EntryKind || (FindAllReferences.EntryKind = {}));
        function nodeEntry(node, kind) {
            if (kind === void 0) { kind = 1 /* Node */; }
            return {
                kind: kind,
                node: node.name || node,
                context: getContextNodeForNodeEntry(node)
            };
        }
        FindAllReferences.nodeEntry = nodeEntry;
        function isContextWithStartAndEndNode(node) {
            return node && node.kind === undefined;
        }
        FindAllReferences.isContextWithStartAndEndNode = isContextWithStartAndEndNode;
        function getContextNodeForNodeEntry(node) {
            if (ts.isDeclaration(node)) {
                return getContextNode(node);
            }
            if (!node.parent)
                return undefined;
            if (!ts.isDeclaration(node.parent) && !ts.isExportAssignment(node.parent)) {
                // Special property assignment in javascript
                if (ts.isInJSFile(node)) {
                    var binaryExpression = ts.isBinaryExpression(node.parent) ?
                        node.parent :
                        ts.isAccessExpression(node.parent) &&
                            ts.isBinaryExpression(node.parent.parent) &&
                            node.parent.parent.left === node.parent ?
                            node.parent.parent :
                            undefined;
                    if (binaryExpression && ts.getAssignmentDeclarationKind(binaryExpression) !== 0 /* None */) {
                        return getContextNode(binaryExpression);
                    }
                }
                // Jsx Tags
                if (ts.isJsxOpeningElement(node.parent) || ts.isJsxClosingElement(node.parent)) {
                    return node.parent.parent;
                }
                else if (ts.isJsxSelfClosingElement(node.parent) ||
                    ts.isLabeledStatement(node.parent) ||
                    ts.isBreakOrContinueStatement(node.parent)) {
                    return node.parent;
                }
                else if (ts.isStringLiteralLike(node)) {
                    var validImport = ts.tryGetImportFromModuleSpecifier(node);
                    if (validImport) {
                        var declOrStatement = ts.findAncestor(validImport, function (node) {
                            return ts.isDeclaration(node) ||
                                ts.isStatement(node) ||
                                ts.isJSDocTag(node);
                        });
                        return ts.isDeclaration(declOrStatement) ?
                            getContextNode(declOrStatement) :
                            declOrStatement;
                    }
                }
                // Handle computed property name
                var propertyName = ts.findAncestor(node, ts.isComputedPropertyName);
                return propertyName ?
                    getContextNode(propertyName.parent) :
                    undefined;
            }
            if (node.parent.name === node || // node is name of declaration, use parent
                ts.isConstructorDeclaration(node.parent) ||
                ts.isExportAssignment(node.parent) ||
                // Property name of the import export specifier or binding pattern, use parent
                ((ts.isImportOrExportSpecifier(node.parent) || ts.isBindingElement(node.parent))
                    && node.parent.propertyName === node) ||
                // Is default export
                (node.kind === 84 /* DefaultKeyword */ && ts.hasModifier(node.parent, 513 /* ExportDefault */))) {
                return getContextNode(node.parent);
            }
            return undefined;
        }
        function getContextNode(node) {
            if (!node)
                return undefined;
            switch (node.kind) {
                case 242 /* VariableDeclaration */:
                    return !ts.isVariableDeclarationList(node.parent) || node.parent.declarations.length !== 1 ?
                        node :
                        ts.isVariableStatement(node.parent.parent) ?
                            node.parent.parent :
                            ts.isForInOrOfStatement(node.parent.parent) ?
                                getContextNode(node.parent.parent) :
                                node.parent;
                case 191 /* BindingElement */:
                    return getContextNode(node.parent.parent);
                case 258 /* ImportSpecifier */:
                    return node.parent.parent.parent;
                case 263 /* ExportSpecifier */:
                case 256 /* NamespaceImport */:
                    return node.parent.parent;
                case 255 /* ImportClause */:
                    return node.parent;
                case 209 /* BinaryExpression */:
                    return ts.isExpressionStatement(node.parent) ?
                        node.parent :
                        node;
                case 232 /* ForOfStatement */:
                case 231 /* ForInStatement */:
                    return {
                        start: node.initializer,
                        end: node.expression
                    };
                case 281 /* PropertyAssignment */:
                case 282 /* ShorthandPropertyAssignment */:
                    return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent) ?
                        getContextNode(ts.findAncestor(node.parent, function (node) {
                            return ts.isBinaryExpression(node) || ts.isForInOrOfStatement(node);
                        })) :
                        node;
                default:
                    return node;
            }
        }
        FindAllReferences.getContextNode = getContextNode;
        function toContextSpan(textSpan, sourceFile, context) {
            if (!context)
                return undefined;
            var contextSpan = isContextWithStartAndEndNode(context) ?
                getTextSpan(context.start, sourceFile, context.end) :
                getTextSpan(context, sourceFile);
            return contextSpan.start !== textSpan.start || contextSpan.length !== textSpan.length ?
                { contextSpan: contextSpan } :
                undefined;
        }
        FindAllReferences.toContextSpan = toContextSpan;
        var FindReferencesUse;
        (function (FindReferencesUse) {
            /**
             * When searching for references to a symbol, the location will not be adjusted (this is the default behavior when not specified).
             */
            FindReferencesUse[FindReferencesUse["Other"] = 0] = "Other";
            /**
             * When searching for references to a symbol, the location will be adjusted if the cursor was on a keyword.
             */
            FindReferencesUse[FindReferencesUse["References"] = 1] = "References";
            /**
             * When searching for references to a symbol, the location will be adjusted if the cursor was on a keyword.
             * Unlike `References`, the location will only be adjusted keyword belonged to a declaration with a valid name.
             * If set, we will find fewer references -- if it is referenced by several different names, we still only find references for the original name.
             */
            FindReferencesUse[FindReferencesUse["Rename"] = 2] = "Rename";
        })(FindReferencesUse = FindAllReferences.FindReferencesUse || (FindAllReferences.FindReferencesUse = {}));
        function findReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            var referencedSymbols = Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, { use: 1 /* References */ });
            var checker = program.getTypeChecker();
            return !referencedSymbols || !referencedSymbols.length ? undefined : ts.mapDefined(referencedSymbols, function (_a) {
                var definition = _a.definition, references = _a.references;
                // Only include referenced symbols that have a valid definition.
                return definition && {
                    definition: checker.runWithCancellationToken(cancellationToken, function (checker) { return definitionToReferencedSymbolDefinitionInfo(definition, checker, node); }),
                    references: references.map(toReferenceEntry)
                };
            });
        }
        FindAllReferences.findReferencedSymbols = findReferencedSymbols;
        function getImplementationsAtPosition(program, cancellationToken, sourceFiles, sourceFile, position) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            var referenceEntries;
            var entries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node, position);
            if (node.parent.kind === 194 /* PropertyAccessExpression */
                || node.parent.kind === 191 /* BindingElement */
                || node.parent.kind === 195 /* ElementAccessExpression */
                || node.kind === 102 /* SuperKeyword */) {
                referenceEntries = entries && __spreadArrays(entries);
            }
            else {
                var queue = entries && __spreadArrays(entries);
                var seenNodes = ts.createMap();
                while (queue && queue.length) {
                    var entry = queue.shift();
                    if (!ts.addToSeen(seenNodes, ts.getNodeId(entry.node))) {
                        continue;
                    }
                    referenceEntries = ts.append(referenceEntries, entry);
                    var entries_1 = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, entry.node, entry.node.pos);
                    if (entries_1) {
                        queue.push.apply(queue, entries_1);
                    }
                }
            }
            var checker = program.getTypeChecker();
            return ts.map(referenceEntries, function (entry) { return toImplementationLocation(entry, checker); });
        }
        FindAllReferences.getImplementationsAtPosition = getImplementationsAtPosition;
        function getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node, position) {
            if (node.kind === 290 /* SourceFile */) {
                return undefined;
            }
            var checker = program.getTypeChecker();
            // If invoked directly on a shorthand property assignment, then return
            // the declaration of the symbol being assigned (not the symbol being assigned to).
            if (node.parent.kind === 282 /* ShorthandPropertyAssignment */) {
                var result_1 = [];
                Core.getReferenceEntriesForShorthandPropertyAssignment(node, checker, function (node) { return result_1.push(nodeEntry(node)); });
                return result_1;
            }
            else if (node.kind === 102 /* SuperKeyword */ || ts.isSuperProperty(node.parent)) {
                // References to and accesses on the super keyword only have one possible implementation, so no
                // need to "Find all References"
                var symbol = checker.getSymbolAtLocation(node);
                return symbol.valueDeclaration && [nodeEntry(symbol.valueDeclaration)];
            }
            else {
                // Perform "Find all References" and retrieve only those that are implementations
                return getReferenceEntriesForNode(position, node, program, sourceFiles, cancellationToken, { implementations: true, use: 1 /* References */ });
            }
        }
        function findReferenceOrRenameEntries(program, cancellationToken, sourceFiles, node, position, options, convertEntry) {
            return ts.map(flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), function (entry) { return convertEntry(entry, node, program.getTypeChecker()); });
        }
        FindAllReferences.findReferenceOrRenameEntries = findReferenceOrRenameEntries;
        function getReferenceEntriesForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet) {
            if (options === void 0) { options = {}; }
            if (sourceFilesSet === void 0) { sourceFilesSet = ts.arrayToSet(sourceFiles, function (f) { return f.fileName; }); }
            return flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet));
        }
        FindAllReferences.getReferenceEntriesForNode = getReferenceEntriesForNode;
        function flattenEntries(referenceSymbols) {
            return referenceSymbols && ts.flatMap(referenceSymbols, function (r) { return r.references; });
        }
        function definitionToReferencedSymbolDefinitionInfo(def, checker, originalNode) {
            var info = (function () {
                switch (def.type) {
                    case 0 /* Symbol */: {
                        var symbol = def.symbol;
                        var _a = getDefinitionKindAndDisplayParts(symbol, checker, originalNode), displayParts_1 = _a.displayParts, kind_1 = _a.kind;
                        var name_1 = displayParts_1.map(function (p) { return p.text; }).join("");
                        var declaration = symbol.declarations ? ts.first(symbol.declarations) : undefined;
                        return {
                            node: declaration ?
                                ts.getNameOfDeclaration(declaration) || declaration :
                                originalNode,
                            name: name_1,
                            kind: kind_1,
                            displayParts: displayParts_1,
                            context: getContextNode(declaration)
                        };
                    }
                    case 1 /* Label */: {
                        var node_1 = def.node;
                        return { node: node_1, name: node_1.text, kind: "label" /* label */, displayParts: [ts.displayPart(node_1.text, ts.SymbolDisplayPartKind.text)] };
                    }
                    case 2 /* Keyword */: {
                        var node_2 = def.node;
                        var name_2 = ts.tokenToString(node_2.kind);
                        return { node: node_2, name: name_2, kind: "keyword" /* keyword */, displayParts: [{ text: name_2, kind: "keyword" /* keyword */ }] };
                    }
                    case 3 /* This */: {
                        var node_3 = def.node;
                        var symbol = checker.getSymbolAtLocation(node_3);
                        var displayParts_2 = symbol && ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node_3.getSourceFile(), ts.getContainerNode(node_3), node_3).displayParts || [ts.textPart("this")];
                        return { node: node_3, name: "this", kind: "var" /* variableElement */, displayParts: displayParts_2 };
                    }
                    case 4 /* String */: {
                        var node_4 = def.node;
                        return { node: node_4, name: node_4.text, kind: "var" /* variableElement */, displayParts: [ts.displayPart(ts.getTextOfNode(node_4), ts.SymbolDisplayPartKind.stringLiteral)] };
                    }
                    default:
                        return ts.Debug.assertNever(def);
                }
            })();
            var node = info.node, name = info.name, kind = info.kind, displayParts = info.displayParts, context = info.context;
            var sourceFile = node.getSourceFile();
            var textSpan = getTextSpan(ts.isComputedPropertyName(node) ? node.expression : node, sourceFile);
            return __assign({ containerKind: "" /* unknown */, containerName: "", fileName: sourceFile.fileName, kind: kind,
                name: name,
                textSpan: textSpan,
                displayParts: displayParts }, toContextSpan(textSpan, sourceFile, context));
        }
        function getDefinitionKindAndDisplayParts(symbol, checker, node) {
            var meaning = Core.getIntersectingMeaningFromDeclarations(node, symbol);
            var enclosingDeclaration = symbol.declarations && ts.firstOrUndefined(symbol.declarations) || node;
            var _a = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, enclosingDeclaration.getSourceFile(), enclosingDeclaration, enclosingDeclaration, meaning), displayParts = _a.displayParts, symbolKind = _a.symbolKind;
            return { displayParts: displayParts, kind: symbolKind };
        }
        function toRenameLocation(entry, originalNode, checker, providePrefixAndSuffixText) {
            return __assign(__assign({}, entryToDocumentSpan(entry)), (providePrefixAndSuffixText && getPrefixAndSuffixText(entry, originalNode, checker)));
        }
        FindAllReferences.toRenameLocation = toRenameLocation;
        function toReferenceEntry(entry) {
            var documentSpan = entryToDocumentSpan(entry);
            if (entry.kind === 0 /* Span */) {
                return __assign(__assign({}, documentSpan), { isWriteAccess: false, isDefinition: false });
            }
            var kind = entry.kind, node = entry.node;
            return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: isDefinitionForReference(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined });
        }
        FindAllReferences.toReferenceEntry = toReferenceEntry;
        function entryToDocumentSpan(entry) {
            if (entry.kind === 0 /* Span */) {
                return { textSpan: entry.textSpan, fileName: entry.fileName };
            }
            else {
                var sourceFile = entry.node.getSourceFile();
                var textSpan = getTextSpan(entry.node, sourceFile);
                return __assign({ textSpan: textSpan, fileName: sourceFile.fileName }, toContextSpan(textSpan, sourceFile, entry.context));
            }
        }
        function getPrefixAndSuffixText(entry, originalNode, checker) {
            if (entry.kind !== 0 /* Span */ && ts.isIdentifier(originalNode)) {
                var node = entry.node, kind = entry.kind;
                var name = originalNode.text;
                var isShorthandAssignment = ts.isShorthandPropertyAssignment(node.parent);
                if (isShorthandAssignment || ts.isObjectBindingElementWithoutPropertyName(node.parent) && node.parent.name === node) {
                    var prefixColon = { prefixText: name + ": " };
                    var suffixColon = { suffixText: ": " + name };
                    return kind === 3 /* SearchedLocalFoundProperty */ ? prefixColon
                        : kind === 4 /* SearchedPropertyFoundLocal */ ? suffixColon
                            // In `const o = { x }; o.x`, symbolAtLocation at `x` in `{ x }` is the property symbol.
                            // For a binding element `const { x } = o;`, symbolAtLocation at `x` is the property symbol.
                            : isShorthandAssignment ? suffixColon : prefixColon;
                }
                else if (ts.isImportSpecifier(entry.node.parent) && !entry.node.parent.propertyName) {
                    // If the original symbol was using this alias, just rename the alias.
                    var originalSymbol = ts.isExportSpecifier(originalNode.parent) ? checker.getExportSpecifierLocalTargetSymbol(originalNode.parent) : checker.getSymbolAtLocation(originalNode);
                    return ts.contains(originalSymbol.declarations, entry.node.parent) ? { prefixText: name + " as " } : ts.emptyOptions;
                }
                else if (ts.isExportSpecifier(entry.node.parent) && !entry.node.parent.propertyName) {
                    // If the symbol for the node is same as declared node symbol use prefix text
                    return originalNode === entry.node || checker.getSymbolAtLocation(originalNode) === checker.getSymbolAtLocation(entry.node) ?
                        { prefixText: name + " as " } :
                        { suffixText: " as " + name };
                }
            }
            return ts.emptyOptions;
        }
        function toImplementationLocation(entry, checker) {
            var documentSpan = entryToDocumentSpan(entry);
            if (entry.kind !== 0 /* Span */) {
                var node = entry.node;
                return __assign(__assign({}, documentSpan), implementationKindDisplayParts(node, checker));
            }
            else {
                return __assign(__assign({}, documentSpan), { kind: "" /* unknown */, displayParts: [] });
            }
        }
        function implementationKindDisplayParts(node, checker) {
            var symbol = checker.getSymbolAtLocation(ts.isDeclaration(node) && node.name ? node.name : node);
            if (symbol) {
                return getDefinitionKindAndDisplayParts(symbol, checker, node);
            }
            else if (node.kind === 193 /* ObjectLiteralExpression */) {
                return {
                    kind: "interface" /* interfaceElement */,
                    displayParts: [ts.punctuationPart(20 /* OpenParenToken */), ts.textPart("object literal"), ts.punctuationPart(21 /* CloseParenToken */)]
                };
            }
            else if (node.kind === 214 /* ClassExpression */) {
                return {
                    kind: "local class" /* localClassElement */,
                    displayParts: [ts.punctuationPart(20 /* OpenParenToken */), ts.textPart("anonymous local class"), ts.punctuationPart(21 /* CloseParenToken */)]
                };
            }
            else {
                return { kind: ts.getNodeKind(node), displayParts: [] };
            }
        }
        function toHighlightSpan(entry) {
            var documentSpan = entryToDocumentSpan(entry);
            if (entry.kind === 0 /* Span */) {
                return {
                    fileName: documentSpan.fileName,
                    span: {
                        textSpan: documentSpan.textSpan,
                        kind: "reference" /* reference */
                    }
                };
            }
            var writeAccess = isWriteAccessForReference(entry.node);
            var span = __assign({ textSpan: documentSpan.textSpan, kind: writeAccess ? "writtenReference" /* writtenReference */ : "reference" /* reference */, isInString: entry.kind === 2 /* StringLiteral */ ? true : undefined }, documentSpan.contextSpan && { contextSpan: documentSpan.contextSpan });
            return { fileName: documentSpan.fileName, span: span };
        }
        FindAllReferences.toHighlightSpan = toHighlightSpan;
        function getTextSpan(node, sourceFile, endNode) {
            var start = node.getStart(sourceFile);
            var end = (endNode || node).getEnd();
            if (ts.isStringLiteralLike(node)) {
                ts.Debug.assert(endNode === undefined);
                start += 1;
                end -= 1;
            }
            return ts.createTextSpanFromBounds(start, end);
        }
        function getTextSpanOfEntry(entry) {
            return entry.kind === 0 /* Span */ ? entry.textSpan :
                getTextSpan(entry.node, entry.node.getSourceFile());
        }
        FindAllReferences.getTextSpanOfEntry = getTextSpanOfEntry;
        /** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */
        function isWriteAccessForReference(node) {
            var decl = ts.getDeclarationFromName(node);
            return !!decl && declarationIsWriteAccess(decl) || node.kind === 84 /* DefaultKeyword */ || ts.isWriteAccess(node);
        }
        function isDefinitionForReference(node) {
            return node.kind === 84 /* DefaultKeyword */
                || !!ts.getDeclarationFromName(node)
                || ts.isLiteralComputedPropertyDeclarationName(node)
                || (node.kind === 129 /* ConstructorKeyword */ && ts.isConstructorDeclaration(node.parent));
        }
        /**
         * True if 'decl' provides a value, as in `function f() {}`;
         * false if 'decl' is just a location for a future write, as in 'let x;'
         */
        function declarationIsWriteAccess(decl) {
            // Consider anything in an ambient declaration to be a write access since it may be coming from JS.
            if (!!(decl.flags & 8388608 /* Ambient */))
                return true;
            switch (decl.kind) {
                case 209 /* BinaryExpression */:
                case 191 /* BindingElement */:
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                case 84 /* DefaultKeyword */:
                case 248 /* EnumDeclaration */:
                case 284 /* EnumMember */:
                case 263 /* ExportSpecifier */:
                case 255 /* ImportClause */: // default import
                case 253 /* ImportEqualsDeclaration */:
                case 258 /* ImportSpecifier */:
                case 246 /* InterfaceDeclaration */:
                case 315 /* JSDocCallbackTag */:
                case 322 /* JSDocTypedefTag */:
                case 273 /* JsxAttribute */:
                case 249 /* ModuleDeclaration */:
                case 252 /* NamespaceExportDeclaration */:
                case 256 /* NamespaceImport */:
                case 262 /* NamespaceExport */:
                case 156 /* Parameter */:
                case 282 /* ShorthandPropertyAssignment */:
                case 247 /* TypeAliasDeclaration */:
                case 155 /* TypeParameter */:
                    return true;
                case 281 /* PropertyAssignment */:
                    // In `({ x: y } = 0);`, `x` is not a write access. (Won't call this function for `y`.)
                    return !ts.isArrayLiteralOrObjectLiteralDestructuringPattern(decl.parent);
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 162 /* Constructor */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return !!decl.body;
                case 242 /* VariableDeclaration */:
                case 159 /* PropertyDeclaration */:
                    return !!decl.initializer || ts.isCatchClause(decl.parent);
                case 160 /* MethodSignature */:
                case 158 /* PropertySignature */:
                case 323 /* JSDocPropertyTag */:
                case 317 /* JSDocParameterTag */:
                    return false;
                default:
                    return ts.Debug.failBadSyntaxKind(decl);
            }
        }
        /** Encapsulates the core find-all-references algorithm. */
        var Core;
        (function (Core) {
            /** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */
            function getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet) {
                if (options === void 0) { options = {}; }
                if (sourceFilesSet === void 0) { sourceFilesSet = ts.arrayToSet(sourceFiles, function (f) { return f.fileName; }); }
                if (options.use === 1 /* References */) {
                    node = ts.getAdjustedReferenceLocation(node);
                }
                else if (options.use === 2 /* Rename */) {
                    node = ts.getAdjustedRenameLocation(node);
                }
                if (ts.isSourceFile(node)) {
                    var reference = ts.GoToDefinition.getReferenceAtPosition(node, position, program);
                    var moduleSymbol = reference && program.getTypeChecker().getMergedSymbol(reference.file.symbol);
                    return moduleSymbol && getReferencedSymbolsForModule(program, moduleSymbol, /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet);
                }
                if (!options.implementations) {
                    var special = getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken);
                    if (special) {
                        return special;
                    }
                }
                var checker = program.getTypeChecker();
                var symbol = checker.getSymbolAtLocation(node);
                // Could not find a symbol e.g. unknown identifier
                if (!symbol) {
                    // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial.
                    return !options.implementations && ts.isStringLiteral(node) ? getReferencesForStringLiteral(node, sourceFiles, cancellationToken) : undefined;
                }
                if (symbol.escapedName === "export=" /* ExportEquals */) {
                    return getReferencedSymbolsForModule(program, symbol.parent, /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet);
                }
                var moduleReferences = getReferencedSymbolsForModuleIfDeclaredBySourceFile(symbol, program, sourceFiles, cancellationToken, options, sourceFilesSet);
                if (moduleReferences && !(symbol.flags & 33554432 /* Transient */)) {
                    return moduleReferences;
                }
                var aliasedSymbol = getMergedAliasedSymbolOfNamespaceExportDeclaration(node, symbol, checker);
                var moduleReferencesOfExportTarget = aliasedSymbol &&
                    getReferencedSymbolsForModuleIfDeclaredBySourceFile(aliasedSymbol, program, sourceFiles, cancellationToken, options, sourceFilesSet);
                var references = getReferencedSymbolsForSymbol(symbol, node, sourceFiles, sourceFilesSet, checker, cancellationToken, options);
                return mergeReferences(program, moduleReferences, references, moduleReferencesOfExportTarget);
            }
            Core.getReferencedSymbolsForNode = getReferencedSymbolsForNode;
            function getMergedAliasedSymbolOfNamespaceExportDeclaration(node, symbol, checker) {
                if (node.parent && ts.isNamespaceExportDeclaration(node.parent)) {
                    var aliasedSymbol = checker.getAliasedSymbol(symbol);
                    var targetSymbol = checker.getMergedSymbol(aliasedSymbol);
                    if (aliasedSymbol !== targetSymbol) {
                        return targetSymbol;
                    }
                }
                return undefined;
            }
            function getReferencedSymbolsForModuleIfDeclaredBySourceFile(symbol, program, sourceFiles, cancellationToken, options, sourceFilesSet) {
                var moduleSourceFile = (symbol.flags & 1536 /* Module */) && symbol.declarations && ts.find(symbol.declarations, ts.isSourceFile);
                if (!moduleSourceFile)
                    return undefined;
                var exportEquals = symbol.exports.get("export=" /* ExportEquals */);
                // If !!exportEquals, we're about to add references to `import("mod")` anyway, so don't double-count them.
                var moduleReferences = getReferencedSymbolsForModule(program, symbol, !!exportEquals, sourceFiles, sourceFilesSet);
                if (!exportEquals || !sourceFilesSet.has(moduleSourceFile.fileName))
                    return moduleReferences;
                // Continue to get references to 'export ='.
                var checker = program.getTypeChecker();
                symbol = ts.skipAlias(exportEquals, checker);
                return mergeReferences(program, moduleReferences, getReferencedSymbolsForSymbol(symbol, /*node*/ undefined, sourceFiles, sourceFilesSet, checker, cancellationToken, options));
            }
            /**
             * Merges the references by sorting them (by file index in sourceFiles and their location in it) that point to same definition symbol
             */
            function mergeReferences(program) {
                var referencesToMerge = [];
                for (var _i = 1; _i < arguments.length; _i++) {
                    referencesToMerge[_i - 1] = arguments[_i];
                }
                var result;
                for (var _a = 0, referencesToMerge_1 = referencesToMerge; _a < referencesToMerge_1.length; _a++) {
                    var references = referencesToMerge_1[_a];
                    if (!references || !references.length)
                        continue;
                    if (!result) {
                        result = references;
                        continue;
                    }
                    var _loop_3 = function (entry) {
                        if (!entry.definition || entry.definition.type !== 0 /* Symbol */) {
                            result.push(entry);
                            return "continue";
                        }
                        var symbol = entry.definition.symbol;
                        var refIndex = ts.findIndex(result, function (ref) { return !!ref.definition &&
                            ref.definition.type === 0 /* Symbol */ &&
                            ref.definition.symbol === symbol; });
                        if (refIndex === -1) {
                            result.push(entry);
                            return "continue";
                        }
                        var reference = result[refIndex];
                        result[refIndex] = {
                            definition: reference.definition,
                            references: reference.references.concat(entry.references).sort(function (entry1, entry2) {
                                var entry1File = getSourceFileIndexOfEntry(program, entry1);
                                var entry2File = getSourceFileIndexOfEntry(program, entry2);
                                if (entry1File !== entry2File) {
                                    return ts.compareValues(entry1File, entry2File);
                                }
                                var entry1Span = getTextSpanOfEntry(entry1);
                                var entry2Span = getTextSpanOfEntry(entry2);
                                return entry1Span.start !== entry2Span.start ?
                                    ts.compareValues(entry1Span.start, entry2Span.start) :
                                    ts.compareValues(entry1Span.length, entry2Span.length);
                            })
                        };
                    };
                    for (var _b = 0, references_1 = references; _b < references_1.length; _b++) {
                        var entry = references_1[_b];
                        _loop_3(entry);
                    }
                }
                return result;
            }
            function getSourceFileIndexOfEntry(program, entry) {
                var sourceFile = entry.kind === 0 /* Span */ ?
                    program.getSourceFile(entry.fileName) :
                    entry.node.getSourceFile();
                return program.getSourceFiles().indexOf(sourceFile);
            }
            function getReferencedSymbolsForModule(program, symbol, excludeImportTypeOfExportEquals, sourceFiles, sourceFilesSet) {
                ts.Debug.assert(!!symbol.valueDeclaration);
                var references = ts.mapDefined(FindAllReferences.findModuleReferences(program, sourceFiles, symbol), function (reference) {
                    if (reference.kind === "import") {
                        var parent = reference.literal.parent;
                        if (ts.isLiteralTypeNode(parent)) {
                            var importType = ts.cast(parent.parent, ts.isImportTypeNode);
                            if (excludeImportTypeOfExportEquals && !importType.qualifier) {
                                return undefined;
                            }
                        }
                        // import("foo") with no qualifier will reference the `export =` of the module, which may be referenced anyway.
                        return nodeEntry(reference.literal);
                    }
                    else {
                        return {
                            kind: 0 /* Span */,
                            fileName: reference.referencingFile.fileName,
                            textSpan: ts.createTextSpanFromRange(reference.ref),
                        };
                    }
                });
                if (symbol.declarations) {
                    for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        switch (decl.kind) {
                            case 290 /* SourceFile */:
                                // Don't include the source file itself. (This may not be ideal behavior, but awkward to include an entire file as a reference.)
                                break;
                            case 249 /* ModuleDeclaration */:
                                if (sourceFilesSet.has(decl.getSourceFile().fileName)) {
                                    references.push(nodeEntry(decl.name));
                                }
                                break;
                            default:
                                // This may be merged with something.
                                ts.Debug.assert(!!(symbol.flags & 33554432 /* Transient */), "Expected a module symbol to be declared by a SourceFile or ModuleDeclaration.");
                        }
                    }
                }
                var exported = symbol.exports.get("export=" /* ExportEquals */);
                if (exported) {
                    for (var _b = 0, _c = exported.declarations; _b < _c.length; _b++) {
                        var decl = _c[_b];
                        var sourceFile = decl.getSourceFile();
                        if (sourceFilesSet.has(sourceFile.fileName)) {
                            // At `module.exports = ...`, reference node is `module`
                            var node = ts.isBinaryExpression(decl) && ts.isPropertyAccessExpression(decl.left) ? decl.left.expression :
                                ts.isExportAssignment(decl) ? ts.Debug.checkDefined(ts.findChildOfKind(decl, 89 /* ExportKeyword */, sourceFile)) :
                                    ts.getNameOfDeclaration(decl) || decl;
                            references.push(nodeEntry(node));
                        }
                    }
                }
                return references.length ? [{ definition: { type: 0 /* Symbol */, symbol: symbol }, references: references }] : ts.emptyArray;
            }
            /** As in a `readonly prop: any` or `constructor(readonly prop: any)`, not a `readonly any[]`. */
            function isReadonlyTypeOperator(node) {
                return node.kind === 138 /* ReadonlyKeyword */
                    && ts.isTypeOperatorNode(node.parent)
                    && node.parent.operator === 138 /* ReadonlyKeyword */;
            }
            /** getReferencedSymbols for special node kinds. */
            function getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken) {
                if (ts.isTypeKeyword(node.kind)) {
                    // A void expression (i.e., `void foo()`) is not special, but the `void` type is.
                    if (node.kind === 110 /* VoidKeyword */ && ts.isVoidExpression(node.parent)) {
                        return undefined;
                    }
                    // A modifier readonly (like on a property declaration) is not special;
                    // a readonly type keyword (like `readonly string[]`) is.
                    if (node.kind === 138 /* ReadonlyKeyword */ && !isReadonlyTypeOperator(node)) {
                        return undefined;
                    }
                    // Likewise, when we *are* looking for a special keyword, make sure we
                    // *don’t* include readonly member modifiers.
                    return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken, node.kind === 138 /* ReadonlyKeyword */ ? isReadonlyTypeOperator : undefined);
                }
                // Labels
                if (ts.isJumpStatementTarget(node)) {
                    var labelDefinition = ts.getTargetLabel(node.parent, node.text);
                    // if we have a label definition, look within its statement for references, if not, then
                    // the label is undefined and we have no results..
                    return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition);
                }
                else if (ts.isLabelOfLabeledStatement(node)) {
                    // it is a label definition and not a target, search within the parent labeledStatement
                    return getLabelReferencesInNode(node.parent, node);
                }
                if (ts.isThis(node)) {
                    return getReferencesForThisKeyword(node, sourceFiles, cancellationToken);
                }
                if (node.kind === 102 /* SuperKeyword */) {
                    return getReferencesForSuperKeyword(node);
                }
                return undefined;
            }
            /** Core find-all-references algorithm for a normal symbol. */
            function getReferencedSymbolsForSymbol(originalSymbol, node, sourceFiles, sourceFilesSet, checker, cancellationToken, options) {
                var symbol = node && skipPastExportOrImportSpecifierOrUnion(originalSymbol, node, checker, /*useLocalSymbolForExportSpecifier*/ !isForRenameWithPrefixAndSuffixText(options)) || originalSymbol;
                // Compute the meaning from the location and the symbol it references
                var searchMeaning = node ? getIntersectingMeaningFromDeclarations(node, symbol) : 7 /* All */;
                var result = [];
                var state = new State(sourceFiles, sourceFilesSet, node ? getSpecialSearchKind(node) : 0 /* None */, checker, cancellationToken, searchMeaning, options, result);
                var exportSpecifier = !isForRenameWithPrefixAndSuffixText(options) ? undefined : ts.find(symbol.declarations, ts.isExportSpecifier);
                if (exportSpecifier) {
                    // When renaming at an export specifier, rename the export and not the thing being exported.
                    getReferencesAtExportSpecifier(exportSpecifier.name, symbol, exportSpecifier, state.createSearch(node, originalSymbol, /*comingFrom*/ undefined), state, /*addReferencesHere*/ true, /*alwaysGetReferences*/ true);
                }
                else if (node && node.kind === 84 /* DefaultKeyword */) {
                    addReference(node, symbol, state);
                    searchForImportsOfExport(node, symbol, { exportingModuleSymbol: ts.Debug.checkDefined(symbol.parent, "Expected export symbol to have a parent"), exportKind: 1 /* Default */ }, state);
                }
                else {
                    var search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: node ? populateSearchSymbolSet(symbol, node, checker, options.use === 2 /* Rename */, !!options.providePrefixAndSuffixTextForRename, !!options.implementations) : [symbol] });
                    getReferencesInContainerOrFiles(symbol, state, search);
                }
                return result;
            }
            function getReferencesInContainerOrFiles(symbol, state, search) {
                // Try to get the smallest valid scope that we can limit our search to;
                // otherwise we'll need to search globally (i.e. include each file).
                var scope = getSymbolScope(symbol);
                if (scope) {
                    getReferencesInContainer(scope, scope.getSourceFile(), search, state, /*addReferencesHere*/ !(ts.isSourceFile(scope) && !ts.contains(state.sourceFiles, scope)));
                }
                else {
                    // Global search
                    for (var _i = 0, _a = state.sourceFiles; _i < _a.length; _i++) {
                        var sourceFile = _a[_i];
                        state.cancellationToken.throwIfCancellationRequested();
                        searchForName(sourceFile, search, state);
                    }
                }
            }
            function getSpecialSearchKind(node) {
                switch (node.kind) {
                    case 129 /* ConstructorKeyword */:
                        return 1 /* Constructor */;
                    case 75 /* Identifier */:
                        if (ts.isClassLike(node.parent)) {
                            ts.Debug.assert(node.parent.name === node);
                            return 2 /* Class */;
                        }
                    // falls through
                    default:
                        return 0 /* None */;
                }
            }
            /** Handle a few special cases relating to export/import specifiers. */
            function skipPastExportOrImportSpecifierOrUnion(symbol, node, checker, useLocalSymbolForExportSpecifier) {
                var parent = node.parent;
                if (ts.isExportSpecifier(parent) && useLocalSymbolForExportSpecifier) {
                    return getLocalSymbolForExportSpecifier(node, symbol, parent, checker);
                }
                // If the symbol is declared as part of a declaration like `{ type: "a" } | { type: "b" }`, use the property on the union type to get more references.
                return ts.firstDefined(symbol.declarations, function (decl) {
                    if (!decl.parent) {
                        // Ignore UMD module and global merge
                        if (symbol.flags & 33554432 /* Transient */)
                            return undefined;
                        // Assertions for GH#21814. We should be handling SourceFile symbols in `getReferencedSymbolsForModule` instead of getting here.
                        ts.Debug.fail("Unexpected symbol at " + ts.Debug.formatSyntaxKind(node.kind) + ": " + ts.Debug.formatSymbol(symbol));
                    }
                    return ts.isTypeLiteralNode(decl.parent) && ts.isUnionTypeNode(decl.parent.parent)
                        ? checker.getPropertyOfType(checker.getTypeFromTypeNode(decl.parent.parent), symbol.name)
                        : undefined;
                });
            }
            var SpecialSearchKind;
            (function (SpecialSearchKind) {
                SpecialSearchKind[SpecialSearchKind["None"] = 0] = "None";
                SpecialSearchKind[SpecialSearchKind["Constructor"] = 1] = "Constructor";
                SpecialSearchKind[SpecialSearchKind["Class"] = 2] = "Class";
            })(SpecialSearchKind || (SpecialSearchKind = {}));
            function getNonModuleSymbolOfMergedModuleSymbol(symbol) {
                if (!(symbol.flags & (1536 /* Module */ | 33554432 /* Transient */)))
                    return undefined;
                var decl = symbol.declarations && ts.find(symbol.declarations, function (d) { return !ts.isSourceFile(d) && !ts.isModuleDeclaration(d); });
                return decl && decl.symbol;
            }
            /**
             * Holds all state needed for the finding references.
             * Unlike `Search`, there is only one `State`.
             */
            var State = /** @class */ (function () {
                function State(sourceFiles, sourceFilesSet, specialSearchKind, checker, cancellationToken, searchMeaning, options, result) {
                    this.sourceFiles = sourceFiles;
                    this.sourceFilesSet = sourceFilesSet;
                    this.specialSearchKind = specialSearchKind;
                    this.checker = checker;
                    this.cancellationToken = cancellationToken;
                    this.searchMeaning = searchMeaning;
                    this.options = options;
                    this.result = result;
                    /** Cache for `explicitlyinheritsFrom`. */
                    this.inheritsFromCache = ts.createMap();
                    /**
                     * Type nodes can contain multiple references to the same type. For example:
                     *      let x: Foo & (Foo & Bar) = ...
                     * Because we are returning the implementation locations and not the identifier locations,
                     * duplicate entries would be returned here as each of the type references is part of
                     * the same implementation. For that reason, check before we add a new entry.
                     */
                    this.markSeenContainingTypeReference = ts.nodeSeenTracker();
                    /**
                     * It's possible that we will encounter the right side of `export { foo as bar } from "x";` more than once.
                     * For example:
                     *     // b.ts
                     *     export { foo as bar } from "./a";
                     *     import { bar } from "./b";
                     *
                     * Normally at `foo as bar` we directly add `foo` and do not locally search for it (since it doesn't declare a local).
                     * But another reference to it may appear in the same source file.
                     * See `tests/cases/fourslash/transitiveExportImports3.ts`.
                     */
                    this.markSeenReExportRHS = ts.nodeSeenTracker();
                    this.symbolIdToReferences = [];
                    // Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
                    this.sourceFileToSeenSymbols = [];
                }
                State.prototype.includesSourceFile = function (sourceFile) {
                    return this.sourceFilesSet.has(sourceFile.fileName);
                };
                /** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */
                State.prototype.getImportSearches = function (exportSymbol, exportInfo) {
                    if (!this.importTracker)
                        this.importTracker = FindAllReferences.createImportTracker(this.sourceFiles, this.sourceFilesSet, this.checker, this.cancellationToken);
                    return this.importTracker(exportSymbol, exportInfo, this.options.use === 2 /* Rename */);
                };
                /** @param allSearchSymbols set of additional symbols for use by `includes`. */
                State.prototype.createSearch = function (location, symbol, comingFrom, searchOptions) {
                    if (searchOptions === void 0) { searchOptions = {}; }
                    // Note: if this is an external module symbol, the name doesn't include quotes.
                    // Note: getLocalSymbolForExportDefault handles `export default class C {}`, but not `export default C` or `export { C as default }`.
                    // The other two forms seem to be handled downstream (e.g. in `skipPastExportOrImportSpecifier`), so special-casing the first form
                    // here appears to be intentional).
                    var _a = searchOptions.text, text = _a === void 0 ? ts.stripQuotes(ts.symbolName(ts.getLocalSymbolForExportDefault(symbol) || getNonModuleSymbolOfMergedModuleSymbol(symbol) || symbol)) : _a, _b = searchOptions.allSearchSymbols, allSearchSymbols = _b === void 0 ? [symbol] : _b;
                    var escapedText = ts.escapeLeadingUnderscores(text);
                    var parents = this.options.implementations && location ? getParentSymbolsOfPropertyAccess(location, symbol, this.checker) : undefined;
                    return { symbol: symbol, comingFrom: comingFrom, text: text, escapedText: escapedText, parents: parents, allSearchSymbols: allSearchSymbols, includes: function (sym) { return ts.contains(allSearchSymbols, sym); } };
                };
                /**
                 * Callback to add references for a particular searched symbol.
                 * This initializes a reference group, so only call this if you will add at least one reference.
                 */
                State.prototype.referenceAdder = function (searchSymbol) {
                    var symbolId = ts.getSymbolId(searchSymbol);
                    var references = this.symbolIdToReferences[symbolId];
                    if (!references) {
                        references = this.symbolIdToReferences[symbolId] = [];
                        this.result.push({ definition: { type: 0 /* Symbol */, symbol: searchSymbol }, references: references });
                    }
                    return function (node, kind) { return references.push(nodeEntry(node, kind)); };
                };
                /** Add a reference with no associated definition. */
                State.prototype.addStringOrCommentReference = function (fileName, textSpan) {
                    this.result.push({
                        definition: undefined,
                        references: [{ kind: 0 /* Span */, fileName: fileName, textSpan: textSpan }]
                    });
                };
                /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
                State.prototype.markSearchedSymbols = function (sourceFile, symbols) {
                    var sourceId = ts.getNodeId(sourceFile);
                    var seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = ts.createMap());
                    var anyNewSymbols = false;
                    for (var _i = 0, symbols_3 = symbols; _i < symbols_3.length; _i++) {
                        var sym = symbols_3[_i];
                        anyNewSymbols = ts.addToSeen(seenSymbols, ts.getSymbolId(sym)) || anyNewSymbols;
                    }
                    return anyNewSymbols;
                };
                return State;
            }());
            /** Search for all imports of a given exported symbol using `State.getImportSearches`. */
            function searchForImportsOfExport(exportLocation, exportSymbol, exportInfo, state) {
                var _a = state.getImportSearches(exportSymbol, exportInfo), importSearches = _a.importSearches, singleReferences = _a.singleReferences, indirectUsers = _a.indirectUsers;
                // For `import { foo as bar }` just add the reference to `foo`, and don't otherwise search in the file.
                if (singleReferences.length) {
                    var addRef = state.referenceAdder(exportSymbol);
                    for (var _i = 0, singleReferences_1 = singleReferences; _i < singleReferences_1.length; _i++) {
                        var singleRef = singleReferences_1[_i];
                        if (shouldAddSingleReference(singleRef, state))
                            addRef(singleRef);
                    }
                }
                // For each import, find all references to that import in its source file.
                for (var _b = 0, importSearches_1 = importSearches; _b < importSearches_1.length; _b++) {
                    var _c = importSearches_1[_b], importLocation = _c[0], importSymbol = _c[1];
                    getReferencesInSourceFile(importLocation.getSourceFile(), state.createSearch(importLocation, importSymbol, 1 /* Export */), state);
                }
                if (indirectUsers.length) {
                    var indirectSearch = void 0;
                    switch (exportInfo.exportKind) {
                        case 0 /* Named */:
                            indirectSearch = state.createSearch(exportLocation, exportSymbol, 1 /* Export */);
                            break;
                        case 1 /* Default */:
                            // Search for a property access to '.default'. This can't be renamed.
                            indirectSearch = state.options.use === 2 /* Rename */ ? undefined : state.createSearch(exportLocation, exportSymbol, 1 /* Export */, { text: "default" });
                            break;
                        case 2 /* ExportEquals */:
                            break;
                    }
                    if (indirectSearch) {
                        for (var _d = 0, indirectUsers_1 = indirectUsers; _d < indirectUsers_1.length; _d++) {
                            var indirectUser = indirectUsers_1[_d];
                            searchForName(indirectUser, indirectSearch, state);
                        }
                    }
                }
            }
            function eachExportReference(sourceFiles, checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName, isDefaultExport, cb) {
                var importTracker = FindAllReferences.createImportTracker(sourceFiles, ts.arrayToSet(sourceFiles, function (f) { return f.fileName; }), checker, cancellationToken);
                var _a = importTracker(exportSymbol, { exportKind: isDefaultExport ? 1 /* Default */ : 0 /* Named */, exportingModuleSymbol: exportingModuleSymbol }, /*isForRename*/ false), importSearches = _a.importSearches, indirectUsers = _a.indirectUsers;
                for (var _i = 0, importSearches_2 = importSearches; _i < importSearches_2.length; _i++) {
                    var importLocation = importSearches_2[_i][0];
                    cb(importLocation);
                }
                for (var _b = 0, indirectUsers_2 = indirectUsers; _b < indirectUsers_2.length; _b++) {
                    var indirectUser = indirectUsers_2[_b];
                    for (var _c = 0, _d = getPossibleSymbolReferenceNodes(indirectUser, isDefaultExport ? "default" : exportName); _c < _d.length; _c++) {
                        var node = _d[_c];
                        // Import specifiers should be handled by importSearches
                        if (ts.isIdentifier(node) && !ts.isImportOrExportSpecifier(node.parent) && checker.getSymbolAtLocation(node) === exportSymbol) {
                            cb(node);
                        }
                    }
                }
            }
            Core.eachExportReference = eachExportReference;
            function shouldAddSingleReference(singleRef, state) {
                if (!hasMatchingMeaning(singleRef, state))
                    return false;
                if (state.options.use !== 2 /* Rename */)
                    return true;
                // Don't rename an import type `import("./module-name")` when renaming `name` in `export = name;`
                if (!ts.isIdentifier(singleRef))
                    return false;
                // At `default` in `import { default as x }` or `export { default as x }`, do add a reference, but do not rename.
                return !(ts.isImportOrExportSpecifier(singleRef.parent) && singleRef.escapedText === "default" /* Default */);
            }
            // Go to the symbol we imported from and find references for it.
            function searchForImportedSymbol(symbol, state) {
                if (!symbol.declarations)
                    return;
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    var exportingFile = declaration.getSourceFile();
                    // Need to search in the file even if it's not in the search-file set, because it might export the symbol.
                    getReferencesInSourceFile(exportingFile, state.createSearch(declaration, symbol, 0 /* Import */), state, state.includesSourceFile(exportingFile));
                }
            }
            /** Search for all occurences of an identifier in a source file (and filter out the ones that match). */
            function searchForName(sourceFile, search, state) {
                if (ts.getNameTable(sourceFile).get(search.escapedText) !== undefined) {
                    getReferencesInSourceFile(sourceFile, search, state);
                }
            }
            function getPropertySymbolOfDestructuringAssignment(location, checker) {
                return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent)
                    ? checker.getPropertySymbolOfDestructuringAssignment(location)
                    : undefined;
            }
            /**
             * Determines the smallest scope in which a symbol may have named references.
             * Note that not every construct has been accounted for. This function can
             * probably be improved.
             *
             * @returns undefined if the scope cannot be determined, implying that
             * a reference to a symbol can occur anywhere.
             */
            function getSymbolScope(symbol) {
                // If this is the symbol of a named function expression or named class expression,
                // then named references are limited to its own scope.
                var declarations = symbol.declarations, flags = symbol.flags, parent = symbol.parent, valueDeclaration = symbol.valueDeclaration;
                if (valueDeclaration && (valueDeclaration.kind === 201 /* FunctionExpression */ || valueDeclaration.kind === 214 /* ClassExpression */)) {
                    return valueDeclaration;
                }
                if (!declarations) {
                    return undefined;
                }
                // If this is private property or method, the scope is the containing class
                if (flags & (4 /* Property */ | 8192 /* Method */)) {
                    var privateDeclaration = ts.find(declarations, function (d) { return ts.hasModifier(d, 8 /* Private */) || ts.isPrivateIdentifierPropertyDeclaration(d); });
                    if (privateDeclaration) {
                        return ts.getAncestor(privateDeclaration, 245 /* ClassDeclaration */);
                    }
                    // Else this is a public property and could be accessed from anywhere.
                    return undefined;
                }
                // If symbol is of object binding pattern element without property name we would want to
                // look for property too and that could be anywhere
                if (declarations.some(ts.isObjectBindingElementWithoutPropertyName)) {
                    return undefined;
                }
                /*
                If the symbol has a parent, it's globally visible unless:
                - It's a private property (handled above).
                - It's a type parameter.
                - The parent is an external module: then we should only search in the module (and recurse on the export later).
                - But if the parent has `export as namespace`, the symbol is globally visible through that namespace.
                */
                var exposedByParent = parent && !(symbol.flags & 262144 /* TypeParameter */);
                if (exposedByParent && !(ts.isExternalModuleSymbol(parent) && !parent.globalExports)) {
                    return undefined;
                }
                var scope;
                for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
                    var declaration = declarations_1[_i];
                    var container = ts.getContainerNode(declaration);
                    if (scope && scope !== container) {
                        // Different declarations have different containers, bail out
                        return undefined;
                    }
                    if (!container || container.kind === 290 /* SourceFile */ && !ts.isExternalOrCommonJsModule(container)) {
                        // This is a global variable and not an external module, any declaration defined
                        // within this scope is visible outside the file
                        return undefined;
                    }
                    // The search scope is the container node
                    scope = container;
                }
                // If symbol.parent, this means we are in an export of an external module. (Otherwise we would have returned `undefined` above.)
                // For an export of a module, we may be in a declaration file, and it may be accessed elsewhere. E.g.:
                //     declare module "a" { export type T = number; }
                //     declare module "b" { import { T } from "a"; export const x: T; }
                // So we must search the whole source file. (Because we will mark the source file as seen, we we won't return to it when searching for imports.)
                return exposedByParent ? scope.getSourceFile() : scope; // TODO: GH#18217
            }
            /** Used as a quick check for whether a symbol is used at all in a file (besides its definition). */
            function isSymbolReferencedInFile(definition, checker, sourceFile, searchContainer) {
                if (searchContainer === void 0) { searchContainer = sourceFile; }
                return eachSymbolReferenceInFile(definition, checker, sourceFile, function () { return true; }, searchContainer) || false;
            }
            Core.isSymbolReferencedInFile = isSymbolReferencedInFile;
            function eachSymbolReferenceInFile(definition, checker, sourceFile, cb, searchContainer) {
                if (searchContainer === void 0) { searchContainer = sourceFile; }
                var symbol = ts.isParameterPropertyDeclaration(definition.parent, definition.parent.parent)
                    ? ts.first(checker.getSymbolsOfParameterPropertyDeclaration(definition.parent, definition.text))
                    : checker.getSymbolAtLocation(definition);
                if (!symbol)
                    return undefined;
                for (var _i = 0, _a = getPossibleSymbolReferenceNodes(sourceFile, symbol.name, searchContainer); _i < _a.length; _i++) {
                    var token = _a[_i];
                    if (!ts.isIdentifier(token) || token === definition || token.escapedText !== definition.escapedText)
                        continue;
                    var referenceSymbol = checker.getSymbolAtLocation(token); // See GH#19955 for why the type annotation is necessary
                    if (referenceSymbol === symbol
                        || checker.getShorthandAssignmentValueSymbol(token.parent) === symbol
                        || ts.isExportSpecifier(token.parent) && getLocalSymbolForExportSpecifier(token, referenceSymbol, token.parent, checker) === symbol) {
                        var res = cb(token);
                        if (res)
                            return res;
                    }
                }
            }
            Core.eachSymbolReferenceInFile = eachSymbolReferenceInFile;
            function eachSignatureCall(signature, sourceFiles, checker, cb) {
                if (!signature.name || !ts.isIdentifier(signature.name))
                    return;
                var symbol = ts.Debug.checkDefined(checker.getSymbolAtLocation(signature.name));
                for (var _i = 0, sourceFiles_3 = sourceFiles; _i < sourceFiles_3.length; _i++) {
                    var sourceFile = sourceFiles_3[_i];
                    for (var _a = 0, _b = getPossibleSymbolReferenceNodes(sourceFile, symbol.name); _a < _b.length; _a++) {
                        var name = _b[_a];
                        if (!ts.isIdentifier(name) || name === signature.name || name.escapedText !== signature.name.escapedText)
                            continue;
                        var called = ts.climbPastPropertyAccess(name);
                        var call = called.parent;
                        if (!ts.isCallExpression(call) || call.expression !== called)
                            continue;
                        var referenceSymbol = checker.getSymbolAtLocation(name);
                        if (referenceSymbol && checker.getRootSymbols(referenceSymbol).some(function (s) { return s === symbol; })) {
                            cb(call);
                        }
                    }
                }
            }
            Core.eachSignatureCall = eachSignatureCall;
            function getPossibleSymbolReferenceNodes(sourceFile, symbolName, container) {
                if (container === void 0) { container = sourceFile; }
                return getPossibleSymbolReferencePositions(sourceFile, symbolName, container).map(function (pos) { return ts.getTouchingPropertyName(sourceFile, pos); });
            }
            function getPossibleSymbolReferencePositions(sourceFile, symbolName, container) {
                if (container === void 0) { container = sourceFile; }
                var positions = [];
                /// TODO: Cache symbol existence for files to save text search
                // Also, need to make this work for unicode escapes.
                // Be resilient in the face of a symbol with no name or zero length name
                if (!symbolName || !symbolName.length) {
                    return positions;
                }
                var text = sourceFile.text;
                var sourceLength = text.length;
                var symbolNameLength = symbolName.length;
                var position = text.indexOf(symbolName, container.pos);
                while (position >= 0) {
                    // If we are past the end, stop looking
                    if (position > container.end)
                        break;
                    // We found a match.  Make sure it's not part of a larger word (i.e. the char
                    // before and after it have to be a non-identifier char).
                    var endPosition = position + symbolNameLength;
                    if ((position === 0 || !ts.isIdentifierPart(text.charCodeAt(position - 1), 99 /* Latest */)) &&
                        (endPosition === sourceLength || !ts.isIdentifierPart(text.charCodeAt(endPosition), 99 /* Latest */))) {
                        // Found a real match.  Keep searching.
                        positions.push(position);
                    }
                    position = text.indexOf(symbolName, position + symbolNameLength + 1);
                }
                return positions;
            }
            function getLabelReferencesInNode(container, targetLabel) {
                var sourceFile = container.getSourceFile();
                var labelName = targetLabel.text;
                var references = ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, labelName, container), function (node) {
                    // Only pick labels that are either the target label, or have a target that is the target label
                    return node === targetLabel || (ts.isJumpStatementTarget(node) && ts.getTargetLabel(node, labelName) === targetLabel) ? nodeEntry(node) : undefined;
                });
                return [{ definition: { type: 1 /* Label */, node: targetLabel }, references: references }];
            }
            function isValidReferencePosition(node, searchSymbolName) {
                // Compare the length so we filter out strict superstrings of the symbol we are looking for
                switch (node.kind) {
                    case 76 /* PrivateIdentifier */:
                    case 75 /* Identifier */:
                        return node.text.length === searchSymbolName.length;
                    case 14 /* NoSubstitutionTemplateLiteral */:
                    case 10 /* StringLiteral */: {
                        var str = node;
                        return (ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(str) || ts.isNameOfModuleDeclaration(node) || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node) || (ts.isCallExpression(node.parent) && ts.isBindableObjectDefinePropertyCall(node.parent) && node.parent.arguments[1] === node)) &&
                            str.text.length === searchSymbolName.length;
                    }
                    case 8 /* NumericLiteral */:
                        return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && node.text.length === searchSymbolName.length;
                    case 84 /* DefaultKeyword */:
                        return "default".length === searchSymbolName.length;
                    default:
                        return false;
                }
            }
            function getAllReferencesForKeyword(sourceFiles, keywordKind, cancellationToken, filter) {
                var references = ts.flatMap(sourceFiles, function (sourceFile) {
                    cancellationToken.throwIfCancellationRequested();
                    return ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, ts.tokenToString(keywordKind), sourceFile), function (referenceLocation) {
                        if (referenceLocation.kind === keywordKind && (!filter || filter(referenceLocation))) {
                            return nodeEntry(referenceLocation);
                        }
                    });
                });
                return references.length ? [{ definition: { type: 2 /* Keyword */, node: references[0].node }, references: references }] : undefined;
            }
            function getReferencesInSourceFile(sourceFile, search, state, addReferencesHere) {
                if (addReferencesHere === void 0) { addReferencesHere = true; }
                state.cancellationToken.throwIfCancellationRequested();
                return getReferencesInContainer(sourceFile, sourceFile, search, state, addReferencesHere);
            }
            /**
             * Search within node "container" for references for a search value, where the search value is defined as a
             * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning).
             * searchLocation: a node where the search value
             */
            function getReferencesInContainer(container, sourceFile, search, state, addReferencesHere) {
                if (!state.markSearchedSymbols(sourceFile, search.allSearchSymbols)) {
                    return;
                }
                for (var _i = 0, _a = getPossibleSymbolReferencePositions(sourceFile, search.text, container); _i < _a.length; _i++) {
                    var position = _a[_i];
                    getReferencesAtLocation(sourceFile, position, search, state, addReferencesHere);
                }
            }
            function hasMatchingMeaning(referenceLocation, state) {
                return !!(ts.getMeaningFromLocation(referenceLocation) & state.searchMeaning);
            }
            function getReferencesAtLocation(sourceFile, position, search, state, addReferencesHere) {
                var referenceLocation = ts.getTouchingPropertyName(sourceFile, position);
                if (!isValidReferencePosition(referenceLocation, search.text)) {
                    // This wasn't the start of a token.  Check to see if it might be a
                    // match in a comment or string if that's what the caller is asking
                    // for.
                    if (!state.options.implementations && (state.options.findInStrings && ts.isInString(sourceFile, position) || state.options.findInComments && ts.isInNonReferenceComment(sourceFile, position))) {
                        // In the case where we're looking inside comments/strings, we don't have
                        // an actual definition.  So just use 'undefined' here.  Features like
                        // 'Rename' won't care (as they ignore the definitions), and features like
                        // 'FindReferences' will just filter out these results.
                        state.addStringOrCommentReference(sourceFile.fileName, ts.createTextSpan(position, search.text.length));
                    }
                    return;
                }
                if (!hasMatchingMeaning(referenceLocation, state))
                    return;
                var referenceSymbol = state.checker.getSymbolAtLocation(referenceLocation);
                if (!referenceSymbol) {
                    return;
                }
                var parent = referenceLocation.parent;
                if (ts.isImportSpecifier(parent) && parent.propertyName === referenceLocation) {
                    // This is added through `singleReferences` in ImportsResult. If we happen to see it again, don't add it again.
                    return;
                }
                if (ts.isExportSpecifier(parent)) {
                    ts.Debug.assert(referenceLocation.kind === 75 /* Identifier */);
                    getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, parent, search, state, addReferencesHere);
                    return;
                }
                var relatedSymbol = getRelatedSymbol(search, referenceSymbol, referenceLocation, state);
                if (!relatedSymbol) {
                    getReferenceForShorthandProperty(referenceSymbol, search, state);
                    return;
                }
                switch (state.specialSearchKind) {
                    case 0 /* None */:
                        if (addReferencesHere)
                            addReference(referenceLocation, relatedSymbol, state);
                        break;
                    case 1 /* Constructor */:
                        addConstructorReferences(referenceLocation, sourceFile, search, state);
                        break;
                    case 2 /* Class */:
                        addClassStaticThisReferences(referenceLocation, search, state);
                        break;
                    default:
                        ts.Debug.assertNever(state.specialSearchKind);
                }
                getImportOrExportReferences(referenceLocation, referenceSymbol, search, state);
            }
            function getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, search, state, addReferencesHere, alwaysGetReferences) {
                ts.Debug.assert(!alwaysGetReferences || !!state.options.providePrefixAndSuffixTextForRename, "If alwaysGetReferences is true, then prefix/suffix text must be enabled");
                var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name;
                var exportDeclaration = parent.parent;
                var localSymbol = getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, state.checker);
                if (!alwaysGetReferences && !search.includes(localSymbol)) {
                    return;
                }
                if (!propertyName) {
                    // Don't rename at `export { default } from "m";`. (but do continue to search for imports of the re-export)
                    if (!(state.options.use === 2 /* Rename */ && (name.escapedText === "default" /* Default */))) {
                        addRef();
                    }
                }
                else if (referenceLocation === propertyName) {
                    // For `export { foo as bar } from "baz"`, "`foo`" will be added from the singleReferences for import searches of the original export.
                    // For `export { foo as bar };`, where `foo` is a local, so add it now.
                    if (!exportDeclaration.moduleSpecifier) {
                        addRef();
                    }
                    if (addReferencesHere && state.options.use !== 2 /* Rename */ && state.markSeenReExportRHS(name)) {
                        addReference(name, ts.Debug.checkDefined(exportSpecifier.symbol), state);
                    }
                }
                else {
                    if (state.markSeenReExportRHS(referenceLocation)) {
                        addRef();
                    }
                }
                // For `export { foo as bar }`, rename `foo`, but not `bar`.
                if (!isForRenameWithPrefixAndSuffixText(state.options) || alwaysGetReferences) {
                    var isDefaultExport = referenceLocation.originalKeywordKind === 84 /* DefaultKeyword */
                        || exportSpecifier.name.originalKeywordKind === 84 /* DefaultKeyword */;
                    var exportKind = isDefaultExport ? 1 /* Default */ : 0 /* Named */;
                    var exportSymbol = ts.Debug.checkDefined(exportSpecifier.symbol);
                    var exportInfo = FindAllReferences.getExportInfo(exportSymbol, exportKind, state.checker);
                    if (exportInfo) {
                        searchForImportsOfExport(referenceLocation, exportSymbol, exportInfo, state);
                    }
                }
                // At `export { x } from "foo"`, also search for the imported symbol `"foo".x`.
                if (search.comingFrom !== 1 /* Export */ && exportDeclaration.moduleSpecifier && !propertyName && !isForRenameWithPrefixAndSuffixText(state.options)) {
                    var imported = state.checker.getExportSpecifierLocalTargetSymbol(exportSpecifier);
                    if (imported)
                        searchForImportedSymbol(imported, state);
                }
                function addRef() {
                    if (addReferencesHere)
                        addReference(referenceLocation, localSymbol, state);
                }
            }
            function getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, checker) {
                return isExportSpecifierAlias(referenceLocation, exportSpecifier) && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier) || referenceSymbol;
            }
            function isExportSpecifierAlias(referenceLocation, exportSpecifier) {
                var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name;
                ts.Debug.assert(propertyName === referenceLocation || name === referenceLocation);
                if (propertyName) {
                    // Given `export { foo as bar } [from "someModule"]`: It's an alias at `foo`, but at `bar` it's a new symbol.
                    return propertyName === referenceLocation;
                }
                else {
                    // `export { foo } from "foo"` is a re-export.
                    // `export { foo };` is not a re-export, it creates an alias for the local variable `foo`.
                    return !parent.parent.moduleSpecifier;
                }
            }
            function getImportOrExportReferences(referenceLocation, referenceSymbol, search, state) {
                var importOrExport = FindAllReferences.getImportOrExportSymbol(referenceLocation, referenceSymbol, state.checker, search.comingFrom === 1 /* Export */);
                if (!importOrExport)
                    return;
                var symbol = importOrExport.symbol;
                if (importOrExport.kind === 0 /* Import */) {
                    if (!(isForRenameWithPrefixAndSuffixText(state.options))) {
                        searchForImportedSymbol(symbol, state);
                    }
                }
                else {
                    searchForImportsOfExport(referenceLocation, symbol, importOrExport.exportInfo, state);
                }
            }
            function getReferenceForShorthandProperty(_a, search, state) {
                var flags = _a.flags, valueDeclaration = _a.valueDeclaration;
                var shorthandValueSymbol = state.checker.getShorthandAssignmentValueSymbol(valueDeclaration);
                var name = valueDeclaration && ts.getNameOfDeclaration(valueDeclaration);
                /*
                * Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment
                * has two meanings: property name and property value. Therefore when we do findAllReference at the position where
                * an identifier is declared, the language service should return the position of the variable declaration as well as
                * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the
                * position of property accessing, the referenceEntry of such position will be handled in the first case.
                */
                if (!(flags & 33554432 /* Transient */) && name && search.includes(shorthandValueSymbol)) {
                    addReference(name, shorthandValueSymbol, state);
                }
            }
            function addReference(referenceLocation, relatedSymbol, state) {
                var _a = "kind" in relatedSymbol ? relatedSymbol : { kind: undefined, symbol: relatedSymbol }, kind = _a.kind, symbol = _a.symbol; // eslint-disable-line no-in-operator
                var addRef = state.referenceAdder(symbol);
                if (state.options.implementations) {
                    addImplementationReferences(referenceLocation, addRef, state);
                }
                else {
                    addRef(referenceLocation, kind);
                }
            }
            /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses.  */
            function addConstructorReferences(referenceLocation, sourceFile, search, state) {
                if (ts.isNewExpressionTarget(referenceLocation)) {
                    addReference(referenceLocation, search.symbol, state);
                }
                var pusher = function () { return state.referenceAdder(search.symbol); };
                if (ts.isClassLike(referenceLocation.parent)) {
                    ts.Debug.assert(referenceLocation.kind === 84 /* DefaultKeyword */ || referenceLocation.parent.name === referenceLocation);
                    // This is the class declaration containing the constructor.
                    findOwnConstructorReferences(search.symbol, sourceFile, pusher());
                }
                else {
                    // If this class appears in `extends C`, then the extending class' "super" calls are references.
                    var classExtending = tryGetClassByExtendingIdentifier(referenceLocation);
                    if (classExtending) {
                        findSuperConstructorAccesses(classExtending, pusher());
                        findInheritedConstructorReferences(classExtending, state);
                    }
                }
            }
            function addClassStaticThisReferences(referenceLocation, search, state) {
                addReference(referenceLocation, search.symbol, state);
                var classLike = referenceLocation.parent;
                if (state.options.use === 2 /* Rename */ || !ts.isClassLike(classLike))
                    return;
                ts.Debug.assert(classLike.name === referenceLocation);
                var addRef = state.referenceAdder(search.symbol);
                for (var _i = 0, _a = classLike.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    if (!(ts.isMethodOrAccessor(member) && ts.hasModifier(member, 32 /* Static */))) {
                        continue;
                    }
                    if (member.body) {
                        member.body.forEachChild(function cb(node) {
                            if (node.kind === 104 /* ThisKeyword */) {
                                addRef(node);
                            }
                            else if (!ts.isFunctionLike(node) && !ts.isClassLike(node)) {
                                node.forEachChild(cb);
                            }
                        });
                    }
                }
            }
            /**
             * `classSymbol` is the class where the constructor was defined.
             * Reference the constructor and all calls to `new this()`.
             */
            function findOwnConstructorReferences(classSymbol, sourceFile, addNode) {
                var constructorSymbol = getClassConstructorSymbol(classSymbol);
                if (constructorSymbol && constructorSymbol.declarations) {
                    for (var _i = 0, _a = constructorSymbol.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        var ctrKeyword = ts.findChildOfKind(decl, 129 /* ConstructorKeyword */, sourceFile);
                        ts.Debug.assert(decl.kind === 162 /* Constructor */ && !!ctrKeyword);
                        addNode(ctrKeyword);
                    }
                }
                if (classSymbol.exports) {
                    classSymbol.exports.forEach(function (member) {
                        var decl = member.valueDeclaration;
                        if (decl && decl.kind === 161 /* MethodDeclaration */) {
                            var body = decl.body;
                            if (body) {
                                forEachDescendantOfKind(body, 104 /* ThisKeyword */, function (thisKeyword) {
                                    if (ts.isNewExpressionTarget(thisKeyword)) {
                                        addNode(thisKeyword);
                                    }
                                });
                            }
                        }
                    });
                }
            }
            function getClassConstructorSymbol(classSymbol) {
                return classSymbol.members && classSymbol.members.get("__constructor" /* Constructor */);
            }
            /** Find references to `super` in the constructor of an extending class.  */
            function findSuperConstructorAccesses(classDeclaration, addNode) {
                var constructor = getClassConstructorSymbol(classDeclaration.symbol);
                if (!(constructor && constructor.declarations)) {
                    return;
                }
                for (var _i = 0, _a = constructor.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    ts.Debug.assert(decl.kind === 162 /* Constructor */);
                    var body = decl.body;
                    if (body) {
                        forEachDescendantOfKind(body, 102 /* SuperKeyword */, function (node) {
                            if (ts.isCallExpressionTarget(node)) {
                                addNode(node);
                            }
                        });
                    }
                }
            }
            function hasOwnConstructor(classDeclaration) {
                return !!getClassConstructorSymbol(classDeclaration.symbol);
            }
            function findInheritedConstructorReferences(classDeclaration, state) {
                if (hasOwnConstructor(classDeclaration))
                    return;
                var classSymbol = classDeclaration.symbol;
                var search = state.createSearch(/*location*/ undefined, classSymbol, /*comingFrom*/ undefined);
                getReferencesInContainerOrFiles(classSymbol, state, search);
            }
            function addImplementationReferences(refNode, addReference, state) {
                // Check if we found a function/propertyAssignment/method with an implementation or initializer
                if (ts.isDeclarationName(refNode) && isImplementation(refNode.parent)) {
                    addReference(refNode);
                    return;
                }
                if (refNode.kind !== 75 /* Identifier */) {
                    return;
                }
                if (refNode.parent.kind === 282 /* ShorthandPropertyAssignment */) {
                    // Go ahead and dereference the shorthand assignment by going to its definition
                    getReferenceEntriesForShorthandPropertyAssignment(refNode, state.checker, addReference);
                }
                // Check if the node is within an extends or implements clause
                var containingClass = getContainingClassIfInHeritageClause(refNode);
                if (containingClass) {
                    addReference(containingClass);
                    return;
                }
                // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface
                // Find the first node whose parent isn't a type node -- i.e., the highest type node.
                var typeNode = ts.findAncestor(refNode, function (a) { return !ts.isQualifiedName(a.parent) && !ts.isTypeNode(a.parent) && !ts.isTypeElement(a.parent); });
                var typeHavingNode = typeNode.parent;
                if (ts.hasType(typeHavingNode) && typeHavingNode.type === typeNode && state.markSeenContainingTypeReference(typeHavingNode)) {
                    if (ts.hasInitializer(typeHavingNode)) {
                        addIfImplementation(typeHavingNode.initializer);
                    }
                    else if (ts.isFunctionLike(typeHavingNode) && typeHavingNode.body) {
                        var body = typeHavingNode.body;
                        if (body.kind === 223 /* Block */) {
                            ts.forEachReturnStatement(body, function (returnStatement) {
                                if (returnStatement.expression)
                                    addIfImplementation(returnStatement.expression);
                            });
                        }
                        else {
                            addIfImplementation(body);
                        }
                    }
                    else if (ts.isAssertionExpression(typeHavingNode)) {
                        addIfImplementation(typeHavingNode.expression);
                    }
                }
                function addIfImplementation(e) {
                    if (isImplementationExpression(e))
                        addReference(e);
                }
            }
            function getContainingClassIfInHeritageClause(node) {
                return ts.isIdentifier(node) || ts.isPropertyAccessExpression(node) ? getContainingClassIfInHeritageClause(node.parent)
                    : ts.isExpressionWithTypeArguments(node) ? ts.tryCast(node.parent.parent, ts.isClassLike) : undefined;
            }
            /**
             * Returns true if this is an expression that can be considered an implementation
             */
            function isImplementationExpression(node) {
                switch (node.kind) {
                    case 200 /* ParenthesizedExpression */:
                        return isImplementationExpression(node.expression);
                    case 202 /* ArrowFunction */:
                    case 201 /* FunctionExpression */:
                    case 193 /* ObjectLiteralExpression */:
                    case 214 /* ClassExpression */:
                    case 192 /* ArrayLiteralExpression */:
                        return true;
                    default:
                        return false;
                }
            }
            /**
             * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol
             * is an interface, determines if some ancestor of the child symbol extends or inherits from it.
             * Also takes in a cache of previous results which makes this slightly more efficient and is
             * necessary to avoid potential loops like so:
             *     class A extends B { }
             *     class B extends A { }
             *
             * We traverse the AST rather than using the type checker because users are typically only interested
             * in explicit implementations of an interface/class when calling "Go to Implementation". Sibling
             * implementations of types that share a common ancestor with the type whose implementation we are
             * searching for need to be filtered out of the results. The type checker doesn't let us make the
             * distinction between structurally compatible implementations and explicit implementations, so we
             * must use the AST.
             *
             * @param symbol         A class or interface Symbol
             * @param parent        Another class or interface Symbol
             * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results
             */
            function explicitlyInheritsFrom(symbol, parent, cachedResults, checker) {
                if (symbol === parent) {
                    return true;
                }
                var key = ts.getSymbolId(symbol) + "," + ts.getSymbolId(parent);
                var cached = cachedResults.get(key);
                if (cached !== undefined) {
                    return cached;
                }
                // Set the key so that we don't infinitely recurse
                cachedResults.set(key, false);
                var inherits = !!symbol.declarations && symbol.declarations.some(function (declaration) {
                    return ts.getAllSuperTypeNodes(declaration).some(function (typeReference) {
                        var type = checker.getTypeAtLocation(typeReference);
                        return !!type && !!type.symbol && explicitlyInheritsFrom(type.symbol, parent, cachedResults, checker);
                    });
                });
                cachedResults.set(key, inherits);
                return inherits;
            }
            function getReferencesForSuperKeyword(superKeyword) {
                var searchSpaceNode = ts.getSuperContainer(superKeyword, /*stopOnFunctions*/ false);
                if (!searchSpaceNode) {
                    return undefined;
                }
                // Whether 'super' occurs in a static context within a class.
                var staticFlag = 32 /* Static */;
                switch (searchSpaceNode.kind) {
                    case 159 /* PropertyDeclaration */:
                    case 158 /* PropertySignature */:
                    case 161 /* MethodDeclaration */:
                    case 160 /* MethodSignature */:
                    case 162 /* Constructor */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        staticFlag &= ts.getModifierFlags(searchSpaceNode);
                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
                        break;
                    default:
                        return undefined;
                }
                var sourceFile = searchSpaceNode.getSourceFile();
                var references = ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, "super", searchSpaceNode), function (node) {
                    if (node.kind !== 102 /* SuperKeyword */) {
                        return;
                    }
                    var container = ts.getSuperContainer(node, /*stopOnFunctions*/ false);
                    // If we have a 'super' container, we must have an enclosing class.
                    // Now make sure the owning class is the same as the search-space
                    // and has the same static qualifier as the original 'super's owner.
                    return container && (32 /* Static */ & ts.getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol ? nodeEntry(node) : undefined;
                });
                return [{ definition: { type: 0 /* Symbol */, symbol: searchSpaceNode.symbol }, references: references }];
            }
            function isParameterName(node) {
                return node.kind === 75 /* Identifier */ && node.parent.kind === 156 /* Parameter */ && node.parent.name === node;
            }
            function getReferencesForThisKeyword(thisOrSuperKeyword, sourceFiles, cancellationToken) {
                var searchSpaceNode = ts.getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
                // Whether 'this' occurs in a static context within a class.
                var staticFlag = 32 /* Static */;
                switch (searchSpaceNode.kind) {
                    case 161 /* MethodDeclaration */:
                    case 160 /* MethodSignature */:
                        if (ts.isObjectLiteralMethod(searchSpaceNode)) {
                            break;
                        }
                    // falls through
                    case 159 /* PropertyDeclaration */:
                    case 158 /* PropertySignature */:
                    case 162 /* Constructor */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        staticFlag &= ts.getModifierFlags(searchSpaceNode);
                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
                        break;
                    case 290 /* SourceFile */:
                        if (ts.isExternalModule(searchSpaceNode) || isParameterName(thisOrSuperKeyword)) {
                            return undefined;
                        }
                    // falls through
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                        break;
                    // Computed properties in classes are not handled here because references to this are illegal,
                    // so there is no point finding references to them.
                    default:
                        return undefined;
                }
                var references = ts.flatMap(searchSpaceNode.kind === 290 /* SourceFile */ ? sourceFiles : [searchSpaceNode.getSourceFile()], function (sourceFile) {
                    cancellationToken.throwIfCancellationRequested();
                    return getPossibleSymbolReferenceNodes(sourceFile, "this", ts.isSourceFile(searchSpaceNode) ? sourceFile : searchSpaceNode).filter(function (node) {
                        if (!ts.isThis(node)) {
                            return false;
                        }
                        var container = ts.getThisContainer(node, /* includeArrowFunctions */ false);
                        switch (searchSpaceNode.kind) {
                            case 201 /* FunctionExpression */:
                            case 244 /* FunctionDeclaration */:
                                return searchSpaceNode.symbol === container.symbol;
                            case 161 /* MethodDeclaration */:
                            case 160 /* MethodSignature */:
                                return ts.isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol;
                            case 214 /* ClassExpression */:
                            case 245 /* ClassDeclaration */:
                                // Make sure the container belongs to the same class
                                // and has the appropriate static modifier from the original container.
                                return container.parent && searchSpaceNode.symbol === container.parent.symbol && (ts.getModifierFlags(container) & 32 /* Static */) === staticFlag;
                            case 290 /* SourceFile */:
                                return container.kind === 290 /* SourceFile */ && !ts.isExternalModule(container) && !isParameterName(node);
                        }
                    });
                }).map(function (n) { return nodeEntry(n); });
                var thisParameter = ts.firstDefined(references, function (r) { return ts.isParameter(r.node.parent) ? r.node : undefined; });
                return [{
                        definition: { type: 3 /* This */, node: thisParameter || thisOrSuperKeyword },
                        references: references
                    }];
            }
            function getReferencesForStringLiteral(node, sourceFiles, cancellationToken) {
                var references = ts.flatMap(sourceFiles, function (sourceFile) {
                    cancellationToken.throwIfCancellationRequested();
                    return ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, node.text), function (ref) {
                        return ts.isStringLiteral(ref) && ref.text === node.text ? nodeEntry(ref, 2 /* StringLiteral */) : undefined;
                    });
                });
                return [{
                        definition: { type: 4 /* String */, node: node },
                        references: references
                    }];
            }
            // For certain symbol kinds, we need to include other symbols in the search set.
            // This is not needed when searching for re-exports.
            function populateSearchSymbolSet(symbol, location, checker, isForRename, providePrefixAndSuffixText, implementations) {
                var result = [];
                forEachRelatedSymbol(symbol, location, checker, isForRename, !(isForRename && providePrefixAndSuffixText), function (sym, root, base) { result.push(base || root || sym); }, 
                /*allowBaseTypes*/ function () { return !implementations; });
                return result;
            }
            function forEachRelatedSymbol(symbol, location, checker, isForRenamePopulateSearchSymbolSet, onlyIncludeBindingElementAtReferenceLocation, cbSymbol, allowBaseTypes) {
                var containingObjectLiteralElement = ts.getContainingObjectLiteralElement(location);
                if (containingObjectLiteralElement) {
                    /* Because in short-hand property assignment, location has two meaning : property name and as value of the property
                    * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of
                    * property name and variable declaration of the identifier.
                    * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service
                    * should show both 'name' in 'obj' and 'name' in variable declaration
                    *      const name = "Foo";
                    *      const obj = { name };
                    * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment
                    * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration
                    * will be included correctly.
                    */
                    var shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent); // gets the local symbol
                    if (shorthandValueSymbol && isForRenamePopulateSearchSymbolSet) {
                        // When renaming 'x' in `const o = { x }`, just rename the local variable, not the property.
                        return cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 3 /* SearchedLocalFoundProperty */);
                    }
                    // If the location is in a context sensitive location (i.e. in an object literal) try
                    // to get a contextual type for it, and add the property symbol from the contextual
                    // type to the search set
                    var contextualType = checker.getContextualType(containingObjectLiteralElement.parent);
                    var res_1 = contextualType && ts.firstDefined(ts.getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker, contextualType, /*unionSymbolOk*/ true), function (sym) { return fromRoot(sym, 4 /* SearchedPropertyFoundLocal */); });
                    if (res_1)
                        return res_1;
                    // If the location is name of property symbol from object literal destructuring pattern
                    // Search the property symbol
                    //      for ( { property: p2 } of elems) { }
                    var propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker);
                    var res1 = propertySymbol && cbSymbol(propertySymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 4 /* SearchedPropertyFoundLocal */);
                    if (res1)
                        return res1;
                    var res2 = shorthandValueSymbol && cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 3 /* SearchedLocalFoundProperty */);
                    if (res2)
                        return res2;
                }
                var aliasedSymbol = getMergedAliasedSymbolOfNamespaceExportDeclaration(location, symbol, checker);
                if (aliasedSymbol) {
                    // In case of UMD module and global merging, search for global as well
                    var res_2 = cbSymbol(aliasedSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 1 /* Node */);
                    if (res_2)
                        return res_2;
                }
                var res = fromRoot(symbol);
                if (res)
                    return res;
                if (symbol.valueDeclaration && ts.isParameterPropertyDeclaration(symbol.valueDeclaration, symbol.valueDeclaration.parent)) {
                    // For a parameter property, now try on the other symbol (property if this was a parameter, parameter if this was a property).
                    var paramProps = checker.getSymbolsOfParameterPropertyDeclaration(ts.cast(symbol.valueDeclaration, ts.isParameter), symbol.name);
                    ts.Debug.assert(paramProps.length === 2 && !!(paramProps[0].flags & 1 /* FunctionScopedVariable */) && !!(paramProps[1].flags & 4 /* Property */)); // is [parameter, property]
                    return fromRoot(symbol.flags & 1 /* FunctionScopedVariable */ ? paramProps[1] : paramProps[0]);
                }
                var exportSpecifier = ts.getDeclarationOfKind(symbol, 263 /* ExportSpecifier */);
                if (!isForRenamePopulateSearchSymbolSet || exportSpecifier && !exportSpecifier.propertyName) {
                    var localSymbol = exportSpecifier && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier);
                    if (localSymbol) {
                        var res_3 = cbSymbol(localSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, 1 /* Node */);
                        if (res_3)
                            return res_3;
                    }
                }
                // symbolAtLocation for a binding element is the local symbol. See if the search symbol is the property.
                // Don't do this when populating search set for a rename when prefix and suffix text will be provided -- just rename the local.
                if (!isForRenamePopulateSearchSymbolSet) {
                    var bindingElementPropertySymbol = void 0;
                    if (onlyIncludeBindingElementAtReferenceLocation) {
                        bindingElementPropertySymbol = ts.isObjectBindingElementWithoutPropertyName(location.parent) ? ts.getPropertySymbolFromBindingElement(checker, location.parent) : undefined;
                    }
                    else {
                        bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
                    }
                    return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol, 4 /* SearchedPropertyFoundLocal */);
                }
                ts.Debug.assert(isForRenamePopulateSearchSymbolSet);
                // due to the above assert and the arguments at the uses of this function,
                // (onlyIncludeBindingElementAtReferenceLocation <=> !providePrefixAndSuffixTextForRename) holds
                var includeOriginalSymbolOfBindingElement = onlyIncludeBindingElementAtReferenceLocation;
                if (includeOriginalSymbolOfBindingElement) {
                    var bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
                    return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol, 4 /* SearchedPropertyFoundLocal */);
                }
                function fromRoot(sym, kind) {
                    // If this is a union property:
                    //   - In populateSearchSymbolsSet we will add all the symbols from all its source symbols in all unioned types.
                    //   - In findRelatedSymbol, we will just use the union symbol if any source symbol is included in the search.
                    // If the symbol is an instantiation from a another symbol (e.g. widened symbol):
                    //   - In populateSearchSymbolsSet, add the root the list
                    //   - In findRelatedSymbol, return the source symbol if that is in the search. (Do not return the instantiation symbol.)
                    return ts.firstDefined(checker.getRootSymbols(sym), function (rootSymbol) {
                        return cbSymbol(sym, rootSymbol, /*baseSymbol*/ undefined, kind)
                            // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
                            || (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */) && allowBaseTypes(rootSymbol)
                                ? ts.getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, function (base) { return cbSymbol(sym, rootSymbol, base, kind); })
                                : undefined);
                    });
                }
                function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker) {
                    var bindingElement = ts.getDeclarationOfKind(symbol, 191 /* BindingElement */);
                    if (bindingElement && ts.isObjectBindingElementWithoutPropertyName(bindingElement)) {
                        return ts.getPropertySymbolFromBindingElement(checker, bindingElement);
                    }
                }
            }
            function getRelatedSymbol(search, referenceSymbol, referenceLocation, state) {
                var checker = state.checker;
                return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker, /*isForRenamePopulateSearchSymbolSet*/ false, 
                /*onlyIncludeBindingElementAtReferenceLocation*/ state.options.use !== 2 /* Rename */ || !!state.options.providePrefixAndSuffixTextForRename, function (sym, rootSymbol, baseSymbol, kind) { return search.includes(baseSymbol || rootSymbol || sym)
                    // For a base type, use the symbol for the derived type. For a synthetic (e.g. union) property, use the union symbol.
                    ? { symbol: rootSymbol && !(ts.getCheckFlags(sym) & 6 /* Synthetic */) ? rootSymbol : sym, kind: kind }
                    : undefined; }, 
                /*allowBaseTypes*/ function (rootSymbol) {
                    return !(search.parents && !search.parents.some(function (parent) { return explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker); }));
                });
            }
            /**
             * Given an initial searchMeaning, extracted from a location, widen the search scope based on the declarations
             * of the corresponding symbol. e.g. if we are searching for "Foo" in value position, but "Foo" references a class
             * then we need to widen the search to include type positions as well.
             * On the contrary, if we are searching for "Bar" in type position and we trace bar to an interface, and an uninstantiated
             * module, we want to keep the search limited to only types, as the two declarations (interface and uninstantiated module)
             * do not intersect in any of the three spaces.
             */
            function getIntersectingMeaningFromDeclarations(node, symbol) {
                var meaning = ts.getMeaningFromLocation(node);
                var declarations = symbol.declarations;
                if (declarations) {
                    var lastIterationMeaning = void 0;
                    do {
                        // The result is order-sensitive, for instance if initialMeaning === Namespace, and declarations = [class, instantiated module]
                        // we need to consider both as they initialMeaning intersects with the module in the namespace space, and the module
                        // intersects with the class in the value space.
                        // To achieve that we will keep iterating until the result stabilizes.
                        // Remember the last meaning
                        lastIterationMeaning = meaning;
                        for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) {
                            var declaration = declarations_2[_i];
                            var declarationMeaning = ts.getMeaningFromDeclaration(declaration);
                            if (declarationMeaning & meaning) {
                                meaning |= declarationMeaning;
                            }
                        }
                    } while (meaning !== lastIterationMeaning);
                }
                return meaning;
            }
            Core.getIntersectingMeaningFromDeclarations = getIntersectingMeaningFromDeclarations;
            function isImplementation(node) {
                return !!(node.flags & 8388608 /* Ambient */) ? !(ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) :
                    (ts.isVariableLike(node) ? ts.hasInitializer(node) :
                        ts.isFunctionLikeDeclaration(node) ? !!node.body :
                            ts.isClassLike(node) || ts.isModuleOrEnumDeclaration(node));
            }
            function getReferenceEntriesForShorthandPropertyAssignment(node, checker, addReference) {
                var refSymbol = checker.getSymbolAtLocation(node);
                var shorthandSymbol = checker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration);
                if (shorthandSymbol) {
                    for (var _i = 0, _a = shorthandSymbol.getDeclarations(); _i < _a.length; _i++) {
                        var declaration = _a[_i];
                        if (ts.getMeaningFromDeclaration(declaration) & 1 /* Value */) {
                            addReference(declaration);
                        }
                    }
                }
            }
            Core.getReferenceEntriesForShorthandPropertyAssignment = getReferenceEntriesForShorthandPropertyAssignment;
            function forEachDescendantOfKind(node, kind, action) {
                ts.forEachChild(node, function (child) {
                    if (child.kind === kind) {
                        action(child);
                    }
                    forEachDescendantOfKind(child, kind, action);
                });
            }
            /** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */
            function tryGetClassByExtendingIdentifier(node) {
                return ts.tryGetClassExtendingExpressionWithTypeArguments(ts.climbPastPropertyAccess(node).parent);
            }
            /**
             * If we are just looking for implementations and this is a property access expression, we need to get the
             * symbol of the local type of the symbol the property is being accessed on. This is because our search
             * symbol may have a different parent symbol if the local type's symbol does not declare the property
             * being accessed (i.e. it is declared in some parent class or interface)
             */
            function getParentSymbolsOfPropertyAccess(location, symbol, checker) {
                var propertyAccessExpression = ts.isRightSideOfPropertyAccess(location) ? location.parent : undefined;
                var lhsType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression);
                var res = ts.mapDefined(lhsType && (lhsType.isUnionOrIntersection() ? lhsType.types : lhsType.symbol === symbol.parent ? undefined : [lhsType]), function (t) {
                    return t.symbol && t.symbol.flags & (32 /* Class */ | 64 /* Interface */) ? t.symbol : undefined;
                });
                return res.length === 0 ? undefined : res;
            }
            function isForRenameWithPrefixAndSuffixText(options) {
                return options.use === 2 /* Rename */ && options.providePrefixAndSuffixTextForRename;
            }
        })(Core = FindAllReferences.Core || (FindAllReferences.Core = {}));
    })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var CallHierarchy;
    (function (CallHierarchy) {
        /** Indictates whether a node is named function or class expression. */
        function isNamedExpression(node) {
            return (ts.isFunctionExpression(node) || ts.isClassExpression(node)) && ts.isNamedDeclaration(node);
        }
        /** Indicates whether a node is a function, arrow, or class expression assigned to a constant variable. */
        function isConstNamedExpression(node) {
            return (ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isClassExpression(node))
                && ts.isVariableDeclaration(node.parent)
                && node === node.parent.initializer
                && ts.isIdentifier(node.parent.name)
                && !!(ts.getCombinedNodeFlags(node.parent) & 2 /* Const */);
        }
        /**
         * Indicates whether a node could possibly be a call hierarchy declaration.
         *
         * See `resolveCallHierarchyDeclaration` for the specific rules.
         */
        function isPossibleCallHierarchyDeclaration(node) {
            return ts.isSourceFile(node)
                || ts.isModuleDeclaration(node)
                || ts.isFunctionDeclaration(node)
                || ts.isFunctionExpression(node)
                || ts.isClassDeclaration(node)
                || ts.isClassExpression(node)
                || ts.isMethodDeclaration(node)
                || ts.isMethodSignature(node)
                || ts.isGetAccessorDeclaration(node)
                || ts.isSetAccessorDeclaration(node);
        }
        /**
         * Indicates whether a node is a valid a call hierarchy declaration.
         *
         * See `resolveCallHierarchyDeclaration` for the specific rules.
         */
        function isValidCallHierarchyDeclaration(node) {
            return ts.isSourceFile(node)
                || ts.isModuleDeclaration(node) && ts.isIdentifier(node.name)
                || ts.isFunctionDeclaration(node)
                || ts.isClassDeclaration(node)
                || ts.isMethodDeclaration(node)
                || ts.isMethodSignature(node)
                || ts.isGetAccessorDeclaration(node)
                || ts.isSetAccessorDeclaration(node)
                || isNamedExpression(node)
                || isConstNamedExpression(node);
        }
        /** Gets the node that can be used as a reference to a call hierarchy declaration. */
        function getCallHierarchyDeclarationReferenceNode(node) {
            if (ts.isSourceFile(node))
                return node;
            if (ts.isNamedDeclaration(node))
                return node.name;
            if (isConstNamedExpression(node))
                return node.parent.name;
            return ts.Debug.checkDefined(node.modifiers && ts.find(node.modifiers, isDefaultModifier));
        }
        function isDefaultModifier(node) {
            return node.kind === 84 /* DefaultKeyword */;
        }
        /** Gets the symbol for a call hierarchy declaration. */
        function getSymbolOfCallHierarchyDeclaration(typeChecker, node) {
            var location = getCallHierarchyDeclarationReferenceNode(node);
            return location && typeChecker.getSymbolAtLocation(location);
        }
        /** Gets the text and range for the name of a call hierarchy declaration. */
        function getCallHierarchyItemName(program, node) {
            if (ts.isSourceFile(node)) {
                return { text: node.fileName, pos: 0, end: 0 };
            }
            if ((ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node)) && !ts.isNamedDeclaration(node)) {
                var defaultModifier = node.modifiers && ts.find(node.modifiers, isDefaultModifier);
                if (defaultModifier) {
                    return { text: "default", pos: defaultModifier.getStart(), end: defaultModifier.getEnd() };
                }
            }
            var declName = isConstNamedExpression(node) ? node.parent.name :
                ts.Debug.checkDefined(ts.getNameOfDeclaration(node), "Expected call hierarchy item to have a name");
            var text = ts.isIdentifier(declName) ? ts.idText(declName) :
                ts.isStringOrNumericLiteralLike(declName) ? declName.text :
                    ts.isComputedPropertyName(declName) ?
                        ts.isStringOrNumericLiteralLike(declName.expression) ? declName.expression.text :
                            undefined :
                        undefined;
            if (text === undefined) {
                var typeChecker = program.getTypeChecker();
                var symbol = typeChecker.getSymbolAtLocation(declName);
                if (symbol) {
                    text = typeChecker.symbolToString(symbol, node);
                }
            }
            if (text === undefined) {
                // get the text from printing the node on a single line without comments...
                var printer_1 = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
                text = ts.usingSingleLineStringWriter(function (writer) { return printer_1.writeNode(4 /* Unspecified */, node, node.getSourceFile(), writer); });
            }
            return { text: text, pos: declName.getStart(), end: declName.getEnd() };
        }
        function findImplementation(typeChecker, node) {
            if (node.body) {
                return node;
            }
            if (ts.isConstructorDeclaration(node)) {
                return ts.getFirstConstructorWithBody(node.parent);
            }
            if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {
                var symbol = getSymbolOfCallHierarchyDeclaration(typeChecker, node);
                if (symbol && symbol.valueDeclaration && ts.isFunctionLikeDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.body) {
                    return symbol.valueDeclaration;
                }
                return undefined;
            }
            return node;
        }
        function findAllInitialDeclarations(typeChecker, node) {
            var symbol = getSymbolOfCallHierarchyDeclaration(typeChecker, node);
            var declarations;
            if (symbol && symbol.declarations) {
                var indices = ts.indicesOf(symbol.declarations);
                var keys_1 = ts.map(symbol.declarations, function (decl) { return ({ file: decl.getSourceFile().fileName, pos: decl.pos }); });
                indices.sort(function (a, b) { return ts.compareStringsCaseSensitive(keys_1[a].file, keys_1[b].file) || keys_1[a].pos - keys_1[b].pos; });
                var sortedDeclarations = ts.map(indices, function (i) { return symbol.declarations[i]; });
                var lastDecl = void 0;
                for (var _i = 0, sortedDeclarations_1 = sortedDeclarations; _i < sortedDeclarations_1.length; _i++) {
                    var decl = sortedDeclarations_1[_i];
                    if (isValidCallHierarchyDeclaration(decl)) {
                        if (!lastDecl || lastDecl.parent !== decl.parent || lastDecl.end !== decl.pos) {
                            declarations = ts.append(declarations, decl);
                        }
                        lastDecl = decl;
                    }
                }
            }
            return declarations;
        }
        /** Find the implementation or the first declaration for a call hierarchy declaration. */
        function findImplementationOrAllInitialDeclarations(typeChecker, node) {
            var _a, _b, _c;
            if (ts.isFunctionLikeDeclaration(node)) {
                return (_b = (_a = findImplementation(typeChecker, node)) !== null && _a !== void 0 ? _a : findAllInitialDeclarations(typeChecker, node)) !== null && _b !== void 0 ? _b : node;
            }
            return (_c = findAllInitialDeclarations(typeChecker, node)) !== null && _c !== void 0 ? _c : node;
        }
        /** Resolves the call hierarchy declaration for a node. */
        function resolveCallHierarchyDeclaration(program, location) {
            // A call hierarchy item must refer to either a SourceFile, Module Declaration, or something intrinsically callable that has a name:
            // - Class Declarations
            // - Class Expressions (with a name)
            // - Function Declarations
            // - Function Expressions (with a name or assigned to a const variable)
            // - Arrow Functions (assigned to a const variable)
            // - Constructors
            // - Methods
            // - Accessors
            //
            // If a call is contained in a non-named callable Node (function expression, arrow function, etc.), then
            // its containing `CallHierarchyItem` is a containing function or SourceFile that matches the above list.
            var typeChecker = program.getTypeChecker();
            var followingSymbol = false;
            while (true) {
                if (isValidCallHierarchyDeclaration(location)) {
                    return findImplementationOrAllInitialDeclarations(typeChecker, location);
                }
                if (isPossibleCallHierarchyDeclaration(location)) {
                    var ancestor = ts.findAncestor(location, isValidCallHierarchyDeclaration);
                    return ancestor && findImplementationOrAllInitialDeclarations(typeChecker, ancestor);
                }
                if (ts.isDeclarationName(location)) {
                    if (isValidCallHierarchyDeclaration(location.parent)) {
                        return findImplementationOrAllInitialDeclarations(typeChecker, location.parent);
                    }
                    if (isPossibleCallHierarchyDeclaration(location.parent)) {
                        var ancestor = ts.findAncestor(location.parent, isValidCallHierarchyDeclaration);
                        return ancestor && findImplementationOrAllInitialDeclarations(typeChecker, ancestor);
                    }
                    if (ts.isVariableDeclaration(location.parent) && location.parent.initializer && isConstNamedExpression(location.parent.initializer)) {
                        return location.parent.initializer;
                    }
                    return undefined;
                }
                if (ts.isConstructorDeclaration(location)) {
                    if (isValidCallHierarchyDeclaration(location.parent)) {
                        return location.parent;
                    }
                    return undefined;
                }
                if (!followingSymbol) {
                    var symbol = typeChecker.getSymbolAtLocation(location);
                    if (symbol) {
                        if (symbol.flags & 2097152 /* Alias */) {
                            symbol = typeChecker.getAliasedSymbol(symbol);
                        }
                        if (symbol.valueDeclaration) {
                            followingSymbol = true;
                            location = symbol.valueDeclaration;
                            continue;
                        }
                    }
                }
                return undefined;
            }
        }
        CallHierarchy.resolveCallHierarchyDeclaration = resolveCallHierarchyDeclaration;
        /** Creates a `CallHierarchyItem` for a call hierarchy declaration. */
        function createCallHierarchyItem(program, node) {
            var sourceFile = node.getSourceFile();
            var name = getCallHierarchyItemName(program, node);
            var kind = ts.getNodeKind(node);
            var span = ts.createTextSpanFromBounds(ts.skipTrivia(sourceFile.text, node.getFullStart(), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true), node.getEnd());
            var selectionSpan = ts.createTextSpanFromBounds(name.pos, name.end);
            return { file: sourceFile.fileName, kind: kind, name: name.text, span: span, selectionSpan: selectionSpan };
        }
        CallHierarchy.createCallHierarchyItem = createCallHierarchyItem;
        function isDefined(x) {
            return x !== undefined;
        }
        function convertEntryToCallSite(entry) {
            if (entry.kind === 1 /* Node */) {
                var node = entry.node;
                if (ts.isCallOrNewExpressionTarget(node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true)
                    || ts.isTaggedTemplateTag(node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true)
                    || ts.isDecoratorTarget(node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true)
                    || ts.isJsxOpeningLikeElementTagName(node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true)
                    || ts.isRightSideOfPropertyAccess(node)
                    || ts.isArgumentExpressionOfElementAccess(node)) {
                    var sourceFile = node.getSourceFile();
                    var ancestor = ts.findAncestor(node, isValidCallHierarchyDeclaration) || sourceFile;
                    return { declaration: ancestor, range: ts.createTextRangeFromNode(node, sourceFile) };
                }
            }
        }
        function getCallSiteGroupKey(entry) {
            return "" + ts.getNodeId(entry.declaration);
        }
        function createCallHierarchyIncomingCall(from, fromSpans) {
            return { from: from, fromSpans: fromSpans };
        }
        function convertCallSiteGroupToIncomingCall(program, entries) {
            return createCallHierarchyIncomingCall(createCallHierarchyItem(program, entries[0].declaration), ts.map(entries, function (entry) { return ts.createTextSpanFromRange(entry.range); }));
        }
        /** Gets the call sites that call into the provided call hierarchy declaration. */
        function getIncomingCalls(program, declaration, cancellationToken) {
            // Source files and modules have no incoming calls.
            if (ts.isSourceFile(declaration) || ts.isModuleDeclaration(declaration)) {
                return [];
            }
            var location = getCallHierarchyDeclarationReferenceNode(declaration);
            var calls = ts.filter(ts.FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, program.getSourceFiles(), location, /*position*/ 0, { use: 1 /* References */ }, convertEntryToCallSite), isDefined);
            return calls ? ts.group(calls, getCallSiteGroupKey, function (entries) { return convertCallSiteGroupToIncomingCall(program, entries); }) : [];
        }
        CallHierarchy.getIncomingCalls = getIncomingCalls;
        function createCallSiteCollector(program, callSites) {
            function recordCallSite(node) {
                var target = ts.isTaggedTemplateExpression(node) ? node.tag :
                    ts.isJsxOpeningLikeElement(node) ? node.tagName :
                        ts.isAccessExpression(node) ? node :
                            node.expression;
                var declaration = resolveCallHierarchyDeclaration(program, target);
                if (declaration) {
                    var range = ts.createTextRangeFromNode(target, node.getSourceFile());
                    if (ts.isArray(declaration)) {
                        for (var _i = 0, declaration_1 = declaration; _i < declaration_1.length; _i++) {
                            var decl = declaration_1[_i];
                            callSites.push({ declaration: decl, range: range });
                        }
                    }
                    else {
                        callSites.push({ declaration: declaration, range: range });
                    }
                }
            }
            function collect(node) {
                if (!node)
                    return;
                if (node.flags & 8388608 /* Ambient */) {
                    // do not descend into ambient nodes.
                    return;
                }
                if (isValidCallHierarchyDeclaration(node)) {
                    // do not descend into other call site declarations, other than class member names
                    if (ts.isClassLike(node)) {
                        for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                            var member = _a[_i];
                            if (member.name && ts.isComputedPropertyName(member.name)) {
                                collect(member.name.expression);
                            }
                        }
                    }
                    return;
                }
                switch (node.kind) {
                    case 75 /* Identifier */:
                    case 253 /* ImportEqualsDeclaration */:
                    case 254 /* ImportDeclaration */:
                    case 260 /* ExportDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                        // do not descend into nodes that cannot contain callable nodes
                        return;
                    case 199 /* TypeAssertionExpression */:
                    case 217 /* AsExpression */:
                        // do not descend into the type side of an assertion
                        collect(node.expression);
                        return;
                    case 242 /* VariableDeclaration */:
                    case 156 /* Parameter */:
                        // do not descend into the type of a variable or parameter declaration
                        collect(node.name);
                        collect(node.initializer);
                        return;
                    case 196 /* CallExpression */:
                        // do not descend into the type arguments of a call expression
                        recordCallSite(node);
                        collect(node.expression);
                        ts.forEach(node.arguments, collect);
                        return;
                    case 197 /* NewExpression */:
                        // do not descend into the type arguments of a new expression
                        recordCallSite(node);
                        collect(node.expression);
                        ts.forEach(node.arguments, collect);
                        return;
                    case 198 /* TaggedTemplateExpression */:
                        // do not descend into the type arguments of a tagged template expression
                        recordCallSite(node);
                        collect(node.tag);
                        collect(node.template);
                        return;
                    case 268 /* JsxOpeningElement */:
                    case 267 /* JsxSelfClosingElement */:
                        // do not descend into the type arguments of a JsxOpeningLikeElement
                        recordCallSite(node);
                        collect(node.tagName);
                        collect(node.attributes);
                        return;
                    case 157 /* Decorator */:
                        recordCallSite(node);
                        collect(node.expression);
                        return;
                    case 194 /* PropertyAccessExpression */:
                    case 195 /* ElementAccessExpression */:
                        recordCallSite(node);
                        ts.forEachChild(node, collect);
                        break;
                }
                if (ts.isPartOfTypeNode(node)) {
                    // do not descend into types
                    return;
                }
                ts.forEachChild(node, collect);
            }
            return collect;
        }
        function collectCallSitesOfSourceFile(node, collect) {
            ts.forEach(node.statements, collect);
        }
        function collectCallSitesOfModuleDeclaration(node, collect) {
            if (!ts.hasModifier(node, 2 /* Ambient */) && node.body && ts.isModuleBlock(node.body)) {
                ts.forEach(node.body.statements, collect);
            }
        }
        function collectCallSitesOfFunctionLikeDeclaration(typeChecker, node, collect) {
            var implementation = findImplementation(typeChecker, node);
            if (implementation) {
                ts.forEach(implementation.parameters, collect);
                collect(implementation.body);
            }
        }
        function collectCallSitesOfClassLikeDeclaration(node, collect) {
            ts.forEach(node.decorators, collect);
            var heritage = ts.getClassExtendsHeritageElement(node);
            if (heritage) {
                collect(heritage.expression);
            }
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                ts.forEach(member.decorators, collect);
                if (ts.isPropertyDeclaration(member)) {
                    collect(member.initializer);
                }
                else if (ts.isConstructorDeclaration(member) && member.body) {
                    ts.forEach(member.parameters, collect);
                    collect(member.body);
                }
            }
        }
        function collectCallSites(program, node) {
            var callSites = [];
            var collect = createCallSiteCollector(program, callSites);
            switch (node.kind) {
                case 290 /* SourceFile */:
                    collectCallSitesOfSourceFile(node, collect);
                    break;
                case 249 /* ModuleDeclaration */:
                    collectCallSitesOfModuleDeclaration(node, collect);
                    break;
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    collectCallSitesOfFunctionLikeDeclaration(program.getTypeChecker(), node, collect);
                    break;
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    collectCallSitesOfClassLikeDeclaration(node, collect);
                    break;
                default:
                    ts.Debug.assertNever(node);
            }
            return callSites;
        }
        function createCallHierarchyOutgoingCall(to, fromSpans) {
            return { to: to, fromSpans: fromSpans };
        }
        function convertCallSiteGroupToOutgoingCall(program, entries) {
            return createCallHierarchyOutgoingCall(createCallHierarchyItem(program, entries[0].declaration), ts.map(entries, function (entry) { return ts.createTextSpanFromRange(entry.range); }));
        }
        /** Gets the call sites that call out of the provided call hierarchy declaration. */
        function getOutgoingCalls(program, declaration) {
            if (declaration.flags & 8388608 /* Ambient */ || ts.isMethodSignature(declaration)) {
                return [];
            }
            return ts.group(collectCallSites(program, declaration), getCallSiteGroupKey, function (entries) { return convertCallSiteGroupToOutgoingCall(program, entries); });
        }
        CallHierarchy.getOutgoingCalls = getOutgoingCalls;
    })(CallHierarchy = ts.CallHierarchy || (ts.CallHierarchy = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getEditsForFileRename(program, oldFileOrDirPath, newFileOrDirPath, host, formatContext, preferences, sourceMapper) {
        var useCaseSensitiveFileNames = ts.hostUsesCaseSensitiveFileNames(host);
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        var oldToNew = getPathUpdater(oldFileOrDirPath, newFileOrDirPath, getCanonicalFileName, sourceMapper);
        var newToOld = getPathUpdater(newFileOrDirPath, oldFileOrDirPath, getCanonicalFileName, sourceMapper);
        return ts.textChanges.ChangeTracker.with({ host: host, formatContext: formatContext, preferences: preferences }, function (changeTracker) {
            updateTsconfigFiles(program, changeTracker, oldToNew, oldFileOrDirPath, newFileOrDirPath, host.getCurrentDirectory(), useCaseSensitiveFileNames);
            updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName);
        });
    }
    ts.getEditsForFileRename = getEditsForFileRename;
    // exported for tests
    function getPathUpdater(oldFileOrDirPath, newFileOrDirPath, getCanonicalFileName, sourceMapper) {
        var canonicalOldPath = getCanonicalFileName(oldFileOrDirPath);
        return function (path) {
            var originalPath = sourceMapper && sourceMapper.tryGetSourcePosition({ fileName: path, pos: 0 });
            var updatedPath = getUpdatedPath(originalPath ? originalPath.fileName : path);
            return originalPath
                ? updatedPath === undefined ? undefined : makeCorrespondingRelativeChange(originalPath.fileName, updatedPath, path, getCanonicalFileName)
                : updatedPath;
        };
        function getUpdatedPath(pathToUpdate) {
            if (getCanonicalFileName(pathToUpdate) === canonicalOldPath)
                return newFileOrDirPath;
            var suffix = ts.tryRemoveDirectoryPrefix(pathToUpdate, canonicalOldPath, getCanonicalFileName);
            return suffix === undefined ? undefined : newFileOrDirPath + "/" + suffix;
        }
    }
    ts.getPathUpdater = getPathUpdater;
    // Relative path from a0 to b0 should be same as relative path from a1 to b1. Returns b1.
    function makeCorrespondingRelativeChange(a0, b0, a1, getCanonicalFileName) {
        var rel = ts.getRelativePathFromFile(a0, b0, getCanonicalFileName);
        return combinePathsSafe(ts.getDirectoryPath(a1), rel);
    }
    function updateTsconfigFiles(program, changeTracker, oldToNew, oldFileOrDirPath, newFileOrDirPath, currentDirectory, useCaseSensitiveFileNames) {
        var configFile = program.getCompilerOptions().configFile;
        if (!configFile)
            return;
        var configDir = ts.getDirectoryPath(configFile.fileName);
        var jsonObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile);
        if (!jsonObjectLiteral)
            return;
        forEachProperty(jsonObjectLiteral, function (property, propertyName) {
            switch (propertyName) {
                case "files":
                case "include":
                case "exclude": {
                    var foundExactMatch = updatePaths(property);
                    if (!foundExactMatch && propertyName === "include" && ts.isArrayLiteralExpression(property.initializer)) {
                        var includes = ts.mapDefined(property.initializer.elements, function (e) { return ts.isStringLiteral(e) ? e.text : undefined; });
                        var matchers = ts.getFileMatcherPatterns(configDir, /*excludes*/ [], includes, useCaseSensitiveFileNames, currentDirectory);
                        // If there isn't some include for this, add a new one.
                        if (ts.getRegexFromPattern(ts.Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(oldFileOrDirPath) &&
                            !ts.getRegexFromPattern(ts.Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) {
                            changeTracker.insertNodeAfter(configFile, ts.last(property.initializer.elements), ts.createStringLiteral(relativePath(newFileOrDirPath)));
                        }
                    }
                    break;
                }
                case "compilerOptions":
                    forEachProperty(property.initializer, function (property, propertyName) {
                        var option = ts.getOptionFromName(propertyName);
                        if (option && (option.isFilePath || option.type === "list" && option.element.isFilePath)) {
                            updatePaths(property);
                        }
                        else if (propertyName === "paths") {
                            forEachProperty(property.initializer, function (pathsProperty) {
                                if (!ts.isArrayLiteralExpression(pathsProperty.initializer))
                                    return;
                                for (var _i = 0, _a = pathsProperty.initializer.elements; _i < _a.length; _i++) {
                                    var e = _a[_i];
                                    tryUpdateString(e);
                                }
                            });
                        }
                    });
                    break;
            }
        });
        function updatePaths(property) {
            // Type annotation needed due to #7294
            var elements = ts.isArrayLiteralExpression(property.initializer) ? property.initializer.elements : [property.initializer];
            var foundExactMatch = false;
            for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
                var element = elements_1[_i];
                foundExactMatch = tryUpdateString(element) || foundExactMatch;
            }
            return foundExactMatch;
        }
        function tryUpdateString(element) {
            if (!ts.isStringLiteral(element))
                return false;
            var elementFileName = combinePathsSafe(configDir, element.text);
            var updated = oldToNew(elementFileName);
            if (updated !== undefined) {
                changeTracker.replaceRangeWithText(configFile, createStringRange(element, configFile), relativePath(updated));
                return true;
            }
            return false;
        }
        function relativePath(path) {
            return ts.getRelativePathFromDirectory(configDir, path, /*ignoreCase*/ !useCaseSensitiveFileNames);
        }
    }
    function updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName) {
        var allFiles = program.getSourceFiles();
        var _loop_4 = function (sourceFile) {
            var newFromOld = oldToNew(sourceFile.path);
            var newImportFromPath = newFromOld !== undefined ? newFromOld : sourceFile.path;
            var newImportFromDirectory = ts.getDirectoryPath(newImportFromPath);
            var oldFromNew = newToOld(sourceFile.fileName);
            var oldImportFromPath = oldFromNew || sourceFile.fileName;
            var oldImportFromDirectory = ts.getDirectoryPath(oldImportFromPath);
            var importingSourceFileMoved = newFromOld !== undefined || oldFromNew !== undefined;
            updateImportsWorker(sourceFile, changeTracker, function (referenceText) {
                if (!ts.pathIsRelative(referenceText))
                    return undefined;
                var oldAbsolute = combinePathsSafe(oldImportFromDirectory, referenceText);
                var newAbsolute = oldToNew(oldAbsolute);
                return newAbsolute === undefined ? undefined : ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(newImportFromDirectory, newAbsolute, getCanonicalFileName));
            }, function (importLiteral) {
                var importedModuleSymbol = program.getTypeChecker().getSymbolAtLocation(importLiteral);
                // No need to update if it's an ambient module^M
                if (importedModuleSymbol && importedModuleSymbol.declarations.some(function (d) { return ts.isAmbientModule(d); }))
                    return undefined;
                var toImport = oldFromNew !== undefined
                    // If we're at the new location (file was already renamed), need to redo module resolution starting from the old location.
                    // TODO:GH#18217
                    ? getSourceFileToImportFromResolved(ts.resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host), oldToNew, allFiles)
                    : getSourceFileToImport(importedModuleSymbol, importLiteral, sourceFile, program, host, oldToNew);
                // Need an update if the imported file moved, or the importing file moved and was using a relative path.
                return toImport !== undefined && (toImport.updated || (importingSourceFileMoved && ts.pathIsRelative(importLiteral.text)))
                    ? ts.moduleSpecifiers.updateModuleSpecifier(program.getCompilerOptions(), newImportFromPath, toImport.newFileName, ts.createModuleSpecifierResolutionHost(program, host), importLiteral.text)
                    : undefined;
            });
        };
        for (var _i = 0, allFiles_1 = allFiles; _i < allFiles_1.length; _i++) {
            var sourceFile = allFiles_1[_i];
            _loop_4(sourceFile);
        }
    }
    function combineNormal(pathA, pathB) {
        return ts.normalizePath(ts.combinePaths(pathA, pathB));
    }
    function combinePathsSafe(pathA, pathB) {
        return ts.ensurePathIsNonModuleName(combineNormal(pathA, pathB));
    }
    function getSourceFileToImport(importedModuleSymbol, importLiteral, importingSourceFile, program, host, oldToNew) {
        if (importedModuleSymbol) {
            // `find` should succeed because we checked for ambient modules before calling this function.
            var oldFileName = ts.find(importedModuleSymbol.declarations, ts.isSourceFile).fileName;
            var newFileName = oldToNew(oldFileName);
            return newFileName === undefined ? { newFileName: oldFileName, updated: false } : { newFileName: newFileName, updated: true };
        }
        else {
            var resolved = host.resolveModuleNames
                ? host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName)
                : program.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName);
            return getSourceFileToImportFromResolved(resolved, oldToNew, program.getSourceFiles());
        }
    }
    function getSourceFileToImportFromResolved(resolved, oldToNew, sourceFiles) {
        // Search through all locations looking for a moved file, and only then test already existing files.
        // This is because if `a.ts` is compiled to `a.js` and `a.ts` is moved, we don't want to resolve anything to `a.js`, but to `a.ts`'s new location.
        if (!resolved)
            return undefined;
        // First try resolved module
        if (resolved.resolvedModule) {
            var result_2 = tryChange(resolved.resolvedModule.resolvedFileName);
            if (result_2)
                return result_2;
        }
        // Then failed lookups that are in the list of sources
        var result = ts.forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJsonExisting)
            // Then failed lookups except package.json since we dont want to touch them (only included ts/js files)
            || ts.forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJson);
        if (result)
            return result;
        // If nothing changed, then result is resolved module file thats not updated
        return resolved.resolvedModule && { newFileName: resolved.resolvedModule.resolvedFileName, updated: false };
        function tryChangeWithIgnoringPackageJsonExisting(oldFileName) {
            var newFileName = oldToNew(oldFileName);
            return newFileName && ts.find(sourceFiles, function (src) { return src.fileName === newFileName; })
                ? tryChangeWithIgnoringPackageJson(oldFileName) : undefined;
        }
        function tryChangeWithIgnoringPackageJson(oldFileName) {
            return !ts.endsWith(oldFileName, "/package.json") ? tryChange(oldFileName) : undefined;
        }
        function tryChange(oldFileName) {
            var newFileName = oldToNew(oldFileName);
            return newFileName && { newFileName: newFileName, updated: true };
        }
    }
    function updateImportsWorker(sourceFile, changeTracker, updateRef, updateImport) {
        for (var _i = 0, _a = sourceFile.referencedFiles || ts.emptyArray; _i < _a.length; _i++) { // TODO: GH#26162
            var ref = _a[_i];
            var updated = updateRef(ref.fileName);
            if (updated !== undefined && updated !== sourceFile.text.slice(ref.pos, ref.end))
                changeTracker.replaceRangeWithText(sourceFile, ref, updated);
        }
        for (var _b = 0, _c = sourceFile.imports; _b < _c.length; _b++) {
            var importStringLiteral = _c[_b];
            var updated = updateImport(importStringLiteral);
            if (updated !== undefined && updated !== importStringLiteral.text)
                changeTracker.replaceRangeWithText(sourceFile, createStringRange(importStringLiteral, sourceFile), updated);
        }
    }
    function createStringRange(node, sourceFile) {
        return ts.createRange(node.getStart(sourceFile) + 1, node.end - 1);
    }
    function forEachProperty(objectLiteral, cb) {
        if (!ts.isObjectLiteralExpression(objectLiteral))
            return;
        for (var _i = 0, _a = objectLiteral.properties; _i < _a.length; _i++) {
            var property = _a[_i];
            if (ts.isPropertyAssignment(property) && ts.isStringLiteral(property.name)) {
                cb(property, property.name.text);
            }
        }
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var GoToDefinition;
    (function (GoToDefinition) {
        function getDefinitionAtPosition(program, sourceFile, position) {
            var reference = getReferenceAtPosition(sourceFile, position, program);
            if (reference) {
                return [getDefinitionInfoForFileReference(reference.fileName, reference.file.fileName)];
            }
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                return undefined;
            }
            var parent = node.parent;
            var typeChecker = program.getTypeChecker();
            // Labels
            if (ts.isJumpStatementTarget(node)) {
                var label = ts.getTargetLabel(node.parent, node.text);
                return label ? [createDefinitionInfoFromName(typeChecker, label, "label" /* label */, node.text, /*containerName*/ undefined)] : undefined; // TODO: GH#18217
            }
            var symbol = getSymbol(node, typeChecker);
            // Could not find a symbol e.g. node is string or number keyword,
            // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
            if (!symbol) {
                return getDefinitionInfoForIndexSignatures(node, typeChecker);
            }
            var calledDeclaration = tryGetSignatureDeclaration(typeChecker, node);
            // Don't go to the component constructor definition for a JSX element, just go to the component definition.
            if (calledDeclaration && !(ts.isJsxOpeningLikeElement(node.parent) && isConstructorLike(calledDeclaration))) {
                var sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration);
                // For a function, if this is the original function definition, return just sigInfo.
                // If this is the original constructor definition, parent is the class.
                if (typeChecker.getRootSymbols(symbol).some(function (s) { return symbolMatchesSignature(s, calledDeclaration); }) ||
                    // TODO: GH#25533 Following check shouldn't be necessary if 'require' is an alias
                    symbol.declarations && symbol.declarations.some(function (d) { return ts.isVariableDeclaration(d) && !!d.initializer && ts.isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ false); })) {
                    return [sigInfo];
                }
                else {
                    var defs = getDefinitionFromSymbol(typeChecker, symbol, node, calledDeclaration) || ts.emptyArray;
                    // For a 'super()' call, put the signature first, else put the variable first.
                    return node.kind === 102 /* SuperKeyword */ ? __spreadArrays([sigInfo], defs) : __spreadArrays(defs, [sigInfo]);
                }
            }
            // Because name in short-hand property assignment has two different meanings: property name and property value,
            // using go-to-definition at such position should go to the variable declaration of the property value rather than
            // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
            // is performed at the location of property access, we would like to go to definition of the property in the short-hand
            // assignment. This case and others are handled by the following code.
            if (node.parent.kind === 282 /* ShorthandPropertyAssignment */) {
                var shorthandSymbol_1 = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
                return shorthandSymbol_1 ? shorthandSymbol_1.declarations.map(function (decl) { return createDefinitionInfo(decl, typeChecker, shorthandSymbol_1, node); }) : [];
            }
            // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
            // declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern
            // and return the property declaration for the referenced property.
            // For example:
            //      import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo"
            //
            //      function bar<T>(onfulfilled: (value: T) => void) { //....}
            //      interface Test {
            //          pr/*destination*/op1: number
            //      }
            //      bar<Test>(({pr/*goto*/op1})=>{});
            if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
                (node === (parent.propertyName || parent.name))) {
                var name_3 = ts.getNameFromPropertyName(node);
                var type = typeChecker.getTypeAtLocation(parent.parent);
                return name_3 === undefined ? ts.emptyArray : ts.flatMap(type.isUnion() ? type.types : [type], function (t) {
                    var prop = t.getProperty(name_3);
                    return prop && getDefinitionFromSymbol(typeChecker, prop, node);
                });
            }
            // If the current location we want to find its definition is in an object literal, try to get the contextual type for the
            // object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
            // For example
            //      interface Props{
            //          /*first*/prop1: number
            //          prop2: boolean
            //      }
            //      function Foo(arg: Props) {}
            //      Foo( { pr/*1*/op1: 10, prop2: true })
            var element = ts.getContainingObjectLiteralElement(node);
            if (element) {
                var contextualType = element && typeChecker.getContextualType(element.parent);
                if (contextualType) {
                    return ts.flatMap(ts.getPropertySymbolsFromContextualType(element, typeChecker, contextualType, /*unionSymbolOk*/ false), function (propertySymbol) {
                        return getDefinitionFromSymbol(typeChecker, propertySymbol, node);
                    });
                }
            }
            return getDefinitionFromSymbol(typeChecker, symbol, node);
        }
        GoToDefinition.getDefinitionAtPosition = getDefinitionAtPosition;
        /**
         * True if we should not add definitions for both the signature symbol and the definition symbol.
         * True for `const |f = |() => 0`, false for `function |f() {} const |g = f;`.
         */
        function symbolMatchesSignature(s, calledDeclaration) {
            return s === calledDeclaration.symbol || s === calledDeclaration.symbol.parent ||
                !ts.isCallLikeExpression(calledDeclaration.parent) && s === calledDeclaration.parent.symbol;
        }
        function getReferenceAtPosition(sourceFile, position, program) {
            var referencePath = findReferenceInPosition(sourceFile.referencedFiles, position);
            if (referencePath) {
                var file = program.getSourceFileFromReference(sourceFile, referencePath);
                return file && { fileName: referencePath.fileName, file: file };
            }
            var typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
            if (typeReferenceDirective) {
                var reference = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName);
                var file = reference && program.getSourceFile(reference.resolvedFileName); // TODO:GH#18217
                return file && { fileName: typeReferenceDirective.fileName, file: file };
            }
            var libReferenceDirective = findReferenceInPosition(sourceFile.libReferenceDirectives, position);
            if (libReferenceDirective) {
                var file = program.getLibFileFromReference(libReferenceDirective);
                return file && { fileName: libReferenceDirective.fileName, file: file };
            }
            return undefined;
        }
        GoToDefinition.getReferenceAtPosition = getReferenceAtPosition;
        /// Goto type
        function getTypeDefinitionAtPosition(typeChecker, sourceFile, position) {
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                return undefined;
            }
            var symbol = typeChecker.getSymbolAtLocation(node);
            if (!symbol)
                return undefined;
            var typeAtLocation = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
            var returnType = tryGetReturnTypeOfFunction(symbol, typeAtLocation, typeChecker);
            var fromReturnType = returnType && definitionFromType(returnType, typeChecker, node);
            // If a function returns 'void' or some other type with no definition, just return the function definition.
            return fromReturnType && fromReturnType.length !== 0 ? fromReturnType : definitionFromType(typeAtLocation, typeChecker, node);
        }
        GoToDefinition.getTypeDefinitionAtPosition = getTypeDefinitionAtPosition;
        function definitionFromType(type, checker, node) {
            return ts.flatMap(type.isUnion() && !(type.flags & 32 /* Enum */) ? type.types : [type], function (t) {
                return t.symbol && getDefinitionFromSymbol(checker, t.symbol, node);
            });
        }
        function tryGetReturnTypeOfFunction(symbol, type, checker) {
            // If the type is just a function's inferred type,
            // go-to-type should go to the return type instead, since go-to-definition takes you to the function anyway.
            if (type.symbol === symbol ||
                // At `const f = () => {}`, the symbol is `f` and the type symbol is at `() => {}`
                symbol.valueDeclaration && type.symbol && ts.isVariableDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.initializer === type.symbol.valueDeclaration) {
                var sigs = type.getCallSignatures();
                if (sigs.length === 1)
                    return checker.getReturnTypeOfSignature(ts.first(sigs));
            }
            return undefined;
        }
        function getDefinitionAndBoundSpan(program, sourceFile, position) {
            var definitions = getDefinitionAtPosition(program, sourceFile, position);
            if (!definitions || definitions.length === 0) {
                return undefined;
            }
            // Check if position is on triple slash reference.
            var comment = findReferenceInPosition(sourceFile.referencedFiles, position) ||
                findReferenceInPosition(sourceFile.typeReferenceDirectives, position) ||
                findReferenceInPosition(sourceFile.libReferenceDirectives, position);
            if (comment) {
                return { definitions: definitions, textSpan: ts.createTextSpanFromRange(comment) };
            }
            var node = ts.getTouchingPropertyName(sourceFile, position);
            var textSpan = ts.createTextSpan(node.getStart(), node.getWidth());
            return { definitions: definitions, textSpan: textSpan };
        }
        GoToDefinition.getDefinitionAndBoundSpan = getDefinitionAndBoundSpan;
        // At 'x.foo', see if the type of 'x' has an index signature, and if so find its declarations.
        function getDefinitionInfoForIndexSignatures(node, checker) {
            if (!ts.isPropertyAccessExpression(node.parent) || node.parent.name !== node)
                return;
            var type = checker.getTypeAtLocation(node.parent.expression);
            return ts.mapDefined(type.isUnionOrIntersection() ? type.types : [type], function (nonUnionType) {
                var info = checker.getIndexInfoOfType(nonUnionType, 0 /* String */);
                return info && info.declaration && createDefinitionFromSignatureDeclaration(checker, info.declaration);
            });
        }
        function getSymbol(node, checker) {
            var symbol = checker.getSymbolAtLocation(node);
            // If this is an alias, and the request came at the declaration location
            // get the aliased symbol instead. This allows for goto def on an import e.g.
            //   import {A, B} from "mod";
            // to jump to the implementation directly.
            if (symbol && symbol.flags & 2097152 /* Alias */ && shouldSkipAlias(node, symbol.declarations[0])) {
                var aliased = checker.getAliasedSymbol(symbol);
                if (aliased.declarations) {
                    return aliased;
                }
            }
            if (symbol && ts.isInJSFile(node)) {
                var requireCall = ts.forEach(symbol.declarations, function (d) { return ts.isVariableDeclaration(d) && !!d.initializer && ts.isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ true) ? d.initializer : undefined; });
                if (requireCall) {
                    var moduleSymbol = checker.getSymbolAtLocation(requireCall.arguments[0]);
                    if (moduleSymbol) {
                        return checker.resolveExternalModuleSymbol(moduleSymbol);
                    }
                }
            }
            return symbol;
        }
        // Go to the original declaration for cases:
        //
        //   (1) when the aliased symbol was declared in the location(parent).
        //   (2) when the aliased symbol is originating from an import.
        //
        function shouldSkipAlias(node, declaration) {
            if (node.kind !== 75 /* Identifier */) {
                return false;
            }
            if (node.parent === declaration) {
                return true;
            }
            switch (declaration.kind) {
                case 255 /* ImportClause */:
                case 253 /* ImportEqualsDeclaration */:
                    return true;
                case 258 /* ImportSpecifier */:
                    return declaration.parent.kind === 257 /* NamedImports */;
                default:
                    return false;
            }
        }
        function getDefinitionFromSymbol(typeChecker, symbol, node, declarationNode) {
            // There are cases when you extend a function by adding properties to it afterwards,
            // we want to strip those extra properties.
            // For deduping purposes, we also want to exclude any declarationNodes if provided.
            var filteredDeclarations = ts.filter(symbol.declarations, function (d) { return d !== declarationNode && (!ts.isAssignmentDeclaration(d) || d === symbol.valueDeclaration); }) || undefined;
            return getConstructSignatureDefinition() || getCallSignatureDefinition() || ts.map(filteredDeclarations, function (declaration) { return createDefinitionInfo(declaration, typeChecker, symbol, node); });
            function getConstructSignatureDefinition() {
                // Applicable only if we are in a new expression, or we are on a constructor declaration
                // and in either case the symbol has a construct signature definition, i.e. class
                if (symbol.flags & 32 /* Class */ && !(symbol.flags & (16 /* Function */ | 3 /* Variable */)) && (ts.isNewExpressionTarget(node) || node.kind === 129 /* ConstructorKeyword */)) {
                    var cls = ts.find(filteredDeclarations, ts.isClassLike) || ts.Debug.fail("Expected declaration to have at least one class-like declaration");
                    return getSignatureDefinition(cls.members, /*selectConstructors*/ true);
                }
            }
            function getCallSignatureDefinition() {
                return ts.isCallOrNewExpressionTarget(node) || ts.isNameOfFunctionDeclaration(node)
                    ? getSignatureDefinition(filteredDeclarations, /*selectConstructors*/ false)
                    : undefined;
            }
            function getSignatureDefinition(signatureDeclarations, selectConstructors) {
                if (!signatureDeclarations) {
                    return undefined;
                }
                var declarations = signatureDeclarations.filter(selectConstructors ? ts.isConstructorDeclaration : ts.isFunctionLike);
                var declarationsWithBody = declarations.filter(function (d) { return !!d.body; });
                // declarations defined on the global scope can be defined on multiple files. Get all of them.
                return declarations.length
                    ? declarationsWithBody.length !== 0
                        ? declarationsWithBody.map(function (x) { return createDefinitionInfo(x, typeChecker, symbol, node); })
                        : [createDefinitionInfo(ts.last(declarations), typeChecker, symbol, node)]
                    : undefined;
            }
        }
        /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */
        function createDefinitionInfo(declaration, checker, symbol, node) {
            var symbolName = checker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
            var symbolKind = ts.SymbolDisplay.getSymbolKind(checker, symbol, node);
            var containerName = symbol.parent ? checker.symbolToString(symbol.parent, node) : "";
            return createDefinitionInfoFromName(checker, declaration, symbolKind, symbolName, containerName);
        }
        /** Creates a DefinitionInfo directly from the name of a declaration. */
        function createDefinitionInfoFromName(checker, declaration, symbolKind, symbolName, containerName) {
            var name = ts.getNameOfDeclaration(declaration) || declaration;
            var sourceFile = name.getSourceFile();
            var textSpan = ts.createTextSpanFromNode(name, sourceFile);
            return __assign(__assign({ fileName: sourceFile.fileName, textSpan: textSpan, kind: symbolKind, name: symbolName, containerKind: undefined, // TODO: GH#18217
                containerName: containerName }, ts.FindAllReferences.toContextSpan(textSpan, sourceFile, ts.FindAllReferences.getContextNode(declaration))), { isLocal: !checker.isDeclarationVisible(declaration) });
        }
        function createDefinitionFromSignatureDeclaration(typeChecker, decl) {
            return createDefinitionInfo(decl, typeChecker, decl.symbol, decl);
        }
        function findReferenceInPosition(refs, pos) {
            return ts.find(refs, function (ref) { return ts.textRangeContainsPositionInclusive(ref, pos); });
        }
        GoToDefinition.findReferenceInPosition = findReferenceInPosition;
        function getDefinitionInfoForFileReference(name, targetFileName) {
            return {
                fileName: targetFileName,
                textSpan: ts.createTextSpanFromBounds(0, 0),
                kind: "script" /* scriptElement */,
                name: name,
                containerName: undefined,
                containerKind: undefined,
            };
        }
        /** Returns a CallLikeExpression where `node` is the target being invoked. */
        function getAncestorCallLikeExpression(node) {
            var target = climbPastManyPropertyAccesses(node);
            var callLike = target.parent;
            return callLike && ts.isCallLikeExpression(callLike) && ts.getInvokedExpression(callLike) === target ? callLike : undefined;
        }
        function climbPastManyPropertyAccesses(node) {
            return ts.isRightSideOfPropertyAccess(node) ? climbPastManyPropertyAccesses(node.parent) : node;
        }
        function tryGetSignatureDeclaration(typeChecker, node) {
            var callLike = getAncestorCallLikeExpression(node);
            var signature = callLike && typeChecker.getResolvedSignature(callLike);
            // Don't go to a function type, go to the value having that type.
            return ts.tryCast(signature && signature.declaration, function (d) { return ts.isFunctionLike(d) && !ts.isFunctionTypeNode(d); });
        }
        function isConstructorLike(node) {
            switch (node.kind) {
                case 162 /* Constructor */:
                case 171 /* ConstructorType */:
                case 166 /* ConstructSignature */:
                    return true;
                default:
                    return false;
            }
        }
    })(GoToDefinition = ts.GoToDefinition || (ts.GoToDefinition = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var JsDoc;
    (function (JsDoc) {
        var jsDocTagNames = [
            "abstract",
            "access",
            "alias",
            "argument",
            "async",
            "augments",
            "author",
            "borrows",
            "callback",
            "class",
            "classdesc",
            "constant",
            "constructor",
            "constructs",
            "copyright",
            "default",
            "deprecated",
            "description",
            "emits",
            "enum",
            "event",
            "example",
            "exports",
            "extends",
            "external",
            "field",
            "file",
            "fileoverview",
            "fires",
            "function",
            "generator",
            "global",
            "hideconstructor",
            "host",
            "ignore",
            "implements",
            "inheritdoc",
            "inner",
            "instance",
            "interface",
            "kind",
            "lends",
            "license",
            "listens",
            "member",
            "memberof",
            "method",
            "mixes",
            "module",
            "name",
            "namespace",
            "override",
            "package",
            "param",
            "private",
            "property",
            "protected",
            "public",
            "readonly",
            "requires",
            "returns",
            "see",
            "since",
            "static",
            "summary",
            "template",
            "this",
            "throws",
            "todo",
            "tutorial",
            "type",
            "typedef",
            "var",
            "variation",
            "version",
            "virtual",
            "yields"
        ];
        var jsDocTagNameCompletionEntries;
        var jsDocTagCompletionEntries;
        function getJsDocCommentsFromDeclarations(declarations) {
            // Only collect doc comments from duplicate declarations once:
            // In case of a union property there might be same declaration multiple times
            // which only varies in type parameter
            // Eg. const a: Array<string> | Array<number>; a.length
            // The property length will have two declarations of property length coming
            // from Array<T> - Array<string> and Array<number>
            var documentationComment = [];
            ts.forEachUnique(declarations, function (declaration) {
                for (var _i = 0, _a = getCommentHavingNodes(declaration); _i < _a.length; _i++) {
                    var comment = _a[_i].comment;
                    if (comment === undefined)
                        continue;
                    if (documentationComment.length) {
                        documentationComment.push(ts.lineBreakPart());
                    }
                    documentationComment.push(ts.textPart(comment));
                }
            });
            return documentationComment;
        }
        JsDoc.getJsDocCommentsFromDeclarations = getJsDocCommentsFromDeclarations;
        function getCommentHavingNodes(declaration) {
            switch (declaration.kind) {
                case 317 /* JSDocParameterTag */:
                case 323 /* JSDocPropertyTag */:
                    return [declaration];
                case 315 /* JSDocCallbackTag */:
                case 322 /* JSDocTypedefTag */:
                    return [declaration, declaration.parent];
                default:
                    return ts.getJSDocCommentsAndTags(declaration);
            }
        }
        function getJsDocTagsFromDeclarations(declarations) {
            // Only collect doc comments from duplicate declarations once.
            var tags = [];
            ts.forEachUnique(declarations, function (declaration) {
                for (var _i = 0, _a = ts.getJSDocTags(declaration); _i < _a.length; _i++) {
                    var tag = _a[_i];
                    tags.push({ name: tag.tagName.text, text: getCommentText(tag) });
                }
            });
            return tags;
        }
        JsDoc.getJsDocTagsFromDeclarations = getJsDocTagsFromDeclarations;
        function getCommentText(tag) {
            var comment = tag.comment;
            switch (tag.kind) {
                case 308 /* JSDocImplementsTag */:
                    return withNode(tag.class);
                case 307 /* JSDocAugmentsTag */:
                    return withNode(tag.class);
                case 321 /* JSDocTemplateTag */:
                    return withList(tag.typeParameters);
                case 320 /* JSDocTypeTag */:
                    return withNode(tag.typeExpression);
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 323 /* JSDocPropertyTag */:
                case 317 /* JSDocParameterTag */:
                    var name = tag.name;
                    return name ? withNode(name) : comment;
                default:
                    return comment;
            }
            function withNode(node) {
                return addComment(node.getText());
            }
            function withList(list) {
                return addComment(list.map(function (x) { return x.getText(); }).join(", "));
            }
            function addComment(s) {
                return comment === undefined ? s : s + " " + comment;
            }
        }
        function getJSDocTagNameCompletions() {
            return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
                return {
                    name: tagName,
                    kind: "keyword" /* keyword */,
                    kindModifiers: "",
                    sortText: "0",
                };
            }));
        }
        JsDoc.getJSDocTagNameCompletions = getJSDocTagNameCompletions;
        JsDoc.getJSDocTagNameCompletionDetails = getJSDocTagCompletionDetails;
        function getJSDocTagCompletions() {
            return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
                return {
                    name: "@" + tagName,
                    kind: "keyword" /* keyword */,
                    kindModifiers: "",
                    sortText: "0"
                };
            }));
        }
        JsDoc.getJSDocTagCompletions = getJSDocTagCompletions;
        function getJSDocTagCompletionDetails(name) {
            return {
                name: name,
                kind: "" /* unknown */,
                kindModifiers: "",
                displayParts: [ts.textPart(name)],
                documentation: ts.emptyArray,
                tags: undefined,
                codeActions: undefined,
            };
        }
        JsDoc.getJSDocTagCompletionDetails = getJSDocTagCompletionDetails;
        function getJSDocParameterNameCompletions(tag) {
            if (!ts.isIdentifier(tag.name)) {
                return ts.emptyArray;
            }
            var nameThusFar = tag.name.text;
            var jsdoc = tag.parent;
            var fn = jsdoc.parent;
            if (!ts.isFunctionLike(fn))
                return [];
            return ts.mapDefined(fn.parameters, function (param) {
                if (!ts.isIdentifier(param.name))
                    return undefined;
                var name = param.name.text;
                if (jsdoc.tags.some(function (t) { return t !== tag && ts.isJSDocParameterTag(t) && ts.isIdentifier(t.name) && t.name.escapedText === name; }) // TODO: GH#18217
                    || nameThusFar !== undefined && !ts.startsWith(name, nameThusFar)) {
                    return undefined;
                }
                return { name: name, kind: "parameter" /* parameterElement */, kindModifiers: "", sortText: "0" };
            });
        }
        JsDoc.getJSDocParameterNameCompletions = getJSDocParameterNameCompletions;
        function getJSDocParameterNameCompletionDetails(name) {
            return {
                name: name,
                kind: "parameter" /* parameterElement */,
                kindModifiers: "",
                displayParts: [ts.textPart(name)],
                documentation: ts.emptyArray,
                tags: undefined,
                codeActions: undefined,
            };
        }
        JsDoc.getJSDocParameterNameCompletionDetails = getJSDocParameterNameCompletionDetails;
        /**
         * Checks if position points to a valid position to add JSDoc comments, and if so,
         * returns the appropriate template. Otherwise returns an empty string.
         * Valid positions are
         *      - outside of comments, statements, and expressions, and
         *      - preceding a:
         *          - function/constructor/method declaration
         *          - class declarations
         *          - variable statements
         *          - namespace declarations
         *          - interface declarations
         *          - method signatures
         *          - type alias declarations
         *
         * Hosts should ideally check that:
         * - The line is all whitespace up to 'position' before performing the insertion.
         * - If the keystroke sequence "/\*\*" induced the call, we also check that the next
         * non-whitespace character is '*', which (approximately) indicates whether we added
         * the second '*' to complete an existing (JSDoc) comment.
         * @param fileName The file in which to perform the check.
         * @param position The (character-indexed) position in the file where the check should
         * be performed.
         */
        function getDocCommentTemplateAtPosition(newLine, sourceFile, position) {
            var tokenAtPos = ts.getTokenAtPosition(sourceFile, position);
            var existingDocComment = ts.findAncestor(tokenAtPos, ts.isJSDoc);
            if (existingDocComment && (existingDocComment.comment !== undefined || ts.length(existingDocComment.tags))) {
                // Non-empty comment already exists.
                return undefined;
            }
            var tokenStart = tokenAtPos.getStart(sourceFile);
            // Don't provide a doc comment template based on a *previous* node. (But an existing empty jsdoc comment will likely start before `position`.)
            if (!existingDocComment && tokenStart < position) {
                return undefined;
            }
            var commentOwnerInfo = getCommentOwnerInfo(tokenAtPos);
            if (!commentOwnerInfo) {
                return undefined;
            }
            var commentOwner = commentOwnerInfo.commentOwner, parameters = commentOwnerInfo.parameters;
            if (commentOwner.getStart(sourceFile) < position) {
                return undefined;
            }
            if (!parameters || parameters.length === 0) {
                // if there are no parameters, just complete to a single line JSDoc comment
                var singleLineResult = "/** */";
                return { newText: singleLineResult, caretOffset: 3 };
            }
            var indentationStr = getIndentationStringAtPosition(sourceFile, position);
            // A doc comment consists of the following
            // * The opening comment line
            // * the first line (without a param) for the object's untagged info (this is also where the caret ends up)
            // * the '@param'-tagged lines
            // * TODO: other tags.
            // * the closing comment line
            // * if the caret was directly in front of the object, then we add an extra line and indentation.
            var preamble = "/**" + newLine + indentationStr + " * ";
            var result = preamble + newLine +
                parameterDocComments(parameters, ts.hasJSFileExtension(sourceFile.fileName), indentationStr, newLine) +
                indentationStr + " */" +
                (tokenStart === position ? newLine + indentationStr : "");
            return { newText: result, caretOffset: preamble.length };
        }
        JsDoc.getDocCommentTemplateAtPosition = getDocCommentTemplateAtPosition;
        function getIndentationStringAtPosition(sourceFile, position) {
            var text = sourceFile.text;
            var lineStart = ts.getLineStartPositionForPosition(position, sourceFile);
            var pos = lineStart;
            for (; pos <= position && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++)
                ;
            return text.slice(lineStart, pos);
        }
        function parameterDocComments(parameters, isJavaScriptFile, indentationStr, newLine) {
            return parameters.map(function (_a, i) {
                var name = _a.name, dotDotDotToken = _a.dotDotDotToken;
                var paramName = name.kind === 75 /* Identifier */ ? name.text : "param" + i;
                var type = isJavaScriptFile ? (dotDotDotToken ? "{...any} " : "{any} ") : "";
                return indentationStr + " * @param " + type + paramName + newLine;
            }).join("");
        }
        function getCommentOwnerInfo(tokenAtPos) {
            return ts.forEachAncestor(tokenAtPos, getCommentOwnerInfoWorker);
        }
        function getCommentOwnerInfoWorker(commentOwner) {
            switch (commentOwner.kind) {
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 161 /* MethodDeclaration */:
                case 162 /* Constructor */:
                case 160 /* MethodSignature */:
                    var parameters = commentOwner.parameters;
                    return { commentOwner: commentOwner, parameters: parameters };
                case 281 /* PropertyAssignment */:
                    return getCommentOwnerInfoWorker(commentOwner.initializer);
                case 245 /* ClassDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 158 /* PropertySignature */:
                case 248 /* EnumDeclaration */:
                case 284 /* EnumMember */:
                case 247 /* TypeAliasDeclaration */:
                    return { commentOwner: commentOwner };
                case 225 /* VariableStatement */: {
                    var varStatement = commentOwner;
                    var varDeclarations = varStatement.declarationList.declarations;
                    var parameters_1 = varDeclarations.length === 1 && varDeclarations[0].initializer
                        ? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer)
                        : undefined;
                    return { commentOwner: commentOwner, parameters: parameters_1 };
                }
                case 290 /* SourceFile */:
                    return "quit";
                case 249 /* ModuleDeclaration */:
                    // If in walking up the tree, we hit a a nested namespace declaration,
                    // then we must be somewhere within a dotted namespace name; however we don't
                    // want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
                    return commentOwner.parent.kind === 249 /* ModuleDeclaration */ ? undefined : { commentOwner: commentOwner };
                case 226 /* ExpressionStatement */:
                    return getCommentOwnerInfoWorker(commentOwner.expression);
                case 209 /* BinaryExpression */: {
                    var be = commentOwner;
                    if (ts.getAssignmentDeclarationKind(be) === 0 /* None */) {
                        return "quit";
                    }
                    var parameters_2 = ts.isFunctionLike(be.right) ? be.right.parameters : ts.emptyArray;
                    return { commentOwner: commentOwner, parameters: parameters_2 };
                }
                case 159 /* PropertyDeclaration */:
                    var init = commentOwner.initializer;
                    if (init && (ts.isFunctionExpression(init) || ts.isArrowFunction(init))) {
                        return { commentOwner: commentOwner, parameters: init.parameters };
                    }
            }
        }
        /**
         * Digs into an an initializer or RHS operand of an assignment operation
         * to get the parameters of an apt signature corresponding to a
         * function expression or a class expression.
         *
         * @param rightHandSide the expression which may contain an appropriate set of parameters
         * @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.
         */
        function getParametersFromRightHandSideOfAssignment(rightHandSide) {
            while (rightHandSide.kind === 200 /* ParenthesizedExpression */) {
                rightHandSide = rightHandSide.expression;
            }
            switch (rightHandSide.kind) {
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return rightHandSide.parameters;
                case 214 /* ClassExpression */: {
                    var ctr = ts.find(rightHandSide.members, ts.isConstructorDeclaration);
                    return ctr ? ctr.parameters : ts.emptyArray;
                }
            }
            return ts.emptyArray;
        }
    })(JsDoc = ts.JsDoc || (ts.JsDoc = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var NavigateTo;
    (function (NavigateTo) {
        function getNavigateToItems(sourceFiles, checker, cancellationToken, searchValue, maxResultCount, excludeDtsFiles) {
            var patternMatcher = ts.createPatternMatcher(searchValue);
            if (!patternMatcher)
                return ts.emptyArray;
            var rawItems = [];
            var _loop_5 = function (sourceFile) {
                cancellationToken.throwIfCancellationRequested();
                if (excludeDtsFiles && sourceFile.isDeclarationFile) {
                    return "continue";
                }
                sourceFile.getNamedDeclarations().forEach(function (declarations, name) {
                    getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, sourceFile.fileName, rawItems);
                });
            };
            // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
            for (var _i = 0, sourceFiles_4 = sourceFiles; _i < sourceFiles_4.length; _i++) {
                var sourceFile = sourceFiles_4[_i];
                _loop_5(sourceFile);
            }
            rawItems.sort(compareNavigateToItems);
            return (maxResultCount === undefined ? rawItems : rawItems.slice(0, maxResultCount)).map(createNavigateToItem);
        }
        NavigateTo.getNavigateToItems = getNavigateToItems;
        function getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, fileName, rawItems) {
            // First do a quick check to see if the name of the declaration matches the
            // last portion of the (possibly) dotted name they're searching for.
            var match = patternMatcher.getMatchForLastSegmentOfPattern(name);
            if (!match) {
                return; // continue to next named declarations
            }
            for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) {
                var declaration = declarations_3[_i];
                if (!shouldKeepItem(declaration, checker))
                    continue;
                if (patternMatcher.patternContainsDots) {
                    // If the pattern has dots in it, then also see if the declaration container matches as well.
                    var fullMatch = patternMatcher.getFullMatch(getContainers(declaration), name);
                    if (fullMatch) {
                        rawItems.push({ name: name, fileName: fileName, matchKind: fullMatch.kind, isCaseSensitive: fullMatch.isCaseSensitive, declaration: declaration });
                    }
                }
                else {
                    rawItems.push({ name: name, fileName: fileName, matchKind: match.kind, isCaseSensitive: match.isCaseSensitive, declaration: declaration });
                }
            }
        }
        function shouldKeepItem(declaration, checker) {
            switch (declaration.kind) {
                case 255 /* ImportClause */:
                case 258 /* ImportSpecifier */:
                case 253 /* ImportEqualsDeclaration */:
                    var importer = checker.getSymbolAtLocation(declaration.name); // TODO: GH#18217
                    var imported = checker.getAliasedSymbol(importer);
                    return importer.escapedName !== imported.escapedName;
                default:
                    return true;
            }
        }
        function tryAddSingleDeclarationName(declaration, containers) {
            var name = ts.getNameOfDeclaration(declaration);
            return !!name && (pushLiteral(name, containers) || name.kind === 154 /* ComputedPropertyName */ && tryAddComputedPropertyName(name.expression, containers));
        }
        // Only added the names of computed properties if they're simple dotted expressions, like:
        //
        //      [X.Y.Z]() { }
        function tryAddComputedPropertyName(expression, containers) {
            return pushLiteral(expression, containers)
                || ts.isPropertyAccessExpression(expression) && (containers.push(expression.name.text), true) && tryAddComputedPropertyName(expression.expression, containers);
        }
        function pushLiteral(node, containers) {
            return ts.isPropertyNameLiteral(node) && (containers.push(ts.getTextOfIdentifierOrLiteral(node)), true);
        }
        function getContainers(declaration) {
            var containers = [];
            // First, if we started with a computed property name, then add all but the last
            // portion into the container array.
            var name = ts.getNameOfDeclaration(declaration);
            if (name && name.kind === 154 /* ComputedPropertyName */ && !tryAddComputedPropertyName(name.expression, containers)) {
                return ts.emptyArray;
            }
            // Don't include the last portion.
            containers.shift();
            // Now, walk up our containers, adding all their names to the container array.
            var container = ts.getContainerNode(declaration);
            while (container) {
                if (!tryAddSingleDeclarationName(container, containers)) {
                    return ts.emptyArray;
                }
                container = ts.getContainerNode(container);
            }
            return containers.reverse();
        }
        function compareNavigateToItems(i1, i2) {
            // TODO(cyrusn): get the gamut of comparisons that VS already uses here.
            return ts.compareValues(i1.matchKind, i2.matchKind)
                || ts.compareStringsCaseSensitiveUI(i1.name, i2.name);
        }
        function createNavigateToItem(rawItem) {
            var declaration = rawItem.declaration;
            var container = ts.getContainerNode(declaration);
            var containerName = container && ts.getNameOfDeclaration(container);
            return {
                name: rawItem.name,
                kind: ts.getNodeKind(declaration),
                kindModifiers: ts.getNodeModifiers(declaration),
                matchKind: ts.PatternMatchKind[rawItem.matchKind],
                isCaseSensitive: rawItem.isCaseSensitive,
                fileName: rawItem.fileName,
                textSpan: ts.createTextSpanFromNode(declaration),
                // TODO(jfreeman): What should be the containerName when the container has a computed name?
                containerName: containerName ? containerName.text : "",
                containerKind: containerName ? ts.getNodeKind(container) : "" /* unknown */,
            };
        }
    })(NavigateTo = ts.NavigateTo || (ts.NavigateTo = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var NavigationBar;
    (function (NavigationBar) {
        var _a;
        /**
         * Matches all whitespace characters in a string. Eg:
         *
         * "app.
         *
         * onactivated"
         *
         * matches because of the newline, whereas
         *
         * "app.onactivated"
         *
         * does not match.
         */
        var whiteSpaceRegex = /\s+/g;
        /**
         * Maximum amount of characters to return
         * The amount was chosen arbitrarily.
         */
        var maxLength = 150;
        // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
        var curCancellationToken;
        var curSourceFile;
        /**
         * For performance, we keep navigation bar parents on a stack rather than passing them through each recursion.
         * `parent` is the current parent and is *not* stored in parentsStack.
         * `startNode` sets a new parent and `endNode` returns to the previous parent.
         */
        var parentsStack = [];
        var parent;
        var trackedEs5ClassesStack = [];
        var trackedEs5Classes;
        // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
        var emptyChildItemArray = [];
        function getNavigationBarItems(sourceFile, cancellationToken) {
            curCancellationToken = cancellationToken;
            curSourceFile = sourceFile;
            try {
                return ts.map(primaryNavBarMenuItems(rootNavigationBarNode(sourceFile)), convertToPrimaryNavBarMenuItem);
            }
            finally {
                reset();
            }
        }
        NavigationBar.getNavigationBarItems = getNavigationBarItems;
        function getNavigationTree(sourceFile, cancellationToken) {
            curCancellationToken = cancellationToken;
            curSourceFile = sourceFile;
            try {
                return convertToTree(rootNavigationBarNode(sourceFile));
            }
            finally {
                reset();
            }
        }
        NavigationBar.getNavigationTree = getNavigationTree;
        function reset() {
            curSourceFile = undefined;
            curCancellationToken = undefined;
            parentsStack = [];
            parent = undefined;
            emptyChildItemArray = [];
        }
        function nodeText(node) {
            return cleanText(node.getText(curSourceFile));
        }
        function navigationBarNodeKind(n) {
            return n.node.kind;
        }
        function pushChild(parent, child) {
            if (parent.children) {
                parent.children.push(child);
            }
            else {
                parent.children = [child];
            }
        }
        function rootNavigationBarNode(sourceFile) {
            ts.Debug.assert(!parentsStack.length);
            var root = { node: sourceFile, name: undefined, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 };
            parent = root;
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                addChildrenRecursively(statement);
            }
            endNode();
            ts.Debug.assert(!parent && !parentsStack.length);
            return root;
        }
        function addLeafNode(node, name) {
            pushChild(parent, emptyNavigationBarNode(node, name));
        }
        function emptyNavigationBarNode(node, name) {
            return {
                node: node,
                name: name || (ts.isDeclaration(node) || ts.isExpression(node) ? ts.getNameOfDeclaration(node) : undefined),
                additionalNodes: undefined,
                parent: parent,
                children: undefined,
                indent: parent.indent + 1
            };
        }
        function addTrackedEs5Class(name) {
            if (!trackedEs5Classes) {
                trackedEs5Classes = ts.createMap();
            }
            trackedEs5Classes.set(name, true);
        }
        function endNestedNodes(depth) {
            for (var i = 0; i < depth; i++)
                endNode();
        }
        function startNestedNodes(targetNode, entityName) {
            var names = [];
            while (!ts.isPropertyNameLiteral(entityName)) {
                var name = ts.getNameOrArgument(entityName);
                var nameText = ts.getElementOrPropertyAccessName(entityName);
                entityName = entityName.expression;
                if (nameText === "prototype" || ts.isPrivateIdentifier(name))
                    continue;
                names.push(name);
            }
            names.push(entityName);
            for (var i = names.length - 1; i > 0; i--) {
                var name = names[i];
                startNode(targetNode, name);
            }
            return [names.length - 1, names[0]];
        }
        /**
         * Add a new level of NavigationBarNodes.
         * This pushes to the stack, so you must call `endNode` when you are done adding to this node.
         */
        function startNode(node, name) {
            var navNode = emptyNavigationBarNode(node, name);
            pushChild(parent, navNode);
            // Save the old parent
            parentsStack.push(parent);
            trackedEs5ClassesStack.push(trackedEs5Classes);
            parent = navNode;
        }
        /** Call after calling `startNode` and adding children to it. */
        function endNode() {
            if (parent.children) {
                mergeChildren(parent.children, parent);
                sortChildren(parent.children);
            }
            parent = parentsStack.pop();
            trackedEs5Classes = trackedEs5ClassesStack.pop();
        }
        function addNodeWithRecursiveChild(node, child, name) {
            startNode(node, name);
            addChildrenRecursively(child);
            endNode();
        }
        /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */
        function addChildrenRecursively(node) {
            var _a;
            curCancellationToken.throwIfCancellationRequested();
            if (!node || ts.isToken(node)) {
                return;
            }
            switch (node.kind) {
                case 162 /* Constructor */:
                    // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it.
                    var ctr = node;
                    addNodeWithRecursiveChild(ctr, ctr.body);
                    // Parameter properties are children of the class, not the constructor.
                    for (var _i = 0, _b = ctr.parameters; _i < _b.length; _i++) {
                        var param = _b[_i];
                        if (ts.isParameterPropertyDeclaration(param, ctr)) {
                            addLeafNode(param);
                        }
                    }
                    break;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 160 /* MethodSignature */:
                    if (!ts.hasDynamicName(node)) {
                        addNodeWithRecursiveChild(node, node.body);
                    }
                    break;
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    if (!ts.hasDynamicName(node)) {
                        addLeafNode(node);
                    }
                    break;
                case 255 /* ImportClause */:
                    var importClause = node;
                    // Handle default import case e.g.:
                    //    import d from "mod";
                    if (importClause.name) {
                        addLeafNode(importClause.name);
                    }
                    // Handle named bindings in imports e.g.:
                    //    import * as NS from "mod";
                    //    import {a, b as B} from "mod";
                    var namedBindings = importClause.namedBindings;
                    if (namedBindings) {
                        if (namedBindings.kind === 256 /* NamespaceImport */) {
                            addLeafNode(namedBindings);
                        }
                        else {
                            for (var _c = 0, _d = namedBindings.elements; _c < _d.length; _c++) {
                                var element = _d[_c];
                                addLeafNode(element);
                            }
                        }
                    }
                    break;
                case 282 /* ShorthandPropertyAssignment */:
                    addNodeWithRecursiveChild(node, node.name);
                    break;
                case 283 /* SpreadAssignment */:
                    var expression = node.expression;
                    // Use the expression as the name of the SpreadAssignment, otherwise show as <unknown>.
                    ts.isIdentifier(expression) ? addLeafNode(node, expression) : addLeafNode(node);
                    break;
                case 191 /* BindingElement */:
                case 281 /* PropertyAssignment */:
                case 242 /* VariableDeclaration */:
                    var _e = node, name = _e.name, initializer = _e.initializer;
                    if (ts.isBindingPattern(name)) {
                        addChildrenRecursively(name);
                    }
                    else if (initializer && isFunctionOrClassExpression(initializer)) {
                        // Add a node for the VariableDeclaration, but not for the initializer.
                        startNode(node);
                        ts.forEachChild(initializer, addChildrenRecursively);
                        endNode();
                    }
                    else {
                        addNodeWithRecursiveChild(node, initializer);
                    }
                    break;
                case 244 /* FunctionDeclaration */:
                    var nameNode = node.name;
                    // If we see a function declaration track as a possible ES5 class
                    if (nameNode && ts.isIdentifier(nameNode)) {
                        addTrackedEs5Class(nameNode.text);
                    }
                    addNodeWithRecursiveChild(node, node.body);
                    break;
                case 202 /* ArrowFunction */:
                case 201 /* FunctionExpression */:
                    addNodeWithRecursiveChild(node, node.body);
                    break;
                case 248 /* EnumDeclaration */:
                    startNode(node);
                    for (var _f = 0, _g = node.members; _f < _g.length; _f++) {
                        var member = _g[_f];
                        if (!isComputedProperty(member)) {
                            addLeafNode(member);
                        }
                    }
                    endNode();
                    break;
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                case 246 /* InterfaceDeclaration */:
                    startNode(node);
                    for (var _h = 0, _j = node.members; _h < _j.length; _h++) {
                        var member = _j[_h];
                        addChildrenRecursively(member);
                    }
                    endNode();
                    break;
                case 249 /* ModuleDeclaration */:
                    addNodeWithRecursiveChild(node, getInteriorModule(node).body);
                    break;
                case 259 /* ExportAssignment */:
                case 263 /* ExportSpecifier */:
                case 253 /* ImportEqualsDeclaration */:
                case 167 /* IndexSignature */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 247 /* TypeAliasDeclaration */:
                    addLeafNode(node);
                    break;
                case 196 /* CallExpression */:
                case 209 /* BinaryExpression */: {
                    var special = ts.getAssignmentDeclarationKind(node);
                    switch (special) {
                        case 1 /* ExportsProperty */:
                        case 2 /* ModuleExports */:
                            addNodeWithRecursiveChild(node, node.right);
                            return;
                        case 6 /* Prototype */:
                        case 3 /* PrototypeProperty */: {
                            var binaryExpression = node;
                            var assignmentTarget = binaryExpression.left;
                            var prototypeAccess = special === 3 /* PrototypeProperty */ ?
                                assignmentTarget.expression :
                                assignmentTarget;
                            var depth = 0;
                            var className = void 0;
                            // If we see a prototype assignment, start tracking the target as a class
                            // This is only done for simple classes not nested assignments.
                            if (ts.isIdentifier(prototypeAccess.expression)) {
                                addTrackedEs5Class(prototypeAccess.expression.text);
                                className = prototypeAccess.expression;
                            }
                            else {
                                _a = startNestedNodes(binaryExpression, prototypeAccess.expression), depth = _a[0], className = _a[1];
                            }
                            if (special === 6 /* Prototype */) {
                                if (ts.isObjectLiteralExpression(binaryExpression.right)) {
                                    if (binaryExpression.right.properties.length > 0) {
                                        startNode(binaryExpression, className);
                                        ts.forEachChild(binaryExpression.right, addChildrenRecursively);
                                        endNode();
                                    }
                                }
                            }
                            else if (ts.isFunctionExpression(binaryExpression.right) || ts.isArrowFunction(binaryExpression.right)) {
                                addNodeWithRecursiveChild(node, binaryExpression.right, className);
                            }
                            else {
                                startNode(binaryExpression, className);
                                addNodeWithRecursiveChild(node, binaryExpression.right, assignmentTarget.name);
                                endNode();
                            }
                            endNestedNodes(depth);
                            return;
                        }
                        case 7 /* ObjectDefinePropertyValue */:
                        case 9 /* ObjectDefinePrototypeProperty */: {
                            var defineCall = node;
                            var className = special === 7 /* ObjectDefinePropertyValue */ ?
                                defineCall.arguments[0] :
                                defineCall.arguments[0].expression;
                            var memberName = defineCall.arguments[1];
                            var _k = startNestedNodes(node, className), depth = _k[0], classNameIdentifier = _k[1];
                            startNode(node, classNameIdentifier);
                            startNode(node, ts.setTextRange(ts.createIdentifier(memberName.text), memberName));
                            addChildrenRecursively(node.arguments[2]);
                            endNode();
                            endNode();
                            endNestedNodes(depth);
                            return;
                        }
                        case 5 /* Property */: {
                            var binaryExpression = node;
                            var assignmentTarget = binaryExpression.left;
                            var targetFunction = assignmentTarget.expression;
                            if (ts.isIdentifier(targetFunction) && ts.getElementOrPropertyAccessName(assignmentTarget) !== "prototype" &&
                                trackedEs5Classes && trackedEs5Classes.has(targetFunction.text)) {
                                if (ts.isFunctionExpression(binaryExpression.right) || ts.isArrowFunction(binaryExpression.right)) {
                                    addNodeWithRecursiveChild(node, binaryExpression.right, targetFunction);
                                }
                                else if (ts.isBindableStaticAccessExpression(assignmentTarget)) {
                                    startNode(binaryExpression, targetFunction);
                                    addNodeWithRecursiveChild(binaryExpression.left, binaryExpression.right, ts.getNameOrArgument(assignmentTarget));
                                    endNode();
                                }
                                return;
                            }
                            break;
                        }
                        case 4 /* ThisProperty */:
                        case 0 /* None */:
                        case 8 /* ObjectDefinePropertyExports */:
                            break;
                        default:
                            ts.Debug.assertNever(special);
                    }
                }
                // falls through
                default:
                    if (ts.hasJSDocNodes(node)) {
                        ts.forEach(node.jsDoc, function (jsDoc) {
                            ts.forEach(jsDoc.tags, function (tag) {
                                if (ts.isJSDocTypeAlias(tag)) {
                                    addLeafNode(tag);
                                }
                            });
                        });
                    }
                    ts.forEachChild(node, addChildrenRecursively);
            }
        }
        /** Merge declarations of the same kind. */
        function mergeChildren(children, node) {
            var nameToItems = ts.createMap();
            ts.filterMutate(children, function (child, index) {
                var declName = child.name || ts.getNameOfDeclaration(child.node);
                var name = declName && nodeText(declName);
                if (!name) {
                    // Anonymous items are never merged.
                    return true;
                }
                var itemsWithSameName = nameToItems.get(name);
                if (!itemsWithSameName) {
                    nameToItems.set(name, child);
                    return true;
                }
                if (itemsWithSameName instanceof Array) {
                    for (var _i = 0, itemsWithSameName_1 = itemsWithSameName; _i < itemsWithSameName_1.length; _i++) {
                        var itemWithSameName = itemsWithSameName_1[_i];
                        if (tryMerge(itemWithSameName, child, index, node)) {
                            return false;
                        }
                    }
                    itemsWithSameName.push(child);
                    return true;
                }
                else {
                    var itemWithSameName = itemsWithSameName;
                    if (tryMerge(itemWithSameName, child, index, node)) {
                        return false;
                    }
                    nameToItems.set(name, [itemWithSameName, child]);
                    return true;
                }
            });
        }
        var isEs5ClassMember = (_a = {},
            _a[5 /* Property */] = true,
            _a[3 /* PrototypeProperty */] = true,
            _a[7 /* ObjectDefinePropertyValue */] = true,
            _a[9 /* ObjectDefinePrototypeProperty */] = true,
            _a[0 /* None */] = false,
            _a[1 /* ExportsProperty */] = false,
            _a[2 /* ModuleExports */] = false,
            _a[8 /* ObjectDefinePropertyExports */] = false,
            _a[6 /* Prototype */] = true,
            _a[4 /* ThisProperty */] = false,
            _a);
        function tryMergeEs5Class(a, b, bIndex, parent) {
            function isPossibleConstructor(node) {
                return ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node) || ts.isVariableDeclaration(node);
            }
            var bAssignmentDeclarationKind = ts.isBinaryExpression(b.node) || ts.isCallExpression(b.node) ?
                ts.getAssignmentDeclarationKind(b.node) :
                0 /* None */;
            var aAssignmentDeclarationKind = ts.isBinaryExpression(a.node) || ts.isCallExpression(a.node) ?
                ts.getAssignmentDeclarationKind(a.node) :
                0 /* None */;
            // We treat this as an es5 class and merge the nodes in in one of several cases
            if ((isEs5ClassMember[bAssignmentDeclarationKind] && isEs5ClassMember[aAssignmentDeclarationKind]) // merge two class elements
                || (isPossibleConstructor(a.node) && isEs5ClassMember[bAssignmentDeclarationKind]) // ctor function & member
                || (isPossibleConstructor(b.node) && isEs5ClassMember[aAssignmentDeclarationKind]) // member & ctor function
                || (ts.isClassDeclaration(a.node) && isEs5ClassMember[bAssignmentDeclarationKind]) // class (generated) & member
                || (ts.isClassDeclaration(b.node) && isEs5ClassMember[aAssignmentDeclarationKind]) // member & class (generated)
                || (ts.isClassDeclaration(a.node) && isPossibleConstructor(b.node)) // class (generated) & ctor
                || (ts.isClassDeclaration(b.node) && isPossibleConstructor(a.node)) // ctor & class (generated)
            ) {
                var lastANode = a.additionalNodes && ts.lastOrUndefined(a.additionalNodes) || a.node;
                if ((!ts.isClassDeclaration(a.node) && !ts.isClassDeclaration(b.node)) // If neither outline node is a class
                    || isPossibleConstructor(a.node) || isPossibleConstructor(b.node) // If either function is a constructor function
                ) {
                    var ctorFunction = isPossibleConstructor(a.node) ? a.node :
                        isPossibleConstructor(b.node) ? b.node :
                            undefined;
                    if (ctorFunction !== undefined) {
                        var ctorNode = ts.setTextRange(ts.createConstructor(/* decorators */ undefined, /* modifiers */ undefined, [], /* body */ undefined), ctorFunction);
                        var ctor = emptyNavigationBarNode(ctorNode);
                        ctor.indent = a.indent + 1;
                        ctor.children = a.node === ctorFunction ? a.children : b.children;
                        a.children = a.node === ctorFunction ? ts.concatenate([ctor], b.children || [b]) : ts.concatenate(a.children || [a], [ctor]);
                    }
                    else {
                        if (a.children || b.children) {
                            a.children = ts.concatenate(a.children || [a], b.children || [b]);
                            if (a.children) {
                                mergeChildren(a.children, a);
                                sortChildren(a.children);
                            }
                        }
                    }
                    lastANode = a.node = ts.setTextRange(ts.createClassDeclaration(
                    /* decorators */ undefined, 
                    /* modifiers */ undefined, a.name || ts.createIdentifier("__class__"), 
                    /* typeParameters */ undefined, 
                    /* heritageClauses */ undefined, []), a.node);
                }
                else {
                    a.children = ts.concatenate(a.children, b.children);
                    if (a.children) {
                        mergeChildren(a.children, a);
                    }
                }
                var bNode = b.node;
                // We merge if the outline node previous to b (bIndex - 1) is already part of the current class
                // We do this so that statements between class members that do not generate outline nodes do not split up the class outline:
                // Ex This should produce one outline node C:
                //    function C() {}; a = 1; C.prototype.m = function () {}
                // Ex This will produce 3 outline nodes: C, a, C
                //    function C() {}; let a = 1; C.prototype.m = function () {}
                if (parent.children[bIndex - 1].node.end === lastANode.end) {
                    ts.setTextRange(lastANode, { pos: lastANode.pos, end: bNode.end });
                }
                else {
                    if (!a.additionalNodes)
                        a.additionalNodes = [];
                    a.additionalNodes.push(ts.setTextRange(ts.createClassDeclaration(
                    /* decorators */ undefined, 
                    /* modifiers */ undefined, a.name || ts.createIdentifier("__class__"), 
                    /* typeParameters */ undefined, 
                    /* heritageClauses */ undefined, []), b.node));
                }
                return true;
            }
            return bAssignmentDeclarationKind === 0 /* None */ ? false : true;
        }
        function tryMerge(a, b, bIndex, parent) {
            // const v = false as boolean;
            if (tryMergeEs5Class(a, b, bIndex, parent)) {
                return true;
            }
            if (shouldReallyMerge(a.node, b.node, parent)) {
                merge(a, b);
                return true;
            }
            return false;
        }
        /** a and b have the same name, but they may not be mergeable. */
        function shouldReallyMerge(a, b, parent) {
            if (a.kind !== b.kind || a.parent !== b.parent && !(isOwnChild(a, parent) && isOwnChild(b, parent))) {
                return false;
            }
            switch (a.kind) {
                case 159 /* PropertyDeclaration */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return ts.hasModifier(a, 32 /* Static */) === ts.hasModifier(b, 32 /* Static */);
                case 249 /* ModuleDeclaration */:
                    return areSameModule(a, b);
                default:
                    return true;
            }
        }
        // We want to merge own children like `I` in in `module A { interface I {} } module A { interface I {} }`
        // We don't want to merge unrelated children like `m` in `const o = { a: { m() {} }, b: { m() {} } };`
        function isOwnChild(n, parent) {
            var par = ts.isModuleBlock(n.parent) ? n.parent.parent : n.parent;
            return par === parent.node || ts.contains(parent.additionalNodes, par);
        }
        // We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes.
        // Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'!
        function areSameModule(a, b) {
            // TODO: GH#18217
            return a.body.kind === b.body.kind && (a.body.kind !== 249 /* ModuleDeclaration */ || areSameModule(a.body, b.body));
        }
        /** Merge source into target. Source should be thrown away after this is called. */
        function merge(target, source) {
            var _a;
            target.additionalNodes = target.additionalNodes || [];
            target.additionalNodes.push(source.node);
            if (source.additionalNodes) {
                (_a = target.additionalNodes).push.apply(_a, source.additionalNodes);
            }
            target.children = ts.concatenate(target.children, source.children);
            if (target.children) {
                mergeChildren(target.children, target);
                sortChildren(target.children);
            }
        }
        /** Recursively ensure that each NavNode's children are in sorted order. */
        function sortChildren(children) {
            children.sort(compareChildren);
        }
        function compareChildren(child1, child2) {
            return ts.compareStringsCaseSensitiveUI(tryGetName(child1.node), tryGetName(child2.node)) // TODO: GH#18217
                || ts.compareValues(navigationBarNodeKind(child1), navigationBarNodeKind(child2));
        }
        /**
         * This differs from getItemName because this is just used for sorting.
         * We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like.
         * So `new()` can still come before an `aardvark` method.
         */
        function tryGetName(node) {
            if (node.kind === 249 /* ModuleDeclaration */) {
                return getModuleName(node);
            }
            var declName = ts.getNameOfDeclaration(node);
            if (declName && ts.isPropertyName(declName)) {
                var propertyName = ts.getPropertyNameForPropertyNameNode(declName);
                return propertyName && ts.unescapeLeadingUnderscores(propertyName);
            }
            switch (node.kind) {
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 214 /* ClassExpression */:
                    return getFunctionOrClassName(node);
                default:
                    return undefined;
            }
        }
        function getItemName(node, name) {
            if (node.kind === 249 /* ModuleDeclaration */) {
                return cleanText(getModuleName(node));
            }
            if (name) {
                var text = ts.isIdentifier(name) ? name.text
                    : ts.isElementAccessExpression(name) ? "[" + nodeText(name.argumentExpression) + "]"
                        : nodeText(name);
                if (text.length > 0) {
                    return cleanText(text);
                }
            }
            switch (node.kind) {
                case 290 /* SourceFile */:
                    var sourceFile = node;
                    return ts.isExternalModule(sourceFile)
                        ? "\"" + ts.escapeString(ts.getBaseFileName(ts.removeFileExtension(ts.normalizePath(sourceFile.fileName)))) + "\""
                        : "<global>";
                case 259 /* ExportAssignment */:
                    return ts.isExportAssignment(node) && node.isExportEquals ? "export=" /* ExportEquals */ : "default" /* Default */;
                case 202 /* ArrowFunction */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    if (ts.getModifierFlags(node) & 512 /* Default */) {
                        return "default";
                    }
                    // We may get a string with newlines or other whitespace in the case of an object dereference
                    // (eg: "app\n.onactivated"), so we should remove the whitespace for readabiltiy in the
                    // navigation bar.
                    return getFunctionOrClassName(node);
                case 162 /* Constructor */:
                    return "constructor";
                case 166 /* ConstructSignature */:
                    return "new()";
                case 165 /* CallSignature */:
                    return "()";
                case 167 /* IndexSignature */:
                    return "[]";
                default:
                    return "<unknown>";
            }
        }
        /** Flattens the NavNode tree to a list of items to appear in the primary navbar menu. */
        function primaryNavBarMenuItems(root) {
            // The primary (middle) navbar menu displays the general code navigation hierarchy, similar to the navtree.
            // The secondary (right) navbar menu displays the child items of whichever primary item is selected.
            // Some less interesting items without their own child navigation items (e.g. a local variable declaration) only show up in the secondary menu.
            var primaryNavBarMenuItems = [];
            function recur(item) {
                if (shouldAppearInPrimaryNavBarMenu(item)) {
                    primaryNavBarMenuItems.push(item);
                    if (item.children) {
                        for (var _i = 0, _a = item.children; _i < _a.length; _i++) {
                            var child = _a[_i];
                            recur(child);
                        }
                    }
                }
            }
            recur(root);
            return primaryNavBarMenuItems;
            /** Determines if a node should appear in the primary navbar menu. */
            function shouldAppearInPrimaryNavBarMenu(item) {
                // Items with children should always appear in the primary navbar menu.
                if (item.children) {
                    return true;
                }
                // Some nodes are otherwise important enough to always include in the primary navigation menu.
                switch (navigationBarNodeKind(item)) {
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 248 /* EnumDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                    case 249 /* ModuleDeclaration */:
                    case 290 /* SourceFile */:
                    case 247 /* TypeAliasDeclaration */:
                    case 322 /* JSDocTypedefTag */:
                    case 315 /* JSDocCallbackTag */:
                        return true;
                    case 202 /* ArrowFunction */:
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                        return isTopLevelFunctionDeclaration(item);
                    default:
                        return false;
                }
                function isTopLevelFunctionDeclaration(item) {
                    if (!item.node.body) {
                        return false;
                    }
                    switch (navigationBarNodeKind(item.parent)) {
                        case 250 /* ModuleBlock */:
                        case 290 /* SourceFile */:
                        case 161 /* MethodDeclaration */:
                        case 162 /* Constructor */:
                            return true;
                        default:
                            return false;
                    }
                }
            }
        }
        function convertToTree(n) {
            return {
                text: getItemName(n.node, n.name),
                kind: ts.getNodeKind(n.node),
                kindModifiers: getModifiers(n.node),
                spans: getSpans(n),
                nameSpan: n.name && getNodeSpan(n.name),
                childItems: ts.map(n.children, convertToTree)
            };
        }
        function convertToPrimaryNavBarMenuItem(n) {
            return {
                text: getItemName(n.node, n.name),
                kind: ts.getNodeKind(n.node),
                kindModifiers: getModifiers(n.node),
                spans: getSpans(n),
                childItems: ts.map(n.children, convertToSecondaryNavBarMenuItem) || emptyChildItemArray,
                indent: n.indent,
                bolded: false,
                grayed: false
            };
            function convertToSecondaryNavBarMenuItem(n) {
                return {
                    text: getItemName(n.node, n.name),
                    kind: ts.getNodeKind(n.node),
                    kindModifiers: ts.getNodeModifiers(n.node),
                    spans: getSpans(n),
                    childItems: emptyChildItemArray,
                    indent: 0,
                    bolded: false,
                    grayed: false
                };
            }
        }
        function getSpans(n) {
            var spans = [getNodeSpan(n.node)];
            if (n.additionalNodes) {
                for (var _i = 0, _a = n.additionalNodes; _i < _a.length; _i++) {
                    var node = _a[_i];
                    spans.push(getNodeSpan(node));
                }
            }
            return spans;
        }
        function getModuleName(moduleDeclaration) {
            // We want to maintain quotation marks.
            if (ts.isAmbientModule(moduleDeclaration)) {
                return ts.getTextOfNode(moduleDeclaration.name);
            }
            // Otherwise, we need to aggregate each identifier to build up the qualified name.
            var result = [];
            result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name));
            while (moduleDeclaration.body && moduleDeclaration.body.kind === 249 /* ModuleDeclaration */) {
                moduleDeclaration = moduleDeclaration.body;
                result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name));
            }
            return result.join(".");
        }
        /**
         * For 'module A.B.C', we want to get the node for 'C'.
         * We store 'A' as associated with a NavNode, and use getModuleName to traverse down again.
         */
        function getInteriorModule(decl) {
            return decl.body && ts.isModuleDeclaration(decl.body) ? getInteriorModule(decl.body) : decl;
        }
        function isComputedProperty(member) {
            return !member.name || member.name.kind === 154 /* ComputedPropertyName */;
        }
        function getNodeSpan(node) {
            return node.kind === 290 /* SourceFile */ ? ts.createTextSpanFromRange(node) : ts.createTextSpanFromNode(node, curSourceFile);
        }
        function getModifiers(node) {
            if (node.parent && node.parent.kind === 242 /* VariableDeclaration */) {
                node = node.parent;
            }
            return ts.getNodeModifiers(node);
        }
        function getFunctionOrClassName(node) {
            var parent = node.parent;
            if (node.name && ts.getFullWidth(node.name) > 0) {
                return cleanText(ts.declarationNameToString(node.name));
            }
            // See if it is a var initializer. If so, use the var name.
            else if (ts.isVariableDeclaration(parent)) {
                return cleanText(ts.declarationNameToString(parent.name));
            }
            // See if it is of the form "<expr> = function(){...}". If so, use the text from the left-hand side.
            else if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === 62 /* EqualsToken */) {
                return nodeText(parent.left).replace(whiteSpaceRegex, "");
            }
            // See if it is a property assignment, and if so use the property name
            else if (ts.isPropertyAssignment(parent)) {
                return nodeText(parent.name);
            }
            // Default exports are named "default"
            else if (ts.getModifierFlags(node) & 512 /* Default */) {
                return "default";
            }
            else if (ts.isClassLike(node)) {
                return "<class>";
            }
            else if (ts.isCallExpression(parent)) {
                var name = getCalledExpressionName(parent.expression);
                if (name !== undefined) {
                    name = cleanText(name);
                    if (name.length > maxLength) {
                        return name + " callback";
                    }
                    var args = cleanText(ts.mapDefined(parent.arguments, function (a) { return ts.isStringLiteralLike(a) ? a.getText(curSourceFile) : undefined; }).join(", "));
                    return name + "(" + args + ") callback";
                }
            }
            return "<function>";
        }
        // See also 'tryGetPropertyAccessOrIdentifierToString'
        function getCalledExpressionName(expr) {
            if (ts.isIdentifier(expr)) {
                return expr.text;
            }
            else if (ts.isPropertyAccessExpression(expr)) {
                var left = getCalledExpressionName(expr.expression);
                var right = expr.name.text;
                return left === undefined ? right : left + "." + right;
            }
            else {
                return undefined;
            }
        }
        function isFunctionOrClassExpression(node) {
            switch (node.kind) {
                case 202 /* ArrowFunction */:
                case 201 /* FunctionExpression */:
                case 214 /* ClassExpression */:
                    return true;
                default:
                    return false;
            }
        }
        function cleanText(text) {
            // Truncate to maximum amount of characters as we don't want to do a big replace operation.
            text = text.length > maxLength ? text.substring(0, maxLength) + "..." : text;
            // Replaces ECMAScript line terminators and removes the trailing `\` from each line:
            // \n - Line Feed
            // \r - Carriage Return
            // \u2028 - Line separator
            // \u2029 - Paragraph separator
            return text.replace(/\\?(\r?\n|\r|\u2028|\u2029)/g, "");
        }
    })(NavigationBar = ts.NavigationBar || (ts.NavigationBar = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var OrganizeImports;
    (function (OrganizeImports) {
        /**
         * Organize imports by:
         *   1) Removing unused imports
         *   2) Coalescing imports from the same module
         *   3) Sorting imports
         */
        function organizeImports(sourceFile, formatContext, host, program, preferences) {
            var changeTracker = ts.textChanges.ChangeTracker.fromContext({ host: host, formatContext: formatContext, preferences: preferences });
            var coalesceAndOrganizeImports = function (importGroup) { return coalesceImports(removeUnusedImports(importGroup, sourceFile, program)); };
            // All of the old ImportDeclarations in the file, in syntactic order.
            var topLevelImportDecls = sourceFile.statements.filter(ts.isImportDeclaration);
            organizeImportsWorker(topLevelImportDecls, coalesceAndOrganizeImports);
            // All of the old ExportDeclarations in the file, in syntactic order.
            var topLevelExportDecls = sourceFile.statements.filter(ts.isExportDeclaration);
            organizeImportsWorker(topLevelExportDecls, coalesceExports);
            for (var _i = 0, _a = sourceFile.statements.filter(ts.isAmbientModule); _i < _a.length; _i++) {
                var ambientModule = _a[_i];
                if (!ambientModule.body) {
                    continue;
                }
                var ambientModuleImportDecls = ambientModule.body.statements.filter(ts.isImportDeclaration);
                organizeImportsWorker(ambientModuleImportDecls, coalesceAndOrganizeImports);
                var ambientModuleExportDecls = ambientModule.body.statements.filter(ts.isExportDeclaration);
                organizeImportsWorker(ambientModuleExportDecls, coalesceExports);
            }
            return changeTracker.getChanges();
            function organizeImportsWorker(oldImportDecls, coalesce) {
                if (ts.length(oldImportDecls) === 0) {
                    return;
                }
                // Special case: normally, we'd expect leading and trailing trivia to follow each import
                // around as it's sorted.  However, we do not want this to happen for leading trivia
                // on the first import because it is probably the header comment for the file.
                // Consider: we could do a more careful check that this trivia is actually a header,
                // but the consequences of being wrong are very minor.
                ts.suppressLeadingTrivia(oldImportDecls[0]);
                var oldImportGroups = ts.group(oldImportDecls, function (importDecl) { return getExternalModuleName(importDecl.moduleSpecifier); });
                var sortedImportGroups = ts.stableSort(oldImportGroups, function (group1, group2) { return compareModuleSpecifiers(group1[0].moduleSpecifier, group2[0].moduleSpecifier); });
                var newImportDecls = ts.flatMap(sortedImportGroups, function (importGroup) {
                    return getExternalModuleName(importGroup[0].moduleSpecifier)
                        ? coalesce(importGroup)
                        : importGroup;
                });
                // Delete or replace the first import.
                if (newImportDecls.length === 0) {
                    changeTracker.delete(sourceFile, oldImportDecls[0]);
                }
                else {
                    // Note: Delete the surrounding trivia because it will have been retained in newImportDecls.
                    changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, {
                        leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude,
                        trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include,
                        suffix: ts.getNewLineOrDefaultFromHost(host, formatContext.options),
                    });
                }
                // Delete any subsequent imports.
                for (var i = 1; i < oldImportDecls.length; i++) {
                    changeTracker.deleteNode(sourceFile, oldImportDecls[i]);
                }
            }
        }
        OrganizeImports.organizeImports = organizeImports;
        function removeUnusedImports(oldImports, sourceFile, program) {
            var typeChecker = program.getTypeChecker();
            var jsxNamespace = typeChecker.getJsxNamespace(sourceFile);
            var jsxElementsPresent = !!(sourceFile.transformFlags & 2 /* ContainsJsx */);
            var usedImports = [];
            for (var _i = 0, oldImports_1 = oldImports; _i < oldImports_1.length; _i++) {
                var importDecl = oldImports_1[_i];
                var importClause = importDecl.importClause, moduleSpecifier = importDecl.moduleSpecifier;
                if (!importClause) {
                    // Imports without import clauses are assumed to be included for their side effects and are not removed.
                    usedImports.push(importDecl);
                    continue;
                }
                var name = importClause.name, namedBindings = importClause.namedBindings;
                // Default import
                if (name && !isDeclarationUsed(name)) {
                    name = undefined;
                }
                if (namedBindings) {
                    if (ts.isNamespaceImport(namedBindings)) {
                        // Namespace import
                        if (!isDeclarationUsed(namedBindings.name)) {
                            namedBindings = undefined;
                        }
                    }
                    else {
                        // List of named imports
                        var newElements = namedBindings.elements.filter(function (e) { return isDeclarationUsed(e.name); });
                        if (newElements.length < namedBindings.elements.length) {
                            namedBindings = newElements.length
                                ? ts.updateNamedImports(namedBindings, newElements)
                                : undefined;
                        }
                    }
                }
                if (name || namedBindings) {
                    usedImports.push(updateImportDeclarationAndClause(importDecl, name, namedBindings));
                }
                // If a module is imported to be augmented, it’s used
                else if (hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier)) {
                    // If we’re in a declaration file, it’s safe to remove the import clause from it
                    if (sourceFile.isDeclarationFile) {
                        usedImports.push(ts.createImportDeclaration(importDecl.decorators, importDecl.modifiers, 
                        /*importClause*/ undefined, moduleSpecifier));
                    }
                    // If we’re not in a declaration file, we can’t remove the import clause even though
                    // the imported symbols are unused, because removing them makes it look like the import
                    // declaration has side effects, which will cause it to be preserved in the JS emit.
                    else {
                        usedImports.push(importDecl);
                    }
                }
            }
            return usedImports;
            function isDeclarationUsed(identifier) {
                // The JSX factory symbol is always used if JSX elements are present - even if they are not allowed.
                return jsxElementsPresent && (identifier.text === jsxNamespace) || ts.FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile);
            }
        }
        function hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier) {
            var moduleSpecifierText = ts.isStringLiteral(moduleSpecifier) && moduleSpecifier.text;
            return ts.isString(moduleSpecifierText) && ts.some(sourceFile.moduleAugmentations, function (moduleName) {
                return ts.isStringLiteral(moduleName)
                    && moduleName.text === moduleSpecifierText;
            });
        }
        function getExternalModuleName(specifier) {
            return specifier !== undefined && ts.isStringLiteralLike(specifier)
                ? specifier.text
                : undefined;
        }
        // Internal for testing
        /**
         * @param importGroup a list of ImportDeclarations, all with the same module name.
         */
        function coalesceImports(importGroup) {
            var _a;
            if (importGroup.length === 0) {
                return importGroup;
            }
            var _b = getCategorizedImports(importGroup), importWithoutClause = _b.importWithoutClause, typeOnlyImports = _b.typeOnlyImports, regularImports = _b.regularImports;
            var coalescedImports = [];
            if (importWithoutClause) {
                coalescedImports.push(importWithoutClause);
            }
            for (var _i = 0, _c = [regularImports, typeOnlyImports]; _i < _c.length; _i++) {
                var group_2 = _c[_i];
                var isTypeOnly = group_2 === typeOnlyImports;
                var defaultImports = group_2.defaultImports, namespaceImports = group_2.namespaceImports, namedImports = group_2.namedImports;
                // Normally, we don't combine default and namespace imports, but it would be silly to
                // produce two import declarations in this special case.
                if (!isTypeOnly && defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) {
                    // Add the namespace import to the existing default ImportDeclaration.
                    var defaultImport = defaultImports[0];
                    coalescedImports.push(updateImportDeclarationAndClause(defaultImport, defaultImport.importClause.name, namespaceImports[0].importClause.namedBindings)); // TODO: GH#18217
                    continue;
                }
                var sortedNamespaceImports = ts.stableSort(namespaceImports, function (i1, i2) {
                    return compareIdentifiers(i1.importClause.namedBindings.name, i2.importClause.namedBindings.name);
                }); // TODO: GH#18217
                for (var _d = 0, sortedNamespaceImports_1 = sortedNamespaceImports; _d < sortedNamespaceImports_1.length; _d++) {
                    var namespaceImport = sortedNamespaceImports_1[_d];
                    // Drop the name, if any
                    coalescedImports.push(updateImportDeclarationAndClause(namespaceImport, /*name*/ undefined, namespaceImport.importClause.namedBindings)); // TODO: GH#18217
                }
                if (defaultImports.length === 0 && namedImports.length === 0) {
                    continue;
                }
                var newDefaultImport = void 0;
                var newImportSpecifiers = [];
                if (defaultImports.length === 1) {
                    newDefaultImport = defaultImports[0].importClause.name;
                }
                else {
                    for (var _e = 0, defaultImports_1 = defaultImports; _e < defaultImports_1.length; _e++) {
                        var defaultImport = defaultImports_1[_e];
                        newImportSpecifiers.push(ts.createImportSpecifier(ts.createIdentifier("default"), defaultImport.importClause.name)); // TODO: GH#18217
                    }
                }
                newImportSpecifiers.push.apply(newImportSpecifiers, ts.flatMap(namedImports, function (i) { return i.importClause.namedBindings.elements; })); // TODO: GH#18217
                var sortedImportSpecifiers = sortSpecifiers(newImportSpecifiers);
                var importDecl = defaultImports.length > 0
                    ? defaultImports[0]
                    : namedImports[0];
                var newNamedImports = sortedImportSpecifiers.length === 0
                    ? newDefaultImport
                        ? undefined
                        : ts.createNamedImports(ts.emptyArray)
                    : namedImports.length === 0
                        ? ts.createNamedImports(sortedImportSpecifiers)
                        : ts.updateNamedImports(namedImports[0].importClause.namedBindings, sortedImportSpecifiers); // TODO: GH#18217
                // Type-only imports are not allowed to mix default, namespace, and named imports in any combination.
                // We could rewrite a default import as a named import (`import { default as name }`), but we currently
                // choose not to as a stylistic preference.
                if (isTypeOnly && newDefaultImport && newNamedImports) {
                    coalescedImports.push(updateImportDeclarationAndClause(importDecl, newDefaultImport, /*namedBindings*/ undefined));
                    coalescedImports.push(updateImportDeclarationAndClause((_a = namedImports[0]) !== null && _a !== void 0 ? _a : importDecl, /*name*/ undefined, newNamedImports));
                }
                else {
                    coalescedImports.push(updateImportDeclarationAndClause(importDecl, newDefaultImport, newNamedImports));
                }
            }
            return coalescedImports;
        }
        OrganizeImports.coalesceImports = coalesceImports;
        /*
         * Returns entire import declarations because they may already have been rewritten and
         * may lack parent pointers.  The desired parts can easily be recovered based on the
         * categorization.
         *
         * NB: There may be overlap between `defaultImports` and `namespaceImports`/`namedImports`.
         */
        function getCategorizedImports(importGroup) {
            var importWithoutClause;
            var typeOnlyImports = { defaultImports: [], namespaceImports: [], namedImports: [] };
            var regularImports = { defaultImports: [], namespaceImports: [], namedImports: [] };
            for (var _i = 0, importGroup_1 = importGroup; _i < importGroup_1.length; _i++) {
                var importDeclaration = importGroup_1[_i];
                if (importDeclaration.importClause === undefined) {
                    // Only the first such import is interesting - the others are redundant.
                    // Note: Unfortunately, we will lose trivia that was on this node.
                    importWithoutClause = importWithoutClause || importDeclaration;
                    continue;
                }
                var group_3 = importDeclaration.importClause.isTypeOnly ? typeOnlyImports : regularImports;
                var _a = importDeclaration.importClause, name = _a.name, namedBindings = _a.namedBindings;
                if (name) {
                    group_3.defaultImports.push(importDeclaration);
                }
                if (namedBindings) {
                    if (ts.isNamespaceImport(namedBindings)) {
                        group_3.namespaceImports.push(importDeclaration);
                    }
                    else {
                        group_3.namedImports.push(importDeclaration);
                    }
                }
            }
            return {
                importWithoutClause: importWithoutClause,
                typeOnlyImports: typeOnlyImports,
                regularImports: regularImports,
            };
        }
        // Internal for testing
        /**
         * @param exportGroup a list of ExportDeclarations, all with the same module name.
         */
        function coalesceExports(exportGroup) {
            if (exportGroup.length === 0) {
                return exportGroup;
            }
            var _a = getCategorizedExports(exportGroup), exportWithoutClause = _a.exportWithoutClause, namedExports = _a.namedExports, typeOnlyExports = _a.typeOnlyExports;
            var coalescedExports = [];
            if (exportWithoutClause) {
                coalescedExports.push(exportWithoutClause);
            }
            for (var _i = 0, _b = [namedExports, typeOnlyExports]; _i < _b.length; _i++) {
                var exportGroup_1 = _b[_i];
                if (exportGroup_1.length === 0) {
                    continue;
                }
                var newExportSpecifiers = [];
                newExportSpecifiers.push.apply(newExportSpecifiers, ts.flatMap(exportGroup_1, function (i) { return i.exportClause && ts.isNamedExports(i.exportClause) ? i.exportClause.elements : ts.emptyArray; }));
                var sortedExportSpecifiers = sortSpecifiers(newExportSpecifiers);
                var exportDecl = exportGroup_1[0];
                coalescedExports.push(ts.updateExportDeclaration(exportDecl, exportDecl.decorators, exportDecl.modifiers, exportDecl.exportClause && (ts.isNamedExports(exportDecl.exportClause) ?
                    ts.updateNamedExports(exportDecl.exportClause, sortedExportSpecifiers) :
                    ts.updateNamespaceExport(exportDecl.exportClause, exportDecl.exportClause.name)), exportDecl.moduleSpecifier, exportDecl.isTypeOnly));
            }
            return coalescedExports;
            /*
             * Returns entire export declarations because they may already have been rewritten and
             * may lack parent pointers.  The desired parts can easily be recovered based on the
             * categorization.
             */
            function getCategorizedExports(exportGroup) {
                var exportWithoutClause;
                var namedExports = [];
                var typeOnlyExports = [];
                for (var _i = 0, exportGroup_2 = exportGroup; _i < exportGroup_2.length; _i++) {
                    var exportDeclaration = exportGroup_2[_i];
                    if (exportDeclaration.exportClause === undefined) {
                        // Only the first such export is interesting - the others are redundant.
                        // Note: Unfortunately, we will lose trivia that was on this node.
                        exportWithoutClause = exportWithoutClause || exportDeclaration;
                    }
                    else if (exportDeclaration.isTypeOnly) {
                        typeOnlyExports.push(exportDeclaration);
                    }
                    else {
                        namedExports.push(exportDeclaration);
                    }
                }
                return {
                    exportWithoutClause: exportWithoutClause,
                    namedExports: namedExports,
                    typeOnlyExports: typeOnlyExports,
                };
            }
        }
        OrganizeImports.coalesceExports = coalesceExports;
        function updateImportDeclarationAndClause(importDeclaration, name, namedBindings) {
            return ts.updateImportDeclaration(importDeclaration, importDeclaration.decorators, importDeclaration.modifiers, ts.updateImportClause(importDeclaration.importClause, name, namedBindings, importDeclaration.importClause.isTypeOnly), // TODO: GH#18217
            importDeclaration.moduleSpecifier);
        }
        function sortSpecifiers(specifiers) {
            return ts.stableSort(specifiers, function (s1, s2) {
                return compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) ||
                    compareIdentifiers(s1.name, s2.name);
            });
        }
        /* internal */ // Exported for testing
        function compareModuleSpecifiers(m1, m2) {
            var name1 = getExternalModuleName(m1);
            var name2 = getExternalModuleName(m2);
            return ts.compareBooleans(name1 === undefined, name2 === undefined) ||
                ts.compareBooleans(ts.isExternalModuleNameRelative(name1), ts.isExternalModuleNameRelative(name2)) ||
                ts.compareStringsCaseInsensitive(name1, name2);
        }
        OrganizeImports.compareModuleSpecifiers = compareModuleSpecifiers;
        function compareIdentifiers(s1, s2) {
            return ts.compareStringsCaseInsensitive(s1.text, s2.text);
        }
    })(OrganizeImports = ts.OrganizeImports || (ts.OrganizeImports = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var OutliningElementsCollector;
    (function (OutliningElementsCollector) {
        function collectElements(sourceFile, cancellationToken) {
            var res = [];
            addNodeOutliningSpans(sourceFile, cancellationToken, res);
            addRegionOutliningSpans(sourceFile, res);
            return res.sort(function (span1, span2) { return span1.textSpan.start - span2.textSpan.start; });
        }
        OutliningElementsCollector.collectElements = collectElements;
        function addNodeOutliningSpans(sourceFile, cancellationToken, out) {
            var depthRemaining = 40;
            var current = 0;
            // Includes the EOF Token so that comments which aren't attached to statements are included
            var statements = __spreadArrays(sourceFile.statements, [sourceFile.endOfFileToken]);
            var n = statements.length;
            while (current < n) {
                while (current < n && !ts.isAnyImportSyntax(statements[current])) {
                    visitNonImportNode(statements[current]);
                    current++;
                }
                if (current === n)
                    break;
                var firstImport = current;
                while (current < n && ts.isAnyImportSyntax(statements[current])) {
                    addOutliningForLeadingCommentsForNode(statements[current], sourceFile, cancellationToken, out);
                    current++;
                }
                var lastImport = current - 1;
                if (lastImport !== firstImport) {
                    out.push(createOutliningSpanFromBounds(ts.findChildOfKind(statements[firstImport], 96 /* ImportKeyword */, sourceFile).getStart(sourceFile), statements[lastImport].getEnd(), "imports" /* Imports */));
                }
            }
            function visitNonImportNode(n) {
                var _a;
                if (depthRemaining === 0)
                    return;
                cancellationToken.throwIfCancellationRequested();
                if (ts.isDeclaration(n) || n.kind === 1 /* EndOfFileToken */) {
                    addOutliningForLeadingCommentsForNode(n, sourceFile, cancellationToken, out);
                }
                if (isFunctionExpressionAssignedToVariable(n)) {
                    addOutliningForLeadingCommentsForNode(n.parent.parent.parent, sourceFile, cancellationToken, out);
                }
                var span = getOutliningSpanForNode(n, sourceFile);
                if (span)
                    out.push(span);
                depthRemaining--;
                if (ts.isCallExpression(n)) {
                    depthRemaining++;
                    visitNonImportNode(n.expression);
                    depthRemaining--;
                    n.arguments.forEach(visitNonImportNode);
                    (_a = n.typeArguments) === null || _a === void 0 ? void 0 : _a.forEach(visitNonImportNode);
                }
                else if (ts.isIfStatement(n) && n.elseStatement && ts.isIfStatement(n.elseStatement)) {
                    // Consider an 'else if' to be on the same depth as the 'if'.
                    visitNonImportNode(n.expression);
                    visitNonImportNode(n.thenStatement);
                    depthRemaining++;
                    visitNonImportNode(n.elseStatement);
                    depthRemaining--;
                }
                else {
                    n.forEachChild(visitNonImportNode);
                }
                depthRemaining++;
            }
            function isFunctionExpressionAssignedToVariable(n) {
                if (!ts.isFunctionExpression(n) && !ts.isArrowFunction(n)) {
                    return false;
                }
                var ancestor = ts.findAncestor(n, ts.isVariableStatement);
                return !!ancestor && ts.getSingleInitializerOfVariableStatementOrPropertyDeclaration(ancestor) === n;
            }
        }
        function addRegionOutliningSpans(sourceFile, out) {
            var regions = [];
            var lineStarts = sourceFile.getLineStarts();
            for (var _i = 0, lineStarts_1 = lineStarts; _i < lineStarts_1.length; _i++) {
                var currentLineStart = lineStarts_1[_i];
                var lineEnd = sourceFile.getLineEndOfPosition(currentLineStart);
                var lineText = sourceFile.text.substring(currentLineStart, lineEnd);
                var result = isRegionDelimiter(lineText);
                if (!result || ts.isInComment(sourceFile, currentLineStart)) {
                    continue;
                }
                if (!result[1]) {
                    var span = ts.createTextSpanFromBounds(sourceFile.text.indexOf("//", currentLineStart), lineEnd);
                    regions.push(createOutliningSpan(span, "region" /* Region */, span, /*autoCollapse*/ false, result[2] || "#region"));
                }
                else {
                    var region = regions.pop();
                    if (region) {
                        region.textSpan.length = lineEnd - region.textSpan.start;
                        region.hintSpan.length = lineEnd - region.textSpan.start;
                        out.push(region);
                    }
                }
            }
        }
        var regionDelimiterRegExp = /^\s*\/\/\s*#(end)?region(?:\s+(.*))?(?:\r)?$/;
        function isRegionDelimiter(lineText) {
            return regionDelimiterRegExp.exec(lineText);
        }
        function addOutliningForLeadingCommentsForNode(n, sourceFile, cancellationToken, out) {
            var comments = ts.getLeadingCommentRangesOfNode(n, sourceFile);
            if (!comments)
                return;
            var firstSingleLineCommentStart = -1;
            var lastSingleLineCommentEnd = -1;
            var singleLineCommentCount = 0;
            var sourceText = sourceFile.getFullText();
            for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
                var _a = comments_1[_i], kind = _a.kind, pos = _a.pos, end = _a.end;
                cancellationToken.throwIfCancellationRequested();
                switch (kind) {
                    case 2 /* SingleLineCommentTrivia */:
                        // never fold region delimiters into single-line comment regions
                        var commentText = sourceText.slice(pos, end);
                        if (isRegionDelimiter(commentText)) {
                            combineAndAddMultipleSingleLineComments();
                            singleLineCommentCount = 0;
                            break;
                        }
                        // For single line comments, combine consecutive ones (2 or more) into
                        // a single span from the start of the first till the end of the last
                        if (singleLineCommentCount === 0) {
                            firstSingleLineCommentStart = pos;
                        }
                        lastSingleLineCommentEnd = end;
                        singleLineCommentCount++;
                        break;
                    case 3 /* MultiLineCommentTrivia */:
                        combineAndAddMultipleSingleLineComments();
                        out.push(createOutliningSpanFromBounds(pos, end, "comment" /* Comment */));
                        singleLineCommentCount = 0;
                        break;
                    default:
                        ts.Debug.assertNever(kind);
                }
            }
            combineAndAddMultipleSingleLineComments();
            function combineAndAddMultipleSingleLineComments() {
                // Only outline spans of two or more consecutive single line comments
                if (singleLineCommentCount > 1) {
                    out.push(createOutliningSpanFromBounds(firstSingleLineCommentStart, lastSingleLineCommentEnd, "comment" /* Comment */));
                }
            }
        }
        function createOutliningSpanFromBounds(pos, end, kind) {
            return createOutliningSpan(ts.createTextSpanFromBounds(pos, end), kind);
        }
        function getOutliningSpanForNode(n, sourceFile) {
            switch (n.kind) {
                case 223 /* Block */:
                    if (ts.isFunctionLike(n.parent)) {
                        return functionSpan(n.parent, n, sourceFile);
                    }
                    // Check if the block is standalone, or 'attached' to some parent statement.
                    // If the latter, we want to collapse the block, but consider its hint span
                    // to be the entire span of the parent.
                    switch (n.parent.kind) {
                        case 228 /* DoStatement */:
                        case 231 /* ForInStatement */:
                        case 232 /* ForOfStatement */:
                        case 230 /* ForStatement */:
                        case 227 /* IfStatement */:
                        case 229 /* WhileStatement */:
                        case 236 /* WithStatement */:
                        case 280 /* CatchClause */:
                            return spanForNode(n.parent);
                        case 240 /* TryStatement */:
                            // Could be the try-block, or the finally-block.
                            var tryStatement = n.parent;
                            if (tryStatement.tryBlock === n) {
                                return spanForNode(n.parent);
                            }
                            else if (tryStatement.finallyBlock === n) {
                                var node = ts.findChildOfKind(tryStatement, 92 /* FinallyKeyword */, sourceFile);
                                if (node)
                                    return spanForNode(node);
                            }
                        // falls through
                        default:
                            // Block was a standalone block.  In this case we want to only collapse
                            // the span of the block, independent of any parent span.
                            return createOutliningSpan(ts.createTextSpanFromNode(n, sourceFile), "code" /* Code */);
                    }
                case 250 /* ModuleBlock */:
                    return spanForNode(n.parent);
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                case 246 /* InterfaceDeclaration */:
                case 248 /* EnumDeclaration */:
                case 251 /* CaseBlock */:
                case 173 /* TypeLiteral */:
                    return spanForNode(n);
                case 277 /* CaseClause */:
                case 278 /* DefaultClause */:
                    return spanForNodeArray(n.statements);
                case 193 /* ObjectLiteralExpression */:
                    return spanForObjectOrArrayLiteral(n);
                case 192 /* ArrayLiteralExpression */:
                    return spanForObjectOrArrayLiteral(n, 22 /* OpenBracketToken */);
                case 266 /* JsxElement */:
                    return spanForJSXElement(n);
                case 270 /* JsxFragment */:
                    return spanForJSXFragment(n);
                case 267 /* JsxSelfClosingElement */:
                case 268 /* JsxOpeningElement */:
                    return spanForJSXAttributes(n.attributes);
                case 211 /* TemplateExpression */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    return spanForTemplateLiteral(n);
            }
            function spanForJSXElement(node) {
                var textSpan = ts.createTextSpanFromBounds(node.openingElement.getStart(sourceFile), node.closingElement.getEnd());
                var tagName = node.openingElement.tagName.getText(sourceFile);
                var bannerText = "<" + tagName + ">...</" + tagName + ">";
                return createOutliningSpan(textSpan, "code" /* Code */, textSpan, /*autoCollapse*/ false, bannerText);
            }
            function spanForJSXFragment(node) {
                var textSpan = ts.createTextSpanFromBounds(node.openingFragment.getStart(sourceFile), node.closingFragment.getEnd());
                var bannerText = "<>...</>";
                return createOutliningSpan(textSpan, "code" /* Code */, textSpan, /*autoCollapse*/ false, bannerText);
            }
            function spanForJSXAttributes(node) {
                if (node.properties.length === 0) {
                    return undefined;
                }
                return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), "code" /* Code */);
            }
            function spanForTemplateLiteral(node) {
                if (node.kind === 14 /* NoSubstitutionTemplateLiteral */ && node.text.length === 0) {
                    return undefined;
                }
                return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), "code" /* Code */);
            }
            function spanForObjectOrArrayLiteral(node, open) {
                if (open === void 0) { open = 18 /* OpenBraceToken */; }
                // If the block has no leading keywords and is inside an array literal or call expression,
                // we only want to collapse the span of the block.
                // Otherwise, the collapsed section will include the end of the previous line.
                return spanForNode(node, /*autoCollapse*/ false, /*useFullStart*/ !ts.isArrayLiteralExpression(node.parent) && !ts.isCallExpression(node.parent), open);
            }
            function spanForNode(hintSpanNode, autoCollapse, useFullStart, open, close) {
                if (autoCollapse === void 0) { autoCollapse = false; }
                if (useFullStart === void 0) { useFullStart = true; }
                if (open === void 0) { open = 18 /* OpenBraceToken */; }
                if (close === void 0) { close = open === 18 /* OpenBraceToken */ ? 19 /* CloseBraceToken */ : 23 /* CloseBracketToken */; }
                var openToken = ts.findChildOfKind(n, open, sourceFile);
                var closeToken = ts.findChildOfKind(n, close, sourceFile);
                return openToken && closeToken && spanBetweenTokens(openToken, closeToken, hintSpanNode, sourceFile, autoCollapse, useFullStart);
            }
            function spanForNodeArray(nodeArray) {
                return nodeArray.length ? createOutliningSpan(ts.createTextSpanFromRange(nodeArray), "code" /* Code */) : undefined;
            }
        }
        function functionSpan(node, body, sourceFile) {
            var openToken = ts.isNodeArrayMultiLine(node.parameters, sourceFile)
                ? ts.findChildOfKind(node, 20 /* OpenParenToken */, sourceFile)
                : ts.findChildOfKind(body, 18 /* OpenBraceToken */, sourceFile);
            var closeToken = ts.findChildOfKind(body, 19 /* CloseBraceToken */, sourceFile);
            return openToken && closeToken && spanBetweenTokens(openToken, closeToken, node, sourceFile, /*autoCollapse*/ node.kind !== 202 /* ArrowFunction */);
        }
        function spanBetweenTokens(openToken, closeToken, hintSpanNode, sourceFile, autoCollapse, useFullStart) {
            if (autoCollapse === void 0) { autoCollapse = false; }
            if (useFullStart === void 0) { useFullStart = true; }
            var textSpan = ts.createTextSpanFromBounds(useFullStart ? openToken.getFullStart() : openToken.getStart(sourceFile), closeToken.getEnd());
            return createOutliningSpan(textSpan, "code" /* Code */, ts.createTextSpanFromNode(hintSpanNode, sourceFile), autoCollapse);
        }
        function createOutliningSpan(textSpan, kind, hintSpan, autoCollapse, bannerText) {
            if (hintSpan === void 0) { hintSpan = textSpan; }
            if (autoCollapse === void 0) { autoCollapse = false; }
            if (bannerText === void 0) { bannerText = "..."; }
            return { textSpan: textSpan, kind: kind, hintSpan: hintSpan, bannerText: bannerText, autoCollapse: autoCollapse };
        }
    })(OutliningElementsCollector = ts.OutliningElementsCollector || (ts.OutliningElementsCollector = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    // Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
    var PatternMatchKind;
    (function (PatternMatchKind) {
        PatternMatchKind[PatternMatchKind["exact"] = 0] = "exact";
        PatternMatchKind[PatternMatchKind["prefix"] = 1] = "prefix";
        PatternMatchKind[PatternMatchKind["substring"] = 2] = "substring";
        PatternMatchKind[PatternMatchKind["camelCase"] = 3] = "camelCase";
    })(PatternMatchKind = ts.PatternMatchKind || (ts.PatternMatchKind = {}));
    function createPatternMatch(kind, isCaseSensitive) {
        return {
            kind: kind,
            isCaseSensitive: isCaseSensitive
        };
    }
    function createPatternMatcher(pattern) {
        // We'll often see the same candidate string many times when searching (For example, when
        // we see the name of a module that is used everywhere, or the name of an overload).  As
        // such, we cache the information we compute about the candidate for the life of this
        // pattern matcher so we don't have to compute it multiple times.
        var stringToWordSpans = ts.createMap();
        var dotSeparatedSegments = pattern.trim().split(".").map(function (p) { return createSegment(p.trim()); });
        // A segment is considered invalid if we couldn't find any words in it.
        if (dotSeparatedSegments.some(function (segment) { return !segment.subWordTextChunks.length; }))
            return undefined;
        return {
            getFullMatch: function (containers, candidate) { return getFullMatch(containers, candidate, dotSeparatedSegments, stringToWordSpans); },
            getMatchForLastSegmentOfPattern: function (candidate) { return matchSegment(candidate, ts.last(dotSeparatedSegments), stringToWordSpans); },
            patternContainsDots: dotSeparatedSegments.length > 1
        };
    }
    ts.createPatternMatcher = createPatternMatcher;
    function getFullMatch(candidateContainers, candidate, dotSeparatedSegments, stringToWordSpans) {
        // First, check that the last part of the dot separated pattern matches the name of the
        // candidate.  If not, then there's no point in proceeding and doing the more
        // expensive work.
        var candidateMatch = matchSegment(candidate, ts.last(dotSeparatedSegments), stringToWordSpans);
        if (!candidateMatch) {
            return undefined;
        }
        // -1 because the last part was checked against the name, and only the rest
        // of the parts are checked against the container.
        if (dotSeparatedSegments.length - 1 > candidateContainers.length) {
            // There weren't enough container parts to match against the pattern parts.
            // So this definitely doesn't match.
            return undefined;
        }
        var bestMatch;
        for (var i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; i >= 0; i -= 1, j -= 1) {
            bestMatch = betterMatch(bestMatch, matchSegment(candidateContainers[j], dotSeparatedSegments[i], stringToWordSpans));
        }
        return bestMatch;
    }
    function getWordSpans(word, stringToWordSpans) {
        var spans = stringToWordSpans.get(word);
        if (!spans) {
            stringToWordSpans.set(word, spans = breakIntoWordSpans(word));
        }
        return spans;
    }
    function matchTextChunk(candidate, chunk, stringToWordSpans) {
        var index = indexOfIgnoringCase(candidate, chunk.textLowerCase);
        if (index === 0) {
            // a) Check if the word is a prefix of the candidate, in a case insensitive or
            //    sensitive manner. If it does, return that there was an exact match if the word and candidate are the same length, else a prefix match.
            return createPatternMatch(chunk.text.length === candidate.length ? PatternMatchKind.exact : PatternMatchKind.prefix, /*isCaseSensitive:*/ ts.startsWith(candidate, chunk.text));
        }
        if (chunk.isLowerCase) {
            if (index === -1)
                return undefined;
            // b) If the part is entirely lowercase, then check if it is contained anywhere in the
            //    candidate in a case insensitive manner.  If so, return that there was a substring
            //    match.
            //
            //    Note: We only have a substring match if the lowercase part is prefix match of some
            //    word part. That way we don't match something like 'Class' when the user types 'a'.
            //    But we would match 'FooAttribute' (since 'Attribute' starts with 'a').
            var wordSpans = getWordSpans(candidate, stringToWordSpans);
            for (var _i = 0, wordSpans_1 = wordSpans; _i < wordSpans_1.length; _i++) {
                var span = wordSpans_1[_i];
                if (partStartsWith(candidate, span, chunk.text, /*ignoreCase:*/ true)) {
                    return createPatternMatch(PatternMatchKind.substring, /*isCaseSensitive:*/ partStartsWith(candidate, span, chunk.text, /*ignoreCase:*/ false));
                }
            }
            // c) Is the pattern a substring of the candidate starting on one of the candidate's word boundaries?
            // We could check every character boundary start of the candidate for the pattern. However, that's
            // an m * n operation in the wost case. Instead, find the first instance of the pattern
            // substring, and see if it starts on a capital letter. It seems unlikely that the user will try to
            // filter the list based on a substring that starts on a capital letter and also with a lowercase one.
            // (Pattern: fogbar, Candidate: quuxfogbarFogBar).
            if (chunk.text.length < candidate.length && isUpperCaseLetter(candidate.charCodeAt(index))) {
                return createPatternMatch(PatternMatchKind.substring, /*isCaseSensitive:*/ false);
            }
        }
        else {
            // d) If the part was not entirely lowercase, then check if it is contained in the
            //    candidate in a case *sensitive* manner. If so, return that there was a substring
            //    match.
            if (candidate.indexOf(chunk.text) > 0) {
                return createPatternMatch(PatternMatchKind.substring, /*isCaseSensitive:*/ true);
            }
            // e) If the part was not entirely lowercase, then attempt a camel cased match as well.
            if (chunk.characterSpans.length > 0) {
                var candidateParts = getWordSpans(candidate, stringToWordSpans);
                var isCaseSensitive = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ false) ? true
                    : tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ true) ? false : undefined;
                if (isCaseSensitive !== undefined) {
                    return createPatternMatch(PatternMatchKind.camelCase, isCaseSensitive);
                }
            }
        }
    }
    function matchSegment(candidate, segment, stringToWordSpans) {
        // First check if the segment matches as is.  This is also useful if the segment contains
        // characters we would normally strip when splitting into parts that we also may want to
        // match in the candidate.  For example if the segment is "@int" and the candidate is
        // "@int", then that will show up as an exact match here.
        //
        // Note: if the segment contains a space or an asterisk then we must assume that it's a
        // multi-word segment.
        if (every(segment.totalTextChunk.text, function (ch) { return ch !== 32 /* space */ && ch !== 42 /* asterisk */; })) {
            var match = matchTextChunk(candidate, segment.totalTextChunk, stringToWordSpans);
            if (match)
                return match;
        }
        // The logic for pattern matching is now as follows:
        //
        // 1) Break the segment passed in into words.  Breaking is rather simple and a
        //    good way to think about it that if gives you all the individual alphanumeric words
        //    of the pattern.
        //
        // 2) For each word try to match the word against the candidate value.
        //
        // 3) Matching is as follows:
        //
        //   a) Check if the word is a prefix of the candidate, in a case insensitive or
        //      sensitive manner. If it does, return that there was an exact match if the word and candidate are the same length, else a prefix match.
        //
        //   If the word is entirely lowercase:
        //      b) Then check if it is contained anywhere in the
        //          candidate in a case insensitive manner.  If so, return that there was a substring
        //          match.
        //
        //          Note: We only have a substring match if the lowercase part is prefix match of
        //          some word part. That way we don't match something like 'Class' when the user
        //          types 'a'. But we would match 'FooAttribute' (since 'Attribute' starts with
        //          'a').
        //
        //       c) The word is all lower case. Is it a case insensitive substring of the candidate starting
        //          on a part boundary of the candidate?
        //
        //   Else:
        //       d) If the word was not entirely lowercase, then check if it is contained in the
        //          candidate in a case *sensitive* manner. If so, return that there was a substring
        //          match.
        //
        //       e) If the word was not entirely lowercase, then attempt a camel cased match as
        //          well.
        //
        // Only if all words have some sort of match is the pattern considered matched.
        var subWordTextChunks = segment.subWordTextChunks;
        var bestMatch;
        for (var _i = 0, subWordTextChunks_1 = subWordTextChunks; _i < subWordTextChunks_1.length; _i++) {
            var subWordTextChunk = subWordTextChunks_1[_i];
            bestMatch = betterMatch(bestMatch, matchTextChunk(candidate, subWordTextChunk, stringToWordSpans));
        }
        return bestMatch;
    }
    function betterMatch(a, b) {
        return ts.min(a, b, compareMatches);
    }
    function compareMatches(a, b) {
        return a === undefined ? 1 /* GreaterThan */ : b === undefined ? -1 /* LessThan */
            : ts.compareValues(a.kind, b.kind) || ts.compareBooleans(!a.isCaseSensitive, !b.isCaseSensitive);
    }
    function partStartsWith(candidate, candidateSpan, pattern, ignoreCase, patternSpan) {
        if (patternSpan === void 0) { patternSpan = { start: 0, length: pattern.length }; }
        return patternSpan.length <= candidateSpan.length // If pattern part is longer than the candidate part there can never be a match.
            && everyInRange(0, patternSpan.length, function (i) { return equalChars(pattern.charCodeAt(patternSpan.start + i), candidate.charCodeAt(candidateSpan.start + i), ignoreCase); });
    }
    function equalChars(ch1, ch2, ignoreCase) {
        return ignoreCase ? toLowerCase(ch1) === toLowerCase(ch2) : ch1 === ch2;
    }
    function tryCamelCaseMatch(candidate, candidateParts, chunk, ignoreCase) {
        var chunkCharacterSpans = chunk.characterSpans;
        // Note: we may have more pattern parts than candidate parts.  This is because multiple
        // pattern parts may match a candidate part.  For example "SiUI" against "SimpleUI".
        // We'll have 3 pattern parts Si/U/I against two candidate parts Simple/UI.  However, U
        // and I will both match in UI.
        var currentCandidate = 0;
        var currentChunkSpan = 0;
        var firstMatch;
        var contiguous;
        while (true) {
            // Let's consider our termination cases
            if (currentChunkSpan === chunkCharacterSpans.length) {
                return true;
            }
            else if (currentCandidate === candidateParts.length) {
                // No match, since we still have more of the pattern to hit
                return false;
            }
            var candidatePart = candidateParts[currentCandidate];
            var gotOneMatchThisCandidate = false;
            // Consider the case of matching SiUI against SimpleUIElement. The candidate parts
            // will be Simple/UI/Element, and the pattern parts will be Si/U/I.  We'll match 'Si'
            // against 'Simple' first.  Then we'll match 'U' against 'UI'. However, we want to
            // still keep matching pattern parts against that candidate part.
            for (; currentChunkSpan < chunkCharacterSpans.length; currentChunkSpan++) {
                var chunkCharacterSpan = chunkCharacterSpans[currentChunkSpan];
                if (gotOneMatchThisCandidate) {
                    // We've already gotten one pattern part match in this candidate.  We will
                    // only continue trying to consumer pattern parts if the last part and this
                    // part are both upper case.
                    if (!isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan - 1].start)) ||
                        !isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan].start))) {
                        break;
                    }
                }
                if (!partStartsWith(candidate, candidatePart, chunk.text, ignoreCase, chunkCharacterSpan)) {
                    break;
                }
                gotOneMatchThisCandidate = true;
                firstMatch = firstMatch === undefined ? currentCandidate : firstMatch;
                // If we were contiguous, then keep that value.  If we weren't, then keep that
                // value.  If we don't know, then set the value to 'true' as an initial match is
                // obviously contiguous.
                contiguous = contiguous === undefined ? true : contiguous;
                candidatePart = ts.createTextSpan(candidatePart.start + chunkCharacterSpan.length, candidatePart.length - chunkCharacterSpan.length);
            }
            // Check if we matched anything at all.  If we didn't, then we need to unset the
            // contiguous bit if we currently had it set.
            // If we haven't set the bit yet, then that means we haven't matched anything so
            // far, and we don't want to change that.
            if (!gotOneMatchThisCandidate && contiguous !== undefined) {
                contiguous = false;
            }
            // Move onto the next candidate.
            currentCandidate++;
        }
    }
    function createSegment(text) {
        return {
            totalTextChunk: createTextChunk(text),
            subWordTextChunks: breakPatternIntoTextChunks(text)
        };
    }
    function isUpperCaseLetter(ch) {
        // Fast check for the ascii range.
        if (ch >= 65 /* A */ && ch <= 90 /* Z */) {
            return true;
        }
        if (ch < 127 /* maxAsciiCharacter */ || !ts.isUnicodeIdentifierStart(ch, 99 /* Latest */)) {
            return false;
        }
        // TODO: find a way to determine this for any unicode characters in a
        // non-allocating manner.
        var str = String.fromCharCode(ch);
        return str === str.toUpperCase();
    }
    function isLowerCaseLetter(ch) {
        // Fast check for the ascii range.
        if (ch >= 97 /* a */ && ch <= 122 /* z */) {
            return true;
        }
        if (ch < 127 /* maxAsciiCharacter */ || !ts.isUnicodeIdentifierStart(ch, 99 /* Latest */)) {
            return false;
        }
        // TODO: find a way to determine this for any unicode characters in a
        // non-allocating manner.
        var str = String.fromCharCode(ch);
        return str === str.toLowerCase();
    }
    // Assumes 'value' is already lowercase.
    function indexOfIgnoringCase(str, value) {
        var n = str.length - value.length;
        var _loop_6 = function (start) {
            if (every(value, function (valueChar, i) { return toLowerCase(str.charCodeAt(i + start)) === valueChar; })) {
                return { value: start };
            }
        };
        for (var start = 0; start <= n; start++) {
            var state_1 = _loop_6(start);
            if (typeof state_1 === "object")
                return state_1.value;
        }
        return -1;
    }
    function toLowerCase(ch) {
        // Fast convert for the ascii range.
        if (ch >= 65 /* A */ && ch <= 90 /* Z */) {
            return 97 /* a */ + (ch - 65 /* A */);
        }
        if (ch < 127 /* maxAsciiCharacter */) {
            return ch;
        }
        // TODO: find a way to compute this for any unicode characters in a
        // non-allocating manner.
        return String.fromCharCode(ch).toLowerCase().charCodeAt(0);
    }
    function isDigit(ch) {
        // TODO(cyrusn): Find a way to support this for unicode digits.
        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
    }
    function isWordChar(ch) {
        return isUpperCaseLetter(ch) || isLowerCaseLetter(ch) || isDigit(ch) || ch === 95 /* _ */ || ch === 36 /* $ */;
    }
    function breakPatternIntoTextChunks(pattern) {
        var result = [];
        var wordStart = 0;
        var wordLength = 0;
        for (var i = 0; i < pattern.length; i++) {
            var ch = pattern.charCodeAt(i);
            if (isWordChar(ch)) {
                if (wordLength === 0) {
                    wordStart = i;
                }
                wordLength++;
            }
            else {
                if (wordLength > 0) {
                    result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
                    wordLength = 0;
                }
            }
        }
        if (wordLength > 0) {
            result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
        }
        return result;
    }
    function createTextChunk(text) {
        var textLowerCase = text.toLowerCase();
        return {
            text: text,
            textLowerCase: textLowerCase,
            isLowerCase: text === textLowerCase,
            characterSpans: breakIntoCharacterSpans(text)
        };
    }
    function breakIntoCharacterSpans(identifier) {
        return breakIntoSpans(identifier, /*word:*/ false);
    }
    ts.breakIntoCharacterSpans = breakIntoCharacterSpans;
    function breakIntoWordSpans(identifier) {
        return breakIntoSpans(identifier, /*word:*/ true);
    }
    ts.breakIntoWordSpans = breakIntoWordSpans;
    function breakIntoSpans(identifier, word) {
        var result = [];
        var wordStart = 0;
        for (var i = 1; i < identifier.length; i++) {
            var lastIsDigit = isDigit(identifier.charCodeAt(i - 1));
            var currentIsDigit = isDigit(identifier.charCodeAt(i));
            var hasTransitionFromLowerToUpper = transitionFromLowerToUpper(identifier, word, i);
            var hasTransitionFromUpperToLower = word && transitionFromUpperToLower(identifier, i, wordStart);
            if (charIsPunctuation(identifier.charCodeAt(i - 1)) ||
                charIsPunctuation(identifier.charCodeAt(i)) ||
                lastIsDigit !== currentIsDigit ||
                hasTransitionFromLowerToUpper ||
                hasTransitionFromUpperToLower) {
                if (!isAllPunctuation(identifier, wordStart, i)) {
                    result.push(ts.createTextSpan(wordStart, i - wordStart));
                }
                wordStart = i;
            }
        }
        if (!isAllPunctuation(identifier, wordStart, identifier.length)) {
            result.push(ts.createTextSpan(wordStart, identifier.length - wordStart));
        }
        return result;
    }
    function charIsPunctuation(ch) {
        switch (ch) {
            case 33 /* exclamation */:
            case 34 /* doubleQuote */:
            case 35 /* hash */:
            case 37 /* percent */:
            case 38 /* ampersand */:
            case 39 /* singleQuote */:
            case 40 /* openParen */:
            case 41 /* closeParen */:
            case 42 /* asterisk */:
            case 44 /* comma */:
            case 45 /* minus */:
            case 46 /* dot */:
            case 47 /* slash */:
            case 58 /* colon */:
            case 59 /* semicolon */:
            case 63 /* question */:
            case 64 /* at */:
            case 91 /* openBracket */:
            case 92 /* backslash */:
            case 93 /* closeBracket */:
            case 95 /* _ */:
            case 123 /* openBrace */:
            case 125 /* closeBrace */:
                return true;
        }
        return false;
    }
    function isAllPunctuation(identifier, start, end) {
        return every(identifier, function (ch) { return charIsPunctuation(ch) && ch !== 95 /* _ */; }, start, end);
    }
    function transitionFromUpperToLower(identifier, index, wordStart) {
        // Cases this supports:
        // 1) IDisposable -> I, Disposable
        // 2) UIElement -> UI, Element
        // 3) HTMLDocument -> HTML, Document
        //
        // etc.
        // We have a transition from an upper to a lower letter here.  But we only
        // want to break if all the letters that preceded are uppercase.  i.e. if we
        // have "Foo" we don't want to break that into "F, oo".  But if we have
        // "IFoo" or "UIFoo", then we want to break that into "I, Foo" and "UI,
        // Foo".  i.e. the last uppercase letter belongs to the lowercase letters
        // that follows.  Note: this will make the following not split properly:
        // "HELLOthere".  However, these sorts of names do not show up in .Net
        // programs.
        return index !== wordStart
            && index + 1 < identifier.length
            && isUpperCaseLetter(identifier.charCodeAt(index))
            && isLowerCaseLetter(identifier.charCodeAt(index + 1))
            && every(identifier, isUpperCaseLetter, wordStart, index);
    }
    function transitionFromLowerToUpper(identifier, word, index) {
        var lastIsUpper = isUpperCaseLetter(identifier.charCodeAt(index - 1));
        var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
        // See if the casing indicates we're starting a new word. Note: if we're breaking on
        // words, then just seeing an upper case character isn't enough.  Instead, it has to
        // be uppercase and the previous character can't be uppercase.
        //
        // For example, breaking "AddMetadata" on words would make: Add Metadata
        //
        // on characters would be: A dd M etadata
        //
        // Break "AM" on words would be: AM
        //
        // on characters would be: A M
        //
        // We break the search string on characters.  But we break the symbol name on words.
        return currentIsUpper && (!word || !lastIsUpper);
    }
    function everyInRange(start, end, pred) {
        for (var i = start; i < end; i++) {
            if (!pred(i)) {
                return false;
            }
        }
        return true;
    }
    function every(s, pred, start, end) {
        if (start === void 0) { start = 0; }
        if (end === void 0) { end = s.length; }
        return everyInRange(start, end, function (i) { return pred(s.charCodeAt(i), i); });
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    function preProcessFile(sourceText, readImportFiles, detectJavaScriptImports) {
        if (readImportFiles === void 0) { readImportFiles = true; }
        if (detectJavaScriptImports === void 0) { detectJavaScriptImports = false; }
        var pragmaContext = {
            languageVersion: 1 /* ES5 */,
            pragmas: undefined,
            checkJsDirective: undefined,
            referencedFiles: [],
            typeReferenceDirectives: [],
            libReferenceDirectives: [],
            amdDependencies: [],
            hasNoDefaultLib: undefined,
            moduleName: undefined
        };
        var importedFiles = [];
        var ambientExternalModules;
        var lastToken;
        var currentToken;
        var braceNesting = 0;
        // assume that text represent an external module if it contains at least one top level import/export
        // ambient modules that are found inside external modules are interpreted as module augmentations
        var externalModule = false;
        function nextToken() {
            lastToken = currentToken;
            currentToken = ts.scanner.scan();
            if (currentToken === 18 /* OpenBraceToken */) {
                braceNesting++;
            }
            else if (currentToken === 19 /* CloseBraceToken */) {
                braceNesting--;
            }
            return currentToken;
        }
        function getFileReference() {
            var fileName = ts.scanner.getTokenValue();
            var pos = ts.scanner.getTokenPos();
            return { fileName: fileName, pos: pos, end: pos + fileName.length };
        }
        function recordAmbientExternalModule() {
            if (!ambientExternalModules) {
                ambientExternalModules = [];
            }
            ambientExternalModules.push({ ref: getFileReference(), depth: braceNesting });
        }
        function recordModuleName() {
            importedFiles.push(getFileReference());
            markAsExternalModuleIfTopLevel();
        }
        function markAsExternalModuleIfTopLevel() {
            if (braceNesting === 0) {
                externalModule = true;
            }
        }
        /**
         * Returns true if at least one token was consumed from the stream
         */
        function tryConsumeDeclare() {
            var token = ts.scanner.getToken();
            if (token === 130 /* DeclareKeyword */) {
                // declare module "mod"
                token = nextToken();
                if (token === 135 /* ModuleKeyword */) {
                    token = nextToken();
                    if (token === 10 /* StringLiteral */) {
                        recordAmbientExternalModule();
                    }
                }
                return true;
            }
            return false;
        }
        /**
         * Returns true if at least one token was consumed from the stream
         */
        function tryConsumeImport() {
            if (lastToken === 24 /* DotToken */) {
                return false;
            }
            var token = ts.scanner.getToken();
            if (token === 96 /* ImportKeyword */) {
                token = nextToken();
                if (token === 20 /* OpenParenToken */) {
                    token = nextToken();
                    if (token === 10 /* StringLiteral */ || token === 14 /* NoSubstitutionTemplateLiteral */) {
                        // import("mod");
                        recordModuleName();
                        return true;
                    }
                }
                else if (token === 10 /* StringLiteral */) {
                    // import "mod";
                    recordModuleName();
                    return true;
                }
                else {
                    if (token === 145 /* TypeKeyword */) {
                        var skipTypeKeyword = ts.scanner.lookAhead(function () {
                            var token = ts.scanner.scan();
                            return token !== 149 /* FromKeyword */ && (token === 41 /* AsteriskToken */ ||
                                token === 18 /* OpenBraceToken */ ||
                                token === 75 /* Identifier */ ||
                                ts.isKeyword(token));
                        });
                        if (skipTypeKeyword) {
                            token = nextToken();
                        }
                    }
                    if (token === 75 /* Identifier */ || ts.isKeyword(token)) {
                        token = nextToken();
                        if (token === 149 /* FromKeyword */) {
                            token = nextToken();
                            if (token === 10 /* StringLiteral */) {
                                // import d from "mod";
                                recordModuleName();
                                return true;
                            }
                        }
                        else if (token === 62 /* EqualsToken */) {
                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
                                return true;
                            }
                        }
                        else if (token === 27 /* CommaToken */) {
                            // consume comma and keep going
                            token = nextToken();
                        }
                        else {
                            // unknown syntax
                            return true;
                        }
                    }
                    if (token === 18 /* OpenBraceToken */) {
                        token = nextToken();
                        // consume "{ a as B, c, d as D}" clauses
                        // make sure that it stops on EOF
                        while (token !== 19 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
                            token = nextToken();
                        }
                        if (token === 19 /* CloseBraceToken */) {
                            token = nextToken();
                            if (token === 149 /* FromKeyword */) {
                                token = nextToken();
                                if (token === 10 /* StringLiteral */) {
                                    // import {a as A} from "mod";
                                    // import d, {a, b as B} from "mod"
                                    recordModuleName();
                                }
                            }
                        }
                    }
                    else if (token === 41 /* AsteriskToken */) {
                        token = nextToken();
                        if (token === 123 /* AsKeyword */) {
                            token = nextToken();
                            if (token === 75 /* Identifier */ || ts.isKeyword(token)) {
                                token = nextToken();
                                if (token === 149 /* FromKeyword */) {
                                    token = nextToken();
                                    if (token === 10 /* StringLiteral */) {
                                        // import * as NS from "mod"
                                        // import d, * as NS from "mod"
                                        recordModuleName();
                                    }
                                }
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeExport() {
            var token = ts.scanner.getToken();
            if (token === 89 /* ExportKeyword */) {
                markAsExternalModuleIfTopLevel();
                token = nextToken();
                if (token === 145 /* TypeKeyword */) {
                    var skipTypeKeyword = ts.scanner.lookAhead(function () {
                        var token = ts.scanner.scan();
                        return token === 41 /* AsteriskToken */ ||
                            token === 18 /* OpenBraceToken */;
                    });
                    if (skipTypeKeyword) {
                        token = nextToken();
                    }
                }
                if (token === 18 /* OpenBraceToken */) {
                    token = nextToken();
                    // consume "{ a as B, c, d as D}" clauses
                    // make sure it stops on EOF
                    while (token !== 19 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
                        token = nextToken();
                    }
                    if (token === 19 /* CloseBraceToken */) {
                        token = nextToken();
                        if (token === 149 /* FromKeyword */) {
                            token = nextToken();
                            if (token === 10 /* StringLiteral */) {
                                // export {a as A} from "mod";
                                // export {a, b as B} from "mod"
                                recordModuleName();
                            }
                        }
                    }
                }
                else if (token === 41 /* AsteriskToken */) {
                    token = nextToken();
                    if (token === 149 /* FromKeyword */) {
                        token = nextToken();
                        if (token === 10 /* StringLiteral */) {
                            // export * from "mod"
                            recordModuleName();
                        }
                    }
                }
                else if (token === 96 /* ImportKeyword */) {
                    token = nextToken();
                    if (token === 145 /* TypeKeyword */) {
                        var skipTypeKeyword = ts.scanner.lookAhead(function () {
                            var token = ts.scanner.scan();
                            return token === 75 /* Identifier */ ||
                                ts.isKeyword(token);
                        });
                        if (skipTypeKeyword) {
                            token = nextToken();
                        }
                    }
                    if (token === 75 /* Identifier */ || ts.isKeyword(token)) {
                        token = nextToken();
                        if (token === 62 /* EqualsToken */) {
                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
                                return true;
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeRequireCall(skipCurrentToken, allowTemplateLiterals) {
            if (allowTemplateLiterals === void 0) { allowTemplateLiterals = false; }
            var token = skipCurrentToken ? nextToken() : ts.scanner.getToken();
            if (token === 139 /* RequireKeyword */) {
                token = nextToken();
                if (token === 20 /* OpenParenToken */) {
                    token = nextToken();
                    if (token === 10 /* StringLiteral */ ||
                        allowTemplateLiterals && token === 14 /* NoSubstitutionTemplateLiteral */) {
                        //  require("mod");
                        recordModuleName();
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeDefine() {
            var token = ts.scanner.getToken();
            if (token === 75 /* Identifier */ && ts.scanner.getTokenValue() === "define") {
                token = nextToken();
                if (token !== 20 /* OpenParenToken */) {
                    return true;
                }
                token = nextToken();
                if (token === 10 /* StringLiteral */ || token === 14 /* NoSubstitutionTemplateLiteral */) {
                    // looks like define ("modname", ... - skip string literal and comma
                    token = nextToken();
                    if (token === 27 /* CommaToken */) {
                        token = nextToken();
                    }
                    else {
                        // unexpected token
                        return true;
                    }
                }
                // should be start of dependency list
                if (token !== 22 /* OpenBracketToken */) {
                    return true;
                }
                // skip open bracket
                token = nextToken();
                // scan until ']' or EOF
                while (token !== 23 /* CloseBracketToken */ && token !== 1 /* EndOfFileToken */) {
                    // record string literals as module names
                    if (token === 10 /* StringLiteral */ || token === 14 /* NoSubstitutionTemplateLiteral */) {
                        recordModuleName();
                    }
                    token = nextToken();
                }
                return true;
            }
            return false;
        }
        function processImports() {
            ts.scanner.setText(sourceText);
            nextToken();
            // Look for:
            //    import "mod";
            //    import d from "mod"
            //    import {a as A } from "mod";
            //    import * as NS from "mod"
            //    import d, {a, b as B} from "mod"
            //    import i = require("mod");
            //    import("mod");
            //    export * from "mod"
            //    export {a as b} from "mod"
            //    export import i = require("mod")
            //    (for JavaScript files) require("mod")
            // Do not look for:
            //    AnySymbol.import("mod")
            //    AnySymbol.nested.import("mod")
            while (true) {
                if (ts.scanner.getToken() === 1 /* EndOfFileToken */) {
                    break;
                }
                // check if at least one of alternative have moved scanner forward
                if (tryConsumeDeclare() ||
                    tryConsumeImport() ||
                    tryConsumeExport() ||
                    (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false, /*allowTemplateLiterals*/ true) ||
                        tryConsumeDefine()))) {
                    continue;
                }
                else {
                    nextToken();
                }
            }
            ts.scanner.setText(undefined);
        }
        if (readImportFiles) {
            processImports();
        }
        ts.processCommentPragmas(pragmaContext, sourceText);
        ts.processPragmasIntoFields(pragmaContext, ts.noop);
        if (externalModule) {
            // for external modules module all nested ambient modules are augmentations
            if (ambientExternalModules) {
                // move all detected ambient modules to imported files since they need to be resolved
                for (var _i = 0, ambientExternalModules_1 = ambientExternalModules; _i < ambientExternalModules_1.length; _i++) {
                    var decl = ambientExternalModules_1[_i];
                    importedFiles.push(decl.ref);
                }
            }
            return { referencedFiles: pragmaContext.referencedFiles, typeReferenceDirectives: pragmaContext.typeReferenceDirectives, libReferenceDirectives: pragmaContext.libReferenceDirectives, importedFiles: importedFiles, isLibFile: !!pragmaContext.hasNoDefaultLib, ambientExternalModules: undefined };
        }
        else {
            // for global scripts ambient modules still can have augmentations - look for ambient modules with depth > 0
            var ambientModuleNames = void 0;
            if (ambientExternalModules) {
                for (var _a = 0, ambientExternalModules_2 = ambientExternalModules; _a < ambientExternalModules_2.length; _a++) {
                    var decl = ambientExternalModules_2[_a];
                    if (decl.depth === 0) {
                        if (!ambientModuleNames) {
                            ambientModuleNames = [];
                        }
                        ambientModuleNames.push(decl.ref.fileName);
                    }
                    else {
                        importedFiles.push(decl.ref);
                    }
                }
            }
            return { referencedFiles: pragmaContext.referencedFiles, typeReferenceDirectives: pragmaContext.typeReferenceDirectives, libReferenceDirectives: pragmaContext.libReferenceDirectives, importedFiles: importedFiles, isLibFile: !!pragmaContext.hasNoDefaultLib, ambientExternalModules: ambientModuleNames };
        }
    }
    ts.preProcessFile = preProcessFile;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Rename;
    (function (Rename) {
        function getRenameInfo(program, sourceFile, position, options) {
            var node = ts.getAdjustedRenameLocation(ts.getTouchingPropertyName(sourceFile, position));
            if (nodeIsEligibleForRename(node)) {
                var renameInfo = getRenameInfoForNode(node, program.getTypeChecker(), sourceFile, function (declaration) { return program.isSourceFileDefaultLibrary(declaration.getSourceFile()); }, options);
                if (renameInfo) {
                    return renameInfo;
                }
            }
            return getRenameInfoError(ts.Diagnostics.You_cannot_rename_this_element);
        }
        Rename.getRenameInfo = getRenameInfo;
        function getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile, options) {
            var symbol = typeChecker.getSymbolAtLocation(node);
            if (!symbol)
                return;
            // Only allow a symbol to be renamed if it actually has at least one declaration.
            var declarations = symbol.declarations;
            if (!declarations || declarations.length === 0)
                return;
            // Disallow rename for elements that are defined in the standard TypeScript library.
            if (declarations.some(isDefinedInLibraryFile)) {
                return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library);
            }
            // Cannot rename `default` as in `import { default as foo } from "./someModule";
            if (ts.isIdentifier(node) && node.originalKeywordKind === 84 /* DefaultKeyword */ && symbol.parent && symbol.parent.flags & 1536 /* Module */) {
                return undefined;
            }
            if (ts.isStringLiteralLike(node) && ts.tryGetImportFromModuleSpecifier(node)) {
                return options && options.allowRenameOfImportPath ? getRenameInfoForModule(node, sourceFile, symbol) : undefined;
            }
            var kind = ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
            var specifierName = (ts.isImportOrExportSpecifierName(node) || ts.isStringOrNumericLiteralLike(node) && node.parent.kind === 154 /* ComputedPropertyName */)
                ? ts.stripQuotes(ts.getTextOfIdentifierOrLiteral(node))
                : undefined;
            var displayName = specifierName || typeChecker.symbolToString(symbol);
            var fullDisplayName = specifierName || typeChecker.getFullyQualifiedName(symbol);
            return getRenameInfoSuccess(displayName, fullDisplayName, kind, ts.SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile);
        }
        function getRenameInfoForModule(node, sourceFile, moduleSymbol) {
            if (!ts.isExternalModuleNameRelative(node.text)) {
                return getRenameInfoError(ts.Diagnostics.You_cannot_rename_a_module_via_a_global_import);
            }
            var moduleSourceFile = ts.find(moduleSymbol.declarations, ts.isSourceFile);
            if (!moduleSourceFile)
                return undefined;
            var withoutIndex = ts.endsWith(node.text, "/index") || ts.endsWith(node.text, "/index.js") ? undefined : ts.tryRemoveSuffix(ts.removeFileExtension(moduleSourceFile.fileName), "/index");
            var name = withoutIndex === undefined ? moduleSourceFile.fileName : withoutIndex;
            var kind = withoutIndex === undefined ? "module" /* moduleElement */ : "directory" /* directory */;
            var indexAfterLastSlash = node.text.lastIndexOf("/") + 1;
            // Span should only be the last component of the path. + 1 to account for the quote character.
            var triggerSpan = ts.createTextSpan(node.getStart(sourceFile) + 1 + indexAfterLastSlash, node.text.length - indexAfterLastSlash);
            return {
                canRename: true,
                fileToRename: name,
                kind: kind,
                displayName: name,
                fullDisplayName: name,
                kindModifiers: "" /* none */,
                triggerSpan: triggerSpan,
            };
        }
        function getRenameInfoSuccess(displayName, fullDisplayName, kind, kindModifiers, node, sourceFile) {
            return {
                canRename: true,
                fileToRename: undefined,
                kind: kind,
                displayName: displayName,
                fullDisplayName: fullDisplayName,
                kindModifiers: kindModifiers,
                triggerSpan: createTriggerSpanForNode(node, sourceFile)
            };
        }
        function getRenameInfoError(diagnostic) {
            return { canRename: false, localizedErrorMessage: ts.getLocaleSpecificMessage(diagnostic) };
        }
        function createTriggerSpanForNode(node, sourceFile) {
            var start = node.getStart(sourceFile);
            var width = node.getWidth(sourceFile);
            if (ts.isStringLiteralLike(node)) {
                // Exclude the quotes
                start += 1;
                width -= 2;
            }
            return ts.createTextSpan(start, width);
        }
        function nodeIsEligibleForRename(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                case 76 /* PrivateIdentifier */:
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 104 /* ThisKeyword */:
                    return true;
                case 8 /* NumericLiteral */:
                    return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node);
                default:
                    return false;
            }
        }
    })(Rename = ts.Rename || (ts.Rename = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var SmartSelectionRange;
    (function (SmartSelectionRange) {
        function getSmartSelectionRange(pos, sourceFile) {
            var selectionRange = {
                textSpan: ts.createTextSpanFromBounds(sourceFile.getFullStart(), sourceFile.getEnd())
            };
            var parentNode = sourceFile;
            outer: while (true) {
                var children = getSelectionChildren(parentNode);
                if (!children.length)
                    break;
                for (var i = 0; i < children.length; i++) {
                    var prevNode = children[i - 1];
                    var node = children[i];
                    var nextNode = children[i + 1];
                    if (node.getStart(sourceFile) > pos) {
                        break outer;
                    }
                    if (positionShouldSnapToNode(sourceFile, pos, node)) {
                        // 1. Blocks are effectively redundant with SyntaxLists.
                        // 2. TemplateSpans, along with the SyntaxLists containing them, are a somewhat unintuitive grouping
                        //    of things that should be considered independently.
                        // 3. A VariableStatement’s children are just a VaraiableDeclarationList and a semicolon.
                        // 4. A lone VariableDeclaration in a VaraibleDeclaration feels redundant with the VariableStatement.
                        //
                        // Dive in without pushing a selection range.
                        if (ts.isBlock(node)
                            || ts.isTemplateSpan(node) || ts.isTemplateHead(node) || ts.isTemplateTail(node)
                            || prevNode && ts.isTemplateHead(prevNode)
                            || ts.isVariableDeclarationList(node) && ts.isVariableStatement(parentNode)
                            || ts.isSyntaxList(node) && ts.isVariableDeclarationList(parentNode)
                            || ts.isVariableDeclaration(node) && ts.isSyntaxList(parentNode) && children.length === 1) {
                            parentNode = node;
                            break;
                        }
                        // Synthesize a stop for '${ ... }' since '${' and '}' actually belong to siblings.
                        if (ts.isTemplateSpan(parentNode) && nextNode && ts.isTemplateMiddleOrTemplateTail(nextNode)) {
                            var start_2 = node.getFullStart() - "${".length;
                            var end_2 = nextNode.getStart() + "}".length;
                            pushSelectionRange(start_2, end_2);
                        }
                        // Blocks with braces, brackets, parens, or JSX tags on separate lines should be
                        // selected from open to close, including whitespace but not including the braces/etc. themselves.
                        var isBetweenMultiLineBookends = ts.isSyntaxList(node)
                            && isListOpener(prevNode)
                            && isListCloser(nextNode)
                            && !ts.positionsAreOnSameLine(prevNode.getStart(), nextNode.getStart(), sourceFile);
                        var jsDocCommentStart = ts.hasJSDocNodes(node) && node.jsDoc[0].getStart();
                        var start = isBetweenMultiLineBookends ? prevNode.getEnd() : node.getStart();
                        var end = isBetweenMultiLineBookends ? nextNode.getStart() : node.getEnd();
                        if (ts.isNumber(jsDocCommentStart)) {
                            pushSelectionRange(jsDocCommentStart, end);
                        }
                        pushSelectionRange(start, end);
                        // String literals should have a stop both inside and outside their quotes.
                        if (ts.isStringLiteral(node) || ts.isTemplateLiteral(node)) {
                            pushSelectionRange(start + 1, end - 1);
                        }
                        parentNode = node;
                        break;
                    }
                    // If we made it to the end of the for loop, we’re done.
                    // In practice, I’ve only seen this happen at the very end
                    // of a SourceFile.
                    if (i === children.length - 1) {
                        break outer;
                    }
                }
            }
            return selectionRange;
            function pushSelectionRange(start, end) {
                // Skip empty ranges
                if (start !== end) {
                    var textSpan = ts.createTextSpanFromBounds(start, end);
                    if (!selectionRange || (
                    // Skip ranges that are identical to the parent
                    !ts.textSpansEqual(textSpan, selectionRange.textSpan) &&
                        // Skip ranges that don’t contain the original position
                        ts.textSpanIntersectsWithPosition(textSpan, pos))) {
                        selectionRange = __assign({ textSpan: textSpan }, selectionRange && { parent: selectionRange });
                    }
                }
            }
        }
        SmartSelectionRange.getSmartSelectionRange = getSmartSelectionRange;
        /**
         * Like `ts.positionBelongsToNode`, except positions immediately after nodes
         * count too, unless that position belongs to the next node. In effect, makes
         * selections able to snap to preceding tokens when the cursor is on the tail
         * end of them with only whitespace ahead.
         * @param sourceFile The source file containing the nodes.
         * @param pos The position to check.
         * @param node The candidate node to snap to.
         */
        function positionShouldSnapToNode(sourceFile, pos, node) {
            // Can’t use 'ts.positionBelongsToNode()' here because it cleverly accounts
            // for missing nodes, which can’t really be considered when deciding what
            // to select.
            ts.Debug.assert(node.pos <= pos);
            if (pos < node.end) {
                return true;
            }
            var nodeEnd = node.getEnd();
            if (nodeEnd === pos) {
                return ts.getTouchingPropertyName(sourceFile, pos).pos < node.end;
            }
            return false;
        }
        var isImport = ts.or(ts.isImportDeclaration, ts.isImportEqualsDeclaration);
        /**
         * Gets the children of a node to be considered for selection ranging,
         * transforming them into an artificial tree according to their intuitive
         * grouping where no grouping actually exists in the parse tree. For example,
         * top-level imports are grouped into their own SyntaxList so they can be
         * selected all together, even though in the AST they’re just siblings of each
         * other as well as of other top-level statements and declarations.
         */
        function getSelectionChildren(node) {
            // Group top-level imports
            if (ts.isSourceFile(node)) {
                return groupChildren(node.getChildAt(0).getChildren(), isImport);
            }
            // Mapped types _look_ like ObjectTypes with a single member,
            // but in fact don’t contain a SyntaxList or a node containing
            // the “key/value” pair like ObjectTypes do, but it seems intuitive
            // that the selection would snap to those points. The philosophy
            // of choosing a selection range is not so much about what the
            // syntax currently _is_ as what the syntax might easily become
            // if the user is making a selection; e.g., we synthesize a selection
            // around the “key/value” pair not because there’s a node there, but
            // because it allows the mapped type to become an object type with a
            // few keystrokes.
            if (ts.isMappedTypeNode(node)) {
                var _a = node.getChildren(), openBraceToken = _a[0], children = _a.slice(1);
                var closeBraceToken = ts.Debug.checkDefined(children.pop());
                ts.Debug.assertEqual(openBraceToken.kind, 18 /* OpenBraceToken */);
                ts.Debug.assertEqual(closeBraceToken.kind, 19 /* CloseBraceToken */);
                // Group `-/+readonly` and `-/+?`
                var groupedWithPlusMinusTokens = groupChildren(children, function (child) {
                    return child === node.readonlyToken || child.kind === 138 /* ReadonlyKeyword */ ||
                        child === node.questionToken || child.kind === 57 /* QuestionToken */;
                });
                // Group type parameter with surrounding brackets
                var groupedWithBrackets = groupChildren(groupedWithPlusMinusTokens, function (_a) {
                    var kind = _a.kind;
                    return kind === 22 /* OpenBracketToken */ ||
                        kind === 155 /* TypeParameter */ ||
                        kind === 23 /* CloseBracketToken */;
                });
                return [
                    openBraceToken,
                    // Pivot on `:`
                    createSyntaxList(splitChildren(groupedWithBrackets, function (_a) {
                        var kind = _a.kind;
                        return kind === 58 /* ColonToken */;
                    })),
                    closeBraceToken,
                ];
            }
            // Group modifiers and property name, then pivot on `:`.
            if (ts.isPropertySignature(node)) {
                var children = groupChildren(node.getChildren(), function (child) {
                    return child === node.name || ts.contains(node.modifiers, child);
                });
                return splitChildren(children, function (_a) {
                    var kind = _a.kind;
                    return kind === 58 /* ColonToken */;
                });
            }
            // Group the parameter name with its `...`, then that group with its `?`, then pivot on `=`.
            if (ts.isParameter(node)) {
                var groupedDotDotDotAndName_1 = groupChildren(node.getChildren(), function (child) {
                    return child === node.dotDotDotToken || child === node.name;
                });
                var groupedWithQuestionToken = groupChildren(groupedDotDotDotAndName_1, function (child) {
                    return child === groupedDotDotDotAndName_1[0] || child === node.questionToken;
                });
                return splitChildren(groupedWithQuestionToken, function (_a) {
                    var kind = _a.kind;
                    return kind === 62 /* EqualsToken */;
                });
            }
            // Pivot on '='
            if (ts.isBindingElement(node)) {
                return splitChildren(node.getChildren(), function (_a) {
                    var kind = _a.kind;
                    return kind === 62 /* EqualsToken */;
                });
            }
            return node.getChildren();
        }
        /**
         * Groups sibling nodes together into their own SyntaxList if they
         * a) are adjacent, AND b) match a predicate function.
         */
        function groupChildren(children, groupOn) {
            var result = [];
            var group;
            for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
                var child = children_1[_i];
                if (groupOn(child)) {
                    group = group || [];
                    group.push(child);
                }
                else {
                    if (group) {
                        result.push(createSyntaxList(group));
                        group = undefined;
                    }
                    result.push(child);
                }
            }
            if (group) {
                result.push(createSyntaxList(group));
            }
            return result;
        }
        /**
         * Splits sibling nodes into up to four partitions:
         * 1) everything left of the first node matched by `pivotOn`,
         * 2) the first node matched by `pivotOn`,
         * 3) everything right of the first node matched by `pivotOn`,
         * 4) a trailing semicolon, if `separateTrailingSemicolon` is enabled.
         * The left and right groups, if not empty, will each be grouped into their own containing SyntaxList.
         * @param children The sibling nodes to split.
         * @param pivotOn The predicate function to match the node to be the pivot. The first node that matches
         * the predicate will be used; any others that may match will be included into the right-hand group.
         * @param separateTrailingSemicolon If the last token is a semicolon, it will be returned as a separate
         * child rather than be included in the right-hand group.
         */
        function splitChildren(children, pivotOn, separateTrailingSemicolon) {
            if (separateTrailingSemicolon === void 0) { separateTrailingSemicolon = true; }
            if (children.length < 2) {
                return children;
            }
            var splitTokenIndex = ts.findIndex(children, pivotOn);
            if (splitTokenIndex === -1) {
                return children;
            }
            var leftChildren = children.slice(0, splitTokenIndex);
            var splitToken = children[splitTokenIndex];
            var lastToken = ts.last(children);
            var separateLastToken = separateTrailingSemicolon && lastToken.kind === 26 /* SemicolonToken */;
            var rightChildren = children.slice(splitTokenIndex + 1, separateLastToken ? children.length - 1 : undefined);
            var result = ts.compact([
                leftChildren.length ? createSyntaxList(leftChildren) : undefined,
                splitToken,
                rightChildren.length ? createSyntaxList(rightChildren) : undefined,
            ]);
            return separateLastToken ? result.concat(lastToken) : result;
        }
        function createSyntaxList(children) {
            ts.Debug.assertGreaterThanOrEqual(children.length, 1);
            var syntaxList = ts.createNode(324 /* SyntaxList */, children[0].pos, ts.last(children).end);
            syntaxList._children = children;
            return syntaxList;
        }
        function isListOpener(token) {
            var kind = token && token.kind;
            return kind === 18 /* OpenBraceToken */
                || kind === 22 /* OpenBracketToken */
                || kind === 20 /* OpenParenToken */
                || kind === 268 /* JsxOpeningElement */;
        }
        function isListCloser(token) {
            var kind = token && token.kind;
            return kind === 19 /* CloseBraceToken */
                || kind === 23 /* CloseBracketToken */
                || kind === 21 /* CloseParenToken */
                || kind === 269 /* JsxClosingElement */;
        }
    })(SmartSelectionRange = ts.SmartSelectionRange || (ts.SmartSelectionRange = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var SignatureHelp;
    (function (SignatureHelp) {
        var InvocationKind;
        (function (InvocationKind) {
            InvocationKind[InvocationKind["Call"] = 0] = "Call";
            InvocationKind[InvocationKind["TypeArgs"] = 1] = "TypeArgs";
            InvocationKind[InvocationKind["Contextual"] = 2] = "Contextual";
        })(InvocationKind || (InvocationKind = {}));
        function getSignatureHelpItems(program, sourceFile, position, triggerReason, cancellationToken) {
            var typeChecker = program.getTypeChecker();
            // Decide whether to show signature help
            var startingToken = ts.findTokenOnLeftOfPosition(sourceFile, position);
            if (!startingToken) {
                // We are at the beginning of the file
                return undefined;
            }
            // Only need to be careful if the user typed a character and signature help wasn't showing.
            var onlyUseSyntacticOwners = !!triggerReason && triggerReason.kind === "characterTyped";
            // Bail out quickly in the middle of a string or comment, don't provide signature help unless the user explicitly requested it.
            if (onlyUseSyntacticOwners && (ts.isInString(sourceFile, position, startingToken) || ts.isInComment(sourceFile, position))) {
                return undefined;
            }
            var isManuallyInvoked = !!triggerReason && triggerReason.kind === "invoked";
            var argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker, isManuallyInvoked);
            if (!argumentInfo)
                return undefined;
            cancellationToken.throwIfCancellationRequested();
            // Extra syntactic and semantic filtering of signature help
            var candidateInfo = getCandidateOrTypeInfo(argumentInfo, typeChecker, sourceFile, startingToken, onlyUseSyntacticOwners);
            cancellationToken.throwIfCancellationRequested();
            if (!candidateInfo) {
                // We didn't have any sig help items produced by the TS compiler.  If this is a JS
                // file, then see if we can figure out anything better.
                return ts.isSourceFileJS(sourceFile) ? createJSSignatureHelpItems(argumentInfo, program, cancellationToken) : undefined;
            }
            return typeChecker.runWithCancellationToken(cancellationToken, function (typeChecker) {
                return candidateInfo.kind === 0 /* Candidate */
                    ? createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker)
                    : createTypeHelpItems(candidateInfo.symbol, argumentInfo, sourceFile, typeChecker);
            });
        }
        SignatureHelp.getSignatureHelpItems = getSignatureHelpItems;
        var CandidateOrTypeKind;
        (function (CandidateOrTypeKind) {
            CandidateOrTypeKind[CandidateOrTypeKind["Candidate"] = 0] = "Candidate";
            CandidateOrTypeKind[CandidateOrTypeKind["Type"] = 1] = "Type";
        })(CandidateOrTypeKind || (CandidateOrTypeKind = {}));
        function getCandidateOrTypeInfo(_a, checker, sourceFile, startingToken, onlyUseSyntacticOwners) {
            var invocation = _a.invocation, argumentCount = _a.argumentCount;
            switch (invocation.kind) {
                case 0 /* Call */: {
                    if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) {
                        return undefined;
                    }
                    var candidates = [];
                    var resolvedSignature = checker.getResolvedSignatureForSignatureHelp(invocation.node, candidates, argumentCount); // TODO: GH#18217
                    return candidates.length === 0 ? undefined : { kind: 0 /* Candidate */, candidates: candidates, resolvedSignature: resolvedSignature };
                }
                case 1 /* TypeArgs */: {
                    var called = invocation.called;
                    if (onlyUseSyntacticOwners && !containsPrecedingToken(startingToken, sourceFile, ts.isIdentifier(called) ? called.parent : called)) {
                        return undefined;
                    }
                    var candidates = ts.getPossibleGenericSignatures(called, argumentCount, checker);
                    if (candidates.length !== 0)
                        return { kind: 0 /* Candidate */, candidates: candidates, resolvedSignature: ts.first(candidates) };
                    var symbol = checker.getSymbolAtLocation(called);
                    return symbol && { kind: 1 /* Type */, symbol: symbol };
                }
                case 2 /* Contextual */:
                    return { kind: 0 /* Candidate */, candidates: [invocation.signature], resolvedSignature: invocation.signature };
                default:
                    return ts.Debug.assertNever(invocation);
            }
        }
        function isSyntacticOwner(startingToken, node, sourceFile) {
            if (!ts.isCallOrNewExpression(node))
                return false;
            var invocationChildren = node.getChildren(sourceFile);
            switch (startingToken.kind) {
                case 20 /* OpenParenToken */:
                    return ts.contains(invocationChildren, startingToken);
                case 27 /* CommaToken */: {
                    var containingList = ts.findContainingList(startingToken);
                    return !!containingList && ts.contains(invocationChildren, containingList);
                }
                case 29 /* LessThanToken */:
                    return containsPrecedingToken(startingToken, sourceFile, node.expression);
                default:
                    return false;
            }
        }
        function createJSSignatureHelpItems(argumentInfo, program, cancellationToken) {
            if (argumentInfo.invocation.kind === 2 /* Contextual */)
                return undefined;
            // See if we can find some symbol with the call expression name that has call signatures.
            var expression = getExpressionFromInvocation(argumentInfo.invocation);
            var name = ts.isIdentifier(expression) ? expression.text : ts.isPropertyAccessExpression(expression) ? expression.name.text : undefined;
            var typeChecker = program.getTypeChecker();
            return name === undefined ? undefined : ts.firstDefined(program.getSourceFiles(), function (sourceFile) {
                return ts.firstDefined(sourceFile.getNamedDeclarations().get(name), function (declaration) {
                    var type = declaration.symbol && typeChecker.getTypeOfSymbolAtLocation(declaration.symbol, declaration);
                    var callSignatures = type && type.getCallSignatures();
                    if (callSignatures && callSignatures.length) {
                        return typeChecker.runWithCancellationToken(cancellationToken, function (typeChecker) { return createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, sourceFile, typeChecker); });
                    }
                });
            });
        }
        function containsPrecedingToken(startingToken, sourceFile, container) {
            var pos = startingToken.getFullStart();
            // There’s a possibility that `startingToken.parent` contains only `startingToken` and
            // missing nodes, none of which are valid to be returned by `findPrecedingToken`. In that
            // case, the preceding token we want is actually higher up the tree—almost definitely the
            // next parent, but theoretically the situation with missing nodes might be happening on
            // multiple nested levels.
            var currentParent = startingToken.parent;
            while (currentParent) {
                var precedingToken = ts.findPrecedingToken(pos, sourceFile, currentParent, /*excludeJsdoc*/ true);
                if (precedingToken) {
                    return ts.rangeContainsRange(container, precedingToken);
                }
                currentParent = currentParent.parent;
            }
            return ts.Debug.fail("Could not find preceding token");
        }
        function getArgumentInfoForCompletions(node, position, sourceFile) {
            var info = getImmediatelyContainingArgumentInfo(node, position, sourceFile);
            return !info || info.isTypeParameterList || info.invocation.kind !== 0 /* Call */ ? undefined
                : { invocation: info.invocation.node, argumentCount: info.argumentCount, argumentIndex: info.argumentIndex };
        }
        SignatureHelp.getArgumentInfoForCompletions = getArgumentInfoForCompletions;
        function getArgumentOrParameterListInfo(node, sourceFile) {
            var info = getArgumentOrParameterListAndIndex(node, sourceFile);
            if (!info)
                return undefined;
            var list = info.list, argumentIndex = info.argumentIndex;
            var argumentCount = getArgumentCount(list);
            if (argumentIndex !== 0) {
                ts.Debug.assertLessThan(argumentIndex, argumentCount);
            }
            var argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
            return { list: list, argumentIndex: argumentIndex, argumentCount: argumentCount, argumentsSpan: argumentsSpan };
        }
        function getArgumentOrParameterListAndIndex(node, sourceFile) {
            if (node.kind === 29 /* LessThanToken */ || node.kind === 20 /* OpenParenToken */) {
                // Find the list that starts right *after* the < or ( token.
                // If the user has just opened a list, consider this item 0.
                return { list: getChildListThatStartsWithOpenerToken(node.parent, node, sourceFile), argumentIndex: 0 };
            }
            else {
                // findListItemInfo can return undefined if we are not in parent's argument list
                // or type argument list. This includes cases where the cursor is:
                //   - To the right of the closing parenthesis, non-substitution template, or template tail.
                //   - Between the type arguments and the arguments (greater than token)
                //   - On the target of the call (parent.func)
                //   - On the 'new' keyword in a 'new' expression
                var list = ts.findContainingList(node);
                return list && { list: list, argumentIndex: getArgumentIndex(list, node) };
            }
        }
        /**
         * Returns relevant information for the argument list and the current argument if we are
         * in the argument of an invocation; returns undefined otherwise.
         */
        function getImmediatelyContainingArgumentInfo(node, position, sourceFile) {
            var parent = node.parent;
            if (ts.isCallOrNewExpression(parent)) {
                var invocation = parent;
                // There are 3 cases to handle:
                //   1. The token introduces a list, and should begin a signature help session
                //   2. The token is either not associated with a list, or ends a list, so the session should end
                //   3. The token is buried inside a list, and should give signature help
                //
                // The following are examples of each:
                //
                //    Case 1:
                //          foo<#T, U>(#a, b)    -> The token introduces a list, and should begin a signature help session
                //    Case 2:
                //          fo#o<T, U>#(a, b)#   -> The token is either not associated with a list, or ends a list, so the session should end
                //    Case 3:
                //          foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give signature help
                // Find out if 'node' is an argument, a type argument, or neither
                var info = getArgumentOrParameterListInfo(node, sourceFile);
                if (!info)
                    return undefined;
                var list = info.list, argumentIndex = info.argumentIndex, argumentCount = info.argumentCount, argumentsSpan = info.argumentsSpan;
                var isTypeParameterList = !!parent.typeArguments && parent.typeArguments.pos === list.pos;
                return { isTypeParameterList: isTypeParameterList, invocation: { kind: 0 /* Call */, node: invocation }, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount };
            }
            else if (ts.isNoSubstitutionTemplateLiteral(node) && ts.isTaggedTemplateExpression(parent)) {
                // Check if we're actually inside the template;
                // otherwise we'll fall out and return undefined.
                if (ts.isInsideTemplateLiteral(node, position, sourceFile)) {
                    return getArgumentListInfoForTemplate(parent, /*argumentIndex*/ 0, sourceFile);
                }
                return undefined;
            }
            else if (ts.isTemplateHead(node) && parent.parent.kind === 198 /* TaggedTemplateExpression */) {
                var templateExpression = parent;
                var tagExpression = templateExpression.parent;
                ts.Debug.assert(templateExpression.kind === 211 /* TemplateExpression */);
                var argumentIndex = ts.isInsideTemplateLiteral(node, position, sourceFile) ? 0 : 1;
                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
            }
            else if (ts.isTemplateSpan(parent) && ts.isTaggedTemplateExpression(parent.parent.parent)) {
                var templateSpan = parent;
                var tagExpression = parent.parent.parent;
                // If we're just after a template tail, don't show signature help.
                if (ts.isTemplateTail(node) && !ts.isInsideTemplateLiteral(node, position, sourceFile)) {
                    return undefined;
                }
                var spanIndex = templateSpan.parent.templateSpans.indexOf(templateSpan);
                var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node, position, sourceFile);
                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
            }
            else if (ts.isJsxOpeningLikeElement(parent)) {
                // Provide a signature help for JSX opening element or JSX self-closing element.
                // This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems")
                // i.e
                //      export function MainButton(props: ButtonProps, context: any): JSX.Element { ... }
                //      <MainButton /*signatureHelp*/
                var attributeSpanStart = parent.attributes.pos;
                var attributeSpanEnd = ts.skipTrivia(sourceFile.text, parent.attributes.end, /*stopAfterLineBreak*/ false);
                return {
                    isTypeParameterList: false,
                    invocation: { kind: 0 /* Call */, node: parent },
                    argumentsSpan: ts.createTextSpan(attributeSpanStart, attributeSpanEnd - attributeSpanStart),
                    argumentIndex: 0,
                    argumentCount: 1
                };
            }
            else {
                var typeArgInfo = ts.getPossibleTypeArgumentsInfo(node, sourceFile);
                if (typeArgInfo) {
                    var called = typeArgInfo.called, nTypeArguments = typeArgInfo.nTypeArguments;
                    var invocation = { kind: 1 /* TypeArgs */, called: called };
                    var argumentsSpan = ts.createTextSpanFromBounds(called.getStart(sourceFile), node.end);
                    return { isTypeParameterList: true, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: nTypeArguments, argumentCount: nTypeArguments + 1 };
                }
                return undefined;
            }
        }
        function getImmediatelyContainingArgumentOrContextualParameterInfo(node, position, sourceFile, checker) {
            return tryGetParameterInfo(node, position, sourceFile, checker) || getImmediatelyContainingArgumentInfo(node, position, sourceFile);
        }
        function getHighestBinary(b) {
            return ts.isBinaryExpression(b.parent) ? getHighestBinary(b.parent) : b;
        }
        function countBinaryExpressionParameters(b) {
            return ts.isBinaryExpression(b.left) ? countBinaryExpressionParameters(b.left) + 1 : 2;
        }
        function tryGetParameterInfo(startingToken, _position, sourceFile, checker) {
            var info = getContextualSignatureLocationInfo(startingToken, sourceFile, checker);
            if (!info)
                return undefined;
            var contextualType = info.contextualType, argumentIndex = info.argumentIndex, argumentCount = info.argumentCount, argumentsSpan = info.argumentsSpan;
            var signatures = contextualType.getCallSignatures();
            if (signatures.length !== 1)
                return undefined;
            var invocation = { kind: 2 /* Contextual */, signature: ts.first(signatures), node: startingToken, symbol: chooseBetterSymbol(contextualType.symbol) };
            return { isTypeParameterList: false, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount };
        }
        function getContextualSignatureLocationInfo(startingToken, sourceFile, checker) {
            if (startingToken.kind !== 20 /* OpenParenToken */ && startingToken.kind !== 27 /* CommaToken */)
                return undefined;
            var parent = startingToken.parent;
            switch (parent.kind) {
                case 200 /* ParenthesizedExpression */:
                case 161 /* MethodDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    var info = getArgumentOrParameterListInfo(startingToken, sourceFile);
                    if (!info)
                        return undefined;
                    var argumentIndex = info.argumentIndex, argumentCount = info.argumentCount, argumentsSpan = info.argumentsSpan;
                    var contextualType = ts.isMethodDeclaration(parent) ? checker.getContextualTypeForObjectLiteralElement(parent) : checker.getContextualType(parent);
                    return contextualType && { contextualType: contextualType, argumentIndex: argumentIndex, argumentCount: argumentCount, argumentsSpan: argumentsSpan };
                case 209 /* BinaryExpression */: {
                    var highestBinary = getHighestBinary(parent);
                    var contextualType_1 = checker.getContextualType(highestBinary);
                    var argumentIndex_1 = startingToken.kind === 20 /* OpenParenToken */ ? 0 : countBinaryExpressionParameters(parent) - 1;
                    var argumentCount_1 = countBinaryExpressionParameters(highestBinary);
                    return contextualType_1 && { contextualType: contextualType_1, argumentIndex: argumentIndex_1, argumentCount: argumentCount_1, argumentsSpan: ts.createTextSpanFromNode(parent) };
                }
                default:
                    return undefined;
            }
        }
        // The type of a function type node has a symbol at that node, but it's better to use the symbol for a parameter or type alias.
        function chooseBetterSymbol(s) {
            return s.name === "__type" /* Type */
                ? ts.firstDefined(s.declarations, function (d) { return ts.isFunctionTypeNode(d) ? d.parent.symbol : undefined; }) || s
                : s;
        }
        function getArgumentIndex(argumentsList, node) {
            // The list we got back can include commas.  In the presence of errors it may
            // also just have nodes without commas.  For example "Foo(a b c)" will have 3
            // args without commas. We want to find what index we're at.  So we count
            // forward until we hit ourselves, only incrementing the index if it isn't a
            // comma.
            //
            // Note: the subtlety around trailing commas (in getArgumentCount) does not apply
            // here.  That's because we're only walking forward until we hit the node we're
            // on.  In that case, even if we're after the trailing comma, we'll still see
            // that trailing comma in the list, and we'll have generated the appropriate
            // arg index.
            var argumentIndex = 0;
            for (var _i = 0, _a = argumentsList.getChildren(); _i < _a.length; _i++) {
                var child = _a[_i];
                if (child === node) {
                    break;
                }
                if (child.kind !== 27 /* CommaToken */) {
                    argumentIndex++;
                }
            }
            return argumentIndex;
        }
        function getArgumentCount(argumentsList) {
            // The argument count for a list is normally the number of non-comma children it has.
            // For example, if you have "Foo(a,b)" then there will be three children of the arg
            // list 'a' '<comma>' 'b'.  So, in this case the arg count will be 2.  However, there
            // is a small subtlety.  If you have "Foo(a,)", then the child list will just have
            // 'a' '<comma>'.  So, in the case where the last child is a comma, we increase the
            // arg count by one to compensate.
            //
            // Note: this subtlety only applies to the last comma.  If you had "Foo(a,," then
            // we'll have: 'a' '<comma>' '<missing>'
            // That will give us 2 non-commas.  We then add one for the last comma, giving us an
            // arg count of 3.
            var listChildren = argumentsList.getChildren();
            var argumentCount = ts.countWhere(listChildren, function (arg) { return arg.kind !== 27 /* CommaToken */; });
            if (listChildren.length > 0 && ts.last(listChildren).kind === 27 /* CommaToken */) {
                argumentCount++;
            }
            return argumentCount;
        }
        // spanIndex is either the index for a given template span.
        // This does not give appropriate results for a NoSubstitutionTemplateLiteral
        function getArgumentIndexForTemplatePiece(spanIndex, node, position, sourceFile) {
            // Because the TemplateStringsArray is the first argument, we have to offset each substitution expression by 1.
            // There are three cases we can encounter:
            //      1. We are precisely in the template literal (argIndex = 0).
            //      2. We are in or to the right of the substitution expression (argIndex = spanIndex + 1).
            //      3. We are directly to the right of the template literal, but because we look for the token on the left,
            //          not enough to put us in the substitution expression; we should consider ourselves part of
            //          the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1).
            //
            /* eslint-disable no-double-space */
            // Example: f  `# abcd $#{#  1 + 1#  }# efghi ${ #"#hello"#  }  #  `
            //              ^       ^ ^       ^   ^          ^ ^      ^     ^
            // Case:        1       1 3       2   1          3 2      2     1
            /* eslint-enable no-double-space */
            ts.Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node.");
            if (ts.isTemplateLiteralToken(node)) {
                if (ts.isInsideTemplateLiteral(node, position, sourceFile)) {
                    return 0;
                }
                return spanIndex + 2;
            }
            return spanIndex + 1;
        }
        function getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile) {
            // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument.
            var argumentCount = ts.isNoSubstitutionTemplateLiteral(tagExpression.template) ? 1 : tagExpression.template.templateSpans.length + 1;
            if (argumentIndex !== 0) {
                ts.Debug.assertLessThan(argumentIndex, argumentCount);
            }
            return {
                isTypeParameterList: false,
                invocation: { kind: 0 /* Call */, node: tagExpression },
                argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression, sourceFile),
                argumentIndex: argumentIndex,
                argumentCount: argumentCount
            };
        }
        function getApplicableSpanForArguments(argumentsList, sourceFile) {
            // We use full start and skip trivia on the end because we want to include trivia on
            // both sides. For example,
            //
            //    foo(   /*comment */     a, b, c      /*comment*/     )
            //        |                                               |
            //
            // The applicable span is from the first bar to the second bar (inclusive,
            // but not including parentheses)
            var applicableSpanStart = argumentsList.getFullStart();
            var applicableSpanEnd = ts.skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false);
            return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
        }
        function getApplicableSpanForTaggedTemplate(taggedTemplate, sourceFile) {
            var template = taggedTemplate.template;
            var applicableSpanStart = template.getStart();
            var applicableSpanEnd = template.getEnd();
            // We need to adjust the end position for the case where the template does not have a tail.
            // Otherwise, we will not show signature help past the expression.
            // For example,
            //
            //      ` ${ 1 + 1 foo(10)
            //       |       |
            // This is because a Missing node has no width. However, what we actually want is to include trivia
            // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail.
            if (template.kind === 211 /* TemplateExpression */) {
                var lastSpan = ts.last(template.templateSpans);
                if (lastSpan.literal.getFullWidth() === 0) {
                    applicableSpanEnd = ts.skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false);
                }
            }
            return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
        }
        function getContainingArgumentInfo(node, position, sourceFile, checker, isManuallyInvoked) {
            var _loop_7 = function (n) {
                // If the node is not a subspan of its parent, this is a big problem.
                // There have been crashes that might be caused by this violation.
                ts.Debug.assert(ts.rangeContainsRange(n.parent, n), "Not a subspan", function () { return "Child: " + ts.Debug.formatSyntaxKind(n.kind) + ", parent: " + ts.Debug.formatSyntaxKind(n.parent.kind); });
                var argumentInfo = getImmediatelyContainingArgumentOrContextualParameterInfo(n, position, sourceFile, checker);
                if (argumentInfo) {
                    return { value: argumentInfo };
                }
            };
            for (var n = node; !ts.isSourceFile(n) && (isManuallyInvoked || !ts.isBlock(n)); n = n.parent) {
                var state_2 = _loop_7(n);
                if (typeof state_2 === "object")
                    return state_2.value;
            }
            return undefined;
        }
        function getChildListThatStartsWithOpenerToken(parent, openerToken, sourceFile) {
            var children = parent.getChildren(sourceFile);
            var indexOfOpenerToken = children.indexOf(openerToken);
            ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1);
            return children[indexOfOpenerToken + 1];
        }
        function getExpressionFromInvocation(invocation) {
            return invocation.kind === 0 /* Call */ ? ts.getInvokedExpression(invocation.node) : invocation.called;
        }
        function getEnclosingDeclarationFromInvocation(invocation) {
            return invocation.kind === 0 /* Call */ ? invocation.node : invocation.kind === 1 /* TypeArgs */ ? invocation.called : invocation.node;
        }
        var signatureHelpNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 70221824 /* IgnoreErrors */ | 16384 /* UseAliasDefinedOutsideCurrentScope */;
        function createSignatureHelpItems(candidates, resolvedSignature, _a, sourceFile, typeChecker) {
            var isTypeParameterList = _a.isTypeParameterList, argumentCount = _a.argumentCount, applicableSpan = _a.argumentsSpan, invocation = _a.invocation, argumentIndex = _a.argumentIndex;
            var enclosingDeclaration = getEnclosingDeclarationFromInvocation(invocation);
            var callTargetSymbol = invocation.kind === 2 /* Contextual */ ? invocation.symbol : typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
            var callTargetDisplayParts = callTargetSymbol ? ts.symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : ts.emptyArray;
            var items = candidates.map(function (candidateSignature) { return getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile); });
            if (argumentIndex !== 0) {
                ts.Debug.assertLessThan(argumentIndex, argumentCount);
            }
            var selectedItemIndex = candidates.indexOf(resolvedSignature);
            ts.Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function.
            return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount };
        }
        function createTypeHelpItems(symbol, _a, sourceFile, checker) {
            var argumentCount = _a.argumentCount, applicableSpan = _a.argumentsSpan, invocation = _a.invocation, argumentIndex = _a.argumentIndex;
            var typeParameters = checker.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
            if (!typeParameters)
                return undefined;
            var items = [getTypeHelpItem(symbol, typeParameters, checker, getEnclosingDeclarationFromInvocation(invocation), sourceFile)];
            return { items: items, applicableSpan: applicableSpan, selectedItemIndex: 0, argumentIndex: argumentIndex, argumentCount: argumentCount };
        }
        function getTypeHelpItem(symbol, typeParameters, checker, enclosingDeclaration, sourceFile) {
            var typeSymbolDisplay = ts.symbolToDisplayParts(checker, symbol);
            var printer = ts.createPrinter({ removeComments: true });
            var parameters = typeParameters.map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); });
            var documentation = symbol.getDocumentationComment(checker);
            var tags = symbol.getJsDocTags();
            var prefixDisplayParts = __spreadArrays(typeSymbolDisplay, [ts.punctuationPart(29 /* LessThanToken */)]);
            return { isVariadic: false, prefixDisplayParts: prefixDisplayParts, suffixDisplayParts: [ts.punctuationPart(31 /* GreaterThanToken */)], separatorDisplayParts: separatorDisplayParts, parameters: parameters, documentation: documentation, tags: tags };
        }
        var separatorDisplayParts = [ts.punctuationPart(27 /* CommaToken */), ts.spacePart()];
        function getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, checker, enclosingDeclaration, sourceFile) {
            var _a = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile), isVariadic = _a.isVariadic, parameters = _a.parameters, prefix = _a.prefix, suffix = _a.suffix;
            var prefixDisplayParts = __spreadArrays(callTargetDisplayParts, prefix);
            var suffixDisplayParts = __spreadArrays(suffix, returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker));
            var documentation = candidateSignature.getDocumentationComment(checker);
            var tags = candidateSignature.getJsDocTags();
            return { isVariadic: isVariadic, prefixDisplayParts: prefixDisplayParts, suffixDisplayParts: suffixDisplayParts, separatorDisplayParts: separatorDisplayParts, parameters: parameters, documentation: documentation, tags: tags };
        }
        function returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker) {
            return ts.mapToDisplayParts(function (writer) {
                writer.writePunctuation(":");
                writer.writeSpace(" ");
                var predicate = checker.getTypePredicateOfSignature(candidateSignature);
                if (predicate) {
                    checker.writeTypePredicate(predicate, enclosingDeclaration, /*flags*/ undefined, writer);
                }
                else {
                    checker.writeType(checker.getReturnTypeOfSignature(candidateSignature), enclosingDeclaration, /*flags*/ undefined, writer);
                }
            });
        }
        function itemInfoForTypeParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) {
            var typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
            var printer = ts.createPrinter({ removeComments: true });
            var parameters = (typeParameters || ts.emptyArray).map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); });
            var parameterParts = ts.mapToDisplayParts(function (writer) {
                var thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)] : [];
                var params = ts.createNodeArray(__spreadArrays(thisParameter, checker.getExpandedParameters(candidateSignature).map(function (param) { return checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags); })));
                printer.writeList(2576 /* CallExpressionArguments */, params, sourceFile, writer);
            });
            return { isVariadic: false, parameters: parameters, prefix: [ts.punctuationPart(29 /* LessThanToken */)], suffix: __spreadArrays([ts.punctuationPart(31 /* GreaterThanToken */)], parameterParts) };
        }
        function itemInfoForParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) {
            var isVariadic = checker.hasEffectiveRestParameter(candidateSignature);
            var printer = ts.createPrinter({ removeComments: true });
            var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
                    var args = ts.createNodeArray(candidateSignature.typeParameters.map(function (p) { return checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags); }));
                    printer.writeList(53776 /* TypeParameters */, args, sourceFile, writer);
                }
            });
            var parameters = checker.getExpandedParameters(candidateSignature).map(function (p) { return createSignatureHelpParameterForParameter(p, checker, enclosingDeclaration, sourceFile, printer); });
            return { isVariadic: isVariadic, parameters: parameters, prefix: __spreadArrays(typeParameterParts, [ts.punctuationPart(20 /* OpenParenToken */)]), suffix: [ts.punctuationPart(21 /* CloseParenToken */)] };
        }
        function createSignatureHelpParameterForParameter(parameter, checker, enclosingDeclaration, sourceFile, printer) {
            var displayParts = ts.mapToDisplayParts(function (writer) {
                var param = checker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags);
                printer.writeNode(4 /* Unspecified */, param, sourceFile, writer);
            });
            var isOptional = checker.isOptionalParameter(parameter.valueDeclaration);
            return { name: parameter.name, documentation: parameter.getDocumentationComment(checker), displayParts: displayParts, isOptional: isOptional };
        }
        function createSignatureHelpParameterForTypeParameter(typeParameter, checker, enclosingDeclaration, sourceFile, printer) {
            var displayParts = ts.mapToDisplayParts(function (writer) {
                var param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags);
                printer.writeNode(4 /* Unspecified */, param, sourceFile, writer);
            });
            return { name: typeParameter.symbol.name, documentation: typeParameter.symbol.getDocumentationComment(checker), displayParts: displayParts, isOptional: false };
        }
    })(SignatureHelp = ts.SignatureHelp || (ts.SignatureHelp = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+\/=]+)$)?/;
    function getSourceMapper(host) {
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        var currentDirectory = host.getCurrentDirectory();
        var sourceFileLike = ts.createMap();
        var documentPositionMappers = ts.createMap();
        return { tryGetSourcePosition: tryGetSourcePosition, tryGetGeneratedPosition: tryGetGeneratedPosition, toLineColumnOffset: toLineColumnOffset, clearCache: clearCache };
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getDocumentPositionMapper(generatedFileName, sourceFileName) {
            var path = toPath(generatedFileName);
            var value = documentPositionMappers.get(path);
            if (value)
                return value;
            var mapper;
            if (host.getDocumentPositionMapper) {
                mapper = host.getDocumentPositionMapper(generatedFileName, sourceFileName);
            }
            else if (host.readFile) {
                var file = getSourceFileLike(generatedFileName);
                mapper = file && ts.getDocumentPositionMapper({ getSourceFileLike: getSourceFileLike, getCanonicalFileName: getCanonicalFileName, log: function (s) { return host.log(s); } }, generatedFileName, ts.getLineInfo(file.text, ts.getLineStarts(file)), function (f) { return !host.fileExists || host.fileExists(f) ? host.readFile(f) : undefined; });
            }
            documentPositionMappers.set(path, mapper || ts.identitySourceMapConsumer);
            return mapper || ts.identitySourceMapConsumer;
        }
        function tryGetSourcePosition(info) {
            if (!ts.isDeclarationFileName(info.fileName))
                return undefined;
            var file = getSourceFile(info.fileName);
            if (!file)
                return undefined;
            var newLoc = getDocumentPositionMapper(info.fileName).getSourcePosition(info);
            return !newLoc || newLoc === info ? undefined : tryGetSourcePosition(newLoc) || newLoc;
        }
        function tryGetGeneratedPosition(info) {
            if (ts.isDeclarationFileName(info.fileName))
                return undefined;
            var sourceFile = getSourceFile(info.fileName);
            if (!sourceFile)
                return undefined;
            var program = host.getProgram();
            // If this is source file of project reference source (instead of redirect) there is no generated position
            if (program.isSourceOfProjectReferenceRedirect(sourceFile.fileName)) {
                return undefined;
            }
            var options = program.getCompilerOptions();
            var outPath = options.outFile || options.out;
            var declarationPath = outPath ?
                ts.removeFileExtension(outPath) + ".d.ts" /* Dts */ :
                ts.getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
            if (declarationPath === undefined)
                return undefined;
            var newLoc = getDocumentPositionMapper(declarationPath, info.fileName).getGeneratedPosition(info);
            return newLoc === info ? undefined : newLoc;
        }
        function getSourceFile(fileName) {
            var program = host.getProgram();
            if (!program)
                return undefined;
            var path = toPath(fileName);
            // file returned here could be .d.ts when asked for .ts file if projectReferences and module resolution created this source file
            var file = program.getSourceFileByPath(path);
            return file && file.resolvedPath === path ? file : undefined;
        }
        function getOrCreateSourceFileLike(fileName) {
            var path = toPath(fileName);
            var fileFromCache = sourceFileLike.get(path);
            if (fileFromCache !== undefined)
                return fileFromCache ? fileFromCache : undefined;
            if (!host.readFile || host.fileExists && !host.fileExists(path)) {
                sourceFileLike.set(path, false);
                return undefined;
            }
            // And failing that, check the disk
            var text = host.readFile(path);
            var file = text ? createSourceFileLike(text) : false;
            sourceFileLike.set(path, file);
            return file ? file : undefined;
        }
        // This can be called from source mapper in either source program or program that includes generated file
        function getSourceFileLike(fileName) {
            return !host.getSourceFileLike ?
                getSourceFile(fileName) || getOrCreateSourceFileLike(fileName) :
                host.getSourceFileLike(fileName);
        }
        function toLineColumnOffset(fileName, position) {
            var file = getSourceFileLike(fileName); // TODO: GH#18217
            return file.getLineAndCharacterOfPosition(position);
        }
        function clearCache() {
            sourceFileLike.clear();
            documentPositionMappers.clear();
        }
    }
    ts.getSourceMapper = getSourceMapper;
    function getDocumentPositionMapper(host, generatedFileName, generatedFileLineInfo, readMapFile) {
        var mapFileName = ts.tryGetSourceMappingURL(generatedFileLineInfo);
        if (mapFileName) {
            var match = base64UrlRegExp.exec(mapFileName);
            if (match) {
                if (match[1]) {
                    var base64Object = match[1];
                    return convertDocumentToSourceMapper(host, ts.base64decode(ts.sys, base64Object), generatedFileName);
                }
                // Not a data URL we can parse, skip it
                mapFileName = undefined;
            }
        }
        var possibleMapLocations = [];
        if (mapFileName) {
            possibleMapLocations.push(mapFileName);
        }
        possibleMapLocations.push(generatedFileName + ".map");
        var originalMapFileName = mapFileName && ts.getNormalizedAbsolutePath(mapFileName, ts.getDirectoryPath(generatedFileName));
        for (var _i = 0, possibleMapLocations_1 = possibleMapLocations; _i < possibleMapLocations_1.length; _i++) {
            var location = possibleMapLocations_1[_i];
            var mapFileName_1 = ts.getNormalizedAbsolutePath(location, ts.getDirectoryPath(generatedFileName));
            var mapFileContents = readMapFile(mapFileName_1, originalMapFileName);
            if (ts.isString(mapFileContents)) {
                return convertDocumentToSourceMapper(host, mapFileContents, mapFileName_1);
            }
            if (mapFileContents !== undefined) {
                return mapFileContents || undefined;
            }
        }
        return undefined;
    }
    ts.getDocumentPositionMapper = getDocumentPositionMapper;
    function convertDocumentToSourceMapper(host, contents, mapFileName) {
        var map = ts.tryParseRawSourceMap(contents);
        if (!map || !map.sources || !map.file || !map.mappings) {
            // obviously invalid map
            return undefined;
        }
        // Dont support sourcemaps that contain inlined sources
        if (map.sourcesContent && map.sourcesContent.some(ts.isString))
            return undefined;
        return ts.createDocumentPositionMapper(host, map, mapFileName);
    }
    function createSourceFileLike(text, lineMap) {
        return {
            text: text,
            lineMap: lineMap,
            getLineAndCharacterOfPosition: function (pos) {
                return ts.computeLineAndCharacterOfPosition(ts.getLineStarts(this), pos);
            }
        };
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var visitedNestedConvertibleFunctions = ts.createMap();
    function computeSuggestionDiagnostics(sourceFile, program, cancellationToken) {
        program.getSemanticDiagnostics(sourceFile, cancellationToken);
        var diags = [];
        var checker = program.getTypeChecker();
        if (sourceFile.commonJsModuleIndicator &&
            (ts.programContainsEs6Modules(program) || ts.compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) &&
            containsTopLevelCommonjs(sourceFile)) {
            diags.push(ts.createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), ts.Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module));
        }
        var isJsFile = ts.isSourceFileJS(sourceFile);
        visitedNestedConvertibleFunctions.clear();
        check(sourceFile);
        if (ts.getAllowSyntheticDefaultImports(program.getCompilerOptions())) {
            for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                var moduleSpecifier = _a[_i];
                var importNode = ts.importFromModuleSpecifier(moduleSpecifier);
                var name = importNameForConvertToDefaultImport(importNode);
                if (!name)
                    continue;
                var module_1 = ts.getResolvedModule(sourceFile, moduleSpecifier.text);
                var resolvedFile = module_1 && program.getSourceFile(module_1.resolvedFileName);
                if (resolvedFile && resolvedFile.externalModuleIndicator && ts.isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals) {
                    diags.push(ts.createDiagnosticForNode(name, ts.Diagnostics.Import_may_be_converted_to_a_default_import));
                }
            }
        }
        ts.addRange(diags, sourceFile.bindSuggestionDiagnostics);
        ts.addRange(diags, program.getSuggestionDiagnostics(sourceFile, cancellationToken));
        return diags.sort(function (d1, d2) { return d1.start - d2.start; });
        function check(node) {
            if (isJsFile) {
                if (canBeConvertedToClass(node)) {
                    diags.push(ts.createDiagnosticForNode(ts.isVariableDeclaration(node.parent) ? node.parent.name : node, ts.Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration));
                }
            }
            else {
                if (ts.isVariableStatement(node) &&
                    node.parent === sourceFile &&
                    node.declarationList.flags & 2 /* Const */ &&
                    node.declarationList.declarations.length === 1) {
                    var init = node.declarationList.declarations[0].initializer;
                    if (init && ts.isRequireCall(init, /*checkArgumentIsStringLiteralLike*/ true)) {
                        diags.push(ts.createDiagnosticForNode(init, ts.Diagnostics.require_call_may_be_converted_to_an_import));
                    }
                }
                if (ts.codefix.parameterShouldGetTypeFromJSDoc(node)) {
                    diags.push(ts.createDiagnosticForNode(node.name || node, ts.Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types));
                }
            }
            if (ts.isFunctionLikeDeclaration(node)) {
                addConvertToAsyncFunctionDiagnostics(node, checker, diags);
            }
            node.forEachChild(check);
        }
    }
    ts.computeSuggestionDiagnostics = computeSuggestionDiagnostics;
    // convertToEs6Module only works on top-level, so don't trigger it if commonjs code only appears in nested scopes.
    function containsTopLevelCommonjs(sourceFile) {
        return sourceFile.statements.some(function (statement) {
            switch (statement.kind) {
                case 225 /* VariableStatement */:
                    return statement.declarationList.declarations.some(function (decl) {
                        return !!decl.initializer && ts.isRequireCall(propertyAccessLeftHandSide(decl.initializer), /*checkArgumentIsStringLiteralLike*/ true);
                    });
                case 226 /* ExpressionStatement */: {
                    var expression = statement.expression;
                    if (!ts.isBinaryExpression(expression))
                        return ts.isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true);
                    var kind = ts.getAssignmentDeclarationKind(expression);
                    return kind === 1 /* ExportsProperty */ || kind === 2 /* ModuleExports */;
                }
                default:
                    return false;
            }
        });
    }
    function propertyAccessLeftHandSide(node) {
        return ts.isPropertyAccessExpression(node) ? propertyAccessLeftHandSide(node.expression) : node;
    }
    function importNameForConvertToDefaultImport(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
                var importClause = node.importClause, moduleSpecifier = node.moduleSpecifier;
                return importClause && !importClause.name && importClause.namedBindings && importClause.namedBindings.kind === 256 /* NamespaceImport */ && ts.isStringLiteral(moduleSpecifier)
                    ? importClause.namedBindings.name
                    : undefined;
            case 253 /* ImportEqualsDeclaration */:
                return node.name;
            default:
                return undefined;
        }
    }
    function addConvertToAsyncFunctionDiagnostics(node, checker, diags) {
        // need to check function before checking map so that deeper levels of nested callbacks are checked
        if (isConvertibleFunction(node, checker) && !visitedNestedConvertibleFunctions.has(getKeyFromNode(node))) {
            diags.push(ts.createDiagnosticForNode(!node.name && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name) ? node.parent.name : node, ts.Diagnostics.This_may_be_converted_to_an_async_function));
        }
    }
    function isConvertibleFunction(node, checker) {
        return !ts.isAsyncFunction(node) &&
            node.body &&
            ts.isBlock(node.body) &&
            hasReturnStatementWithPromiseHandler(node.body) &&
            returnsPromise(node, checker);
    }
    function returnsPromise(node, checker) {
        var functionType = checker.getTypeAtLocation(node);
        var callSignatures = checker.getSignaturesOfType(functionType, 0 /* Call */);
        var returnType = callSignatures.length ? checker.getReturnTypeOfSignature(callSignatures[0]) : undefined;
        return !!returnType && !!checker.getPromisedTypeOfPromise(returnType);
    }
    function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator) {
        return ts.isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator;
    }
    function hasReturnStatementWithPromiseHandler(body) {
        return !!ts.forEachReturnStatement(body, isReturnStatementWithFixablePromiseHandler);
    }
    function isReturnStatementWithFixablePromiseHandler(node) {
        return ts.isReturnStatement(node) && !!node.expression && isFixablePromiseHandler(node.expression);
    }
    ts.isReturnStatementWithFixablePromiseHandler = isReturnStatementWithFixablePromiseHandler;
    // Should be kept up to date with transformExpression in convertToAsyncFunction.ts
    function isFixablePromiseHandler(node) {
        // ensure outermost call exists and is a promise handler
        if (!isPromiseHandler(node) || !node.arguments.every(isFixablePromiseArgument)) {
            return false;
        }
        // ensure all chained calls are valid
        var currentNode = node.expression;
        while (isPromiseHandler(currentNode) || ts.isPropertyAccessExpression(currentNode)) {
            if (ts.isCallExpression(currentNode) && !currentNode.arguments.every(isFixablePromiseArgument)) {
                return false;
            }
            currentNode = currentNode.expression;
        }
        return true;
    }
    ts.isFixablePromiseHandler = isFixablePromiseHandler;
    function isPromiseHandler(node) {
        return ts.isCallExpression(node) && (ts.hasPropertyAccessExpressionWithName(node, "then") && hasSupportedNumberOfArguments(node) ||
            ts.hasPropertyAccessExpressionWithName(node, "catch"));
    }
    function hasSupportedNumberOfArguments(node) {
        if (node.arguments.length > 2)
            return false;
        if (node.arguments.length < 2)
            return true;
        return ts.some(node.arguments, function (arg) {
            return arg.kind === 100 /* NullKeyword */ ||
                ts.isIdentifier(arg) && arg.text === "undefined";
        });
    }
    // should be kept up to date with getTransformationBody in convertToAsyncFunction.ts
    function isFixablePromiseArgument(arg) {
        switch (arg.kind) {
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
                visitedNestedConvertibleFunctions.set(getKeyFromNode(arg), true);
            // falls through
            case 100 /* NullKeyword */:
            case 75 /* Identifier */: // identifier includes undefined
                return true;
            default:
                return false;
        }
    }
    function getKeyFromNode(exp) {
        return exp.pos.toString() + ":" + exp.end.toString();
    }
    function canBeConvertedToClass(node) {
        var _a, _b, _c, _d;
        if (node.kind === 201 /* FunctionExpression */) {
            if (ts.isVariableDeclaration(node.parent) && ((_a = node.symbol.members) === null || _a === void 0 ? void 0 : _a.size)) {
                return true;
            }
            var decl = ts.getDeclarationOfExpando(node);
            var symbol = decl === null || decl === void 0 ? void 0 : decl.symbol;
            return !!(symbol && (((_b = symbol.exports) === null || _b === void 0 ? void 0 : _b.size) || ((_c = symbol.members) === null || _c === void 0 ? void 0 : _c.size)));
        }
        if (node.kind === 244 /* FunctionDeclaration */) {
            return !!((_d = node.symbol.members) === null || _d === void 0 ? void 0 : _d.size);
        }
        return false;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var SymbolDisplay;
    (function (SymbolDisplay) {
        var symbolDisplayNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 70221824 /* IgnoreErrors */ | 16384 /* UseAliasDefinedOutsideCurrentScope */;
        // TODO(drosen): use contextual SemanticMeaning.
        function getSymbolKind(typeChecker, symbol, location) {
            var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
            if (result !== "" /* unknown */) {
                return result;
            }
            var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            if (flags & 32 /* Class */) {
                return ts.getDeclarationOfKind(symbol, 214 /* ClassExpression */) ?
                    "local class" /* localClassElement */ : "class" /* classElement */;
            }
            if (flags & 384 /* Enum */)
                return "enum" /* enumElement */;
            if (flags & 524288 /* TypeAlias */)
                return "type" /* typeElement */;
            if (flags & 64 /* Interface */)
                return "interface" /* interfaceElement */;
            if (flags & 262144 /* TypeParameter */)
                return "type parameter" /* typeParameterElement */;
            if (flags & 8 /* EnumMember */)
                return "enum member" /* enumMemberElement */;
            if (flags & 2097152 /* Alias */)
                return "alias" /* alias */;
            if (flags & 1536 /* Module */)
                return "module" /* moduleElement */;
            return result;
        }
        SymbolDisplay.getSymbolKind = getSymbolKind;
        function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) {
            var roots = typeChecker.getRootSymbols(symbol);
            // If this is a method from a mapped type, leave as a method so long as it still has a call signature.
            if (roots.length === 1
                && ts.first(roots).flags & 8192 /* Method */
                // Ensure the mapped version is still a method, as opposed to `{ [K in keyof I]: number }`.
                && typeChecker.getTypeOfSymbolAtLocation(symbol, location).getNonNullableType().getCallSignatures().length !== 0) {
                return "method" /* memberFunctionElement */;
            }
            if (typeChecker.isUndefinedSymbol(symbol)) {
                return "var" /* variableElement */;
            }
            if (typeChecker.isArgumentsSymbol(symbol)) {
                return "local var" /* localVariableElement */;
            }
            if (location.kind === 104 /* ThisKeyword */ && ts.isExpression(location)) {
                return "parameter" /* parameterElement */;
            }
            var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            if (flags & 3 /* Variable */) {
                if (ts.isFirstDeclarationOfSymbolParameter(symbol)) {
                    return "parameter" /* parameterElement */;
                }
                else if (symbol.valueDeclaration && ts.isVarConst(symbol.valueDeclaration)) {
                    return "const" /* constElement */;
                }
                else if (ts.forEach(symbol.declarations, ts.isLet)) {
                    return "let" /* letElement */;
                }
                return isLocalVariableOrFunction(symbol) ? "local var" /* localVariableElement */ : "var" /* variableElement */;
            }
            if (flags & 16 /* Function */)
                return isLocalVariableOrFunction(symbol) ? "local function" /* localFunctionElement */ : "function" /* functionElement */;
            if (flags & 32768 /* GetAccessor */)
                return "getter" /* memberGetAccessorElement */;
            if (flags & 65536 /* SetAccessor */)
                return "setter" /* memberSetAccessorElement */;
            if (flags & 8192 /* Method */)
                return "method" /* memberFunctionElement */;
            if (flags & 16384 /* Constructor */)
                return "constructor" /* constructorImplementationElement */;
            if (flags & 4 /* Property */) {
                if (flags & 33554432 /* Transient */ && symbol.checkFlags & 6 /* Synthetic */) {
                    // If union property is result of union of non method (property/accessors/variables), it is labeled as property
                    var unionPropertyKind = ts.forEach(typeChecker.getRootSymbols(symbol), function (rootSymbol) {
                        var rootSymbolFlags = rootSymbol.getFlags();
                        if (rootSymbolFlags & (98308 /* PropertyOrAccessor */ | 3 /* Variable */)) {
                            return "property" /* memberVariableElement */;
                        }
                        // May be a Function if this was from `typeof N` with `namespace N { function f();. }`.
                        ts.Debug.assert(!!(rootSymbolFlags & (8192 /* Method */ | 16 /* Function */)));
                    });
                    if (!unionPropertyKind) {
                        // If this was union of all methods,
                        // make sure it has call signatures before we can label it as method
                        var typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location);
                        if (typeOfUnionProperty.getCallSignatures().length) {
                            return "method" /* memberFunctionElement */;
                        }
                        return "property" /* memberVariableElement */;
                    }
                    return unionPropertyKind;
                }
                // If we requested completions after `x.` at the top-level, we may be at a source file location.
                switch (location.parent && location.parent.kind) {
                    // If we've typed a character of the attribute name, will be 'JsxAttribute', else will be 'JsxOpeningElement'.
                    case 268 /* JsxOpeningElement */:
                    case 266 /* JsxElement */:
                    case 267 /* JsxSelfClosingElement */:
                        return location.kind === 75 /* Identifier */ ? "property" /* memberVariableElement */ : "JSX attribute" /* jsxAttribute */;
                    case 273 /* JsxAttribute */:
                        return "JSX attribute" /* jsxAttribute */;
                    default:
                        return "property" /* memberVariableElement */;
                }
            }
            return "" /* unknown */;
        }
        function getSymbolModifiers(symbol) {
            var nodeModifiers = symbol && symbol.declarations && symbol.declarations.length > 0
                ? ts.getNodeModifiers(symbol.declarations[0])
                : "" /* none */;
            var symbolModifiers = symbol && symbol.flags & 16777216 /* Optional */ ?
                "optional" /* optionalModifier */
                : "" /* none */;
            return nodeModifiers && symbolModifiers ? nodeModifiers + "," + symbolModifiers : nodeModifiers || symbolModifiers;
        }
        SymbolDisplay.getSymbolModifiers = getSymbolModifiers;
        // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location
        function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, enclosingDeclaration, location, semanticMeaning, alias) {
            if (semanticMeaning === void 0) { semanticMeaning = ts.getMeaningFromLocation(location); }
            var displayParts = [];
            var documentation = [];
            var tags = [];
            var symbolFlags = ts.getCombinedLocalAndExportSymbolFlags(symbol);
            var symbolKind = semanticMeaning & 1 /* Value */ ? getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) : "" /* unknown */;
            var hasAddedSymbolInfo = false;
            var isThisExpression = location.kind === 104 /* ThisKeyword */ && ts.isInExpressionContext(location);
            var type;
            var printer;
            var documentationFromAlias;
            var tagsFromAlias;
            var hasMultipleSignatures = false;
            if (location.kind === 104 /* ThisKeyword */ && !isThisExpression) {
                return { displayParts: [ts.keywordPart(104 /* ThisKeyword */)], documentation: [], symbolKind: "primitive type" /* primitiveType */, tags: undefined };
            }
            // Class at constructor site need to be shown as constructor apart from property,method, vars
            if (symbolKind !== "" /* unknown */ || symbolFlags & 32 /* Class */ || symbolFlags & 2097152 /* Alias */) {
                // If it is accessor they are allowed only if location is at name of the accessor
                if (symbolKind === "getter" /* memberGetAccessorElement */ || symbolKind === "setter" /* memberSetAccessorElement */) {
                    symbolKind = "property" /* memberVariableElement */;
                }
                var signature = void 0;
                type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol.exportSymbol || symbol, location);
                if (location.parent && location.parent.kind === 194 /* PropertyAccessExpression */) {
                    var right = location.parent.name;
                    // Either the location is on the right of a property access, or on the left and the right is missing
                    if (right === location || (right && right.getFullWidth() === 0)) {
                        location = location.parent;
                    }
                }
                // try get the call/construct signature from the type if it matches
                var callExpressionLike = void 0;
                if (ts.isCallOrNewExpression(location)) {
                    callExpressionLike = location;
                }
                else if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location)) {
                    callExpressionLike = location.parent;
                }
                else if (location.parent && ts.isJsxOpeningLikeElement(location.parent) && ts.isFunctionLike(symbol.valueDeclaration)) {
                    callExpressionLike = location.parent;
                }
                if (callExpressionLike) {
                    signature = typeChecker.getResolvedSignature(callExpressionLike); // TODO: GH#18217
                    var useConstructSignatures = callExpressionLike.kind === 197 /* NewExpression */ || (ts.isCallExpression(callExpressionLike) && callExpressionLike.expression.kind === 102 /* SuperKeyword */);
                    var allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures();
                    if (!ts.contains(allSignatures, signature.target) && !ts.contains(allSignatures, signature)) {
                        // Get the first signature if there is one -- allSignatures may contain
                        // either the original signature or its target, so check for either
                        signature = allSignatures.length ? allSignatures[0] : undefined;
                    }
                    if (signature) {
                        if (useConstructSignatures && (symbolFlags & 32 /* Class */)) {
                            // Constructor
                            symbolKind = "constructor" /* constructorImplementationElement */;
                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                        }
                        else if (symbolFlags & 2097152 /* Alias */) {
                            symbolKind = "alias" /* alias */;
                            pushSymbolKind(symbolKind);
                            displayParts.push(ts.spacePart());
                            if (useConstructSignatures) {
                                displayParts.push(ts.keywordPart(99 /* NewKeyword */));
                                displayParts.push(ts.spacePart());
                            }
                            addFullSymbolName(symbol);
                        }
                        else {
                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                        }
                        switch (symbolKind) {
                            case "JSX attribute" /* jsxAttribute */:
                            case "property" /* memberVariableElement */:
                            case "var" /* variableElement */:
                            case "const" /* constElement */:
                            case "let" /* letElement */:
                            case "parameter" /* parameterElement */:
                            case "local var" /* localVariableElement */:
                                // If it is call or construct signature of lambda's write type name
                                displayParts.push(ts.punctuationPart(58 /* ColonToken */));
                                displayParts.push(ts.spacePart());
                                if (!(ts.getObjectFlags(type) & 16 /* Anonymous */) && type.symbol) {
                                    ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 4 /* AllowAnyNodeKind */ | 1 /* WriteTypeParametersOrArguments */));
                                    displayParts.push(ts.lineBreakPart());
                                }
                                if (useConstructSignatures) {
                                    displayParts.push(ts.keywordPart(99 /* NewKeyword */));
                                    displayParts.push(ts.spacePart());
                                }
                                addSignatureDisplayParts(signature, allSignatures, 262144 /* WriteArrowStyleSignature */);
                                break;
                            default:
                                // Just signature
                                addSignatureDisplayParts(signature, allSignatures);
                        }
                        hasAddedSymbolInfo = true;
                        hasMultipleSignatures = allSignatures.length > 1;
                    }
                }
                else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || // name of function declaration
                    (location.kind === 129 /* ConstructorKeyword */ && location.parent.kind === 162 /* Constructor */)) { // At constructor keyword of constructor declaration
                    // get the signature from the declaration and write it
                    var functionDeclaration_1 = location.parent;
                    // Use function declaration to write the signatures only if the symbol corresponding to this declaration
                    var locationIsSymbolDeclaration = symbol.declarations && ts.find(symbol.declarations, function (declaration) {
                        return declaration === (location.kind === 129 /* ConstructorKeyword */ ? functionDeclaration_1.parent : functionDeclaration_1);
                    });
                    if (locationIsSymbolDeclaration) {
                        var allSignatures = functionDeclaration_1.kind === 162 /* Constructor */ ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
                        if (!typeChecker.isImplementationOfOverload(functionDeclaration_1)) {
                            signature = typeChecker.getSignatureFromDeclaration(functionDeclaration_1); // TODO: GH#18217
                        }
                        else {
                            signature = allSignatures[0];
                        }
                        if (functionDeclaration_1.kind === 162 /* Constructor */) {
                            // show (constructor) Type(...) signature
                            symbolKind = "constructor" /* constructorImplementationElement */;
                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                        }
                        else {
                            // (function/method) symbol(..signature)
                            addPrefixForAnyFunctionOrVar(functionDeclaration_1.kind === 165 /* CallSignature */ &&
                                !(type.symbol.flags & 2048 /* TypeLiteral */ || type.symbol.flags & 4096 /* ObjectLiteral */) ? type.symbol : symbol, symbolKind);
                        }
                        addSignatureDisplayParts(signature, allSignatures);
                        hasAddedSymbolInfo = true;
                        hasMultipleSignatures = allSignatures.length > 1;
                    }
                }
            }
            if (symbolFlags & 32 /* Class */ && !hasAddedSymbolInfo && !isThisExpression) {
                addAliasPrefixIfNecessary();
                if (ts.getDeclarationOfKind(symbol, 214 /* ClassExpression */)) {
                    // Special case for class expressions because we would like to indicate that
                    // the class name is local to the class body (similar to function expression)
                    //      (local class) class <className>
                    pushSymbolKind("local class" /* localClassElement */);
                }
                else {
                    // Class declaration has name which is not local.
                    displayParts.push(ts.keywordPart(80 /* ClassKeyword */));
                }
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
            }
            if ((symbolFlags & 64 /* Interface */) && (semanticMeaning & 2 /* Type */)) {
                prefixNextMeaning();
                displayParts.push(ts.keywordPart(114 /* InterfaceKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
            }
            if ((symbolFlags & 524288 /* TypeAlias */) && (semanticMeaning & 2 /* Type */)) {
                prefixNextMeaning();
                displayParts.push(ts.keywordPart(145 /* TypeKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
                displayParts.push(ts.spacePart());
                displayParts.push(ts.operatorPart(62 /* EqualsToken */));
                displayParts.push(ts.spacePart());
                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, 8388608 /* InTypeAlias */));
            }
            if (symbolFlags & 384 /* Enum */) {
                prefixNextMeaning();
                if (ts.some(symbol.declarations, function (d) { return ts.isEnumDeclaration(d) && ts.isEnumConst(d); })) {
                    displayParts.push(ts.keywordPart(81 /* ConstKeyword */));
                    displayParts.push(ts.spacePart());
                }
                displayParts.push(ts.keywordPart(88 /* EnumKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
            }
            if (symbolFlags & 1536 /* Module */ && !isThisExpression) {
                prefixNextMeaning();
                var declaration = ts.getDeclarationOfKind(symbol, 249 /* ModuleDeclaration */);
                var isNamespace = declaration && declaration.name && declaration.name.kind === 75 /* Identifier */;
                displayParts.push(ts.keywordPart(isNamespace ? 136 /* NamespaceKeyword */ : 135 /* ModuleKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
            }
            if ((symbolFlags & 262144 /* TypeParameter */) && (semanticMeaning & 2 /* Type */)) {
                prefixNextMeaning();
                displayParts.push(ts.punctuationPart(20 /* OpenParenToken */));
                displayParts.push(ts.textPart("type parameter"));
                displayParts.push(ts.punctuationPart(21 /* CloseParenToken */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                if (symbol.parent) {
                    // Class/Interface type parameter
                    addInPrefix();
                    addFullSymbolName(symbol.parent, enclosingDeclaration);
                    writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
                }
                else {
                    // Method/function type parameter
                    var decl = ts.getDeclarationOfKind(symbol, 155 /* TypeParameter */);
                    if (decl === undefined)
                        return ts.Debug.fail();
                    var declaration = decl.parent;
                    if (declaration) {
                        if (ts.isFunctionLikeKind(declaration.kind)) {
                            addInPrefix();
                            var signature = typeChecker.getSignatureFromDeclaration(declaration); // TODO: GH#18217
                            if (declaration.kind === 166 /* ConstructSignature */) {
                                displayParts.push(ts.keywordPart(99 /* NewKeyword */));
                                displayParts.push(ts.spacePart());
                            }
                            else if (declaration.kind !== 165 /* CallSignature */ && declaration.name) {
                                addFullSymbolName(declaration.symbol);
                            }
                            ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */));
                        }
                        else if (declaration.kind === 247 /* TypeAliasDeclaration */) {
                            // Type alias type parameter
                            // For example
                            //      type list<T> = T[]; // Both T will go through same code path
                            addInPrefix();
                            displayParts.push(ts.keywordPart(145 /* TypeKeyword */));
                            displayParts.push(ts.spacePart());
                            addFullSymbolName(declaration.symbol);
                            writeTypeParametersOfSymbol(declaration.symbol, sourceFile);
                        }
                    }
                }
            }
            if (symbolFlags & 8 /* EnumMember */) {
                symbolKind = "enum member" /* enumMemberElement */;
                addPrefixForAnyFunctionOrVar(symbol, "enum member");
                var declaration = symbol.declarations[0];
                if (declaration.kind === 284 /* EnumMember */) {
                    var constantValue = typeChecker.getConstantValue(declaration);
                    if (constantValue !== undefined) {
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.operatorPart(62 /* EqualsToken */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.displayPart(ts.getTextOfConstantValue(constantValue), typeof constantValue === "number" ? ts.SymbolDisplayPartKind.numericLiteral : ts.SymbolDisplayPartKind.stringLiteral));
                    }
                }
            }
            if (symbolFlags & 2097152 /* Alias */) {
                prefixNextMeaning();
                if (!hasAddedSymbolInfo) {
                    var resolvedSymbol = typeChecker.getAliasedSymbol(symbol);
                    if (resolvedSymbol !== symbol && resolvedSymbol.declarations && resolvedSymbol.declarations.length > 0) {
                        var resolvedNode = resolvedSymbol.declarations[0];
                        var declarationName = ts.getNameOfDeclaration(resolvedNode);
                        if (declarationName) {
                            var isExternalModuleDeclaration = ts.isModuleWithStringLiteralName(resolvedNode) &&
                                ts.hasModifier(resolvedNode, 2 /* Ambient */);
                            var shouldUseAliasName = symbol.name !== "default" && !isExternalModuleDeclaration;
                            var resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, resolvedSymbol, ts.getSourceFileOfNode(resolvedNode), resolvedNode, declarationName, semanticMeaning, shouldUseAliasName ? symbol : resolvedSymbol);
                            displayParts.push.apply(displayParts, resolvedInfo.displayParts);
                            displayParts.push(ts.lineBreakPart());
                            documentationFromAlias = resolvedInfo.documentation;
                            tagsFromAlias = resolvedInfo.tags;
                        }
                    }
                }
                switch (symbol.declarations[0].kind) {
                    case 252 /* NamespaceExportDeclaration */:
                        displayParts.push(ts.keywordPart(89 /* ExportKeyword */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.keywordPart(136 /* NamespaceKeyword */));
                        break;
                    case 259 /* ExportAssignment */:
                        displayParts.push(ts.keywordPart(89 /* ExportKeyword */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.keywordPart(symbol.declarations[0].isExportEquals ? 62 /* EqualsToken */ : 84 /* DefaultKeyword */));
                        break;
                    case 263 /* ExportSpecifier */:
                        displayParts.push(ts.keywordPart(89 /* ExportKeyword */));
                        break;
                    default:
                        displayParts.push(ts.keywordPart(96 /* ImportKeyword */));
                }
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                ts.forEach(symbol.declarations, function (declaration) {
                    if (declaration.kind === 253 /* ImportEqualsDeclaration */) {
                        var importEqualsDeclaration = declaration;
                        if (ts.isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) {
                            displayParts.push(ts.spacePart());
                            displayParts.push(ts.operatorPart(62 /* EqualsToken */));
                            displayParts.push(ts.spacePart());
                            displayParts.push(ts.keywordPart(139 /* RequireKeyword */));
                            displayParts.push(ts.punctuationPart(20 /* OpenParenToken */));
                            displayParts.push(ts.displayPart(ts.getTextOfNode(ts.getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), ts.SymbolDisplayPartKind.stringLiteral));
                            displayParts.push(ts.punctuationPart(21 /* CloseParenToken */));
                        }
                        else {
                            var internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference);
                            if (internalAliasSymbol) {
                                displayParts.push(ts.spacePart());
                                displayParts.push(ts.operatorPart(62 /* EqualsToken */));
                                displayParts.push(ts.spacePart());
                                addFullSymbolName(internalAliasSymbol, enclosingDeclaration);
                            }
                        }
                        return true;
                    }
                });
            }
            if (!hasAddedSymbolInfo) {
                if (symbolKind !== "" /* unknown */) {
                    if (type) {
                        if (isThisExpression) {
                            prefixNextMeaning();
                            displayParts.push(ts.keywordPart(104 /* ThisKeyword */));
                        }
                        else {
                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                        }
                        // For properties, variables and local vars: show the type
                        if (symbolKind === "property" /* memberVariableElement */ ||
                            symbolKind === "JSX attribute" /* jsxAttribute */ ||
                            symbolFlags & 3 /* Variable */ ||
                            symbolKind === "local var" /* localVariableElement */ ||
                            isThisExpression) {
                            displayParts.push(ts.punctuationPart(58 /* ColonToken */));
                            displayParts.push(ts.spacePart());
                            // If the type is type parameter, format it specially
                            if (type.symbol && type.symbol.flags & 262144 /* TypeParameter */) {
                                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                                    var param = typeChecker.typeParameterToDeclaration(type, enclosingDeclaration, symbolDisplayNodeBuilderFlags);
                                    getPrinter().writeNode(4 /* Unspecified */, param, ts.getSourceFileOfNode(ts.getParseTreeNode(enclosingDeclaration)), writer);
                                });
                                ts.addRange(displayParts, typeParameterParts);
                            }
                            else {
                                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, type, enclosingDeclaration));
                            }
                        }
                        else if (symbolFlags & 16 /* Function */ ||
                            symbolFlags & 8192 /* Method */ ||
                            symbolFlags & 16384 /* Constructor */ ||
                            symbolFlags & 131072 /* Signature */ ||
                            symbolFlags & 98304 /* Accessor */ ||
                            symbolKind === "method" /* memberFunctionElement */) {
                            var allSignatures = type.getNonNullableType().getCallSignatures();
                            if (allSignatures.length) {
                                addSignatureDisplayParts(allSignatures[0], allSignatures);
                                hasMultipleSignatures = allSignatures.length > 1;
                            }
                        }
                    }
                }
                else {
                    symbolKind = getSymbolKind(typeChecker, symbol, location);
                }
            }
            if (documentation.length === 0 && !hasMultipleSignatures) {
                documentation = symbol.getDocumentationComment(typeChecker);
            }
            if (documentation.length === 0 && symbolFlags & 4 /* Property */) {
                // For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo`
                // there documentation comments might be attached to the right hand side symbol of their declarations.
                // The pattern of such special property access is that the parent symbol is the symbol of the file.
                if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 290 /* SourceFile */; })) {
                    for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                        var declaration = _a[_i];
                        if (!declaration.parent || declaration.parent.kind !== 209 /* BinaryExpression */) {
                            continue;
                        }
                        var rhsSymbol = typeChecker.getSymbolAtLocation(declaration.parent.right);
                        if (!rhsSymbol) {
                            continue;
                        }
                        documentation = rhsSymbol.getDocumentationComment(typeChecker);
                        tags = rhsSymbol.getJsDocTags();
                        if (documentation.length > 0) {
                            break;
                        }
                    }
                }
            }
            if (tags.length === 0 && !hasMultipleSignatures) {
                tags = symbol.getJsDocTags();
            }
            if (documentation.length === 0 && documentationFromAlias) {
                documentation = documentationFromAlias;
            }
            if (tags.length === 0 && tagsFromAlias) {
                tags = tagsFromAlias;
            }
            return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags.length === 0 ? undefined : tags };
            function getPrinter() {
                if (!printer) {
                    printer = ts.createPrinter({ removeComments: true });
                }
                return printer;
            }
            function prefixNextMeaning() {
                if (displayParts.length) {
                    displayParts.push(ts.lineBreakPart());
                }
                addAliasPrefixIfNecessary();
            }
            function addAliasPrefixIfNecessary() {
                if (alias) {
                    pushSymbolKind("alias" /* alias */);
                    displayParts.push(ts.spacePart());
                }
            }
            function addInPrefix() {
                displayParts.push(ts.spacePart());
                displayParts.push(ts.keywordPart(97 /* InKeyword */));
                displayParts.push(ts.spacePart());
            }
            function addFullSymbolName(symbolToDisplay, enclosingDeclaration) {
                if (alias && symbolToDisplay === symbol) {
                    symbolToDisplay = alias;
                }
                var fullSymbolDisplayParts = ts.symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */ | 2 /* UseOnlyExternalAliasing */ | 4 /* AllowAnyNodeKind */);
                ts.addRange(displayParts, fullSymbolDisplayParts);
                if (symbol.flags & 16777216 /* Optional */) {
                    displayParts.push(ts.punctuationPart(57 /* QuestionToken */));
                }
            }
            function addPrefixForAnyFunctionOrVar(symbol, symbolKind) {
                prefixNextMeaning();
                if (symbolKind) {
                    pushSymbolKind(symbolKind);
                    if (symbol && !ts.some(symbol.declarations, function (d) { return ts.isArrowFunction(d) || (ts.isFunctionExpression(d) || ts.isClassExpression(d)) && !d.name; })) {
                        displayParts.push(ts.spacePart());
                        addFullSymbolName(symbol);
                    }
                }
            }
            function pushSymbolKind(symbolKind) {
                switch (symbolKind) {
                    case "var" /* variableElement */:
                    case "function" /* functionElement */:
                    case "let" /* letElement */:
                    case "const" /* constElement */:
                    case "constructor" /* constructorImplementationElement */:
                        displayParts.push(ts.textOrKeywordPart(symbolKind));
                        return;
                    default:
                        displayParts.push(ts.punctuationPart(20 /* OpenParenToken */));
                        displayParts.push(ts.textOrKeywordPart(symbolKind));
                        displayParts.push(ts.punctuationPart(21 /* CloseParenToken */));
                        return;
                }
            }
            function addSignatureDisplayParts(signature, allSignatures, flags) {
                if (flags === void 0) { flags = 0 /* None */; }
                ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | 32 /* WriteTypeArgumentsOfSignature */));
                if (allSignatures.length > 1) {
                    displayParts.push(ts.spacePart());
                    displayParts.push(ts.punctuationPart(20 /* OpenParenToken */));
                    displayParts.push(ts.operatorPart(39 /* PlusToken */));
                    displayParts.push(ts.displayPart((allSignatures.length - 1).toString(), ts.SymbolDisplayPartKind.numericLiteral));
                    displayParts.push(ts.spacePart());
                    displayParts.push(ts.textPart(allSignatures.length === 2 ? "overload" : "overloads"));
                    displayParts.push(ts.punctuationPart(21 /* CloseParenToken */));
                }
                documentation = signature.getDocumentationComment(typeChecker);
                tags = signature.getJsDocTags();
                if (allSignatures.length > 1 && documentation.length === 0 && tags.length === 0) {
                    documentation = allSignatures[0].getDocumentationComment(typeChecker);
                    tags = allSignatures[0].getJsDocTags();
                }
            }
            function writeTypeParametersOfSymbol(symbol, enclosingDeclaration) {
                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                    var params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration, symbolDisplayNodeBuilderFlags);
                    getPrinter().writeList(53776 /* TypeParameters */, params, ts.getSourceFileOfNode(ts.getParseTreeNode(enclosingDeclaration)), writer);
                });
                ts.addRange(displayParts, typeParameterParts);
            }
        }
        SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind;
        function isLocalVariableOrFunction(symbol) {
            if (symbol.parent) {
                return false; // This is exported symbol
            }
            return ts.forEach(symbol.declarations, function (declaration) {
                // Function expressions are local
                if (declaration.kind === 201 /* FunctionExpression */) {
                    return true;
                }
                if (declaration.kind !== 242 /* VariableDeclaration */ && declaration.kind !== 244 /* FunctionDeclaration */) {
                    return false;
                }
                // If the parent is not sourceFile or module block it is local variable
                for (var parent = declaration.parent; !ts.isFunctionBlock(parent); parent = parent.parent) {
                    // Reached source file or module block
                    if (parent.kind === 290 /* SourceFile */ || parent.kind === 250 /* ModuleBlock */) {
                        return false;
                    }
                }
                // parent is in function block
                return true;
            });
        }
    })(SymbolDisplay = ts.SymbolDisplay || (ts.SymbolDisplay = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    /*
     * This function will compile source text from 'input' argument using specified compiler options.
     * If not options are provided - it will use a set of default compiler options.
     * Extra compiler options that will unconditionally be used by this function are:
     * - isolatedModules = true
     * - allowNonTsExtensions = true
     * - noLib = true
     * - noResolve = true
     */
    function transpileModule(input, transpileOptions) {
        var diagnostics = [];
        var options = transpileOptions.compilerOptions ? fixupCompilerOptions(transpileOptions.compilerOptions, diagnostics) : {};
        // mix in default options
        var defaultOptions = ts.getDefaultCompilerOptions();
        for (var key in defaultOptions) {
            if (ts.hasProperty(defaultOptions, key) && options[key] === undefined) {
                options[key] = defaultOptions[key];
            }
        }
        for (var _i = 0, transpileOptionValueCompilerOptions_1 = ts.transpileOptionValueCompilerOptions; _i < transpileOptionValueCompilerOptions_1.length; _i++) {
            var option = transpileOptionValueCompilerOptions_1[_i];
            options[option.name] = option.transpileOptionValue;
        }
        // transpileModule does not write anything to disk so there is no need to verify that there are no conflicts between input and output paths.
        options.suppressOutputPathCheck = true;
        // Filename can be non-ts file.
        options.allowNonTsExtensions = true;
        // if jsx is specified then treat file as .tsx
        var inputFileName = transpileOptions.fileName || (transpileOptions.compilerOptions && transpileOptions.compilerOptions.jsx ? "module.tsx" : "module.ts");
        var sourceFile = ts.createSourceFile(inputFileName, input, options.target); // TODO: GH#18217
        if (transpileOptions.moduleName) {
            sourceFile.moduleName = transpileOptions.moduleName;
        }
        if (transpileOptions.renamedDependencies) {
            sourceFile.renamedDependencies = ts.createMapFromTemplate(transpileOptions.renamedDependencies);
        }
        var newLine = ts.getNewLineCharacter(options);
        // Output
        var outputText;
        var sourceMapText;
        // Create a compilerHost object to allow the compiler to read and write files
        var compilerHost = {
            getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; },
            writeFile: function (name, text) {
                if (ts.fileExtensionIs(name, ".map")) {
                    ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name);
                    sourceMapText = text;
                }
                else {
                    ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name);
                    outputText = text;
                }
            },
            getDefaultLibFileName: function () { return "lib.d.ts"; },
            useCaseSensitiveFileNames: function () { return false; },
            getCanonicalFileName: function (fileName) { return fileName; },
            getCurrentDirectory: function () { return ""; },
            getNewLine: function () { return newLine; },
            fileExists: function (fileName) { return fileName === inputFileName; },
            readFile: function () { return ""; },
            directoryExists: function () { return true; },
            getDirectories: function () { return []; }
        };
        var program = ts.createProgram([inputFileName], options, compilerHost);
        if (transpileOptions.reportDiagnostics) {
            ts.addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
            ts.addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
        }
        // Emit
        program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers);
        if (outputText === undefined)
            return ts.Debug.fail("Output generation failed");
        return { outputText: outputText, diagnostics: diagnostics, sourceMapText: sourceMapText };
    }
    ts.transpileModule = transpileModule;
    /*
     * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result.
     */
    function transpile(input, compilerOptions, fileName, diagnostics, moduleName) {
        var output = transpileModule(input, { compilerOptions: compilerOptions, fileName: fileName, reportDiagnostics: !!diagnostics, moduleName: moduleName });
        // addRange correctly handles cases when wither 'from' or 'to' argument is missing
        ts.addRange(diagnostics, output.diagnostics);
        return output.outputText;
    }
    ts.transpile = transpile;
    var commandLineOptionsStringToEnum;
    /** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */
    /*@internal*/
    function fixupCompilerOptions(options, diagnostics) {
        // Lazily create this value to fix module loading errors.
        commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || ts.filter(ts.optionDeclarations, function (o) {
            return typeof o.type === "object" && !ts.forEachEntry(o.type, function (v) { return typeof v !== "number"; });
        });
        options = ts.cloneCompilerOptions(options);
        var _loop_8 = function (opt) {
            if (!ts.hasProperty(options, opt.name)) {
                return "continue";
            }
            var value = options[opt.name];
            // Value should be a key of opt.type
            if (ts.isString(value)) {
                // If value is not a string, this will fail
                options[opt.name] = ts.parseCustomTypeOption(opt, value, diagnostics);
            }
            else {
                if (!ts.forEachEntry(opt.type, function (v) { return v === value; })) {
                    // Supplied value isn't a valid enum value.
                    diagnostics.push(ts.createCompilerDiagnosticForInvalidCustomType(opt));
                }
            }
        };
        for (var _i = 0, commandLineOptionsStringToEnum_1 = commandLineOptionsStringToEnum; _i < commandLineOptionsStringToEnum_1.length; _i++) {
            var opt = commandLineOptionsStringToEnum_1[_i];
            _loop_8(opt);
        }
        return options;
    }
    ts.fixupCompilerOptions = fixupCompilerOptions;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var FormattingRequestKind;
        (function (FormattingRequestKind) {
            FormattingRequestKind[FormattingRequestKind["FormatDocument"] = 0] = "FormatDocument";
            FormattingRequestKind[FormattingRequestKind["FormatSelection"] = 1] = "FormatSelection";
            FormattingRequestKind[FormattingRequestKind["FormatOnEnter"] = 2] = "FormatOnEnter";
            FormattingRequestKind[FormattingRequestKind["FormatOnSemicolon"] = 3] = "FormatOnSemicolon";
            FormattingRequestKind[FormattingRequestKind["FormatOnOpeningCurlyBrace"] = 4] = "FormatOnOpeningCurlyBrace";
            FormattingRequestKind[FormattingRequestKind["FormatOnClosingCurlyBrace"] = 5] = "FormatOnClosingCurlyBrace";
        })(FormattingRequestKind = formatting.FormattingRequestKind || (formatting.FormattingRequestKind = {}));
        var FormattingContext = /** @class */ (function () {
            function FormattingContext(sourceFile, formattingRequestKind, options) {
                this.sourceFile = sourceFile;
                this.formattingRequestKind = formattingRequestKind;
                this.options = options;
            }
            FormattingContext.prototype.updateContext = function (currentRange, currentTokenParent, nextRange, nextTokenParent, commonParent) {
                this.currentTokenSpan = ts.Debug.checkDefined(currentRange);
                this.currentTokenParent = ts.Debug.checkDefined(currentTokenParent);
                this.nextTokenSpan = ts.Debug.checkDefined(nextRange);
                this.nextTokenParent = ts.Debug.checkDefined(nextTokenParent);
                this.contextNode = ts.Debug.checkDefined(commonParent);
                // drop cached results
                this.contextNodeAllOnSameLine = undefined;
                this.nextNodeAllOnSameLine = undefined;
                this.tokensAreOnSameLine = undefined;
                this.contextNodeBlockIsOnOneLine = undefined;
                this.nextNodeBlockIsOnOneLine = undefined;
            };
            FormattingContext.prototype.ContextNodeAllOnSameLine = function () {
                if (this.contextNodeAllOnSameLine === undefined) {
                    this.contextNodeAllOnSameLine = this.NodeIsOnOneLine(this.contextNode);
                }
                return this.contextNodeAllOnSameLine;
            };
            FormattingContext.prototype.NextNodeAllOnSameLine = function () {
                if (this.nextNodeAllOnSameLine === undefined) {
                    this.nextNodeAllOnSameLine = this.NodeIsOnOneLine(this.nextTokenParent);
                }
                return this.nextNodeAllOnSameLine;
            };
            FormattingContext.prototype.TokensAreOnSameLine = function () {
                if (this.tokensAreOnSameLine === undefined) {
                    var startLine = this.sourceFile.getLineAndCharacterOfPosition(this.currentTokenSpan.pos).line;
                    var endLine = this.sourceFile.getLineAndCharacterOfPosition(this.nextTokenSpan.pos).line;
                    this.tokensAreOnSameLine = (startLine === endLine);
                }
                return this.tokensAreOnSameLine;
            };
            FormattingContext.prototype.ContextNodeBlockIsOnOneLine = function () {
                if (this.contextNodeBlockIsOnOneLine === undefined) {
                    this.contextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.contextNode);
                }
                return this.contextNodeBlockIsOnOneLine;
            };
            FormattingContext.prototype.NextNodeBlockIsOnOneLine = function () {
                if (this.nextNodeBlockIsOnOneLine === undefined) {
                    this.nextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.nextTokenParent);
                }
                return this.nextNodeBlockIsOnOneLine;
            };
            FormattingContext.prototype.NodeIsOnOneLine = function (node) {
                var startLine = this.sourceFile.getLineAndCharacterOfPosition(node.getStart(this.sourceFile)).line;
                var endLine = this.sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
                return startLine === endLine;
            };
            FormattingContext.prototype.BlockIsOnOneLine = function (node) {
                var openBrace = ts.findChildOfKind(node, 18 /* OpenBraceToken */, this.sourceFile);
                var closeBrace = ts.findChildOfKind(node, 19 /* CloseBraceToken */, this.sourceFile);
                if (openBrace && closeBrace) {
                    var startLine = this.sourceFile.getLineAndCharacterOfPosition(openBrace.getEnd()).line;
                    var endLine = this.sourceFile.getLineAndCharacterOfPosition(closeBrace.getStart(this.sourceFile)).line;
                    return startLine === endLine;
                }
                return false;
            };
            return FormattingContext;
        }());
        formatting.FormattingContext = FormattingContext;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var standardScanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ false, 0 /* Standard */);
        var jsxScanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ false, 1 /* JSX */);
        var ScanAction;
        (function (ScanAction) {
            ScanAction[ScanAction["Scan"] = 0] = "Scan";
            ScanAction[ScanAction["RescanGreaterThanToken"] = 1] = "RescanGreaterThanToken";
            ScanAction[ScanAction["RescanSlashToken"] = 2] = "RescanSlashToken";
            ScanAction[ScanAction["RescanTemplateToken"] = 3] = "RescanTemplateToken";
            ScanAction[ScanAction["RescanJsxIdentifier"] = 4] = "RescanJsxIdentifier";
            ScanAction[ScanAction["RescanJsxText"] = 5] = "RescanJsxText";
            ScanAction[ScanAction["RescanJsxAttributeValue"] = 6] = "RescanJsxAttributeValue";
        })(ScanAction || (ScanAction = {}));
        function getFormattingScanner(text, languageVariant, startPos, endPos, cb) {
            var scanner = languageVariant === 1 /* JSX */ ? jsxScanner : standardScanner;
            scanner.setText(text);
            scanner.setTextPos(startPos);
            var wasNewLine = true;
            var leadingTrivia;
            var trailingTrivia;
            var savedPos;
            var lastScanAction;
            var lastTokenInfo;
            var res = cb({
                advance: advance,
                readTokenInfo: readTokenInfo,
                readEOFTokenRange: readEOFTokenRange,
                isOnToken: isOnToken,
                isOnEOF: isOnEOF,
                getCurrentLeadingTrivia: function () { return leadingTrivia; },
                lastTrailingTriviaWasNewLine: function () { return wasNewLine; },
                skipToEndOf: skipToEndOf,
            });
            lastTokenInfo = undefined;
            scanner.setText(undefined);
            return res;
            function advance() {
                lastTokenInfo = undefined;
                var isStarted = scanner.getStartPos() !== startPos;
                if (isStarted) {
                    wasNewLine = !!trailingTrivia && ts.last(trailingTrivia).kind === 4 /* NewLineTrivia */;
                }
                else {
                    scanner.scan();
                }
                leadingTrivia = undefined;
                trailingTrivia = undefined;
                var pos = scanner.getStartPos();
                // Read leading trivia and token
                while (pos < endPos) {
                    var t = scanner.getToken();
                    if (!ts.isTrivia(t)) {
                        break;
                    }
                    // consume leading trivia
                    scanner.scan();
                    var item = {
                        pos: pos,
                        end: scanner.getStartPos(),
                        kind: t
                    };
                    pos = scanner.getStartPos();
                    leadingTrivia = ts.append(leadingTrivia, item);
                }
                savedPos = scanner.getStartPos();
            }
            function shouldRescanGreaterThanToken(node) {
                switch (node.kind) {
                    case 33 /* GreaterThanEqualsToken */:
                    case 70 /* GreaterThanGreaterThanEqualsToken */:
                    case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                    case 48 /* GreaterThanGreaterThanToken */:
                        return true;
                }
                return false;
            }
            function shouldRescanJsxIdentifier(node) {
                if (node.parent) {
                    switch (node.parent.kind) {
                        case 273 /* JsxAttribute */:
                        case 268 /* JsxOpeningElement */:
                        case 269 /* JsxClosingElement */:
                        case 267 /* JsxSelfClosingElement */:
                            // May parse an identifier like `module-layout`; that will be scanned as a keyword at first, but we should parse the whole thing to get an identifier.
                            return ts.isKeyword(node.kind) || node.kind === 75 /* Identifier */;
                    }
                }
                return false;
            }
            function shouldRescanJsxText(node) {
                var isJSXText = ts.isJsxText(node);
                if (isJSXText) {
                    var containingElement = ts.findAncestor(node.parent, function (p) { return ts.isJsxElement(p); });
                    if (!containingElement)
                        return false; // should never happen
                    return !ts.isParenthesizedExpression(containingElement.parent);
                }
                return false;
            }
            function shouldRescanSlashToken(container) {
                return container.kind === 13 /* RegularExpressionLiteral */;
            }
            function shouldRescanTemplateToken(container) {
                return container.kind === 16 /* TemplateMiddle */ ||
                    container.kind === 17 /* TemplateTail */;
            }
            function shouldRescanJsxAttributeValue(node) {
                return node.parent && ts.isJsxAttribute(node.parent) && node.parent.initializer === node;
            }
            function startsWithSlashToken(t) {
                return t === 43 /* SlashToken */ || t === 67 /* SlashEqualsToken */;
            }
            function readTokenInfo(n) {
                ts.Debug.assert(isOnToken());
                // normally scanner returns the smallest available token
                // check the kind of context node to determine if scanner should have more greedy behavior and consume more text.
                var expectedScanAction = shouldRescanGreaterThanToken(n) ? 1 /* RescanGreaterThanToken */ :
                    shouldRescanSlashToken(n) ? 2 /* RescanSlashToken */ :
                        shouldRescanTemplateToken(n) ? 3 /* RescanTemplateToken */ :
                            shouldRescanJsxIdentifier(n) ? 4 /* RescanJsxIdentifier */ :
                                shouldRescanJsxText(n) ? 5 /* RescanJsxText */ :
                                    shouldRescanJsxAttributeValue(n) ? 6 /* RescanJsxAttributeValue */ :
                                        0 /* Scan */;
                if (lastTokenInfo && expectedScanAction === lastScanAction) {
                    // readTokenInfo was called before with the same expected scan action.
                    // No need to re-scan text, return existing 'lastTokenInfo'
                    // it is ok to call fixTokenKind here since it does not affect
                    // what portion of text is consumed. In contrast rescanning can change it,
                    // i.e. for '>=' when originally scanner eats just one character
                    // and rescanning forces it to consume more.
                    return fixTokenKind(lastTokenInfo, n);
                }
                if (scanner.getStartPos() !== savedPos) {
                    ts.Debug.assert(lastTokenInfo !== undefined);
                    // readTokenInfo was called before but scan action differs - rescan text
                    scanner.setTextPos(savedPos);
                    scanner.scan();
                }
                var currentToken = getNextToken(n, expectedScanAction);
                var token = formatting.createTextRangeWithKind(scanner.getStartPos(), scanner.getTextPos(), currentToken);
                // consume trailing trivia
                if (trailingTrivia) {
                    trailingTrivia = undefined;
                }
                while (scanner.getStartPos() < endPos) {
                    currentToken = scanner.scan();
                    if (!ts.isTrivia(currentToken)) {
                        break;
                    }
                    var trivia = formatting.createTextRangeWithKind(scanner.getStartPos(), scanner.getTextPos(), currentToken);
                    if (!trailingTrivia) {
                        trailingTrivia = [];
                    }
                    trailingTrivia.push(trivia);
                    if (currentToken === 4 /* NewLineTrivia */) {
                        // move past new line
                        scanner.scan();
                        break;
                    }
                }
                lastTokenInfo = { leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia, token: token };
                return fixTokenKind(lastTokenInfo, n);
            }
            function getNextToken(n, expectedScanAction) {
                var token = scanner.getToken();
                lastScanAction = 0 /* Scan */;
                switch (expectedScanAction) {
                    case 1 /* RescanGreaterThanToken */:
                        if (token === 31 /* GreaterThanToken */) {
                            lastScanAction = 1 /* RescanGreaterThanToken */;
                            var newToken = scanner.reScanGreaterToken();
                            ts.Debug.assert(n.kind === newToken);
                            return newToken;
                        }
                        break;
                    case 2 /* RescanSlashToken */:
                        if (startsWithSlashToken(token)) {
                            lastScanAction = 2 /* RescanSlashToken */;
                            var newToken = scanner.reScanSlashToken();
                            ts.Debug.assert(n.kind === newToken);
                            return newToken;
                        }
                        break;
                    case 3 /* RescanTemplateToken */:
                        if (token === 19 /* CloseBraceToken */) {
                            lastScanAction = 3 /* RescanTemplateToken */;
                            return scanner.reScanTemplateToken(/* isTaggedTemplate */ false);
                        }
                        break;
                    case 4 /* RescanJsxIdentifier */:
                        lastScanAction = 4 /* RescanJsxIdentifier */;
                        return scanner.scanJsxIdentifier();
                    case 5 /* RescanJsxText */:
                        lastScanAction = 5 /* RescanJsxText */;
                        return scanner.reScanJsxToken();
                    case 6 /* RescanJsxAttributeValue */:
                        lastScanAction = 6 /* RescanJsxAttributeValue */;
                        return scanner.reScanJsxAttributeValue();
                    case 0 /* Scan */:
                        break;
                    default:
                        ts.Debug.assertNever(expectedScanAction);
                }
                return token;
            }
            function readEOFTokenRange() {
                ts.Debug.assert(isOnEOF());
                return formatting.createTextRangeWithKind(scanner.getStartPos(), scanner.getTextPos(), 1 /* EndOfFileToken */);
            }
            function isOnToken() {
                var current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken();
                var startPos = lastTokenInfo ? lastTokenInfo.token.pos : scanner.getStartPos();
                return startPos < endPos && current !== 1 /* EndOfFileToken */ && !ts.isTrivia(current);
            }
            function isOnEOF() {
                var current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken();
                return current === 1 /* EndOfFileToken */;
            }
            // when containing node in the tree is token
            // but its kind differs from the kind that was returned by the scanner,
            // then kind needs to be fixed. This might happen in cases
            // when parser interprets token differently, i.e keyword treated as identifier
            function fixTokenKind(tokenInfo, container) {
                if (ts.isToken(container) && tokenInfo.token.kind !== container.kind) {
                    tokenInfo.token.kind = container.kind;
                }
                return tokenInfo;
            }
            function skipToEndOf(node) {
                scanner.setTextPos(node.end);
                savedPos = scanner.getStartPos();
                lastScanAction = undefined;
                lastTokenInfo = undefined;
                wasNewLine = false;
                leadingTrivia = undefined;
                trailingTrivia = undefined;
            }
        }
        formatting.getFormattingScanner = getFormattingScanner;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        formatting.anyContext = ts.emptyArray;
        var RuleAction;
        (function (RuleAction) {
            RuleAction[RuleAction["StopProcessingSpaceActions"] = 1] = "StopProcessingSpaceActions";
            RuleAction[RuleAction["StopProcessingTokenActions"] = 2] = "StopProcessingTokenActions";
            RuleAction[RuleAction["InsertSpace"] = 4] = "InsertSpace";
            RuleAction[RuleAction["InsertNewLine"] = 8] = "InsertNewLine";
            RuleAction[RuleAction["DeleteSpace"] = 16] = "DeleteSpace";
            RuleAction[RuleAction["DeleteToken"] = 32] = "DeleteToken";
            RuleAction[RuleAction["InsertTrailingSemicolon"] = 64] = "InsertTrailingSemicolon";
            RuleAction[RuleAction["StopAction"] = 3] = "StopAction";
            RuleAction[RuleAction["ModifySpaceAction"] = 28] = "ModifySpaceAction";
            RuleAction[RuleAction["ModifyTokenAction"] = 96] = "ModifyTokenAction";
        })(RuleAction = formatting.RuleAction || (formatting.RuleAction = {}));
        var RuleFlags;
        (function (RuleFlags) {
            RuleFlags[RuleFlags["None"] = 0] = "None";
            RuleFlags[RuleFlags["CanDeleteNewLines"] = 1] = "CanDeleteNewLines";
        })(RuleFlags = formatting.RuleFlags || (formatting.RuleFlags = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        function getAllRules() {
            var allTokens = [];
            for (var token = 0 /* FirstToken */; token <= 152 /* LastToken */; token++) {
                if (token !== 1 /* EndOfFileToken */) {
                    allTokens.push(token);
                }
            }
            function anyTokenExcept() {
                var tokens = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    tokens[_i] = arguments[_i];
                }
                return { tokens: allTokens.filter(function (t) { return !tokens.some(function (t2) { return t2 === t; }); }), isSpecific: false };
            }
            var anyToken = { tokens: allTokens, isSpecific: false };
            var anyTokenIncludingMultilineComments = tokenRangeFrom(__spreadArrays(allTokens, [3 /* MultiLineCommentTrivia */]));
            var anyTokenIncludingEOF = tokenRangeFrom(__spreadArrays(allTokens, [1 /* EndOfFileToken */]));
            var keywords = tokenRangeFromRange(77 /* FirstKeyword */, 152 /* LastKeyword */);
            var binaryOperators = tokenRangeFromRange(29 /* FirstBinaryOperator */, 74 /* LastBinaryOperator */);
            var binaryKeywordOperators = [97 /* InKeyword */, 98 /* InstanceOfKeyword */, 152 /* OfKeyword */, 123 /* AsKeyword */, 133 /* IsKeyword */];
            var unaryPrefixOperators = [45 /* PlusPlusToken */, 46 /* MinusMinusToken */, 54 /* TildeToken */, 53 /* ExclamationToken */];
            var unaryPrefixExpressions = [
                8 /* NumericLiteral */, 9 /* BigIntLiteral */, 75 /* Identifier */, 20 /* OpenParenToken */,
                22 /* OpenBracketToken */, 18 /* OpenBraceToken */, 104 /* ThisKeyword */, 99 /* NewKeyword */
            ];
            var unaryPreincrementExpressions = [75 /* Identifier */, 20 /* OpenParenToken */, 104 /* ThisKeyword */, 99 /* NewKeyword */];
            var unaryPostincrementExpressions = [75 /* Identifier */, 21 /* CloseParenToken */, 23 /* CloseBracketToken */, 99 /* NewKeyword */];
            var unaryPredecrementExpressions = [75 /* Identifier */, 20 /* OpenParenToken */, 104 /* ThisKeyword */, 99 /* NewKeyword */];
            var unaryPostdecrementExpressions = [75 /* Identifier */, 21 /* CloseParenToken */, 23 /* CloseBracketToken */, 99 /* NewKeyword */];
            var comments = [2 /* SingleLineCommentTrivia */, 3 /* MultiLineCommentTrivia */];
            var typeNames = __spreadArrays([75 /* Identifier */], ts.typeKeywords);
            // Place a space before open brace in a function declaration
            // TypeScript: Function can have return types, which can be made of tons of different token kinds
            var functionOpenBraceLeftTokenRange = anyTokenIncludingMultilineComments;
            // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc)
            var typeScriptOpenBraceLeftTokenRange = tokenRangeFrom([75 /* Identifier */, 3 /* MultiLineCommentTrivia */, 80 /* ClassKeyword */, 89 /* ExportKeyword */, 96 /* ImportKeyword */]);
            // Place a space before open brace in a control flow construct
            var controlOpenBraceLeftTokenRange = tokenRangeFrom([21 /* CloseParenToken */, 3 /* MultiLineCommentTrivia */, 86 /* DoKeyword */, 107 /* TryKeyword */, 92 /* FinallyKeyword */, 87 /* ElseKeyword */]);
            // These rules are higher in priority than user-configurable
            var highPriorityCommonRules = [
                // Leave comments alone
                rule("IgnoreBeforeComment", anyToken, comments, formatting.anyContext, 1 /* StopProcessingSpaceActions */),
                rule("IgnoreAfterLineComment", 2 /* SingleLineCommentTrivia */, anyToken, formatting.anyContext, 1 /* StopProcessingSpaceActions */),
                rule("NotSpaceBeforeColon", anyToken, 58 /* ColonToken */, [isNonJsxSameLineTokenContext, isNotBinaryOpContext, isNotTypeAnnotationContext], 16 /* DeleteSpace */),
                rule("SpaceAfterColon", 58 /* ColonToken */, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 4 /* InsertSpace */),
                rule("NoSpaceBeforeQuestionMark", anyToken, 57 /* QuestionToken */, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 16 /* DeleteSpace */),
                // insert space after '?' only when it is used in conditional operator
                rule("SpaceAfterQuestionMarkInConditionalOperator", 57 /* QuestionToken */, anyToken, [isNonJsxSameLineTokenContext, isConditionalOperatorContext], 4 /* InsertSpace */),
                // in other cases there should be no space between '?' and next token
                rule("NoSpaceAfterQuestionMark", 57 /* QuestionToken */, anyToken, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeDot", anyToken, [24 /* DotToken */, 28 /* QuestionDotToken */], [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterDot", [24 /* DotToken */, 28 /* QuestionDotToken */], anyToken, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceBetweenImportParenInImportType", 96 /* ImportKeyword */, 20 /* OpenParenToken */, [isNonJsxSameLineTokenContext, isImportTypeContext], 16 /* DeleteSpace */),
                // Special handling of unary operators.
                // Prefix operators generally shouldn't have a space between
                // them and their target unary expression.
                rule("NoSpaceAfterUnaryPrefixOperator", unaryPrefixOperators, unaryPrefixExpressions, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterUnaryPreincrementOperator", 45 /* PlusPlusToken */, unaryPreincrementExpressions, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterUnaryPredecrementOperator", 46 /* MinusMinusToken */, unaryPredecrementExpressions, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeUnaryPostincrementOperator", unaryPostincrementExpressions, 45 /* PlusPlusToken */, [isNonJsxSameLineTokenContext, isNotStatementConditionContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, 46 /* MinusMinusToken */, [isNonJsxSameLineTokenContext, isNotStatementConditionContext], 16 /* DeleteSpace */),
                // More unary operator special-casing.
                // DevDiv 181814: Be careful when removing leading whitespace
                // around unary operators.  Examples:
                //      1 - -2  --X--> 1--2
                //      a + ++b --X--> a+++b
                rule("SpaceAfterPostincrementWhenFollowedByAdd", 45 /* PlusPlusToken */, 39 /* PlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("SpaceAfterAddWhenFollowedByUnaryPlus", 39 /* PlusToken */, 39 /* PlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("SpaceAfterAddWhenFollowedByPreincrement", 39 /* PlusToken */, 45 /* PlusPlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("SpaceAfterPostdecrementWhenFollowedBySubtract", 46 /* MinusMinusToken */, 40 /* MinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", 40 /* MinusToken */, 40 /* MinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("SpaceAfterSubtractWhenFollowedByPredecrement", 40 /* MinusToken */, 46 /* MinusMinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterCloseBrace", 19 /* CloseBraceToken */, [27 /* CommaToken */, 26 /* SemicolonToken */], [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // For functions and control block place } on a new line [multi-line rule]
                rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, 19 /* CloseBraceToken */, [isMultilineBlockContext], 8 /* InsertNewLine */),
                // Space/new line after }.
                rule("SpaceAfterCloseBrace", 19 /* CloseBraceToken */, anyTokenExcept(21 /* CloseParenToken */), [isNonJsxSameLineTokenContext, isAfterCodeBlockContext], 4 /* InsertSpace */),
                // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied
                // Also should not apply to })
                rule("SpaceBetweenCloseBraceAndElse", 19 /* CloseBraceToken */, 87 /* ElseKeyword */, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceBetweenCloseBraceAndWhile", 19 /* CloseBraceToken */, 111 /* WhileKeyword */, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("NoSpaceBetweenEmptyBraceBrackets", 18 /* OpenBraceToken */, 19 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectContext], 16 /* DeleteSpace */),
                // Add a space after control dec context if the next character is an open bracket ex: 'if (false)[a, b] = [1, 2];' -> 'if (false) [a, b] = [1, 2];'
                rule("SpaceAfterConditionalClosingParen", 21 /* CloseParenToken */, 22 /* OpenBracketToken */, [isControlDeclContext], 4 /* InsertSpace */),
                rule("NoSpaceBetweenFunctionKeywordAndStar", 94 /* FunctionKeyword */, 41 /* AsteriskToken */, [isFunctionDeclarationOrFunctionExpressionContext], 16 /* DeleteSpace */),
                rule("SpaceAfterStarInGeneratorDeclaration", 41 /* AsteriskToken */, 75 /* Identifier */, [isFunctionDeclarationOrFunctionExpressionContext], 4 /* InsertSpace */),
                rule("SpaceAfterFunctionInFuncDecl", 94 /* FunctionKeyword */, anyToken, [isFunctionDeclContext], 4 /* InsertSpace */),
                // Insert new line after { and before } in multi-line contexts.
                rule("NewLineAfterOpenBraceInBlockContext", 18 /* OpenBraceToken */, anyToken, [isMultilineBlockContext], 8 /* InsertNewLine */),
                // For get/set members, we check for (identifier,identifier) since get/set don't have tokens and they are represented as just an identifier token.
                // Though, we do extra check on the context to make sure we are dealing with get/set node. Example:
                //      get x() {}
                //      set x(val) {}
                rule("SpaceAfterGetSetInMember", [131 /* GetKeyword */, 142 /* SetKeyword */], 75 /* Identifier */, [isFunctionDeclContext], 4 /* InsertSpace */),
                rule("NoSpaceBetweenYieldKeywordAndStar", 121 /* YieldKeyword */, 41 /* AsteriskToken */, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], 16 /* DeleteSpace */),
                rule("SpaceBetweenYieldOrYieldStarAndOperand", [121 /* YieldKeyword */, 41 /* AsteriskToken */], anyToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], 4 /* InsertSpace */),
                rule("NoSpaceBetweenReturnAndSemicolon", 101 /* ReturnKeyword */, 26 /* SemicolonToken */, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("SpaceAfterCertainKeywords", [109 /* VarKeyword */, 105 /* ThrowKeyword */, 99 /* NewKeyword */, 85 /* DeleteKeyword */, 101 /* ReturnKeyword */, 108 /* TypeOfKeyword */, 127 /* AwaitKeyword */], anyToken, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceAfterLetConstInVariableDeclaration", [115 /* LetKeyword */, 81 /* ConstKeyword */], anyToken, [isNonJsxSameLineTokenContext, isStartOfVariableDeclarationList], 4 /* InsertSpace */),
                rule("NoSpaceBeforeOpenParenInFuncCall", anyToken, 20 /* OpenParenToken */, [isNonJsxSameLineTokenContext, isFunctionCallOrNewContext, isPreviousTokenNotComma], 16 /* DeleteSpace */),
                // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options.
                rule("SpaceBeforeBinaryKeywordOperator", anyToken, binaryKeywordOperators, [isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("SpaceAfterBinaryKeywordOperator", binaryKeywordOperators, anyToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("SpaceAfterVoidOperator", 110 /* VoidKeyword */, anyToken, [isNonJsxSameLineTokenContext, isVoidOpContext], 4 /* InsertSpace */),
                // Async-await
                rule("SpaceBetweenAsyncAndOpenParen", 126 /* AsyncKeyword */, 20 /* OpenParenToken */, [isArrowFunctionContext, isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceBetweenAsyncAndFunctionKeyword", 126 /* AsyncKeyword */, [94 /* FunctionKeyword */, 75 /* Identifier */], [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                // Template string
                rule("NoSpaceBetweenTagAndTemplateString", [75 /* Identifier */, 21 /* CloseParenToken */], [14 /* NoSubstitutionTemplateLiteral */, 15 /* TemplateHead */], [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // JSX opening elements
                rule("SpaceBeforeJsxAttribute", anyToken, 75 /* Identifier */, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceBeforeSlashInJsxOpeningElement", anyToken, 43 /* SlashToken */, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("NoSpaceBeforeGreaterThanTokenInJsxOpeningElement", 43 /* SlashToken */, 31 /* GreaterThanToken */, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeEqualInJsxAttribute", anyToken, 62 /* EqualsToken */, [isJsxAttributeContext, isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterEqualInJsxAttribute", 62 /* EqualsToken */, anyToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // TypeScript-specific rules
                // Use of module as a function call. e.g.: import m2 = module("m2");
                rule("NoSpaceAfterModuleImport", [135 /* ModuleKeyword */, 139 /* RequireKeyword */], 20 /* OpenParenToken */, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // Add a space around certain TypeScript keywords
                rule("SpaceAfterCertainTypeScriptKeywords", [
                    122 /* AbstractKeyword */,
                    80 /* ClassKeyword */,
                    130 /* DeclareKeyword */,
                    84 /* DefaultKeyword */,
                    88 /* EnumKeyword */,
                    89 /* ExportKeyword */,
                    90 /* ExtendsKeyword */,
                    131 /* GetKeyword */,
                    113 /* ImplementsKeyword */,
                    96 /* ImportKeyword */,
                    114 /* InterfaceKeyword */,
                    135 /* ModuleKeyword */,
                    136 /* NamespaceKeyword */,
                    117 /* PrivateKeyword */,
                    119 /* PublicKeyword */,
                    118 /* ProtectedKeyword */,
                    138 /* ReadonlyKeyword */,
                    142 /* SetKeyword */,
                    120 /* StaticKeyword */,
                    145 /* TypeKeyword */,
                    149 /* FromKeyword */,
                    134 /* KeyOfKeyword */,
                    132 /* InferKeyword */,
                ], anyToken, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceBeforeCertainTypeScriptKeywords", anyToken, [90 /* ExtendsKeyword */, 113 /* ImplementsKeyword */, 149 /* FromKeyword */], [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
                rule("SpaceAfterModuleName", 10 /* StringLiteral */, 18 /* OpenBraceToken */, [isModuleDeclContext], 4 /* InsertSpace */),
                // Lambda expressions
                rule("SpaceBeforeArrow", anyToken, 38 /* EqualsGreaterThanToken */, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceAfterArrow", 38 /* EqualsGreaterThanToken */, anyToken, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                // Optional parameters and let args
                rule("NoSpaceAfterEllipsis", 25 /* DotDotDotToken */, 75 /* Identifier */, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterOptionalParameters", 57 /* QuestionToken */, [21 /* CloseParenToken */, 27 /* CommaToken */], [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 16 /* DeleteSpace */),
                // Remove spaces in empty interface literals. e.g.: x: {}
                rule("NoSpaceBetweenEmptyInterfaceBraceBrackets", 18 /* OpenBraceToken */, 19 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectTypeContext], 16 /* DeleteSpace */),
                // generics and type assertions
                rule("NoSpaceBeforeOpenAngularBracket", typeNames, 29 /* LessThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 16 /* DeleteSpace */),
                rule("NoSpaceBetweenCloseParenAndAngularBracket", 21 /* CloseParenToken */, 29 /* LessThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterOpenAngularBracket", 29 /* LessThanToken */, anyToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeCloseAngularBracket", anyToken, 31 /* GreaterThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterCloseAngularBracket", 31 /* GreaterThanToken */, [20 /* OpenParenToken */, 22 /* OpenBracketToken */, 31 /* GreaterThanToken */, 27 /* CommaToken */], [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext, isNotFunctionDeclContext /*To prevent an interference with the SpaceBeforeOpenParenInFuncDecl rule*/], 16 /* DeleteSpace */),
                // decorators
                rule("SpaceBeforeAt", [21 /* CloseParenToken */, 75 /* Identifier */], 59 /* AtToken */, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterAt", 59 /* AtToken */, anyToken, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // Insert space after @ in decorator
                rule("SpaceAfterDecorator", anyToken, [
                    122 /* AbstractKeyword */,
                    75 /* Identifier */,
                    89 /* ExportKeyword */,
                    84 /* DefaultKeyword */,
                    80 /* ClassKeyword */,
                    120 /* StaticKeyword */,
                    119 /* PublicKeyword */,
                    117 /* PrivateKeyword */,
                    118 /* ProtectedKeyword */,
                    131 /* GetKeyword */,
                    142 /* SetKeyword */,
                    22 /* OpenBracketToken */,
                    41 /* AsteriskToken */,
                ], [isEndOfDecoratorContextOnSameLine], 4 /* InsertSpace */),
                rule("NoSpaceBeforeNonNullAssertionOperator", anyToken, 53 /* ExclamationToken */, [isNonJsxSameLineTokenContext, isNonNullAssertionContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterNewKeywordOnConstructorSignature", 99 /* NewKeyword */, 20 /* OpenParenToken */, [isNonJsxSameLineTokenContext, isConstructorSignatureContext], 16 /* DeleteSpace */),
                rule("SpaceLessThanAndNonJSXTypeAnnotation", 29 /* LessThanToken */, 29 /* LessThanToken */, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
            ];
            // These rules are applied after high priority
            var userConfigurableRules = [
                // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
                rule("SpaceAfterConstructor", 129 /* ConstructorKeyword */, 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterConstructor", 129 /* ConstructorKeyword */, 20 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("SpaceAfterComma", 27 /* CommaToken */, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNextTokenNotCloseBracket, isNextTokenNotCloseParen], 4 /* InsertSpace */),
                rule("NoSpaceAfterComma", 27 /* CommaToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext], 16 /* DeleteSpace */),
                // Insert space after function keyword for anonymous functions
                rule("SpaceAfterAnonymousFunctionKeyword", [94 /* FunctionKeyword */, 41 /* AsteriskToken */], 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterAnonymousFunctionKeyword", [94 /* FunctionKeyword */, 41 /* AsteriskToken */], 20 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], 16 /* DeleteSpace */),
                // Insert space after keywords in control flow statements
                rule("SpaceAfterKeywordInControl", keywords, 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterKeywordInControl", keywords, 20 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], 16 /* DeleteSpace */),
                // Insert space after opening and before closing nonempty parenthesis
                rule("SpaceAfterOpenParen", 20 /* OpenParenToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceBeforeCloseParen", anyToken, 21 /* CloseParenToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceBetweenOpenParens", 20 /* OpenParenToken */, 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("NoSpaceBetweenParens", 20 /* OpenParenToken */, 21 /* CloseParenToken */, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterOpenParen", 20 /* OpenParenToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeCloseParen", anyToken, 21 /* CloseParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // Insert space after opening and before closing nonempty brackets
                rule("SpaceAfterOpenBracket", 22 /* OpenBracketToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceBeforeCloseBracket", anyToken, 23 /* CloseBracketToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("NoSpaceBetweenBrackets", 22 /* OpenBracketToken */, 23 /* CloseBracketToken */, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterOpenBracket", 22 /* OpenBracketToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeCloseBracket", anyToken, 23 /* CloseBracketToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
                rule("SpaceAfterOpenBrace", 18 /* OpenBraceToken */, anyToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], 4 /* InsertSpace */),
                rule("SpaceBeforeCloseBrace", anyToken, 19 /* CloseBraceToken */, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], 4 /* InsertSpace */),
                rule("NoSpaceBetweenEmptyBraceBrackets", 18 /* OpenBraceToken */, 19 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterOpenBrace", 18 /* OpenBraceToken */, anyToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeCloseBrace", anyToken, 19 /* CloseBraceToken */, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // Insert a space after opening and before closing empty brace brackets
                rule("SpaceBetweenEmptyBraceBrackets", 18 /* OpenBraceToken */, 19 /* CloseBraceToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingEmptyBraces")], 4 /* InsertSpace */),
                rule("NoSpaceBetweenEmptyBraceBrackets", 18 /* OpenBraceToken */, 19 /* CloseBraceToken */, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingEmptyBraces"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // Insert space after opening and before closing template string braces
                rule("SpaceAfterTemplateHeadAndMiddle", [15 /* TemplateHead */, 16 /* TemplateMiddle */], anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("SpaceBeforeTemplateMiddleAndTail", anyToken, [16 /* TemplateMiddle */, 17 /* TemplateTail */], [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterTemplateHeadAndMiddle", [15 /* TemplateHead */, 16 /* TemplateMiddle */], anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeTemplateMiddleAndTail", anyToken, [16 /* TemplateMiddle */, 17 /* TemplateTail */], [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // No space after { and before } in JSX expression
                rule("SpaceAfterOpenBraceInJsxExpression", 18 /* OpenBraceToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 4 /* InsertSpace */),
                rule("SpaceBeforeCloseBraceInJsxExpression", anyToken, 19 /* CloseBraceToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterOpenBraceInJsxExpression", 18 /* OpenBraceToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 16 /* DeleteSpace */),
                rule("NoSpaceBeforeCloseBraceInJsxExpression", anyToken, 19 /* CloseBraceToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 16 /* DeleteSpace */),
                // Insert space after semicolon in for statement
                rule("SpaceAfterSemicolonInFor", 26 /* SemicolonToken */, anyToken, [isOptionEnabled("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterSemicolonInFor", 26 /* SemicolonToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], 16 /* DeleteSpace */),
                // Insert space before and after binary operators
                rule("SpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("SpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 4 /* InsertSpace */),
                rule("NoSpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 16 /* DeleteSpace */),
                rule("SpaceBeforeOpenParenInFuncDecl", anyToken, 20 /* OpenParenToken */, [isOptionEnabled("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], 4 /* InsertSpace */),
                rule("NoSpaceBeforeOpenParenInFuncDecl", anyToken, 20 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], 16 /* DeleteSpace */),
                // Open Brace braces after control block
                rule("NewLineBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isBeforeMultilineBlockContext], 8 /* InsertNewLine */, 1 /* CanDeleteNewLines */),
                // Open Brace braces after function
                // TypeScript: Function can have return types, which can be made of tons of different token kinds
                rule("NewLineBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeMultilineBlockContext], 8 /* InsertNewLine */, 1 /* CanDeleteNewLines */),
                // Open Brace braces after TypeScript module/class/interface
                rule("NewLineBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isBeforeMultilineBlockContext], 8 /* InsertNewLine */, 1 /* CanDeleteNewLines */),
                rule("SpaceAfterTypeAssertion", 31 /* GreaterThanToken */, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], 4 /* InsertSpace */),
                rule("NoSpaceAfterTypeAssertion", 31 /* GreaterThanToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], 16 /* DeleteSpace */),
                rule("SpaceBeforeTypeAnnotation", anyToken, 58 /* ColonToken */, [isOptionEnabled("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], 4 /* InsertSpace */),
                rule("NoSpaceBeforeTypeAnnotation", anyToken, 58 /* ColonToken */, [isOptionDisabledOrUndefined("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], 16 /* DeleteSpace */),
                rule("NoOptionalSemicolon", 26 /* SemicolonToken */, anyTokenIncludingEOF, [optionEquals("semicolons", ts.SemicolonPreference.Remove), isSemicolonDeletionContext], 32 /* DeleteToken */),
                rule("OptionalSemicolon", anyToken, anyTokenIncludingEOF, [optionEquals("semicolons", ts.SemicolonPreference.Insert), isSemicolonInsertionContext], 64 /* InsertTrailingSemicolon */),
            ];
            // These rules are lower in priority than user-configurable. Rules earlier in this list have priority over rules later in the list.
            var lowPriorityCommonRules = [
                // Space after keyword but not before ; or : or ?
                rule("NoSpaceBeforeSemicolon", anyToken, 26 /* SemicolonToken */, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("SpaceBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 4 /* InsertSpace */, 1 /* CanDeleteNewLines */),
                rule("SpaceBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 4 /* InsertSpace */, 1 /* CanDeleteNewLines */),
                rule("SpaceBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, 18 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 4 /* InsertSpace */, 1 /* CanDeleteNewLines */),
                rule("NoSpaceBeforeComma", anyToken, 27 /* CommaToken */, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                // No space before and after indexer `x[]`
                rule("NoSpaceBeforeOpenBracket", anyTokenExcept(126 /* AsyncKeyword */, 78 /* CaseKeyword */), 22 /* OpenBracketToken */, [isNonJsxSameLineTokenContext], 16 /* DeleteSpace */),
                rule("NoSpaceAfterCloseBracket", 23 /* CloseBracketToken */, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], 16 /* DeleteSpace */),
                rule("SpaceAfterSemicolon", 26 /* SemicolonToken */, anyToken, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                // Remove extra space between for and await
                rule("SpaceBetweenForAndAwaitKeyword", 93 /* ForKeyword */, 127 /* AwaitKeyword */, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
                // Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
                // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
                rule("SpaceBetweenStatements", [21 /* CloseParenToken */, 86 /* DoKeyword */, 87 /* ElseKeyword */, 78 /* CaseKeyword */], anyToken, [isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNotForContext], 4 /* InsertSpace */),
                // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
                rule("SpaceAfterTryFinally", [107 /* TryKeyword */, 92 /* FinallyKeyword */], 18 /* OpenBraceToken */, [isNonJsxSameLineTokenContext], 4 /* InsertSpace */),
            ];
            return __spreadArrays(highPriorityCommonRules, userConfigurableRules, lowPriorityCommonRules);
        }
        formatting.getAllRules = getAllRules;
        /**
         * A rule takes a two tokens (left/right) and a particular context
         * for which you're meant to look at them. You then declare what should the
         * whitespace annotation be between these tokens via the action param.
         *
         * @param debugName Name to print
         * @param left The left side of the comparison
         * @param right The right side of the comparison
         * @param context A set of filters to narrow down the space in which this formatter rule applies
         * @param action a declaration of the expected whitespace
         * @param flags whether the rule deletes a line or not, defaults to no-op
         */
        function rule(debugName, left, right, context, action, flags) {
            if (flags === void 0) { flags = 0 /* None */; }
            return { leftTokenRange: toTokenRange(left), rightTokenRange: toTokenRange(right), rule: { debugName: debugName, context: context, action: action, flags: flags } };
        }
        function tokenRangeFrom(tokens) {
            return { tokens: tokens, isSpecific: true };
        }
        function toTokenRange(arg) {
            return typeof arg === "number" ? tokenRangeFrom([arg]) : ts.isArray(arg) ? tokenRangeFrom(arg) : arg;
        }
        function tokenRangeFromRange(from, to, except) {
            if (except === void 0) { except = []; }
            var tokens = [];
            for (var token = from; token <= to; token++) {
                if (!ts.contains(except, token)) {
                    tokens.push(token);
                }
            }
            return tokenRangeFrom(tokens);
        }
        ///
        /// Contexts
        ///
        function optionEquals(optionName, optionValue) {
            return function (context) { return context.options && context.options[optionName] === optionValue; };
        }
        function isOptionEnabled(optionName) {
            return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; };
        }
        function isOptionDisabled(optionName) {
            return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; };
        }
        function isOptionDisabledOrUndefined(optionName) {
            return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; };
        }
        function isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName) {
            return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); };
        }
        function isOptionEnabledOrUndefined(optionName) {
            return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; };
        }
        function isForContext(context) {
            return context.contextNode.kind === 230 /* ForStatement */;
        }
        function isNotForContext(context) {
            return !isForContext(context);
        }
        function isBinaryOpContext(context) {
            switch (context.contextNode.kind) {
                case 209 /* BinaryExpression */:
                    return context.contextNode.operatorToken.kind !== 27 /* CommaToken */;
                case 210 /* ConditionalExpression */:
                case 180 /* ConditionalType */:
                case 217 /* AsExpression */:
                case 263 /* ExportSpecifier */:
                case 258 /* ImportSpecifier */:
                case 168 /* TypePredicate */:
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                    return true;
                // equals in binding elements: function foo([[x, y] = [1, 2]])
                case 191 /* BindingElement */:
                // equals in type X = ...
                // falls through
                case 247 /* TypeAliasDeclaration */:
                // equal in import a = module('a');
                // falls through
                case 253 /* ImportEqualsDeclaration */:
                // equal in let a = 0
                // falls through
                case 242 /* VariableDeclaration */:
                // equal in p = 0
                // falls through
                case 156 /* Parameter */:
                case 284 /* EnumMember */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    return context.currentTokenSpan.kind === 62 /* EqualsToken */ || context.nextTokenSpan.kind === 62 /* EqualsToken */;
                // "in" keyword in for (let x in []) { }
                case 231 /* ForInStatement */:
                // "in" keyword in [P in keyof T]: T[P]
                // falls through
                case 155 /* TypeParameter */:
                    return context.currentTokenSpan.kind === 97 /* InKeyword */ || context.nextTokenSpan.kind === 97 /* InKeyword */ || context.currentTokenSpan.kind === 62 /* EqualsToken */ || context.nextTokenSpan.kind === 62 /* EqualsToken */;
                // Technically, "of" is not a binary operator, but format it the same way as "in"
                case 232 /* ForOfStatement */:
                    return context.currentTokenSpan.kind === 152 /* OfKeyword */ || context.nextTokenSpan.kind === 152 /* OfKeyword */;
            }
            return false;
        }
        function isNotBinaryOpContext(context) {
            return !isBinaryOpContext(context);
        }
        function isNotTypeAnnotationContext(context) {
            return !isTypeAnnotationContext(context);
        }
        function isTypeAnnotationContext(context) {
            var contextKind = context.contextNode.kind;
            return contextKind === 159 /* PropertyDeclaration */ ||
                contextKind === 158 /* PropertySignature */ ||
                contextKind === 156 /* Parameter */ ||
                contextKind === 242 /* VariableDeclaration */ ||
                ts.isFunctionLikeKind(contextKind);
        }
        function isConditionalOperatorContext(context) {
            return context.contextNode.kind === 210 /* ConditionalExpression */ ||
                context.contextNode.kind === 180 /* ConditionalType */;
        }
        function isSameLineTokenOrBeforeBlockContext(context) {
            return context.TokensAreOnSameLine() || isBeforeBlockContext(context);
        }
        function isBraceWrappedContext(context) {
            return context.contextNode.kind === 189 /* ObjectBindingPattern */ ||
                context.contextNode.kind === 186 /* MappedType */ ||
                isSingleLineBlockContext(context);
        }
        // This check is done before an open brace in a control construct, a function, or a typescript block declaration
        function isBeforeMultilineBlockContext(context) {
            return isBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
        }
        function isMultilineBlockContext(context) {
            return isBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
        }
        function isSingleLineBlockContext(context) {
            return isBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
        }
        function isBlockContext(context) {
            return nodeIsBlockContext(context.contextNode);
        }
        function isBeforeBlockContext(context) {
            return nodeIsBlockContext(context.nextTokenParent);
        }
        // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children
        function nodeIsBlockContext(node) {
            if (nodeIsTypeScriptDeclWithBlockContext(node)) {
                // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc).
                return true;
            }
            switch (node.kind) {
                case 223 /* Block */:
                case 251 /* CaseBlock */:
                case 193 /* ObjectLiteralExpression */:
                case 250 /* ModuleBlock */:
                    return true;
            }
            return false;
        }
        function isFunctionDeclContext(context) {
            switch (context.contextNode.kind) {
                case 244 /* FunctionDeclaration */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                // case SyntaxKind.MemberFunctionDeclaration:
                // falls through
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                // case SyntaxKind.MethodSignature:
                // falls through
                case 165 /* CallSignature */:
                case 201 /* FunctionExpression */:
                case 162 /* Constructor */:
                case 202 /* ArrowFunction */:
                // case SyntaxKind.ConstructorDeclaration:
                // case SyntaxKind.SimpleArrowFunctionExpression:
                // case SyntaxKind.ParenthesizedArrowFunctionExpression:
                // falls through
                case 246 /* InterfaceDeclaration */: // This one is not truly a function, but for formatting purposes, it acts just like one
                    return true;
            }
            return false;
        }
        function isNotFunctionDeclContext(context) {
            return !isFunctionDeclContext(context);
        }
        function isFunctionDeclarationOrFunctionExpressionContext(context) {
            return context.contextNode.kind === 244 /* FunctionDeclaration */ || context.contextNode.kind === 201 /* FunctionExpression */;
        }
        function isTypeScriptDeclWithBlockContext(context) {
            return nodeIsTypeScriptDeclWithBlockContext(context.contextNode);
        }
        function nodeIsTypeScriptDeclWithBlockContext(node) {
            switch (node.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                case 246 /* InterfaceDeclaration */:
                case 248 /* EnumDeclaration */:
                case 173 /* TypeLiteral */:
                case 249 /* ModuleDeclaration */:
                case 260 /* ExportDeclaration */:
                case 261 /* NamedExports */:
                case 254 /* ImportDeclaration */:
                case 257 /* NamedImports */:
                    return true;
            }
            return false;
        }
        function isAfterCodeBlockContext(context) {
            switch (context.currentTokenParent.kind) {
                case 245 /* ClassDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 248 /* EnumDeclaration */:
                case 280 /* CatchClause */:
                case 250 /* ModuleBlock */:
                case 237 /* SwitchStatement */:
                    return true;
                case 223 /* Block */: {
                    var blockParent = context.currentTokenParent.parent;
                    // In a codefix scenario, we can't rely on parents being set. So just always return true.
                    if (!blockParent || blockParent.kind !== 202 /* ArrowFunction */ && blockParent.kind !== 201 /* FunctionExpression */) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isControlDeclContext(context) {
            switch (context.contextNode.kind) {
                case 227 /* IfStatement */:
                case 237 /* SwitchStatement */:
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                case 229 /* WhileStatement */:
                case 240 /* TryStatement */:
                case 228 /* DoStatement */:
                case 236 /* WithStatement */:
                // TODO
                // case SyntaxKind.ElseClause:
                // falls through
                case 280 /* CatchClause */:
                    return true;
                default:
                    return false;
            }
        }
        function isObjectContext(context) {
            return context.contextNode.kind === 193 /* ObjectLiteralExpression */;
        }
        function isFunctionCallContext(context) {
            return context.contextNode.kind === 196 /* CallExpression */;
        }
        function isNewContext(context) {
            return context.contextNode.kind === 197 /* NewExpression */;
        }
        function isFunctionCallOrNewContext(context) {
            return isFunctionCallContext(context) || isNewContext(context);
        }
        function isPreviousTokenNotComma(context) {
            return context.currentTokenSpan.kind !== 27 /* CommaToken */;
        }
        function isNextTokenNotCloseBracket(context) {
            return context.nextTokenSpan.kind !== 23 /* CloseBracketToken */;
        }
        function isNextTokenNotCloseParen(context) {
            return context.nextTokenSpan.kind !== 21 /* CloseParenToken */;
        }
        function isArrowFunctionContext(context) {
            return context.contextNode.kind === 202 /* ArrowFunction */;
        }
        function isImportTypeContext(context) {
            return context.contextNode.kind === 188 /* ImportType */;
        }
        function isNonJsxSameLineTokenContext(context) {
            return context.TokensAreOnSameLine() && context.contextNode.kind !== 11 /* JsxText */;
        }
        function isNonJsxElementOrFragmentContext(context) {
            return context.contextNode.kind !== 266 /* JsxElement */ && context.contextNode.kind !== 270 /* JsxFragment */;
        }
        function isJsxExpressionContext(context) {
            return context.contextNode.kind === 276 /* JsxExpression */ || context.contextNode.kind === 275 /* JsxSpreadAttribute */;
        }
        function isNextTokenParentJsxAttribute(context) {
            return context.nextTokenParent.kind === 273 /* JsxAttribute */;
        }
        function isJsxAttributeContext(context) {
            return context.contextNode.kind === 273 /* JsxAttribute */;
        }
        function isJsxSelfClosingElementContext(context) {
            return context.contextNode.kind === 267 /* JsxSelfClosingElement */;
        }
        function isNotBeforeBlockInFunctionDeclarationContext(context) {
            return !isFunctionDeclContext(context) && !isBeforeBlockContext(context);
        }
        function isEndOfDecoratorContextOnSameLine(context) {
            return context.TokensAreOnSameLine() &&
                !!context.contextNode.decorators &&
                nodeIsInDecoratorContext(context.currentTokenParent) &&
                !nodeIsInDecoratorContext(context.nextTokenParent);
        }
        function nodeIsInDecoratorContext(node) {
            while (ts.isExpressionNode(node)) {
                node = node.parent;
            }
            return node.kind === 157 /* Decorator */;
        }
        function isStartOfVariableDeclarationList(context) {
            return context.currentTokenParent.kind === 243 /* VariableDeclarationList */ &&
                context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos;
        }
        function isNotFormatOnEnter(context) {
            return context.formattingRequestKind !== 2 /* FormatOnEnter */;
        }
        function isModuleDeclContext(context) {
            return context.contextNode.kind === 249 /* ModuleDeclaration */;
        }
        function isObjectTypeContext(context) {
            return context.contextNode.kind === 173 /* TypeLiteral */; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration;
        }
        function isConstructorSignatureContext(context) {
            return context.contextNode.kind === 166 /* ConstructSignature */;
        }
        function isTypeArgumentOrParameterOrAssertion(token, parent) {
            if (token.kind !== 29 /* LessThanToken */ && token.kind !== 31 /* GreaterThanToken */) {
                return false;
            }
            switch (parent.kind) {
                case 169 /* TypeReference */:
                case 199 /* TypeAssertionExpression */:
                case 247 /* TypeAliasDeclaration */:
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                case 246 /* InterfaceDeclaration */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 196 /* CallExpression */:
                case 197 /* NewExpression */:
                case 216 /* ExpressionWithTypeArguments */:
                    return true;
                default:
                    return false;
            }
        }
        function isTypeArgumentOrParameterOrAssertionContext(context) {
            return isTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) ||
                isTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent);
        }
        function isTypeAssertionContext(context) {
            return context.contextNode.kind === 199 /* TypeAssertionExpression */;
        }
        function isVoidOpContext(context) {
            return context.currentTokenSpan.kind === 110 /* VoidKeyword */ && context.currentTokenParent.kind === 205 /* VoidExpression */;
        }
        function isYieldOrYieldStarWithOperand(context) {
            return context.contextNode.kind === 212 /* YieldExpression */ && context.contextNode.expression !== undefined;
        }
        function isNonNullAssertionContext(context) {
            return context.contextNode.kind === 218 /* NonNullExpression */;
        }
        function isNotStatementConditionContext(context) {
            return !isStatementConditionContext(context);
        }
        function isStatementConditionContext(context) {
            switch (context.contextNode.kind) {
                case 227 /* IfStatement */:
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                    return true;
                default:
                    return false;
            }
        }
        function isSemicolonDeletionContext(context) {
            var nextTokenKind = context.nextTokenSpan.kind;
            var nextTokenStart = context.nextTokenSpan.pos;
            if (ts.isTrivia(nextTokenKind)) {
                var nextRealToken = context.nextTokenParent === context.currentTokenParent
                    ? ts.findNextToken(context.currentTokenParent, ts.findAncestor(context.currentTokenParent, function (a) { return !a.parent; }), context.sourceFile)
                    : context.nextTokenParent.getFirstToken(context.sourceFile);
                if (!nextRealToken) {
                    return true;
                }
                nextTokenKind = nextRealToken.kind;
                nextTokenStart = nextRealToken.getStart(context.sourceFile);
            }
            var startLine = context.sourceFile.getLineAndCharacterOfPosition(context.currentTokenSpan.pos).line;
            var endLine = context.sourceFile.getLineAndCharacterOfPosition(nextTokenStart).line;
            if (startLine === endLine) {
                return nextTokenKind === 19 /* CloseBraceToken */
                    || nextTokenKind === 1 /* EndOfFileToken */;
            }
            if (nextTokenKind === 222 /* SemicolonClassElement */ ||
                nextTokenKind === 26 /* SemicolonToken */) {
                return false;
            }
            if (context.contextNode.kind === 246 /* InterfaceDeclaration */ ||
                context.contextNode.kind === 247 /* TypeAliasDeclaration */) {
                // Can’t remove semicolon after `foo`; it would parse as a method declaration:
                //
                // interface I {
                //   foo;
                //   (): void
                // }
                return !ts.isPropertySignature(context.currentTokenParent)
                    || !!context.currentTokenParent.type
                    || nextTokenKind !== 20 /* OpenParenToken */;
            }
            if (ts.isPropertyDeclaration(context.currentTokenParent)) {
                return !context.currentTokenParent.initializer;
            }
            return context.currentTokenParent.kind !== 230 /* ForStatement */
                && context.currentTokenParent.kind !== 224 /* EmptyStatement */
                && context.currentTokenParent.kind !== 222 /* SemicolonClassElement */
                && nextTokenKind !== 22 /* OpenBracketToken */
                && nextTokenKind !== 20 /* OpenParenToken */
                && nextTokenKind !== 39 /* PlusToken */
                && nextTokenKind !== 40 /* MinusToken */
                && nextTokenKind !== 43 /* SlashToken */
                && nextTokenKind !== 13 /* RegularExpressionLiteral */
                && nextTokenKind !== 27 /* CommaToken */
                && nextTokenKind !== 211 /* TemplateExpression */
                && nextTokenKind !== 15 /* TemplateHead */
                && nextTokenKind !== 14 /* NoSubstitutionTemplateLiteral */
                && nextTokenKind !== 24 /* DotToken */;
        }
        function isSemicolonInsertionContext(context) {
            return ts.positionIsASICandidate(context.currentTokenSpan.end, context.currentTokenParent, context.sourceFile);
        }
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        function getFormatContext(options, host) {
            return { options: options, getRules: getRulesMap(), host: host };
        }
        formatting.getFormatContext = getFormatContext;
        var rulesMapCache;
        function getRulesMap() {
            if (rulesMapCache === undefined) {
                rulesMapCache = createRulesMap(formatting.getAllRules());
            }
            return rulesMapCache;
        }
        /**
         * For a given rule action, gets a mask of other rule actions that
         * cannot be applied at the same position.
         */
        function getRuleActionExclusion(ruleAction) {
            var mask = 0;
            if (ruleAction & 1 /* StopProcessingSpaceActions */) {
                mask |= 28 /* ModifySpaceAction */;
            }
            if (ruleAction & 2 /* StopProcessingTokenActions */) {
                mask |= 96 /* ModifyTokenAction */;
            }
            if (ruleAction & 28 /* ModifySpaceAction */) {
                mask |= 28 /* ModifySpaceAction */;
            }
            if (ruleAction & 96 /* ModifyTokenAction */) {
                mask |= 96 /* ModifyTokenAction */;
            }
            return mask;
        }
        function createRulesMap(rules) {
            var map = buildMap(rules);
            return function (context) {
                var bucket = map[getRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind)];
                if (bucket) {
                    var rules_1 = [];
                    var ruleActionMask = 0;
                    for (var _i = 0, bucket_1 = bucket; _i < bucket_1.length; _i++) {
                        var rule = bucket_1[_i];
                        var acceptRuleActions = ~getRuleActionExclusion(ruleActionMask);
                        if (rule.action & acceptRuleActions && ts.every(rule.context, function (c) { return c(context); })) {
                            rules_1.push(rule);
                            ruleActionMask |= rule.action;
                        }
                    }
                    if (rules_1.length) {
                        return rules_1;
                    }
                }
            };
        }
        function buildMap(rules) {
            // Map from bucket index to array of rules
            var map = new Array(mapRowLength * mapRowLength);
            // This array is used only during construction of the rulesbucket in the map
            var rulesBucketConstructionStateList = new Array(map.length);
            for (var _i = 0, rules_2 = rules; _i < rules_2.length; _i++) {
                var rule = rules_2[_i];
                var specificRule = rule.leftTokenRange.isSpecific && rule.rightTokenRange.isSpecific;
                for (var _a = 0, _b = rule.leftTokenRange.tokens; _a < _b.length; _a++) {
                    var left = _b[_a];
                    for (var _c = 0, _d = rule.rightTokenRange.tokens; _c < _d.length; _c++) {
                        var right = _d[_c];
                        var index = getRuleBucketIndex(left, right);
                        var rulesBucket = map[index];
                        if (rulesBucket === undefined) {
                            rulesBucket = map[index] = [];
                        }
                        addRule(rulesBucket, rule.rule, specificRule, rulesBucketConstructionStateList, index);
                    }
                }
            }
            return map;
        }
        function getRuleBucketIndex(row, column) {
            ts.Debug.assert(row <= 152 /* LastKeyword */ && column <= 152 /* LastKeyword */, "Must compute formatting context from tokens");
            return (row * mapRowLength) + column;
        }
        var maskBitSize = 5;
        var mask = 31; // MaskBitSize bits
        var mapRowLength = 152 /* LastToken */ + 1;
        var RulesPosition;
        (function (RulesPosition) {
            RulesPosition[RulesPosition["StopRulesSpecific"] = 0] = "StopRulesSpecific";
            RulesPosition[RulesPosition["StopRulesAny"] = maskBitSize * 1] = "StopRulesAny";
            RulesPosition[RulesPosition["ContextRulesSpecific"] = maskBitSize * 2] = "ContextRulesSpecific";
            RulesPosition[RulesPosition["ContextRulesAny"] = maskBitSize * 3] = "ContextRulesAny";
            RulesPosition[RulesPosition["NoContextRulesSpecific"] = maskBitSize * 4] = "NoContextRulesSpecific";
            RulesPosition[RulesPosition["NoContextRulesAny"] = maskBitSize * 5] = "NoContextRulesAny";
        })(RulesPosition || (RulesPosition = {}));
        // The Rules list contains all the inserted rules into a rulebucket in the following order:
        //    1- Ignore rules with specific token combination
        //    2- Ignore rules with any token combination
        //    3- Context rules with specific token combination
        //    4- Context rules with any token combination
        //    5- Non-context rules with specific token combination
        //    6- Non-context rules with any token combination
        //
        // The member rulesInsertionIndexBitmap is used to describe the number of rules
        // in each sub-bucket (above) hence can be used to know the index of where to insert
        // the next rule. It's a bitmap which contains 6 different sections each is given 5 bits.
        //
        // Example:
        // In order to insert a rule to the end of sub-bucket (3), we get the index by adding
        // the values in the bitmap segments 3rd, 2nd, and 1st.
        function addRule(rules, rule, specificTokens, constructionState, rulesBucketIndex) {
            var position = rule.action & 3 /* StopAction */ ?
                specificTokens ? RulesPosition.StopRulesSpecific : RulesPosition.StopRulesAny :
                rule.context !== formatting.anyContext ?
                    specificTokens ? RulesPosition.ContextRulesSpecific : RulesPosition.ContextRulesAny :
                    specificTokens ? RulesPosition.NoContextRulesSpecific : RulesPosition.NoContextRulesAny;
            var state = constructionState[rulesBucketIndex] || 0;
            rules.splice(getInsertionIndex(state, position), 0, rule);
            constructionState[rulesBucketIndex] = increaseInsertionIndex(state, position);
        }
        function getInsertionIndex(indexBitmap, maskPosition) {
            var index = 0;
            for (var pos = 0; pos <= maskPosition; pos += maskBitSize) {
                index += indexBitmap & mask;
                indexBitmap >>= maskBitSize;
            }
            return index;
        }
        function increaseInsertionIndex(indexBitmap, maskPosition) {
            var value = ((indexBitmap >> maskPosition) & mask) + 1;
            ts.Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
            return (indexBitmap & ~(mask << maskPosition)) | (value << maskPosition);
        }
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        function createTextRangeWithKind(pos, end, kind) {
            var textRangeWithKind = { pos: pos, end: end, kind: kind };
            if (ts.Debug.isDebugging) {
                Object.defineProperty(textRangeWithKind, "__debugKind", {
                    get: function () { return ts.Debug.formatSyntaxKind(kind); },
                });
            }
            return textRangeWithKind;
        }
        formatting.createTextRangeWithKind = createTextRangeWithKind;
        var Constants;
        (function (Constants) {
            Constants[Constants["Unknown"] = -1] = "Unknown";
        })(Constants || (Constants = {}));
        function formatOnEnter(position, sourceFile, formatContext) {
            var line = sourceFile.getLineAndCharacterOfPosition(position).line;
            if (line === 0) {
                return [];
            }
            // After the enter key, the cursor is now at a new line. The new line may or may not contain non-whitespace characters.
            // If the new line has only whitespaces, we won't want to format this line, because that would remove the indentation as
            // trailing whitespaces. So the end of the formatting span should be the later one between:
            //  1. the end of the previous line
            //  2. the last non-whitespace character in the current line
            var endOfFormatSpan = ts.getEndLinePosition(line, sourceFile);
            while (ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(endOfFormatSpan))) {
                endOfFormatSpan--;
            }
            // if the character at the end of the span is a line break, we shouldn't include it, because it indicates we don't want to
            // touch the current line at all. Also, on some OSes the line break consists of two characters (\r\n), we should test if the
            // previous character before the end of format span is line break character as well.
            if (ts.isLineBreak(sourceFile.text.charCodeAt(endOfFormatSpan))) {
                endOfFormatSpan--;
            }
            var span = {
                // get start position for the previous line
                pos: ts.getStartPositionOfLine(line - 1, sourceFile),
                // end value is exclusive so add 1 to the result
                end: endOfFormatSpan + 1
            };
            return formatSpan(span, sourceFile, formatContext, 2 /* FormatOnEnter */);
        }
        formatting.formatOnEnter = formatOnEnter;
        function formatOnSemicolon(position, sourceFile, formatContext) {
            var semicolon = findImmediatelyPrecedingTokenOfKind(position, 26 /* SemicolonToken */, sourceFile);
            return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, formatContext, 3 /* FormatOnSemicolon */);
        }
        formatting.formatOnSemicolon = formatOnSemicolon;
        function formatOnOpeningCurly(position, sourceFile, formatContext) {
            var openingCurly = findImmediatelyPrecedingTokenOfKind(position, 18 /* OpenBraceToken */, sourceFile);
            if (!openingCurly) {
                return [];
            }
            var curlyBraceRange = openingCurly.parent;
            var outermostNode = findOutermostNodeWithinListLevel(curlyBraceRange);
            /**
             * We limit the span to end at the opening curly to handle the case where
             * the brace matched to that just typed will be incorrect after further edits.
             * For example, we could type the opening curly for the following method
             * body without brace-matching activated:
             * ```
             * class C {
             *     foo()
             * }
             * ```
             * and we wouldn't want to move the closing brace.
             */
            var textRange = {
                pos: ts.getLineStartPositionForPosition(outermostNode.getStart(sourceFile), sourceFile),
                end: position
            };
            return formatSpan(textRange, sourceFile, formatContext, 4 /* FormatOnOpeningCurlyBrace */);
        }
        formatting.formatOnOpeningCurly = formatOnOpeningCurly;
        function formatOnClosingCurly(position, sourceFile, formatContext) {
            var precedingToken = findImmediatelyPrecedingTokenOfKind(position, 19 /* CloseBraceToken */, sourceFile);
            return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, formatContext, 5 /* FormatOnClosingCurlyBrace */);
        }
        formatting.formatOnClosingCurly = formatOnClosingCurly;
        function formatDocument(sourceFile, formatContext) {
            var span = {
                pos: 0,
                end: sourceFile.text.length
            };
            return formatSpan(span, sourceFile, formatContext, 0 /* FormatDocument */);
        }
        formatting.formatDocument = formatDocument;
        function formatSelection(start, end, sourceFile, formatContext) {
            // format from the beginning of the line
            var span = {
                pos: ts.getLineStartPositionForPosition(start, sourceFile),
                end: end,
            };
            return formatSpan(span, sourceFile, formatContext, 1 /* FormatSelection */);
        }
        formatting.formatSelection = formatSelection;
        /**
         * Validating `expectedTokenKind` ensures the token was typed in the context we expect (eg: not a comment).
         * @param expectedTokenKind The kind of the last token constituting the desired parent node.
         */
        function findImmediatelyPrecedingTokenOfKind(end, expectedTokenKind, sourceFile) {
            var precedingToken = ts.findPrecedingToken(end, sourceFile);
            return precedingToken && precedingToken.kind === expectedTokenKind && end === precedingToken.getEnd() ?
                precedingToken :
                undefined;
        }
        /**
         * Finds the highest node enclosing `node` at the same list level as `node`
         * and whose end does not exceed `node.end`.
         *
         * Consider typing the following
         * ```
         * let x = 1;
         * while (true) {
         * }
         * ```
         * Upon typing the closing curly, we want to format the entire `while`-statement, but not the preceding
         * variable declaration.
         */
        function findOutermostNodeWithinListLevel(node) {
            var current = node;
            while (current &&
                current.parent &&
                current.parent.end === node.end &&
                !isListElement(current.parent, current)) {
                current = current.parent;
            }
            return current;
        }
        // Returns true if node is a element in some list in parent
        // i.e. parent is class declaration with the list of members and node is one of members.
        function isListElement(parent, node) {
            switch (parent.kind) {
                case 245 /* ClassDeclaration */:
                case 246 /* InterfaceDeclaration */:
                    return ts.rangeContainsRange(parent.members, node);
                case 249 /* ModuleDeclaration */:
                    var body = parent.body;
                    return !!body && body.kind === 250 /* ModuleBlock */ && ts.rangeContainsRange(body.statements, node);
                case 290 /* SourceFile */:
                case 223 /* Block */:
                case 250 /* ModuleBlock */:
                    return ts.rangeContainsRange(parent.statements, node);
                case 280 /* CatchClause */:
                    return ts.rangeContainsRange(parent.block.statements, node);
            }
            return false;
        }
        /** find node that fully contains given text range */
        function findEnclosingNode(range, sourceFile) {
            return find(sourceFile);
            function find(n) {
                var candidate = ts.forEachChild(n, function (c) { return ts.startEndContainsRange(c.getStart(sourceFile), c.end, range) && c; });
                if (candidate) {
                    var result = find(candidate);
                    if (result) {
                        return result;
                    }
                }
                return n;
            }
        }
        /** formatting is not applied to ranges that contain parse errors.
         * This function will return a predicate that for a given text range will tell
         * if there are any parse errors that overlap with the range.
         */
        function prepareRangeContainsErrorFunction(errors, originalRange) {
            if (!errors.length) {
                return rangeHasNoErrors;
            }
            // pick only errors that fall in range
            var sorted = errors
                .filter(function (d) { return ts.rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length); }) // TODO: GH#18217
                .sort(function (e1, e2) { return e1.start - e2.start; });
            if (!sorted.length) {
                return rangeHasNoErrors;
            }
            var index = 0;
            return function (r) {
                // in current implementation sequence of arguments [r1, r2...] is monotonically increasing.
                // 'index' tracks the index of the most recent error that was checked.
                while (true) {
                    if (index >= sorted.length) {
                        // all errors in the range were already checked -> no error in specified range
                        return false;
                    }
                    var error = sorted[index];
                    if (r.end <= error.start) {
                        // specified range ends before the error referred by 'index' - no error in range
                        return false;
                    }
                    if (ts.startEndOverlapsWithStartEnd(r.pos, r.end, error.start, error.start + error.length)) {
                        // specified range overlaps with error range
                        return true;
                    }
                    index++;
                }
            };
            function rangeHasNoErrors() {
                return false;
            }
        }
        /**
         * Start of the original range might fall inside the comment - scanner will not yield appropriate results
         * This function will look for token that is located before the start of target range
         * and return its end as start position for the scanner.
         */
        function getScanStartPosition(enclosingNode, originalRange, sourceFile) {
            var start = enclosingNode.getStart(sourceFile);
            if (start === originalRange.pos && enclosingNode.end === originalRange.end) {
                return start;
            }
            var precedingToken = ts.findPrecedingToken(originalRange.pos, sourceFile);
            if (!precedingToken) {
                // no preceding token found - start from the beginning of enclosing node
                return enclosingNode.pos;
            }
            // preceding token ends after the start of original range (i.e when originalRange.pos falls in the middle of literal)
            // start from the beginning of enclosingNode to handle the entire 'originalRange'
            if (precedingToken.end >= originalRange.pos) {
                return enclosingNode.pos;
            }
            return precedingToken.end;
        }
        /*
         * For cases like
         * if (a ||
         *     b ||$
         *     c) {...}
         * If we hit Enter at $ we want line '    b ||' to be indented.
         * Formatting will be applied to the last two lines.
         * Node that fully encloses these lines is binary expression 'a ||...'.
         * Initial indentation for this node will be 0.
         * Binary expressions don't introduce new indentation scopes, however it is possible
         * that some parent node on the same line does - like if statement in this case.
         * Note that we are considering parents only from the same line with initial node -
         * if parent is on the different line - its delta was already contributed
         * to the initial indentation.
         */
        function getOwnOrInheritedDelta(n, options, sourceFile) {
            var previousLine = -1 /* Unknown */;
            var child;
            while (n) {
                var line = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)).line;
                if (previousLine !== -1 /* Unknown */ && line !== previousLine) {
                    break;
                }
                if (formatting.SmartIndenter.shouldIndentChildNode(options, n, child, sourceFile)) {
                    return options.indentSize;
                }
                previousLine = line;
                child = n;
                n = n.parent;
            }
            return 0;
        }
        function formatNodeGivenIndentation(node, sourceFileLike, languageVariant, initialIndentation, delta, formatContext) {
            var range = { pos: 0, end: sourceFileLike.text.length };
            return formatting.getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, function (scanner) { return formatSpanWorker(range, node, initialIndentation, delta, scanner, formatContext, 1 /* FormatSelection */, function (_) { return false; }, // assume that node does not have any errors
            sourceFileLike); });
        }
        formatting.formatNodeGivenIndentation = formatNodeGivenIndentation;
        function formatNodeLines(node, sourceFile, formatContext, requestKind) {
            if (!node) {
                return [];
            }
            var span = {
                pos: ts.getLineStartPositionForPosition(node.getStart(sourceFile), sourceFile),
                end: node.end
            };
            return formatSpan(span, sourceFile, formatContext, requestKind);
        }
        function formatSpan(originalRange, sourceFile, formatContext, requestKind) {
            // find the smallest node that fully wraps the range and compute the initial indentation for the node
            var enclosingNode = findEnclosingNode(originalRange, sourceFile);
            return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); });
        }
        function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, _a, requestKind, rangeContainsError, sourceFile) {
            var options = _a.options, getRules = _a.getRules, host = _a.host;
            // formatting context is used by rules provider
            var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options);
            var previousRange;
            var previousParent;
            var previousRangeStartLine;
            var lastIndentedLine;
            var indentationOnLastIndentedLine = -1 /* Unknown */;
            var edits = [];
            formattingScanner.advance();
            if (formattingScanner.isOnToken()) {
                var startLine = sourceFile.getLineAndCharacterOfPosition(enclosingNode.getStart(sourceFile)).line;
                var undecoratedStartLine = startLine;
                if (enclosingNode.decorators) {
                    undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(enclosingNode, sourceFile)).line;
                }
                processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta);
            }
            if (!formattingScanner.isOnToken()) {
                var leadingTrivia = formattingScanner.getCurrentLeadingTrivia();
                if (leadingTrivia) {
                    indentTriviaItems(leadingTrivia, initialIndentation, /*indentNextTokenOrTrivia*/ false, function (item) { return processRange(item, sourceFile.getLineAndCharacterOfPosition(item.pos), enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined); });
                    if (options.trimTrailingWhitespace !== false) {
                        trimTrailingWhitespacesForRemainingRange();
                    }
                }
            }
            return edits;
            // local functions
            /** Tries to compute the indentation for a list element.
             * If list element is not in range then
             * function will pick its actual indentation
             * so it can be pushed downstream as inherited indentation.
             * If list element is in the range - its indentation will be equal
             * to inherited indentation from its predecessors.
             */
            function tryComputeIndentationForListItem(startPos, endPos, parentStartLine, range, inheritedIndentation) {
                if (ts.rangeOverlapsWithStartEnd(range, startPos, endPos) ||
                    ts.rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) {
                    if (inheritedIndentation !== -1 /* Unknown */) {
                        return inheritedIndentation;
                    }
                }
                else {
                    var startLine = sourceFile.getLineAndCharacterOfPosition(startPos).line;
                    var startLinePosition = ts.getLineStartPositionForPosition(startPos, sourceFile);
                    var column = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, startPos, sourceFile, options);
                    if (startLine !== parentStartLine || startPos === column) {
                        // Use the base indent size if it is greater than
                        // the indentation of the inherited predecessor.
                        var baseIndentSize = formatting.SmartIndenter.getBaseIndentation(options);
                        return baseIndentSize > column ? baseIndentSize : column;
                    }
                }
                return -1 /* Unknown */;
            }
            function computeIndentation(node, startLine, inheritedIndentation, parent, parentDynamicIndentation, effectiveParentStartLine) {
                var delta = formatting.SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize : 0;
                if (effectiveParentStartLine === startLine) {
                    // if node is located on the same line with the parent
                    // - inherit indentation from the parent
                    // - push children if either parent of node itself has non-zero delta
                    return {
                        indentation: startLine === lastIndentedLine ? indentationOnLastIndentedLine : parentDynamicIndentation.getIndentation(),
                        delta: Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta)
                    };
                }
                else if (inheritedIndentation === -1 /* Unknown */) {
                    if (node.kind === 20 /* OpenParenToken */ && startLine === lastIndentedLine) {
                        // the is used for chaining methods formatting
                        // - we need to get the indentation on last line and the delta of parent
                        return { indentation: indentationOnLastIndentedLine, delta: parentDynamicIndentation.getDelta(node) };
                    }
                    else if (formatting.SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) {
                        return { indentation: parentDynamicIndentation.getIndentation(), delta: delta };
                    }
                    else if (formatting.SmartIndenter.argumentStartsOnSameLineAsPreviousArgument(parent, node, startLine, sourceFile)) {
                        return { indentation: parentDynamicIndentation.getIndentation(), delta: delta };
                    }
                    else {
                        return { indentation: parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node), delta: delta };
                    }
                }
                else {
                    return { indentation: inheritedIndentation, delta: delta };
                }
            }
            function getFirstNonDecoratorTokenOfNode(node) {
                if (node.modifiers && node.modifiers.length) {
                    return node.modifiers[0].kind;
                }
                switch (node.kind) {
                    case 245 /* ClassDeclaration */: return 80 /* ClassKeyword */;
                    case 246 /* InterfaceDeclaration */: return 114 /* InterfaceKeyword */;
                    case 244 /* FunctionDeclaration */: return 94 /* FunctionKeyword */;
                    case 248 /* EnumDeclaration */: return 248 /* EnumDeclaration */;
                    case 163 /* GetAccessor */: return 131 /* GetKeyword */;
                    case 164 /* SetAccessor */: return 142 /* SetKeyword */;
                    case 161 /* MethodDeclaration */:
                        if (node.asteriskToken) {
                            return 41 /* AsteriskToken */;
                        }
                    // falls through
                    case 159 /* PropertyDeclaration */:
                    case 156 /* Parameter */:
                        var name = ts.getNameOfDeclaration(node);
                        if (name) {
                            return name.kind;
                        }
                }
            }
            function getDynamicIndentation(node, nodeStartLine, indentation, delta) {
                return {
                    getIndentationForComment: function (kind, tokenIndentation, container) {
                        switch (kind) {
                            // preceding comment to the token that closes the indentation scope inherits the indentation from the scope
                            // ..  {
                            //     // comment
                            // }
                            case 19 /* CloseBraceToken */:
                            case 23 /* CloseBracketToken */:
                            case 21 /* CloseParenToken */:
                                return indentation + getDelta(container);
                        }
                        return tokenIndentation !== -1 /* Unknown */ ? tokenIndentation : indentation;
                    },
                    // if list end token is LessThanToken '>' then its delta should be explicitly suppressed
                    // so that LessThanToken as a binary operator can still be indented.
                    // foo.then
                    //     <
                    //         number,
                    //         string,
                    //     >();
                    // vs
                    // var a = xValue
                    //     > yValue;
                    getIndentationForToken: function (line, kind, container, suppressDelta) {
                        return !suppressDelta && shouldAddDelta(line, kind, container) ? indentation + getDelta(container) : indentation;
                    },
                    getIndentation: function () { return indentation; },
                    getDelta: getDelta,
                    recomputeIndentation: function (lineAdded, parent) {
                        if (formatting.SmartIndenter.shouldIndentChildNode(options, parent, node, sourceFile)) {
                            indentation += lineAdded ? options.indentSize : -options.indentSize;
                            delta = formatting.SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize : 0;
                        }
                    }
                };
                function shouldAddDelta(line, kind, container) {
                    switch (kind) {
                        // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
                        case 18 /* OpenBraceToken */:
                        case 19 /* CloseBraceToken */:
                        case 21 /* CloseParenToken */:
                        case 87 /* ElseKeyword */:
                        case 111 /* WhileKeyword */:
                        case 59 /* AtToken */:
                            return false;
                        case 43 /* SlashToken */:
                        case 31 /* GreaterThanToken */:
                            switch (container.kind) {
                                case 268 /* JsxOpeningElement */:
                                case 269 /* JsxClosingElement */:
                                case 267 /* JsxSelfClosingElement */:
                                    return false;
                            }
                            break;
                        case 22 /* OpenBracketToken */:
                        case 23 /* CloseBracketToken */:
                            if (container.kind !== 186 /* MappedType */) {
                                return false;
                            }
                            break;
                    }
                    // if token line equals to the line of containing node (this is a first token in the node) - use node indentation
                    return nodeStartLine !== line
                        // if this token is the first token following the list of decorators, we do not need to indent
                        && !(node.decorators && kind === getFirstNonDecoratorTokenOfNode(node));
                }
                function getDelta(child) {
                    // Delta value should be zero when the node explicitly prevents indentation of the child node
                    return formatting.SmartIndenter.nodeWillIndentChild(options, node, child, sourceFile, /*indentByDefault*/ true) ? delta : 0;
                }
            }
            function processNode(node, contextNode, nodeStartLine, undecoratedNodeStartLine, indentation, delta) {
                if (!ts.rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) {
                    return;
                }
                var nodeDynamicIndentation = getDynamicIndentation(node, nodeStartLine, indentation, delta);
                // a useful observations when tracking context node
                //        /
                //      [a]
                //   /   |   \
                //  [b] [c] [d]
                // node 'a' is a context node for nodes 'b', 'c', 'd'
                // except for the leftmost leaf token in [b] - in this case context node ('e') is located somewhere above 'a'
                // this rule can be applied recursively to child nodes of 'a'.
                //
                // context node is set to parent node value after processing every child node
                // context node is set to parent of the token after processing every token
                var childContextNode = contextNode;
                // if there are any tokens that logically belong to node and interleave child nodes
                // such tokens will be consumed in processChildNode for the child that follows them
                ts.forEachChild(node, function (child) {
                    processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListItem*/ false);
                }, function (nodes) {
                    processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation);
                });
                // proceed any tokens in the node that are located after child nodes
                while (formattingScanner.isOnToken()) {
                    var tokenInfo = formattingScanner.readTokenInfo(node);
                    if (tokenInfo.token.end > node.end) {
                        break;
                    }
                    if (node.kind === 11 /* JsxText */) {
                        // Intentation rules for jsx text are handled by `indentMultilineCommentOrJsxText` inside `processChildNode`; just fastforward past it here
                        formattingScanner.advance();
                        continue;
                    }
                    consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation, node);
                }
                if (!node.parent && formattingScanner.isOnEOF()) {
                    var token = formattingScanner.readEOFTokenRange();
                    if (token.end <= node.end && previousRange) {
                        processPair(token, sourceFile.getLineAndCharacterOfPosition(token.pos).line, node, previousRange, previousRangeStartLine, previousParent, contextNode, nodeDynamicIndentation);
                    }
                }
                function processChildNode(child, inheritedIndentation, parent, parentDynamicIndentation, parentStartLine, undecoratedParentStartLine, isListItem, isFirstListItem) {
                    var childStartPos = child.getStart(sourceFile);
                    var childStartLine = sourceFile.getLineAndCharacterOfPosition(childStartPos).line;
                    var undecoratedChildStartLine = childStartLine;
                    if (child.decorators) {
                        undecoratedChildStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(child, sourceFile)).line;
                    }
                    // if child is a list item - try to get its indentation, only if parent is within the original range.
                    var childIndentationAmount = -1 /* Unknown */;
                    if (isListItem && ts.rangeContainsRange(originalRange, parent)) {
                        childIndentationAmount = tryComputeIndentationForListItem(childStartPos, child.end, parentStartLine, originalRange, inheritedIndentation);
                        if (childIndentationAmount !== -1 /* Unknown */) {
                            inheritedIndentation = childIndentationAmount;
                        }
                    }
                    // child node is outside the target range - do not dive inside
                    if (!ts.rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) {
                        if (child.end < originalRange.pos) {
                            formattingScanner.skipToEndOf(child);
                        }
                        return inheritedIndentation;
                    }
                    if (child.getFullWidth() === 0) {
                        return inheritedIndentation;
                    }
                    while (formattingScanner.isOnToken()) {
                        // proceed any parent tokens that are located prior to child.getStart()
                        var tokenInfo = formattingScanner.readTokenInfo(node);
                        if (tokenInfo.token.end > childStartPos) {
                            // stop when formatting scanner advances past the beginning of the child
                            break;
                        }
                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, node);
                    }
                    if (!formattingScanner.isOnToken()) {
                        return inheritedIndentation;
                    }
                    // JSX text shouldn't affect indenting
                    if (ts.isToken(child) && child.kind !== 11 /* JsxText */) {
                        // if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules
                        var tokenInfo = formattingScanner.readTokenInfo(child);
                        ts.Debug.assert(tokenInfo.token.end === child.end, "Token end is child end");
                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child);
                        return inheritedIndentation;
                    }
                    var effectiveParentStartLine = child.kind === 157 /* Decorator */ ? childStartLine : undecoratedParentStartLine;
                    var childIndentation = computeIndentation(child, childStartLine, childIndentationAmount, node, parentDynamicIndentation, effectiveParentStartLine);
                    processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta);
                    if (child.kind === 11 /* JsxText */) {
                        var range = { pos: child.getStart(), end: child.getEnd() };
                        if (range.pos !== range.end) { // don't indent zero-width jsx text
                            var siblings = parent.getChildren(sourceFile);
                            var currentIndex = ts.findIndex(siblings, function (arg) { return arg.pos === child.pos; });
                            var previousNode = siblings[currentIndex - 1];
                            if (previousNode) {
                                // The jsx text needs no indentation whatsoever if it ends on the same line the previous sibling ends on
                                if (sourceFile.getLineAndCharacterOfPosition(range.end).line !== sourceFile.getLineAndCharacterOfPosition(previousNode.end).line) {
                                    // The first line is (already) "indented" if the text starts on the same line as the previous sibling element ends on
                                    var firstLineIsIndented = sourceFile.getLineAndCharacterOfPosition(range.pos).line === sourceFile.getLineAndCharacterOfPosition(previousNode.end).line;
                                    indentMultilineCommentOrJsxText(range, childIndentation.indentation, firstLineIsIndented, /*indentFinalLine*/ false, /*jsxStyle*/ true);
                                }
                            }
                        }
                    }
                    childContextNode = node;
                    if (isFirstListItem && parent.kind === 192 /* ArrayLiteralExpression */ && inheritedIndentation === -1 /* Unknown */) {
                        inheritedIndentation = childIndentation.indentation;
                    }
                    return inheritedIndentation;
                }
                function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) {
                    ts.Debug.assert(ts.isNodeArray(nodes));
                    var listStartToken = getOpenTokenForList(parent, nodes);
                    var listDynamicIndentation = parentDynamicIndentation;
                    var startLine = parentStartLine;
                    if (listStartToken !== 0 /* Unknown */) {
                        // introduce a new indentation scope for lists (including list start and end tokens)
                        while (formattingScanner.isOnToken()) {
                            var tokenInfo = formattingScanner.readTokenInfo(parent);
                            if (tokenInfo.token.end > nodes.pos) {
                                // stop when formatting scanner moves past the beginning of node list
                                break;
                            }
                            else if (tokenInfo.token.kind === listStartToken) {
                                // consume list start token
                                startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line;
                                consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation, parent);
                                var indentationOnListStartToken = void 0;
                                if (indentationOnLastIndentedLine !== -1 /* Unknown */) {
                                    // scanner just processed list start token so consider last indentation as list indentation
                                    // function foo(): { // last indentation was 0, list item will be indented based on this value
                                    //   foo: number;
                                    // }: {};
                                    indentationOnListStartToken = indentationOnLastIndentedLine;
                                }
                                else {
                                    var startLinePosition = ts.getLineStartPositionForPosition(tokenInfo.token.pos, sourceFile);
                                    indentationOnListStartToken = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, tokenInfo.token.pos, sourceFile, options);
                                }
                                listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentationOnListStartToken, options.indentSize); // TODO: GH#18217
                            }
                            else {
                                // consume any tokens that precede the list as child elements of 'node' using its indentation scope
                                consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation, parent);
                            }
                        }
                    }
                    var inheritedIndentation = -1 /* Unknown */;
                    for (var i = 0; i < nodes.length; i++) {
                        var child = nodes[i];
                        inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListItem*/ true, /*isFirstListItem*/ i === 0);
                    }
                    var listEndToken = getCloseTokenForOpenToken(listStartToken);
                    if (listEndToken !== 0 /* Unknown */ && formattingScanner.isOnToken()) {
                        var tokenInfo = formattingScanner.readTokenInfo(parent);
                        if (tokenInfo.token.kind === 27 /* CommaToken */ && ts.isCallLikeExpression(parent)) {
                            var commaTokenLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line;
                            if (startLine !== commaTokenLine) {
                                formattingScanner.advance();
                                tokenInfo = formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(parent) : undefined;
                            }
                        }
                        // consume the list end token only if it is still belong to the parent
                        // there might be the case when current token matches end token but does not considered as one
                        // function (x: function) <--
                        // without this check close paren will be interpreted as list end token for function expression which is wrong
                        if (tokenInfo && tokenInfo.token.kind === listEndToken && ts.rangeContainsRange(parent, tokenInfo.token)) {
                            // consume list end token
                            consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent, /*isListEndToken*/ true);
                        }
                    }
                }
                function consumeTokenAndAdvanceScanner(currentTokenInfo, parent, dynamicIndentation, container, isListEndToken) {
                    ts.Debug.assert(ts.rangeContainsRange(parent, currentTokenInfo.token));
                    var lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine();
                    var indentToken = false;
                    if (currentTokenInfo.leadingTrivia) {
                        processTrivia(currentTokenInfo.leadingTrivia, parent, childContextNode, dynamicIndentation);
                    }
                    var lineAction = 0 /* None */;
                    var isTokenInRange = ts.rangeContainsRange(originalRange, currentTokenInfo.token);
                    var tokenStart = sourceFile.getLineAndCharacterOfPosition(currentTokenInfo.token.pos);
                    if (isTokenInRange) {
                        var rangeHasError = rangeContainsError(currentTokenInfo.token);
                        // save previousRange since processRange will overwrite this value with current one
                        var savePreviousRange = previousRange;
                        lineAction = processRange(currentTokenInfo.token, tokenStart, parent, childContextNode, dynamicIndentation);
                        // do not indent comments\token if token range overlaps with some error
                        if (!rangeHasError) {
                            if (lineAction === 0 /* None */) {
                                // indent token only if end line of previous range does not match start line of the token
                                var prevEndLine = savePreviousRange && sourceFile.getLineAndCharacterOfPosition(savePreviousRange.end).line;
                                indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine;
                            }
                            else {
                                indentToken = lineAction === 1 /* LineAdded */;
                            }
                        }
                    }
                    if (currentTokenInfo.trailingTrivia) {
                        processTrivia(currentTokenInfo.trailingTrivia, parent, childContextNode, dynamicIndentation);
                    }
                    if (indentToken) {
                        var tokenIndentation = (isTokenInRange && !rangeContainsError(currentTokenInfo.token)) ?
                            dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind, container, !!isListEndToken) :
                            -1 /* Unknown */;
                        var indentNextTokenOrTrivia = true;
                        if (currentTokenInfo.leadingTrivia) {
                            var commentIndentation_1 = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container);
                            indentNextTokenOrTrivia = indentTriviaItems(currentTokenInfo.leadingTrivia, commentIndentation_1, indentNextTokenOrTrivia, function (item) { return insertIndentation(item.pos, commentIndentation_1, /*lineAdded*/ false); });
                        }
                        // indent token only if is it is in target range and does not overlap with any error ranges
                        if (tokenIndentation !== -1 /* Unknown */ && indentNextTokenOrTrivia) {
                            insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAction === 1 /* LineAdded */);
                            lastIndentedLine = tokenStart.line;
                            indentationOnLastIndentedLine = tokenIndentation;
                        }
                    }
                    formattingScanner.advance();
                    childContextNode = parent;
                }
            }
            function indentTriviaItems(trivia, commentIndentation, indentNextTokenOrTrivia, indentSingleLine) {
                for (var _i = 0, trivia_1 = trivia; _i < trivia_1.length; _i++) {
                    var triviaItem = trivia_1[_i];
                    var triviaInRange = ts.rangeContainsRange(originalRange, triviaItem);
                    switch (triviaItem.kind) {
                        case 3 /* MultiLineCommentTrivia */:
                            if (triviaInRange) {
                                indentMultilineCommentOrJsxText(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
                            }
                            indentNextTokenOrTrivia = false;
                            break;
                        case 2 /* SingleLineCommentTrivia */:
                            if (indentNextTokenOrTrivia && triviaInRange) {
                                indentSingleLine(triviaItem);
                            }
                            indentNextTokenOrTrivia = false;
                            break;
                        case 4 /* NewLineTrivia */:
                            indentNextTokenOrTrivia = true;
                            break;
                    }
                }
                return indentNextTokenOrTrivia;
            }
            function processTrivia(trivia, parent, contextNode, dynamicIndentation) {
                for (var _i = 0, trivia_2 = trivia; _i < trivia_2.length; _i++) {
                    var triviaItem = trivia_2[_i];
                    if (ts.isComment(triviaItem.kind) && ts.rangeContainsRange(originalRange, triviaItem)) {
                        var triviaItemStart = sourceFile.getLineAndCharacterOfPosition(triviaItem.pos);
                        processRange(triviaItem, triviaItemStart, parent, contextNode, dynamicIndentation);
                    }
                }
            }
            function processRange(range, rangeStart, parent, contextNode, dynamicIndentation) {
                var rangeHasError = rangeContainsError(range);
                var lineAction = 0 /* None */;
                if (!rangeHasError) {
                    if (!previousRange) {
                        // trim whitespaces starting from the beginning of the span up to the current line
                        var originalStart = sourceFile.getLineAndCharacterOfPosition(originalRange.pos);
                        trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line);
                    }
                    else {
                        lineAction =
                            processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation);
                    }
                }
                previousRange = range;
                previousParent = parent;
                previousRangeStartLine = rangeStart.line;
                return lineAction;
            }
            function processPair(currentItem, currentStartLine, currentParent, previousItem, previousStartLine, previousParent, contextNode, dynamicIndentation) {
                formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode);
                var rules = getRules(formattingContext);
                var trimTrailingWhitespaces = formattingContext.options.trimTrailingWhitespace !== false;
                var lineAction = 0 /* None */;
                if (rules) {
                    // Apply rules in reverse order so that higher priority rules (which are first in the array)
                    // win in a conflict with lower priority rules.
                    ts.forEachRight(rules, function (rule) {
                        lineAction = applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
                        switch (lineAction) {
                            case 2 /* LineRemoved */:
                                // Handle the case where the next line is moved to be the end of this line.
                                // In this case we don't indent the next line in the next pass.
                                if (currentParent.getStart(sourceFile) === currentItem.pos) {
                                    dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false, contextNode);
                                }
                                break;
                            case 1 /* LineAdded */:
                                // Handle the case where token2 is moved to the new line.
                                // In this case we indent token2 in the next pass but we set
                                // sameLineIndent flag to notify the indenter that the indentation is within the line.
                                if (currentParent.getStart(sourceFile) === currentItem.pos) {
                                    dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true, contextNode);
                                }
                                break;
                            default:
                                ts.Debug.assert(lineAction === 0 /* None */);
                        }
                        // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
                        trimTrailingWhitespaces = trimTrailingWhitespaces && !(rule.action & 16 /* DeleteSpace */) && rule.flags !== 1 /* CanDeleteNewLines */;
                    });
                }
                else {
                    trimTrailingWhitespaces = trimTrailingWhitespaces && currentItem.kind !== 1 /* EndOfFileToken */;
                }
                if (currentStartLine !== previousStartLine && trimTrailingWhitespaces) {
                    // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
                    trimTrailingWhitespacesForLines(previousStartLine, currentStartLine, previousItem);
                }
                return lineAction;
            }
            function insertIndentation(pos, indentation, lineAdded) {
                var indentationString = getIndentationString(indentation, options);
                if (lineAdded) {
                    // new line is added before the token by the formatting rules
                    // insert indentation string at the very beginning of the token
                    recordReplace(pos, 0, indentationString);
                }
                else {
                    var tokenStart = sourceFile.getLineAndCharacterOfPosition(pos);
                    var startLinePosition = ts.getStartPositionOfLine(tokenStart.line, sourceFile);
                    if (indentation !== characterToColumn(startLinePosition, tokenStart.character) || indentationIsDifferent(indentationString, startLinePosition)) {
                        recordReplace(startLinePosition, tokenStart.character, indentationString);
                    }
                }
            }
            function characterToColumn(startLinePosition, characterInLine) {
                var column = 0;
                for (var i = 0; i < characterInLine; i++) {
                    if (sourceFile.text.charCodeAt(startLinePosition + i) === 9 /* tab */) {
                        column += options.tabSize - column % options.tabSize;
                    }
                    else {
                        column++;
                    }
                }
                return column;
            }
            function indentationIsDifferent(indentationString, startLinePosition) {
                return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
            }
            function indentMultilineCommentOrJsxText(commentRange, indentation, firstLineIsIndented, indentFinalLine, jsxTextStyleIndent) {
                if (indentFinalLine === void 0) { indentFinalLine = true; }
                // split comment in lines
                var startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line;
                var endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line;
                if (startLine === endLine) {
                    if (!firstLineIsIndented) {
                        // treat as single line comment
                        insertIndentation(commentRange.pos, indentation, /*lineAdded*/ false);
                    }
                    return;
                }
                var parts = [];
                var startPos = commentRange.pos;
                for (var line = startLine; line < endLine; line++) {
                    var endOfLine = ts.getEndLinePosition(line, sourceFile);
                    parts.push({ pos: startPos, end: endOfLine });
                    startPos = ts.getStartPositionOfLine(line + 1, sourceFile);
                }
                if (indentFinalLine) {
                    parts.push({ pos: startPos, end: commentRange.end });
                }
                if (parts.length === 0)
                    return;
                var startLinePos = ts.getStartPositionOfLine(startLine, sourceFile);
                var nonWhitespaceColumnInFirstPart = formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(startLinePos, parts[0].pos, sourceFile, options);
                if (indentation === nonWhitespaceColumnInFirstPart.column && !jsxTextStyleIndent) {
                    return;
                }
                var startIndex = 0;
                if (firstLineIsIndented) {
                    startIndex = 1;
                    startLine++;
                }
                // shift all parts on the delta size
                var delta = indentation - nonWhitespaceColumnInFirstPart.column;
                for (var i = startIndex; i < parts.length; i++, startLine++) {
                    var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile);
                    var nonWhitespaceCharacterAndColumn = i === 0
                        ? nonWhitespaceColumnInFirstPart
                        : formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(parts[i].pos, parts[i].end, sourceFile, options);
                    if (jsxTextStyleIndent) {
                        // skip adding indentation to blank lines
                        if (ts.isLineBreak(sourceFile.text.charCodeAt(ts.getStartPositionOfLine(startLine, sourceFile))))
                            continue;
                        // reset delta on every line
                        delta = indentation - nonWhitespaceCharacterAndColumn.column;
                    }
                    var newIndentation = nonWhitespaceCharacterAndColumn.column + delta;
                    if (newIndentation > 0) {
                        var indentationString = getIndentationString(newIndentation, options);
                        recordReplace(startLinePos_1, nonWhitespaceCharacterAndColumn.character, indentationString);
                    }
                    else {
                        recordDelete(startLinePos_1, nonWhitespaceCharacterAndColumn.character);
                    }
                }
            }
            function trimTrailingWhitespacesForLines(line1, line2, range) {
                for (var line = line1; line < line2; line++) {
                    var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile);
                    var lineEndPosition = ts.getEndLinePosition(line, sourceFile);
                    // do not trim whitespaces in comments or template expression
                    if (range && (ts.isComment(range.kind) || ts.isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) {
                        continue;
                    }
                    var whitespaceStart = getTrailingWhitespaceStartPosition(lineStartPosition, lineEndPosition);
                    if (whitespaceStart !== -1) {
                        ts.Debug.assert(whitespaceStart === lineStartPosition || !ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(whitespaceStart - 1)));
                        recordDelete(whitespaceStart, lineEndPosition + 1 - whitespaceStart);
                    }
                }
            }
            /**
             * @param start The position of the first character in range
             * @param end The position of the last character in range
             */
            function getTrailingWhitespaceStartPosition(start, end) {
                var pos = end;
                while (pos >= start && ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) {
                    pos--;
                }
                if (pos !== end) {
                    return pos + 1;
                }
                return -1;
            }
            /**
             * Trimming will be done for lines after the previous range
             */
            function trimTrailingWhitespacesForRemainingRange() {
                var startPosition = previousRange ? previousRange.end : originalRange.pos;
                var startLine = sourceFile.getLineAndCharacterOfPosition(startPosition).line;
                var endLine = sourceFile.getLineAndCharacterOfPosition(originalRange.end).line;
                trimTrailingWhitespacesForLines(startLine, endLine + 1, previousRange);
            }
            function recordDelete(start, len) {
                if (len) {
                    edits.push(ts.createTextChangeFromStartLength(start, len, ""));
                }
            }
            function recordReplace(start, len, newText) {
                if (len || newText) {
                    edits.push(ts.createTextChangeFromStartLength(start, len, newText));
                }
            }
            function recordInsert(start, text) {
                if (text) {
                    edits.push(ts.createTextChangeFromStartLength(start, 0, text));
                }
            }
            function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) {
                var onLaterLine = currentStartLine !== previousStartLine;
                switch (rule.action) {
                    case 1 /* StopProcessingSpaceActions */:
                        // no action required
                        return 0 /* None */;
                    case 16 /* DeleteSpace */:
                        if (previousRange.end !== currentRange.pos) {
                            // delete characters starting from t1.end up to t2.pos exclusive
                            recordDelete(previousRange.end, currentRange.pos - previousRange.end);
                            return onLaterLine ? 2 /* LineRemoved */ : 0 /* None */;
                        }
                        break;
                    case 32 /* DeleteToken */:
                        recordDelete(previousRange.pos, previousRange.end - previousRange.pos);
                        break;
                    case 8 /* InsertNewLine */:
                        // exit early if we on different lines and rule cannot change number of newlines
                        // if line1 and line2 are on subsequent lines then no edits are required - ok to exit
                        // if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines
                        if (rule.flags !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
                            return 0 /* None */;
                        }
                        // edit should not be applied if we have one line feed between elements
                        var lineDelta = currentStartLine - previousStartLine;
                        if (lineDelta !== 1) {
                            recordReplace(previousRange.end, currentRange.pos - previousRange.end, ts.getNewLineOrDefaultFromHost(host, options));
                            return onLaterLine ? 0 /* None */ : 1 /* LineAdded */;
                        }
                        break;
                    case 4 /* InsertSpace */:
                        // exit early if we on different lines and rule cannot change number of newlines
                        if (rule.flags !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
                            return 0 /* None */;
                        }
                        var posDelta = currentRange.pos - previousRange.end;
                        if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== 32 /* space */) {
                            recordReplace(previousRange.end, currentRange.pos - previousRange.end, " ");
                            return onLaterLine ? 2 /* LineRemoved */ : 0 /* None */;
                        }
                        break;
                    case 64 /* InsertTrailingSemicolon */:
                        recordInsert(previousRange.end, ";");
                }
                return 0 /* None */;
            }
        }
        var LineAction;
        (function (LineAction) {
            LineAction[LineAction["None"] = 0] = "None";
            LineAction[LineAction["LineAdded"] = 1] = "LineAdded";
            LineAction[LineAction["LineRemoved"] = 2] = "LineRemoved";
        })(LineAction || (LineAction = {}));
        /**
         * @param precedingToken pass `null` if preceding token was already computed and result was `undefined`.
         */
        function getRangeOfEnclosingComment(sourceFile, position, precedingToken, tokenAtPosition) {
            if (tokenAtPosition === void 0) { tokenAtPosition = ts.getTokenAtPosition(sourceFile, position); }
            var jsdoc = ts.findAncestor(tokenAtPosition, ts.isJSDoc);
            if (jsdoc)
                tokenAtPosition = jsdoc.parent;
            var tokenStart = tokenAtPosition.getStart(sourceFile);
            if (tokenStart <= position && position < tokenAtPosition.getEnd()) {
                return undefined;
            }
            // eslint-disable-next-line no-null/no-null
            precedingToken = precedingToken === null ? undefined : precedingToken === undefined ? ts.findPrecedingToken(position, sourceFile) : precedingToken;
            // Between two consecutive tokens, all comments are either trailing on the former
            // or leading on the latter (and none are in both lists).
            var trailingRangesOfPreviousToken = precedingToken && ts.getTrailingCommentRanges(sourceFile.text, precedingToken.end);
            var leadingCommentRangesOfNextToken = ts.getLeadingCommentRangesOfNode(tokenAtPosition, sourceFile);
            var commentRanges = ts.concatenate(trailingRangesOfPreviousToken, leadingCommentRangesOfNextToken);
            return commentRanges && ts.find(commentRanges, function (range) { return ts.rangeContainsPositionExclusive(range, position) ||
                // The end marker of a single-line comment does not include the newline character.
                // With caret at `^`, in the following case, we are inside a comment (^ denotes the cursor position):
                //
                //    // asdf   ^\n
                //
                // But for closed multi-line comments, we don't want to be inside the comment in the following case:
                //
                //    /* asdf */^
                //
                // However, unterminated multi-line comments *do* contain their end.
                //
                // Internally, we represent the end of the comment at the newline and closing '/', respectively.
                //
                position === range.end && (range.kind === 2 /* SingleLineCommentTrivia */ || position === sourceFile.getFullWidth()); });
        }
        formatting.getRangeOfEnclosingComment = getRangeOfEnclosingComment;
        function getOpenTokenForList(node, list) {
            switch (node.kind) {
                case 162 /* Constructor */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 202 /* ArrowFunction */:
                    if (node.typeParameters === list) {
                        return 29 /* LessThanToken */;
                    }
                    else if (node.parameters === list) {
                        return 20 /* OpenParenToken */;
                    }
                    break;
                case 196 /* CallExpression */:
                case 197 /* NewExpression */:
                    if (node.typeArguments === list) {
                        return 29 /* LessThanToken */;
                    }
                    else if (node.arguments === list) {
                        return 20 /* OpenParenToken */;
                    }
                    break;
                case 169 /* TypeReference */:
                    if (node.typeArguments === list) {
                        return 29 /* LessThanToken */;
                    }
                    break;
                case 173 /* TypeLiteral */:
                    return 18 /* OpenBraceToken */;
            }
            return 0 /* Unknown */;
        }
        function getCloseTokenForOpenToken(kind) {
            switch (kind) {
                case 20 /* OpenParenToken */:
                    return 21 /* CloseParenToken */;
                case 29 /* LessThanToken */:
                    return 31 /* GreaterThanToken */;
                case 18 /* OpenBraceToken */:
                    return 19 /* CloseBraceToken */;
            }
            return 0 /* Unknown */;
        }
        var internedSizes;
        var internedTabsIndentation;
        var internedSpacesIndentation;
        function getIndentationString(indentation, options) {
            // reset interned strings if FormatCodeOptions were changed
            var resetInternedStrings = !internedSizes || (internedSizes.tabSize !== options.tabSize || internedSizes.indentSize !== options.indentSize);
            if (resetInternedStrings) {
                internedSizes = { tabSize: options.tabSize, indentSize: options.indentSize };
                internedTabsIndentation = internedSpacesIndentation = undefined;
            }
            if (!options.convertTabsToSpaces) {
                var tabs = Math.floor(indentation / options.tabSize);
                var spaces = indentation - tabs * options.tabSize;
                var tabString = void 0;
                if (!internedTabsIndentation) {
                    internedTabsIndentation = [];
                }
                if (internedTabsIndentation[tabs] === undefined) {
                    internedTabsIndentation[tabs] = tabString = ts.repeatString("\t", tabs);
                }
                else {
                    tabString = internedTabsIndentation[tabs];
                }
                return spaces ? tabString + ts.repeatString(" ", spaces) : tabString;
            }
            else {
                var spacesString = void 0;
                var quotient = Math.floor(indentation / options.indentSize);
                var remainder = indentation % options.indentSize;
                if (!internedSpacesIndentation) {
                    internedSpacesIndentation = [];
                }
                if (internedSpacesIndentation[quotient] === undefined) {
                    spacesString = ts.repeatString(" ", options.indentSize * quotient);
                    internedSpacesIndentation[quotient] = spacesString;
                }
                else {
                    spacesString = internedSpacesIndentation[quotient];
                }
                return remainder ? spacesString + ts.repeatString(" ", remainder) : spacesString;
            }
        }
        formatting.getIndentationString = getIndentationString;
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var SmartIndenter;
        (function (SmartIndenter) {
            var Value;
            (function (Value) {
                Value[Value["Unknown"] = -1] = "Unknown";
            })(Value || (Value = {}));
            /**
             * @param assumeNewLineBeforeCloseBrace
             * `false` when called on text from a real source file.
             * `true` when we need to assume `position` is on a newline.
             *
             * This is useful for codefixes. Consider
             * ```
             * function f() {
             * |}
             * ```
             * with `position` at `|`.
             *
             * When inserting some text after an open brace, we would like to get indentation as if a newline was already there.
             * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior.
             */
            function getIndentation(position, sourceFile, options, assumeNewLineBeforeCloseBrace) {
                if (assumeNewLineBeforeCloseBrace === void 0) { assumeNewLineBeforeCloseBrace = false; }
                if (position > sourceFile.text.length) {
                    return getBaseIndentation(options); // past EOF
                }
                // no indentation when the indent style is set to none,
                // so we can return fast
                if (options.indentStyle === ts.IndentStyle.None) {
                    return 0;
                }
                var precedingToken = ts.findPrecedingToken(position, sourceFile, /*startNode*/ undefined, /*excludeJsdoc*/ true);
                // eslint-disable-next-line no-null/no-null
                var enclosingCommentRange = formatting.getRangeOfEnclosingComment(sourceFile, position, precedingToken || null);
                if (enclosingCommentRange && enclosingCommentRange.kind === 3 /* MultiLineCommentTrivia */) {
                    return getCommentIndent(sourceFile, position, options, enclosingCommentRange);
                }
                if (!precedingToken) {
                    return getBaseIndentation(options);
                }
                // no indentation in string \regex\template literals
                var precedingTokenIsLiteral = ts.isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind);
                if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && position < precedingToken.end) {
                    return 0;
                }
                var lineAtPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
                // indentation is first non-whitespace character in a previous line
                // for block indentation, we should look for a line which contains something that's not
                // whitespace.
                if (options.indentStyle === ts.IndentStyle.Block) {
                    return getBlockIndent(sourceFile, position, options);
                }
                if (precedingToken.kind === 27 /* CommaToken */ && precedingToken.parent.kind !== 209 /* BinaryExpression */) {
                    // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
                    var actualIndentation = getActualIndentationForListItemBeforeComma(precedingToken, sourceFile, options);
                    if (actualIndentation !== -1 /* Unknown */) {
                        return actualIndentation;
                    }
                }
                var containerList = getListByPosition(position, precedingToken.parent, sourceFile);
                // use list position if the preceding token is before any list items
                if (containerList && !ts.rangeContainsRange(containerList, precedingToken)) {
                    return getActualIndentationForListStartLine(containerList, sourceFile, options) + options.indentSize; // TODO: GH#18217
                }
                return getSmartIndent(sourceFile, position, precedingToken, lineAtPosition, assumeNewLineBeforeCloseBrace, options);
            }
            SmartIndenter.getIndentation = getIndentation;
            function getCommentIndent(sourceFile, position, options, enclosingCommentRange) {
                var previousLine = ts.getLineAndCharacterOfPosition(sourceFile, position).line - 1;
                var commentStartLine = ts.getLineAndCharacterOfPosition(sourceFile, enclosingCommentRange.pos).line;
                ts.Debug.assert(commentStartLine >= 0);
                if (previousLine <= commentStartLine) {
                    return findFirstNonWhitespaceColumn(ts.getStartPositionOfLine(commentStartLine, sourceFile), position, sourceFile, options);
                }
                var startPositionOfLine = ts.getStartPositionOfLine(previousLine, sourceFile);
                var _a = findFirstNonWhitespaceCharacterAndColumn(startPositionOfLine, position, sourceFile, options), column = _a.column, character = _a.character;
                if (column === 0) {
                    return column;
                }
                var firstNonWhitespaceCharacterCode = sourceFile.text.charCodeAt(startPositionOfLine + character);
                return firstNonWhitespaceCharacterCode === 42 /* asterisk */ ? column - 1 : column;
            }
            function getBlockIndent(sourceFile, position, options) {
                // move backwards until we find a line with a non-whitespace character,
                // then find the first non-whitespace character for that line.
                var current = position;
                while (current > 0) {
                    var char = sourceFile.text.charCodeAt(current);
                    if (!ts.isWhiteSpaceLike(char)) {
                        break;
                    }
                    current--;
                }
                var lineStart = ts.getLineStartPositionForPosition(current, sourceFile);
                return findFirstNonWhitespaceColumn(lineStart, current, sourceFile, options);
            }
            function getSmartIndent(sourceFile, position, precedingToken, lineAtPosition, assumeNewLineBeforeCloseBrace, options) {
                // try to find node that can contribute to indentation and includes 'position' starting from 'precedingToken'
                // if such node is found - compute initial indentation for 'position' inside this node
                var previous;
                var current = precedingToken;
                while (current) {
                    if (ts.positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(options, current, previous, sourceFile, /*isNextChild*/ true)) {
                        var currentStart = getStartLineAndCharacterForNode(current, sourceFile);
                        var nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile);
                        var indentationDelta = nextTokenKind !== 0 /* Unknown */
                            // handle cases when codefix is about to be inserted before the close brace
                            ? assumeNewLineBeforeCloseBrace && nextTokenKind === 2 /* CloseBrace */ ? options.indentSize : 0
                            : lineAtPosition !== currentStart.line ? options.indentSize : 0;
                        return getIndentationForNodeWorker(current, currentStart, /*ignoreActualIndentationRange*/ undefined, indentationDelta, sourceFile, /*isNextChild*/ true, options); // TODO: GH#18217
                    }
                    // check if current node is a list item - if yes, take indentation from it
                    // do not consider parent-child line sharing yet:
                    // function foo(a
                    //    | preceding node 'a' does share line with its parent but indentation is expected
                    var actualIndentation = getActualIndentationForListItem(current, sourceFile, options, /*listIndentsChild*/ true);
                    if (actualIndentation !== -1 /* Unknown */) {
                        return actualIndentation;
                    }
                    previous = current;
                    current = current.parent;
                }
                // no parent was found - return the base indentation of the SourceFile
                return getBaseIndentation(options);
            }
            function getIndentationForNode(n, ignoreActualIndentationRange, sourceFile, options) {
                var start = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
                return getIndentationForNodeWorker(n, start, ignoreActualIndentationRange, /*indentationDelta*/ 0, sourceFile, /*isNextChild*/ false, options);
            }
            SmartIndenter.getIndentationForNode = getIndentationForNode;
            function getBaseIndentation(options) {
                return options.baseIndentSize || 0;
            }
            SmartIndenter.getBaseIndentation = getBaseIndentation;
            function getIndentationForNodeWorker(current, currentStart, ignoreActualIndentationRange, indentationDelta, sourceFile, isNextChild, options) {
                var parent = current.parent;
                // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if
                // * parent and child nodes start on the same line, or
                // * parent is an IfStatement and child starts on the same line as an 'else clause'.
                while (parent) {
                    var useActualIndentation = true;
                    if (ignoreActualIndentationRange) {
                        var start = current.getStart(sourceFile);
                        useActualIndentation = start < ignoreActualIndentationRange.pos || start > ignoreActualIndentationRange.end;
                    }
                    var containingListOrParentStart = getContainingListOrParentStart(parent, current, sourceFile);
                    var parentAndChildShareLine = containingListOrParentStart.line === currentStart.line ||
                        childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile);
                    if (useActualIndentation) {
                        // check if current node is a list item - if yes, take indentation from it
                        var actualIndentation = getActualIndentationForListItem(current, sourceFile, options, !parentAndChildShareLine);
                        if (actualIndentation !== -1 /* Unknown */) {
                            return actualIndentation + indentationDelta;
                        }
                        // try to fetch actual indentation for current node from source text
                        actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options);
                        if (actualIndentation !== -1 /* Unknown */) {
                            return actualIndentation + indentationDelta;
                        }
                    }
                    // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line
                    if (shouldIndentChildNode(options, parent, current, sourceFile, isNextChild) && !parentAndChildShareLine) {
                        indentationDelta += options.indentSize;
                    }
                    // In our AST, a call argument's `parent` is the call-expression, not the argument list.
                    // We would like to increase indentation based on the relationship between an argument and its argument-list,
                    // so we spoof the starting position of the (parent) call-expression to match the (non-parent) argument-list.
                    // But, the spoofed start-value could then cause a problem when comparing the start position of the call-expression
                    // to *its* parent (in the case of an iife, an expression statement), adding an extra level of indentation.
                    //
                    // Instead, when at an argument, we unspoof the starting position of the enclosing call expression
                    // *after* applying indentation for the argument.
                    var useTrueStart = isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile);
                    current = parent;
                    parent = current.parent;
                    currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart(sourceFile)) : containingListOrParentStart;
                }
                return indentationDelta + getBaseIndentation(options);
            }
            function getContainingListOrParentStart(parent, child, sourceFile) {
                var containingList = getContainingList(child, sourceFile);
                var startPos = containingList ? containingList.pos : parent.getStart(sourceFile);
                return sourceFile.getLineAndCharacterOfPosition(startPos);
            }
            /*
             * Function returns Value.Unknown if indentation cannot be determined
             */
            function getActualIndentationForListItemBeforeComma(commaToken, sourceFile, options) {
                // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
                var commaItemInfo = ts.findListItemInfo(commaToken);
                if (commaItemInfo && commaItemInfo.listItemIndex > 0) {
                    return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options);
                }
                else {
                    // handle broken code gracefully
                    return -1 /* Unknown */;
                }
            }
            /*
             * Function returns Value.Unknown if actual indentation for node should not be used (i.e because node is nested expression)
             */
            function getActualIndentationForNode(current, parent, currentLineAndChar, parentAndChildShareLine, sourceFile, options) {
                // actual indentation is used for statements\declarations if one of cases below is true:
                // - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually
                // - parent and child are not on the same line
                var useActualIndentation = (ts.isDeclaration(current) || ts.isStatementButNotDeclaration(current)) &&
                    (parent.kind === 290 /* SourceFile */ || !parentAndChildShareLine);
                if (!useActualIndentation) {
                    return -1 /* Unknown */;
                }
                return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options);
            }
            var NextTokenKind;
            (function (NextTokenKind) {
                NextTokenKind[NextTokenKind["Unknown"] = 0] = "Unknown";
                NextTokenKind[NextTokenKind["OpenBrace"] = 1] = "OpenBrace";
                NextTokenKind[NextTokenKind["CloseBrace"] = 2] = "CloseBrace";
            })(NextTokenKind || (NextTokenKind = {}));
            function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile) {
                var nextToken = ts.findNextToken(precedingToken, current, sourceFile);
                if (!nextToken) {
                    return 0 /* Unknown */;
                }
                if (nextToken.kind === 18 /* OpenBraceToken */) {
                    // open braces are always indented at the parent level
                    return 1 /* OpenBrace */;
                }
                else if (nextToken.kind === 19 /* CloseBraceToken */) {
                    // close braces are indented at the parent level if they are located on the same line with cursor
                    // this means that if new line will be added at $ position, this case will be indented
                    // class A {
                    //    $
                    // }
                    /// and this one - not
                    // class A {
                    // $}
                    var nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line;
                    return lineAtPosition === nextTokenStartLine ? 2 /* CloseBrace */ : 0 /* Unknown */;
                }
                return 0 /* Unknown */;
            }
            function getStartLineAndCharacterForNode(n, sourceFile) {
                return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
            }
            function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, child, childStartLine, sourceFile) {
                if (!(ts.isCallExpression(parent) && ts.contains(parent.arguments, child))) {
                    return false;
                }
                var expressionOfCallExpressionEnd = parent.expression.getEnd();
                var expressionOfCallExpressionEndLine = ts.getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line;
                return expressionOfCallExpressionEndLine === childStartLine;
            }
            SmartIndenter.isArgumentAndStartLineOverlapsExpressionBeingCalled = isArgumentAndStartLineOverlapsExpressionBeingCalled;
            function childStartsOnTheSameLineWithElseInIfStatement(parent, child, childStartLine, sourceFile) {
                if (parent.kind === 227 /* IfStatement */ && parent.elseStatement === child) {
                    var elseKeyword = ts.findChildOfKind(parent, 87 /* ElseKeyword */, sourceFile);
                    ts.Debug.assert(elseKeyword !== undefined);
                    var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
                    return elseKeywordStartLine === childStartLine;
                }
                return false;
            }
            SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement = childStartsOnTheSameLineWithElseInIfStatement;
            function argumentStartsOnSameLineAsPreviousArgument(parent, child, childStartLine, sourceFile) {
                if (ts.isCallOrNewExpression(parent)) {
                    if (!parent.arguments)
                        return false;
                    var currentNode = ts.find(parent.arguments, function (arg) { return arg.pos === child.pos; });
                    // If it's not one of the arguments, don't look past this
                    if (!currentNode)
                        return false;
                    var currentIndex = parent.arguments.indexOf(currentNode);
                    if (currentIndex === 0)
                        return false; // Can't look at previous node if first
                    var previousNode = parent.arguments[currentIndex - 1];
                    var lineOfPreviousNode = ts.getLineAndCharacterOfPosition(sourceFile, previousNode.getEnd()).line;
                    if (childStartLine === lineOfPreviousNode) {
                        return true;
                    }
                }
                return false;
            }
            SmartIndenter.argumentStartsOnSameLineAsPreviousArgument = argumentStartsOnSameLineAsPreviousArgument;
            function getContainingList(node, sourceFile) {
                return node.parent && getListByRange(node.getStart(sourceFile), node.getEnd(), node.parent, sourceFile);
            }
            SmartIndenter.getContainingList = getContainingList;
            function getListByPosition(pos, node, sourceFile) {
                return node && getListByRange(pos, pos, node, sourceFile);
            }
            function getListByRange(start, end, node, sourceFile) {
                switch (node.kind) {
                    case 169 /* TypeReference */:
                        return getList(node.typeArguments);
                    case 193 /* ObjectLiteralExpression */:
                        return getList(node.properties);
                    case 192 /* ArrayLiteralExpression */:
                        return getList(node.elements);
                    case 173 /* TypeLiteral */:
                        return getList(node.members);
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                    case 161 /* MethodDeclaration */:
                    case 160 /* MethodSignature */:
                    case 165 /* CallSignature */:
                    case 162 /* Constructor */:
                    case 171 /* ConstructorType */:
                    case 166 /* ConstructSignature */:
                        return getList(node.typeParameters) || getList(node.parameters);
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                    case 321 /* JSDocTemplateTag */:
                        return getList(node.typeParameters);
                    case 197 /* NewExpression */:
                    case 196 /* CallExpression */:
                        return getList(node.typeArguments) || getList(node.arguments);
                    case 243 /* VariableDeclarationList */:
                        return getList(node.declarations);
                    case 257 /* NamedImports */:
                    case 261 /* NamedExports */:
                        return getList(node.elements);
                    case 189 /* ObjectBindingPattern */:
                    case 190 /* ArrayBindingPattern */:
                        return getList(node.elements);
                }
                function getList(list) {
                    return list && ts.rangeContainsStartEnd(getVisualListRange(node, list, sourceFile), start, end) ? list : undefined;
                }
            }
            function getVisualListRange(node, list, sourceFile) {
                var children = node.getChildren(sourceFile);
                for (var i = 1; i < children.length - 1; i++) {
                    if (children[i].pos === list.pos && children[i].end === list.end) {
                        return { pos: children[i - 1].end, end: children[i + 1].getStart(sourceFile) };
                    }
                }
                return list;
            }
            function getActualIndentationForListStartLine(list, sourceFile, options) {
                if (!list) {
                    return -1 /* Unknown */;
                }
                return findColumnForFirstNonWhitespaceCharacterInLine(sourceFile.getLineAndCharacterOfPosition(list.pos), sourceFile, options);
            }
            function getActualIndentationForListItem(node, sourceFile, options, listIndentsChild) {
                if (node.parent && node.parent.kind === 243 /* VariableDeclarationList */) {
                    // VariableDeclarationList has no wrapping tokens
                    return -1 /* Unknown */;
                }
                var containingList = getContainingList(node, sourceFile);
                if (containingList) {
                    var index = containingList.indexOf(node);
                    if (index !== -1) {
                        var result = deriveActualIndentationFromList(containingList, index, sourceFile, options);
                        if (result !== -1 /* Unknown */) {
                            return result;
                        }
                    }
                    return getActualIndentationForListStartLine(containingList, sourceFile, options) + (listIndentsChild ? options.indentSize : 0); // TODO: GH#18217
                }
                return -1 /* Unknown */;
            }
            function deriveActualIndentationFromList(list, index, sourceFile, options) {
                ts.Debug.assert(index >= 0 && index < list.length);
                var node = list[index];
                // walk toward the start of the list starting from current node and check if the line is the same for all items.
                // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i]
                var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile);
                for (var i = index - 1; i >= 0; i--) {
                    if (list[i].kind === 27 /* CommaToken */) {
                        continue;
                    }
                    // skip list items that ends on the same line with the current list element
                    var prevEndLine = sourceFile.getLineAndCharacterOfPosition(list[i].end).line;
                    if (prevEndLine !== lineAndCharacter.line) {
                        return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options);
                    }
                    lineAndCharacter = getStartLineAndCharacterForNode(list[i], sourceFile);
                }
                return -1 /* Unknown */;
            }
            function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options) {
                var lineStart = sourceFile.getPositionOfLineAndCharacter(lineAndCharacter.line, 0);
                return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options);
            }
            /**
             * Character is the actual index of the character since the beginning of the line.
             * Column - position of the character after expanding tabs to spaces.
             * "0\t2$"
             * value of 'character' for '$' is 3
             * value of 'column' for '$' is 6 (assuming that tab size is 4)
             */
            function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) {
                var character = 0;
                var column = 0;
                for (var pos = startPos; pos < endPos; pos++) {
                    var ch = sourceFile.text.charCodeAt(pos);
                    if (!ts.isWhiteSpaceSingleLine(ch)) {
                        break;
                    }
                    if (ch === 9 /* tab */) {
                        column += options.tabSize + (column % options.tabSize);
                    }
                    else {
                        column++;
                    }
                    character++;
                }
                return { column: column, character: character };
            }
            SmartIndenter.findFirstNonWhitespaceCharacterAndColumn = findFirstNonWhitespaceCharacterAndColumn;
            function findFirstNonWhitespaceColumn(startPos, endPos, sourceFile, options) {
                return findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options).column;
            }
            SmartIndenter.findFirstNonWhitespaceColumn = findFirstNonWhitespaceColumn;
            function nodeWillIndentChild(settings, parent, child, sourceFile, indentByDefault) {
                var childKind = child ? child.kind : 0 /* Unknown */;
                switch (parent.kind) {
                    case 226 /* ExpressionStatement */:
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                    case 248 /* EnumDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                    case 192 /* ArrayLiteralExpression */:
                    case 223 /* Block */:
                    case 250 /* ModuleBlock */:
                    case 193 /* ObjectLiteralExpression */:
                    case 173 /* TypeLiteral */:
                    case 186 /* MappedType */:
                    case 175 /* TupleType */:
                    case 251 /* CaseBlock */:
                    case 278 /* DefaultClause */:
                    case 277 /* CaseClause */:
                    case 200 /* ParenthesizedExpression */:
                    case 194 /* PropertyAccessExpression */:
                    case 196 /* CallExpression */:
                    case 197 /* NewExpression */:
                    case 225 /* VariableStatement */:
                    case 259 /* ExportAssignment */:
                    case 235 /* ReturnStatement */:
                    case 210 /* ConditionalExpression */:
                    case 190 /* ArrayBindingPattern */:
                    case 189 /* ObjectBindingPattern */:
                    case 268 /* JsxOpeningElement */:
                    case 271 /* JsxOpeningFragment */:
                    case 267 /* JsxSelfClosingElement */:
                    case 276 /* JsxExpression */:
                    case 160 /* MethodSignature */:
                    case 165 /* CallSignature */:
                    case 166 /* ConstructSignature */:
                    case 156 /* Parameter */:
                    case 170 /* FunctionType */:
                    case 171 /* ConstructorType */:
                    case 182 /* ParenthesizedType */:
                    case 198 /* TaggedTemplateExpression */:
                    case 206 /* AwaitExpression */:
                    case 261 /* NamedExports */:
                    case 257 /* NamedImports */:
                    case 263 /* ExportSpecifier */:
                    case 258 /* ImportSpecifier */:
                    case 159 /* PropertyDeclaration */:
                        return true;
                    case 242 /* VariableDeclaration */:
                    case 281 /* PropertyAssignment */:
                    case 209 /* BinaryExpression */:
                        if (!settings.indentMultiLineObjectLiteralBeginningOnBlankLine && sourceFile && childKind === 193 /* ObjectLiteralExpression */) { // TODO: GH#18217
                            return rangeIsOnOneLine(sourceFile, child);
                        }
                        if (parent.kind !== 209 /* BinaryExpression */) {
                            return true;
                        }
                        break;
                    case 228 /* DoStatement */:
                    case 229 /* WhileStatement */:
                    case 231 /* ForInStatement */:
                    case 232 /* ForOfStatement */:
                    case 230 /* ForStatement */:
                    case 227 /* IfStatement */:
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                    case 161 /* MethodDeclaration */:
                    case 202 /* ArrowFunction */:
                    case 162 /* Constructor */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        return childKind !== 223 /* Block */;
                    case 260 /* ExportDeclaration */:
                        return childKind !== 261 /* NamedExports */;
                    case 254 /* ImportDeclaration */:
                        return childKind !== 255 /* ImportClause */ ||
                            (!!child.namedBindings && child.namedBindings.kind !== 257 /* NamedImports */);
                    case 266 /* JsxElement */:
                        return childKind !== 269 /* JsxClosingElement */;
                    case 270 /* JsxFragment */:
                        return childKind !== 272 /* JsxClosingFragment */;
                    case 179 /* IntersectionType */:
                    case 178 /* UnionType */:
                        if (childKind === 173 /* TypeLiteral */) {
                            return false;
                        }
                    // falls through
                }
                // No explicit rule for given nodes so the result will follow the default value argument
                return indentByDefault;
            }
            SmartIndenter.nodeWillIndentChild = nodeWillIndentChild;
            function isControlFlowEndingStatement(kind, parent) {
                switch (kind) {
                    case 235 /* ReturnStatement */:
                    case 239 /* ThrowStatement */:
                    case 233 /* ContinueStatement */:
                    case 234 /* BreakStatement */:
                        return parent.kind !== 223 /* Block */;
                    default:
                        return false;
                }
            }
            /**
             * True when the parent node should indent the given child by an explicit rule.
             * @param isNextChild If true, we are judging indent of a hypothetical child *after* this one, not the current child.
             */
            function shouldIndentChildNode(settings, parent, child, sourceFile, isNextChild) {
                if (isNextChild === void 0) { isNextChild = false; }
                return nodeWillIndentChild(settings, parent, child, sourceFile, /*indentByDefault*/ false)
                    && !(isNextChild && child && isControlFlowEndingStatement(child.kind, parent));
            }
            SmartIndenter.shouldIndentChildNode = shouldIndentChildNode;
            function rangeIsOnOneLine(sourceFile, range) {
                var rangeStart = ts.skipTrivia(sourceFile.text, range.pos);
                var startLine = sourceFile.getLineAndCharacterOfPosition(rangeStart).line;
                var endLine = sourceFile.getLineAndCharacterOfPosition(range.end).line;
                return startLine === endLine;
            }
        })(SmartIndenter = formatting.SmartIndenter || (formatting.SmartIndenter = {}));
    })(formatting = ts.formatting || (ts.formatting = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var textChanges;
    (function (textChanges_3) {
        /**
         * Currently for simplicity we store recovered positions on the node itself.
         * It can be changed to side-table later if we decide that current design is too invasive.
         */
        function getPos(n) {
            var result = n.__pos;
            ts.Debug.assert(typeof result === "number");
            return result;
        }
        function setPos(n, pos) {
            ts.Debug.assert(typeof pos === "number");
            n.__pos = pos;
        }
        function getEnd(n) {
            var result = n.__end;
            ts.Debug.assert(typeof result === "number");
            return result;
        }
        function setEnd(n, end) {
            ts.Debug.assert(typeof end === "number");
            n.__end = end;
        }
        var LeadingTriviaOption;
        (function (LeadingTriviaOption) {
            /** Exclude all leading trivia (use getStart()) */
            LeadingTriviaOption[LeadingTriviaOption["Exclude"] = 0] = "Exclude";
            /** Include leading trivia and,
             * if there are no line breaks between the node and the previous token,
             * include all trivia between the node and the previous token
             */
            LeadingTriviaOption[LeadingTriviaOption["IncludeAll"] = 1] = "IncludeAll";
            /**
             * Include attached JSDoc comments
             */
            LeadingTriviaOption[LeadingTriviaOption["JSDoc"] = 2] = "JSDoc";
            /**
             * Only delete trivia on the same line as getStart().
             * Used to avoid deleting leading comments
             */
            LeadingTriviaOption[LeadingTriviaOption["StartLine"] = 3] = "StartLine";
        })(LeadingTriviaOption = textChanges_3.LeadingTriviaOption || (textChanges_3.LeadingTriviaOption = {}));
        var TrailingTriviaOption;
        (function (TrailingTriviaOption) {
            /** Exclude all trailing trivia (use getEnd()) */
            TrailingTriviaOption[TrailingTriviaOption["Exclude"] = 0] = "Exclude";
            /** Include trailing trivia */
            TrailingTriviaOption[TrailingTriviaOption["Include"] = 1] = "Include";
        })(TrailingTriviaOption = textChanges_3.TrailingTriviaOption || (textChanges_3.TrailingTriviaOption = {}));
        function skipWhitespacesAndLineBreaks(text, start) {
            return ts.skipTrivia(text, start, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        function hasCommentsBeforeLineBreak(text, start) {
            var i = start;
            while (i < text.length) {
                var ch = text.charCodeAt(i);
                if (ts.isWhiteSpaceSingleLine(ch)) {
                    i++;
                    continue;
                }
                return ch === 47 /* slash */;
            }
            return false;
        }
        var useNonAdjustedPositions = {
            leadingTriviaOption: LeadingTriviaOption.Exclude,
            trailingTriviaOption: TrailingTriviaOption.Exclude,
        };
        var ChangeKind;
        (function (ChangeKind) {
            ChangeKind[ChangeKind["Remove"] = 0] = "Remove";
            ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode";
            ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes";
            ChangeKind[ChangeKind["Text"] = 3] = "Text";
        })(ChangeKind || (ChangeKind = {}));
        function getAdjustedRange(sourceFile, startNode, endNode, options) {
            return { pos: getAdjustedStartPosition(sourceFile, startNode, options), end: getAdjustedEndPosition(sourceFile, endNode, options) };
        }
        function getAdjustedStartPosition(sourceFile, node, options) {
            var leadingTriviaOption = options.leadingTriviaOption;
            if (leadingTriviaOption === LeadingTriviaOption.Exclude) {
                return node.getStart(sourceFile);
            }
            if (leadingTriviaOption === LeadingTriviaOption.StartLine) {
                return ts.getLineStartPositionForPosition(node.getStart(sourceFile), sourceFile);
            }
            if (leadingTriviaOption === LeadingTriviaOption.JSDoc) {
                var JSDocComments = ts.getJSDocCommentRanges(node, sourceFile.text);
                if (JSDocComments === null || JSDocComments === void 0 ? void 0 : JSDocComments.length) {
                    return ts.getLineStartPositionForPosition(JSDocComments[0].pos, sourceFile);
                }
            }
            var fullStart = node.getFullStart();
            var start = node.getStart(sourceFile);
            if (fullStart === start) {
                return start;
            }
            var fullStartLine = ts.getLineStartPositionForPosition(fullStart, sourceFile);
            var startLine = ts.getLineStartPositionForPosition(start, sourceFile);
            if (startLine === fullStartLine) {
                // full start and start of the node are on the same line
                //   a,     b;
                //    ^     ^
                //    |   start
                // fullstart
                // when b is replaced - we usually want to keep the leading trvia
                // when b is deleted - we delete it
                return leadingTriviaOption === LeadingTriviaOption.IncludeAll ? fullStart : start;
            }
            // get start position of the line following the line that contains fullstart position
            // (but only if the fullstart isn't the very beginning of the file)
            var nextLineStart = fullStart > 0 ? 1 : 0;
            var adjustedStartPosition = ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, fullStartLine) + nextLineStart, sourceFile);
            // skip whitespaces/newlines
            adjustedStartPosition = skipWhitespacesAndLineBreaks(sourceFile.text, adjustedStartPosition);
            return ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile);
        }
        function getAdjustedEndPosition(sourceFile, node, options) {
            var end = node.end;
            var trailingTriviaOption = options.trailingTriviaOption;
            if (trailingTriviaOption === TrailingTriviaOption.Exclude || (ts.isExpression(node) && trailingTriviaOption !== TrailingTriviaOption.Include)) {
                return end;
            }
            var newEnd = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true);
            return newEnd !== end && (trailingTriviaOption === TrailingTriviaOption.Include || ts.isLineBreak(sourceFile.text.charCodeAt(newEnd - 1)))
                ? newEnd
                : end;
        }
        /**
         * Checks if 'candidate' argument is a legal separator in the list that contains 'node' as an element
         */
        function isSeparator(node, candidate) {
            return !!candidate && !!node.parent && (candidate.kind === 27 /* CommaToken */ || (candidate.kind === 26 /* SemicolonToken */ && node.parent.kind === 193 /* ObjectLiteralExpression */));
        }
        function spaces(count) {
            var s = "";
            for (var i = 0; i < count; i++) {
                s += " ";
            }
            return s;
        }
        function isThisTypeAnnotatable(containingFunction) {
            return ts.isFunctionExpression(containingFunction) || ts.isFunctionDeclaration(containingFunction);
        }
        textChanges_3.isThisTypeAnnotatable = isThisTypeAnnotatable;
        var ChangeTracker = /** @class */ (function () {
            /** Public for tests only. Other callers should use `ChangeTracker.with`. */
            function ChangeTracker(newLineCharacter, formatContext) {
                this.newLineCharacter = newLineCharacter;
                this.formatContext = formatContext;
                this.changes = [];
                this.newFiles = [];
                this.classesWithNodesInsertedAtStart = ts.createMap(); // Set<ClassDeclaration> implemented as Map<node id, ClassDeclaration>
                this.deletedNodes = [];
            }
            ChangeTracker.fromContext = function (context) {
                return new ChangeTracker(ts.getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext);
            };
            ChangeTracker.with = function (context, cb) {
                var tracker = ChangeTracker.fromContext(context);
                cb(tracker);
                return tracker.getChanges();
            };
            ChangeTracker.prototype.pushRaw = function (sourceFile, change) {
                ts.Debug.assertEqual(sourceFile.fileName, change.fileName);
                for (var _i = 0, _a = change.textChanges; _i < _a.length; _i++) {
                    var c = _a[_i];
                    this.changes.push({
                        kind: ChangeKind.Text,
                        sourceFile: sourceFile,
                        text: c.newText,
                        range: ts.createTextRangeFromSpan(c.span),
                    });
                }
            };
            ChangeTracker.prototype.deleteRange = function (sourceFile, range) {
                this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range });
            };
            ChangeTracker.prototype.delete = function (sourceFile, node) {
                this.deletedNodes.push({ sourceFile: sourceFile, node: node });
            };
            ChangeTracker.prototype.deleteNode = function (sourceFile, node, options) {
                if (options === void 0) { options = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }; }
                this.deleteRange(sourceFile, getAdjustedRange(sourceFile, node, node, options));
            };
            ChangeTracker.prototype.deleteModifier = function (sourceFile, modifier) {
                this.deleteRange(sourceFile, { pos: modifier.getStart(sourceFile), end: ts.skipTrivia(sourceFile.text, modifier.end, /*stopAfterLineBreak*/ true) });
            };
            ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) {
                if (options === void 0) { options = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }; }
                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options);
                var endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
                this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
            };
            ChangeTracker.prototype.deleteNodeRangeExcludingEnd = function (sourceFile, startNode, afterEndNode, options) {
                if (options === void 0) { options = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }; }
                var startPosition = getAdjustedStartPosition(sourceFile, startNode, options);
                var endPosition = afterEndNode === undefined ? sourceFile.text.length : getAdjustedStartPosition(sourceFile, afterEndNode, options);
                this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
            };
            ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) {
                if (options === void 0) { options = {}; }
                this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode });
            };
            ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) {
                if (options === void 0) { options = useNonAdjustedPositions; }
                this.replaceRange(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNode, options);
            };
            ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) {
                if (options === void 0) { options = useNonAdjustedPositions; }
                this.replaceRange(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNode, options);
            };
            ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) {
                if (options === void 0) { options = {}; }
                this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile: sourceFile, range: range, options: options, nodes: newNodes });
            };
            ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) {
                if (options === void 0) { options = useNonAdjustedPositions; }
                this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNodes, options);
            };
            ChangeTracker.prototype.replaceNodeWithText = function (sourceFile, oldNode, text) {
                this.replaceRangeWithText(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, useNonAdjustedPositions), text);
            };
            ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) {
                if (options === void 0) { options = useNonAdjustedPositions; }
                this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNodes, options);
            };
            ChangeTracker.prototype.nextCommaToken = function (sourceFile, node) {
                var next = ts.findNextToken(node, node.parent, sourceFile);
                return next && next.kind === 27 /* CommaToken */ ? next : undefined;
            };
            ChangeTracker.prototype.replacePropertyAssignment = function (sourceFile, oldNode, newNode) {
                var suffix = this.nextCommaToken(sourceFile, oldNode) ? "" : ("," + this.newLineCharacter);
                this.replaceNode(sourceFile, oldNode, newNode, { suffix: suffix });
            };
            ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) {
                if (options === void 0) { options = {}; }
                this.replaceRange(sourceFile, ts.createRange(pos), newNode, options);
            };
            ChangeTracker.prototype.insertNodesAt = function (sourceFile, pos, newNodes, options) {
                if (options === void 0) { options = {}; }
                this.replaceRangeWithNodes(sourceFile, ts.createRange(pos), newNodes, options);
            };
            ChangeTracker.prototype.insertNodeAtTopOfFile = function (sourceFile, newNode, blankLineBetween) {
                this.insertAtTopOfFile(sourceFile, newNode, blankLineBetween);
            };
            ChangeTracker.prototype.insertNodesAtTopOfFile = function (sourceFile, newNodes, blankLineBetween) {
                this.insertAtTopOfFile(sourceFile, newNodes, blankLineBetween);
            };
            ChangeTracker.prototype.insertAtTopOfFile = function (sourceFile, insert, blankLineBetween) {
                var pos = getInsertionPositionAtSourceFileTop(sourceFile);
                var options = {
                    prefix: pos === 0 ? undefined : this.newLineCharacter,
                    suffix: (ts.isLineBreak(sourceFile.text.charCodeAt(pos)) ? "" : this.newLineCharacter) + (blankLineBetween ? this.newLineCharacter : ""),
                };
                if (ts.isArray(insert)) {
                    this.insertNodesAt(sourceFile, pos, insert, options);
                }
                else {
                    this.insertNodeAt(sourceFile, pos, insert, options);
                }
            };
            ChangeTracker.prototype.insertFirstParameter = function (sourceFile, parameters, newParam) {
                var p0 = ts.firstOrUndefined(parameters);
                if (p0) {
                    this.insertNodeBefore(sourceFile, p0, newParam);
                }
                else {
                    this.insertNodeAt(sourceFile, parameters.pos, newParam);
                }
            };
            ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, blankLineBetween) {
                if (blankLineBetween === void 0) { blankLineBetween = false; }
                this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}), newNode, this.getOptionsForInsertNodeBefore(before, newNode, blankLineBetween));
            };
            ChangeTracker.prototype.insertModifierBefore = function (sourceFile, modifier, before) {
                var pos = before.getStart(sourceFile);
                this.insertNodeAt(sourceFile, pos, ts.createToken(modifier), { suffix: " " });
            };
            ChangeTracker.prototype.insertLastModifierBefore = function (sourceFile, modifier, before) {
                if (!before.modifiers) {
                    this.insertModifierBefore(sourceFile, modifier, before);
                    return;
                }
                var pos = before.modifiers.end;
                this.insertNodeAt(sourceFile, pos, ts.createToken(modifier), { prefix: " " });
            };
            ChangeTracker.prototype.insertCommentBeforeLine = function (sourceFile, lineNumber, position, commentText) {
                var lineStartPosition = ts.getStartPositionOfLine(lineNumber, sourceFile);
                var startPosition = ts.getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
                // First try to see if we can put the comment on the previous line.
                // We need to make sure that we are not in the middle of a string literal or a comment.
                // If so, we do not want to separate the node from its comment if we can.
                // Otherwise, add an extra new line immediately before the error span.
                var insertAtLineStart = isValidLocationToAddComment(sourceFile, startPosition);
                var token = ts.getTouchingToken(sourceFile, insertAtLineStart ? startPosition : position);
                var indent = sourceFile.text.slice(lineStartPosition, startPosition);
                var text = (insertAtLineStart ? "" : this.newLineCharacter) + "//" + commentText + this.newLineCharacter + indent;
                this.insertText(sourceFile, token.getStart(sourceFile), text);
            };
            ChangeTracker.prototype.insertJsdocCommentBefore = function (sourceFile, node, tag) {
                var fnStart = node.getStart(sourceFile);
                if (node.jsDoc) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsdoc = _a[_i];
                        this.deleteRange(sourceFile, {
                            pos: ts.getLineStartPositionForPosition(jsdoc.getStart(sourceFile), sourceFile),
                            end: getAdjustedEndPosition(sourceFile, jsdoc, /*options*/ {})
                        });
                    }
                }
                var startPosition = ts.getPrecedingNonSpaceCharacterPosition(sourceFile.text, fnStart - 1);
                var indent = sourceFile.text.slice(startPosition, fnStart);
                this.insertNodeAt(sourceFile, fnStart, tag, { preserveLeadingWhitespace: false, suffix: this.newLineCharacter + indent });
            };
            ChangeTracker.prototype.replaceRangeWithText = function (sourceFile, range, text) {
                this.changes.push({ kind: ChangeKind.Text, sourceFile: sourceFile, range: range, text: text });
            };
            ChangeTracker.prototype.insertText = function (sourceFile, pos, text) {
                this.replaceRangeWithText(sourceFile, ts.createRange(pos), text);
            };
            /** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */
            ChangeTracker.prototype.tryInsertTypeAnnotation = function (sourceFile, node, type) {
                var _a;
                var endNode;
                if (ts.isFunctionLike(node)) {
                    endNode = ts.findChildOfKind(node, 21 /* CloseParenToken */, sourceFile);
                    if (!endNode) {
                        if (!ts.isArrowFunction(node))
                            return false; // Function missing parentheses, give up
                        // If no `)`, is an arrow function `x => x`, so use the end of the first parameter
                        endNode = ts.first(node.parameters);
                    }
                }
                else {
                    endNode = (_a = (node.kind === 242 /* VariableDeclaration */ ? node.exclamationToken : node.questionToken)) !== null && _a !== void 0 ? _a : node.name;
                }
                this.insertNodeAt(sourceFile, endNode.end, type, { prefix: ": " });
                return true;
            };
            ChangeTracker.prototype.tryInsertThisTypeAnnotation = function (sourceFile, node, type) {
                var start = ts.findChildOfKind(node, 20 /* OpenParenToken */, sourceFile).getStart(sourceFile) + 1;
                var suffix = node.parameters.length ? ", " : "";
                this.insertNodeAt(sourceFile, start, type, { prefix: "this: ", suffix: suffix });
            };
            ChangeTracker.prototype.insertTypeParameters = function (sourceFile, node, typeParameters) {
                // If no `(`, is an arrow function `x => x`, so use the pos of the first parameter
                var start = (ts.findChildOfKind(node, 20 /* OpenParenToken */, sourceFile) || ts.first(node.parameters)).getStart(sourceFile);
                this.insertNodesAt(sourceFile, start, typeParameters, { prefix: "<", suffix: ">" });
            };
            ChangeTracker.prototype.getOptionsForInsertNodeBefore = function (before, inserted, doubleNewlines) {
                if (ts.isStatement(before) || ts.isClassElement(before)) {
                    return { suffix: doubleNewlines ? this.newLineCharacter + this.newLineCharacter : this.newLineCharacter };
                }
                else if (ts.isVariableDeclaration(before)) { // insert `x = 1, ` into `const x = 1, y = 2;
                    return { suffix: ", " };
                }
                else if (ts.isParameter(before)) {
                    return ts.isParameter(inserted) ? { suffix: ", " } : {};
                }
                else if (ts.isStringLiteral(before) && ts.isImportDeclaration(before.parent) || ts.isNamedImports(before)) {
                    return { suffix: ", " };
                }
                return ts.Debug.failBadSyntaxKind(before); // We haven't handled this kind of node yet -- add it
            };
            ChangeTracker.prototype.insertNodeAtConstructorStart = function (sourceFile, ctr, newStatement) {
                var firstStatement = ts.firstOrUndefined(ctr.body.statements);
                if (!firstStatement || !ctr.body.multiLine) {
                    this.replaceConstructorBody(sourceFile, ctr, __spreadArrays([newStatement], ctr.body.statements));
                }
                else {
                    this.insertNodeBefore(sourceFile, firstStatement, newStatement);
                }
            };
            ChangeTracker.prototype.insertNodeAtConstructorEnd = function (sourceFile, ctr, newStatement) {
                var lastStatement = ts.lastOrUndefined(ctr.body.statements);
                if (!lastStatement || !ctr.body.multiLine) {
                    this.replaceConstructorBody(sourceFile, ctr, __spreadArrays(ctr.body.statements, [newStatement]));
                }
                else {
                    this.insertNodeAfter(sourceFile, lastStatement, newStatement);
                }
            };
            ChangeTracker.prototype.replaceConstructorBody = function (sourceFile, ctr, statements) {
                this.replaceNode(sourceFile, ctr.body, ts.createBlock(statements, /*multiLine*/ true));
            };
            ChangeTracker.prototype.insertNodeAtEndOfScope = function (sourceFile, scope, newNode) {
                var pos = getAdjustedStartPosition(sourceFile, scope.getLastToken(), {});
                this.insertNodeAt(sourceFile, pos, newNode, {
                    prefix: ts.isLineBreak(sourceFile.text.charCodeAt(scope.getLastToken().pos)) ? this.newLineCharacter : this.newLineCharacter + this.newLineCharacter,
                    suffix: this.newLineCharacter
                });
            };
            ChangeTracker.prototype.insertNodeAtClassStart = function (sourceFile, cls, newElement) {
                this.insertNodeAtStartWorker(sourceFile, cls, newElement);
            };
            ChangeTracker.prototype.insertNodeAtObjectStart = function (sourceFile, obj, newElement) {
                this.insertNodeAtStartWorker(sourceFile, obj, newElement);
            };
            ChangeTracker.prototype.insertNodeAtStartWorker = function (sourceFile, cls, newElement) {
                var _a;
                var indentation = (_a = this.guessIndentationFromExistingMembers(sourceFile, cls)) !== null && _a !== void 0 ? _a : this.computeIndentationForNewMember(sourceFile, cls);
                this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, this.getInsertNodeAtStartInsertOptions(sourceFile, cls, indentation));
            };
            /**
             * Tries to guess the indentation from the existing members of a class/interface/object. All members must be on
             * new lines and must share the same indentation.
             */
            ChangeTracker.prototype.guessIndentationFromExistingMembers = function (sourceFile, cls) {
                var indentation;
                var lastRange = cls;
                for (var _i = 0, _a = getMembersOrProperties(cls); _i < _a.length; _i++) {
                    var member = _a[_i];
                    if (ts.rangeStartPositionsAreOnSameLine(lastRange, member, sourceFile)) {
                        // each indented member must be on a new line
                        return undefined;
                    }
                    var memberStart = member.getStart(sourceFile);
                    var memberIndentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options);
                    if (indentation === undefined) {
                        indentation = memberIndentation;
                    }
                    else if (memberIndentation !== indentation) {
                        // indentation of multiple members is not consistent
                        return undefined;
                    }
                    lastRange = member;
                }
                return indentation;
            };
            ChangeTracker.prototype.computeIndentationForNewMember = function (sourceFile, cls) {
                var _a;
                var clsStart = cls.getStart(sourceFile);
                return ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options)
                    + ((_a = this.formatContext.options.indentSize) !== null && _a !== void 0 ? _a : 4);
            };
            ChangeTracker.prototype.getInsertNodeAtStartInsertOptions = function (sourceFile, cls, indentation) {
                // Rules:
                // - Always insert leading newline.
                // - For object literals:
                //   - Add a trailing comma if there are existing members in the node, or the source file is not a JSON file
                //     (because trailing commas are generally illegal in a JSON file).
                //   - Add a leading comma if the source file is not a JSON file, there are existing insertions,
                //     and the node is empty (because we didn't add a trailing comma per the previous rule).
                // - Only insert a trailing newline if body is single-line and there are no other insertions for the node.
                //   NOTE: This is handled in `finishClassesWithNodesInsertedAtStart`.
                var members = getMembersOrProperties(cls);
                var isEmpty = members.length === 0;
                var isFirstInsertion = ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile });
                var insertTrailingComma = ts.isObjectLiteralExpression(cls) && (!ts.isJsonSourceFile(sourceFile) || !isEmpty);
                var insertLeadingComma = ts.isObjectLiteralExpression(cls) && ts.isJsonSourceFile(sourceFile) && isEmpty && !isFirstInsertion;
                return {
                    indentation: indentation,
                    prefix: (insertLeadingComma ? "," : "") + this.newLineCharacter,
                    suffix: insertTrailingComma ? "," : ""
                };
            };
            ChangeTracker.prototype.insertNodeAfterComma = function (sourceFile, after, newNode) {
                var endPosition = this.insertNodeAfterWorker(sourceFile, this.nextCommaToken(sourceFile, after) || after, newNode);
                this.insertNodeAt(sourceFile, endPosition, newNode, this.getInsertNodeAfterOptions(sourceFile, after));
            };
            ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode) {
                var endPosition = this.insertNodeAfterWorker(sourceFile, after, newNode);
                this.insertNodeAt(sourceFile, endPosition, newNode, this.getInsertNodeAfterOptions(sourceFile, after));
            };
            ChangeTracker.prototype.insertNodeAtEndOfList = function (sourceFile, list, newNode) {
                this.insertNodeAt(sourceFile, list.end, newNode, { prefix: ", " });
            };
            ChangeTracker.prototype.insertNodesAfter = function (sourceFile, after, newNodes) {
                var endPosition = this.insertNodeAfterWorker(sourceFile, after, ts.first(newNodes));
                this.insertNodesAt(sourceFile, endPosition, newNodes, this.getInsertNodeAfterOptions(sourceFile, after));
            };
            ChangeTracker.prototype.insertNodeAfterWorker = function (sourceFile, after, newNode) {
                if (needSemicolonBetween(after, newNode)) {
                    // check if previous statement ends with semicolon
                    // if not - insert semicolon to preserve the code from changing the meaning due to ASI
                    if (sourceFile.text.charCodeAt(after.end - 1) !== 59 /* semicolon */) {
                        this.replaceRange(sourceFile, ts.createRange(after.end), ts.createToken(26 /* SemicolonToken */));
                    }
                }
                var endPosition = getAdjustedEndPosition(sourceFile, after, {});
                return endPosition;
            };
            ChangeTracker.prototype.getInsertNodeAfterOptions = function (sourceFile, after) {
                var options = this.getInsertNodeAfterOptionsWorker(after);
                return __assign(__assign({}, options), { prefix: after.end === sourceFile.end && ts.isStatement(after) ? (options.prefix ? "\n" + options.prefix : "\n") : options.prefix });
            };
            ChangeTracker.prototype.getInsertNodeAfterOptionsWorker = function (node) {
                switch (node.kind) {
                    case 245 /* ClassDeclaration */:
                    case 249 /* ModuleDeclaration */:
                        return { prefix: this.newLineCharacter, suffix: this.newLineCharacter };
                    case 242 /* VariableDeclaration */:
                    case 10 /* StringLiteral */:
                    case 75 /* Identifier */:
                        return { prefix: ", " };
                    case 281 /* PropertyAssignment */:
                        return { suffix: "," + this.newLineCharacter };
                    case 89 /* ExportKeyword */:
                        return { prefix: " " };
                    case 156 /* Parameter */:
                        return {};
                    default:
                        ts.Debug.assert(ts.isStatement(node) || ts.isClassOrTypeElement(node)); // Else we haven't handled this kind of node yet -- add it
                        return { suffix: this.newLineCharacter };
                }
            };
            ChangeTracker.prototype.insertName = function (sourceFile, node, name) {
                ts.Debug.assert(!node.name);
                if (node.kind === 202 /* ArrowFunction */) {
                    var arrow = ts.findChildOfKind(node, 38 /* EqualsGreaterThanToken */, sourceFile);
                    var lparen = ts.findChildOfKind(node, 20 /* OpenParenToken */, sourceFile);
                    if (lparen) {
                        // `() => {}` --> `function f() {}`
                        this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [ts.createToken(94 /* FunctionKeyword */), ts.createIdentifier(name)], { joiner: " " });
                        deleteNode(this, sourceFile, arrow);
                    }
                    else {
                        // `x => {}` -> `function f(x) {}`
                        this.insertText(sourceFile, ts.first(node.parameters).getStart(sourceFile), "function " + name + "(");
                        // Replacing full range of arrow to get rid of the leading space -- replace ` =>` with `)`
                        this.replaceRange(sourceFile, arrow, ts.createToken(21 /* CloseParenToken */));
                    }
                    if (node.body.kind !== 223 /* Block */) {
                        // `() => 0` => `function f() { return 0; }`
                        this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [ts.createToken(18 /* OpenBraceToken */), ts.createToken(101 /* ReturnKeyword */)], { joiner: " ", suffix: " " });
                        this.insertNodesAt(sourceFile, node.body.end, [ts.createToken(26 /* SemicolonToken */), ts.createToken(19 /* CloseBraceToken */)], { joiner: " " });
                    }
                }
                else {
                    var pos = ts.findChildOfKind(node, node.kind === 201 /* FunctionExpression */ ? 94 /* FunctionKeyword */ : 80 /* ClassKeyword */, sourceFile).end;
                    this.insertNodeAt(sourceFile, pos, ts.createIdentifier(name), { prefix: " " });
                }
            };
            ChangeTracker.prototype.insertExportModifier = function (sourceFile, node) {
                this.insertText(sourceFile, node.getStart(sourceFile), "export ");
            };
            /**
             * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range,
             * i.e. arguments in arguments lists, parameters in parameter lists etc.
             * Note that separators are part of the node in statements and class elements.
             */
            ChangeTracker.prototype.insertNodeInListAfter = function (sourceFile, after, newNode, containingList) {
                if (containingList === void 0) { containingList = ts.formatting.SmartIndenter.getContainingList(after, sourceFile); }
                if (!containingList) {
                    ts.Debug.fail("node is not a list element");
                    return;
                }
                var index = ts.indexOfNode(containingList, after);
                if (index < 0) {
                    return;
                }
                var end = after.getEnd();
                if (index !== containingList.length - 1) {
                    // any element except the last one
                    // use next sibling as an anchor
                    var nextToken = ts.getTokenAtPosition(sourceFile, after.end);
                    if (nextToken && isSeparator(after, nextToken)) {
                        // for list
                        // a, b, c
                        // create change for adding 'e' after 'a' as
                        // - find start of next element after a (it is b)
                        // - use this start as start and end position in final change
                        // - build text of change by formatting the text of node + separator + whitespace trivia of b
                        // in multiline case it will work as
                        //   a,
                        //   b,
                        //   c,
                        // result - '*' denotes leading trivia that will be inserted after new text (displayed as '#')
                        //   a,*
                        // ***insertedtext<separator>#
                        // ###b,
                        //   c,
                        // find line and character of the next element
                        var lineAndCharOfNextElement = ts.getLineAndCharacterOfPosition(sourceFile, skipWhitespacesAndLineBreaks(sourceFile.text, containingList[index + 1].getFullStart()));
                        // find line and character of the token that precedes next element (usually it is separator)
                        var lineAndCharOfNextToken = ts.getLineAndCharacterOfPosition(sourceFile, nextToken.end);
                        var prefix = void 0;
                        var startPos = void 0;
                        if (lineAndCharOfNextToken.line === lineAndCharOfNextElement.line) {
                            // next element is located on the same line with separator:
                            // a,$$$$b
                            //  ^    ^
                            //  |    |-next element
                            //  |-separator
                            // where $$$ is some leading trivia
                            // for a newly inserted node we'll maintain the same relative position comparing to separator and replace leading trivia with spaces
                            // a,    x,$$$$b
                            //  ^    ^     ^
                            //  |    |     |-next element
                            //  |    |-new inserted node padded with spaces
                            //  |-separator
                            startPos = nextToken.end;
                            prefix = spaces(lineAndCharOfNextElement.character - lineAndCharOfNextToken.character);
                        }
                        else {
                            // next element is located on different line that separator
                            // let insert position be the beginning of the line that contains next element
                            startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile);
                        }
                        // write separator and leading trivia of the next element as suffix
                        var suffix = "" + ts.tokenToString(nextToken.kind) + sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile));
                        this.replaceRange(sourceFile, ts.createRange(startPos, containingList[index + 1].getStart(sourceFile)), newNode, { prefix: prefix, suffix: suffix });
                    }
                }
                else {
                    var afterStart = after.getStart(sourceFile);
                    var afterStartLinePosition = ts.getLineStartPositionForPosition(afterStart, sourceFile);
                    var separator = void 0;
                    var multilineList = false;
                    // insert element after the last element in the list that has more than one item
                    // pick the element preceding the after element to:
                    // - pick the separator
                    // - determine if list is a multiline
                    if (containingList.length === 1) {
                        // if list has only one element then we'll format is as multiline if node has comment in trailing trivia, or as singleline otherwise
                        // i.e. var x = 1 // this is x
                        //     | new element will be inserted at this position
                        separator = 27 /* CommaToken */;
                    }
                    else {
                        // element has more than one element, pick separator from the list
                        var tokenBeforeInsertPosition = ts.findPrecedingToken(after.pos, sourceFile);
                        separator = isSeparator(after, tokenBeforeInsertPosition) ? tokenBeforeInsertPosition.kind : 27 /* CommaToken */;
                        // determine if list is multiline by checking lines of after element and element that precedes it.
                        var afterMinusOneStartLinePosition = ts.getLineStartPositionForPosition(containingList[index - 1].getStart(sourceFile), sourceFile);
                        multilineList = afterMinusOneStartLinePosition !== afterStartLinePosition;
                    }
                    if (hasCommentsBeforeLineBreak(sourceFile.text, after.end)) {
                        // in this case we'll always treat containing list as multiline
                        multilineList = true;
                    }
                    if (multilineList) {
                        // insert separator immediately following the 'after' node to preserve comments in trailing trivia
                        this.replaceRange(sourceFile, ts.createRange(end), ts.createToken(separator));
                        // use the same indentation as 'after' item
                        var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options);
                        // insert element before the line break on the line that contains 'after' element
                        var insertPos = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false);
                        if (insertPos !== end && ts.isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) {
                            insertPos--;
                        }
                        this.replaceRange(sourceFile, ts.createRange(insertPos), newNode, { indentation: indentation, prefix: this.newLineCharacter });
                    }
                    else {
                        this.replaceRange(sourceFile, ts.createRange(end), newNode, { prefix: ts.tokenToString(separator) + " " });
                    }
                }
            };
            ChangeTracker.prototype.parenthesizeExpression = function (sourceFile, expression) {
                this.replaceRange(sourceFile, ts.rangeOfNode(expression), ts.createParen(expression));
            };
            ChangeTracker.prototype.finishClassesWithNodesInsertedAtStart = function () {
                var _this = this;
                this.classesWithNodesInsertedAtStart.forEach(function (_a) {
                    var node = _a.node, sourceFile = _a.sourceFile;
                    var _b = getClassOrObjectBraceEnds(node, sourceFile), openBraceEnd = _b[0], closeBraceEnd = _b[1];
                    if (openBraceEnd !== undefined && closeBraceEnd !== undefined) {
                        var isEmpty = getMembersOrProperties(node).length === 0;
                        var isSingleLine = ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile);
                        if (isEmpty && isSingleLine && openBraceEnd !== closeBraceEnd - 1) {
                            // For `class C { }` remove the whitespace inside the braces.
                            _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1));
                        }
                        if (isSingleLine) {
                            _this.insertText(sourceFile, closeBraceEnd - 1, _this.newLineCharacter);
                        }
                    }
                });
            };
            ChangeTracker.prototype.finishDeleteDeclarations = function () {
                var _this = this;
                var deletedNodesInLists = new ts.NodeSet(); // Stores nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`.
                var _loop_9 = function (sourceFile, node) {
                    if (!this_1.deletedNodes.some(function (d) { return d.sourceFile === sourceFile && ts.rangeContainsRangeExclusive(d.node, node); })) {
                        if (ts.isArray(node)) {
                            this_1.deleteRange(sourceFile, ts.rangeOfTypeParameters(node));
                        }
                        else {
                            deleteDeclaration.deleteDeclaration(this_1, deletedNodesInLists, sourceFile, node);
                        }
                    }
                };
                var this_1 = this;
                for (var _i = 0, _a = this.deletedNodes; _i < _a.length; _i++) {
                    var _b = _a[_i], sourceFile = _b.sourceFile, node = _b.node;
                    _loop_9(sourceFile, node);
                }
                deletedNodesInLists.forEach(function (node) {
                    var sourceFile = node.getSourceFile();
                    var list = ts.formatting.SmartIndenter.getContainingList(node, sourceFile);
                    if (node !== ts.last(list))
                        return;
                    var lastNonDeletedIndex = ts.findLastIndex(list, function (n) { return !deletedNodesInLists.has(n); }, list.length - 2);
                    if (lastNonDeletedIndex !== -1) {
                        _this.deleteRange(sourceFile, { pos: list[lastNonDeletedIndex].end, end: startPositionToDeleteNodeInList(sourceFile, list[lastNonDeletedIndex + 1]) });
                    }
                });
            };
            /**
             * Note: after calling this, the TextChanges object must be discarded!
             * @param validate only for tests
             *    The reason we must validate as part of this method is that `getNonFormattedText` changes the node's positions,
             *    so we can only call this once and can't get the non-formatted text separately.
             */
            ChangeTracker.prototype.getChanges = function (validate) {
                this.finishDeleteDeclarations();
                this.finishClassesWithNodesInsertedAtStart();
                var changes = changesToText.getTextChangesFromChanges(this.changes, this.newLineCharacter, this.formatContext, validate);
                for (var _i = 0, _a = this.newFiles; _i < _a.length; _i++) {
                    var _b = _a[_i], oldFile = _b.oldFile, fileName = _b.fileName, statements = _b.statements;
                    changes.push(changesToText.newFileChanges(oldFile, fileName, statements, this.newLineCharacter, this.formatContext));
                }
                return changes;
            };
            ChangeTracker.prototype.createNewFile = function (oldFile, fileName, statements) {
                this.newFiles.push({ oldFile: oldFile, fileName: fileName, statements: statements });
            };
            return ChangeTracker;
        }());
        textChanges_3.ChangeTracker = ChangeTracker;
        // find first non-whitespace position in the leading trivia of the node
        function startPositionToDeleteNodeInList(sourceFile, node) {
            return ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, { leadingTriviaOption: LeadingTriviaOption.IncludeAll }), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        function getClassOrObjectBraceEnds(cls, sourceFile) {
            var open = ts.findChildOfKind(cls, 18 /* OpenBraceToken */, sourceFile);
            var close = ts.findChildOfKind(cls, 19 /* CloseBraceToken */, sourceFile);
            return [open === null || open === void 0 ? void 0 : open.end, close === null || close === void 0 ? void 0 : close.end];
        }
        function getMembersOrProperties(cls) {
            return ts.isObjectLiteralExpression(cls) ? cls.properties : cls.members;
        }
        function getNewFileText(statements, scriptKind, newLineCharacter, formatContext) {
            return changesToText.newFileChangesWorker(/*oldFile*/ undefined, scriptKind, statements, newLineCharacter, formatContext);
        }
        textChanges_3.getNewFileText = getNewFileText;
        var changesToText;
        (function (changesToText) {
            function getTextChangesFromChanges(changes, newLineCharacter, formatContext, validate) {
                return ts.mapDefined(ts.group(changes, function (c) { return c.sourceFile.path; }), function (changesInFile) {
                    var sourceFile = changesInFile[0].sourceFile;
                    // order changes by start position
                    // If the start position is the same, put the shorter range first, since an empty range (x, x) may precede (x, y) but not vice-versa.
                    var normalized = ts.stableSort(changesInFile, function (a, b) { return (a.range.pos - b.range.pos) || (a.range.end - b.range.end); });
                    var _loop_10 = function (i) {
                        ts.Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos, "Changes overlap", function () {
                            return JSON.stringify(normalized[i].range) + " and " + JSON.stringify(normalized[i + 1].range);
                        });
                    };
                    // verify that change intervals do not overlap, except possibly at end points.
                    for (var i = 0; i < normalized.length - 1; i++) {
                        _loop_10(i);
                    }
                    var textChanges = ts.mapDefined(normalized, function (c) {
                        var span = ts.createTextSpanFromRange(c.range);
                        var newText = computeNewText(c, sourceFile, newLineCharacter, formatContext, validate);
                        // Filter out redundant changes.
                        if (span.length === newText.length && ts.stringContainsAt(sourceFile.text, newText, span.start)) {
                            return undefined;
                        }
                        return ts.createTextChange(span, newText);
                    });
                    return textChanges.length > 0 ? { fileName: sourceFile.fileName, textChanges: textChanges } : undefined;
                });
            }
            changesToText.getTextChangesFromChanges = getTextChangesFromChanges;
            function newFileChanges(oldFile, fileName, statements, newLineCharacter, formatContext) {
                var text = newFileChangesWorker(oldFile, ts.getScriptKindFromFileName(fileName), statements, newLineCharacter, formatContext);
                return { fileName: fileName, textChanges: [ts.createTextChange(ts.createTextSpan(0, 0), text)], isNewFile: true };
            }
            changesToText.newFileChanges = newFileChanges;
            function newFileChangesWorker(oldFile, scriptKind, statements, newLineCharacter, formatContext) {
                // TODO: this emits the file, parses it back, then formats it that -- may be a less roundabout way to do this
                var nonFormattedText = statements.map(function (s) { return getNonformattedText(s, oldFile, newLineCharacter).text; }).join(newLineCharacter);
                var sourceFile = ts.createSourceFile("any file name", nonFormattedText, 99 /* ESNext */, /*setParentNodes*/ true, scriptKind);
                var changes = ts.formatting.formatDocument(sourceFile, formatContext);
                return applyChanges(nonFormattedText, changes) + newLineCharacter;
            }
            changesToText.newFileChangesWorker = newFileChangesWorker;
            function computeNewText(change, sourceFile, newLineCharacter, formatContext, validate) {
                if (change.kind === ChangeKind.Remove) {
                    return "";
                }
                if (change.kind === ChangeKind.Text) {
                    return change.text;
                }
                var _a = change.options, options = _a === void 0 ? {} : _a, pos = change.range.pos;
                var format = function (n) { return getFormattedTextOfNode(n, sourceFile, pos, options, newLineCharacter, formatContext, validate); };
                var text = change.kind === ChangeKind.ReplaceWithMultipleNodes
                    ? change.nodes.map(function (n) { return ts.removeSuffix(format(n), newLineCharacter); }).join(change.options.joiner || newLineCharacter) // TODO: GH#18217
                    : format(change.node);
                // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line
                var noIndent = (options.preserveLeadingWhitespace || options.indentation !== undefined || ts.getLineStartPositionForPosition(pos, sourceFile) === pos) ? text : text.replace(/^\s+/, "");
                return (options.prefix || "") + noIndent
                    + ((!options.suffix || ts.endsWith(noIndent, options.suffix))
                        ? "" : options.suffix);
            }
            function getFormatCodeSettingsForWriting(_a, sourceFile) {
                var options = _a.options;
                var shouldAutoDetectSemicolonPreference = !options.semicolons || options.semicolons === ts.SemicolonPreference.Ignore;
                var shouldRemoveSemicolons = options.semicolons === ts.SemicolonPreference.Remove || shouldAutoDetectSemicolonPreference && !ts.probablyUsesSemicolons(sourceFile);
                return __assign(__assign({}, options), { semicolons: shouldRemoveSemicolons ? ts.SemicolonPreference.Remove : ts.SemicolonPreference.Ignore });
            }
            /** Note: this may mutate `nodeIn`. */
            function getFormattedTextOfNode(nodeIn, sourceFile, pos, _a, newLineCharacter, formatContext, validate) {
                var indentation = _a.indentation, prefix = _a.prefix, delta = _a.delta;
                var _b = getNonformattedText(nodeIn, sourceFile, newLineCharacter), node = _b.node, text = _b.text;
                if (validate)
                    validate(node, text);
                var formatOptions = getFormatCodeSettingsForWriting(formatContext, sourceFile);
                var initialIndentation = indentation !== undefined
                    ? indentation
                    : ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, prefix === newLineCharacter || ts.getLineStartPositionForPosition(pos, sourceFile) === pos);
                if (delta === undefined) {
                    delta = ts.formatting.SmartIndenter.shouldIndentChildNode(formatOptions, nodeIn) ? (formatOptions.indentSize || 0) : 0;
                }
                var file = { text: text, getLineAndCharacterOfPosition: function (pos) { return ts.getLineAndCharacterOfPosition(this, pos); } };
                var changes = ts.formatting.formatNodeGivenIndentation(node, file, sourceFile.languageVariant, initialIndentation, delta, __assign(__assign({}, formatContext), { options: formatOptions }));
                return applyChanges(text, changes);
            }
            /** Note: output node may be mutated input node. */
            function getNonformattedText(node, sourceFile, newLineCharacter) {
                var writer = createWriter(newLineCharacter);
                var newLine = newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */;
                ts.createPrinter({ newLine: newLine, neverAsciiEscape: true, preserveSourceNewlines: true }, writer).writeNode(4 /* Unspecified */, node, sourceFile, writer);
                return { text: writer.getText(), node: assignPositionsToNode(node) };
            }
            changesToText.getNonformattedText = getNonformattedText;
        })(changesToText || (changesToText = {}));
        function applyChanges(text, changes) {
            for (var i = changes.length - 1; i >= 0; i--) {
                var _a = changes[i], span = _a.span, newText = _a.newText;
                text = "" + text.substring(0, span.start) + newText + text.substring(ts.textSpanEnd(span));
            }
            return text;
        }
        textChanges_3.applyChanges = applyChanges;
        function isTrivia(s) {
            return ts.skipTrivia(s, 0) === s.length;
        }
        function assignPositionsToNode(node) {
            var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // TODO: GH#18217
            // create proxy node for non synthesized nodes
            var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited);
            newNode.pos = getPos(node);
            newNode.end = getEnd(node);
            return newNode;
        }
        function assignPositionsToNodeArray(nodes, visitor, test, start, count) {
            var visited = ts.visitNodes(nodes, visitor, test, start, count);
            if (!visited) {
                return visited;
            }
            // clone nodearray if necessary
            var nodeArray = visited === nodes ? ts.createNodeArray(visited.slice(0)) : visited;
            nodeArray.pos = getPos(nodes);
            nodeArray.end = getEnd(nodes);
            return nodeArray;
        }
        function createWriter(newLine) {
            var lastNonTriviaPosition = 0;
            var writer = ts.createTextWriter(newLine);
            var onEmitNode = function (hint, node, printCallback) {
                if (node) {
                    setPos(node, lastNonTriviaPosition);
                }
                printCallback(hint, node);
                if (node) {
                    setEnd(node, lastNonTriviaPosition);
                }
            };
            var onBeforeEmitNodeArray = function (nodes) {
                if (nodes) {
                    setPos(nodes, lastNonTriviaPosition);
                }
            };
            var onAfterEmitNodeArray = function (nodes) {
                if (nodes) {
                    setEnd(nodes, lastNonTriviaPosition);
                }
            };
            var onBeforeEmitToken = function (node) {
                if (node) {
                    setPos(node, lastNonTriviaPosition);
                }
            };
            var onAfterEmitToken = function (node) {
                if (node) {
                    setEnd(node, lastNonTriviaPosition);
                }
            };
            function setLastNonTriviaPosition(s, force) {
                if (force || !isTrivia(s)) {
                    lastNonTriviaPosition = writer.getTextPos();
                    var i = 0;
                    while (ts.isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) {
                        i++;
                    }
                    // trim trailing whitespaces
                    lastNonTriviaPosition -= i;
                }
            }
            function write(s) {
                writer.write(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeComment(s) {
                writer.writeComment(s);
            }
            function writeKeyword(s) {
                writer.writeKeyword(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeOperator(s) {
                writer.writeOperator(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writePunctuation(s) {
                writer.writePunctuation(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeTrailingSemicolon(s) {
                writer.writeTrailingSemicolon(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeParameter(s) {
                writer.writeParameter(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeProperty(s) {
                writer.writeProperty(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeSpace(s) {
                writer.writeSpace(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeStringLiteral(s) {
                writer.writeStringLiteral(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeSymbol(s, sym) {
                writer.writeSymbol(s, sym);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeLine(force) {
                writer.writeLine(force);
            }
            function increaseIndent() {
                writer.increaseIndent();
            }
            function decreaseIndent() {
                writer.decreaseIndent();
            }
            function getText() {
                return writer.getText();
            }
            function rawWrite(s) {
                writer.rawWrite(s);
                setLastNonTriviaPosition(s, /*force*/ false);
            }
            function writeLiteral(s) {
                writer.writeLiteral(s);
                setLastNonTriviaPosition(s, /*force*/ true);
            }
            function getTextPos() {
                return writer.getTextPos();
            }
            function getLine() {
                return writer.getLine();
            }
            function getColumn() {
                return writer.getColumn();
            }
            function getIndent() {
                return writer.getIndent();
            }
            function isAtStartOfLine() {
                return writer.isAtStartOfLine();
            }
            function clear() {
                writer.clear();
                lastNonTriviaPosition = 0;
            }
            return {
                onEmitNode: onEmitNode,
                onBeforeEmitNodeArray: onBeforeEmitNodeArray,
                onAfterEmitNodeArray: onAfterEmitNodeArray,
                onBeforeEmitToken: onBeforeEmitToken,
                onAfterEmitToken: onAfterEmitToken,
                write: write,
                writeComment: writeComment,
                writeKeyword: writeKeyword,
                writeOperator: writeOperator,
                writePunctuation: writePunctuation,
                writeTrailingSemicolon: writeTrailingSemicolon,
                writeParameter: writeParameter,
                writeProperty: writeProperty,
                writeSpace: writeSpace,
                writeStringLiteral: writeStringLiteral,
                writeSymbol: writeSymbol,
                writeLine: writeLine,
                increaseIndent: increaseIndent,
                decreaseIndent: decreaseIndent,
                getText: getText,
                rawWrite: rawWrite,
                writeLiteral: writeLiteral,
                getTextPos: getTextPos,
                getLine: getLine,
                getColumn: getColumn,
                getIndent: getIndent,
                isAtStartOfLine: isAtStartOfLine,
                hasTrailingComment: function () { return writer.hasTrailingComment(); },
                hasTrailingWhitespace: function () { return writer.hasTrailingWhitespace(); },
                clear: clear
            };
        }
        function getInsertionPositionAtSourceFileTop(sourceFile) {
            var lastPrologue;
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var node = _a[_i];
                if (ts.isPrologueDirective(node)) {
                    lastPrologue = node;
                }
                else {
                    break;
                }
            }
            var position = 0;
            var text = sourceFile.text;
            if (lastPrologue) {
                position = lastPrologue.end;
                advancePastLineBreak();
                return position;
            }
            var shebang = ts.getShebang(text);
            if (shebang !== undefined) {
                position = shebang.length;
                advancePastLineBreak();
            }
            var ranges = ts.getLeadingCommentRanges(text, position);
            if (!ranges)
                return position;
            // Find the first attached comment to the first node and add before it
            var lastComment;
            var firstNodeLine;
            for (var _b = 0, ranges_1 = ranges; _b < ranges_1.length; _b++) {
                var range = ranges_1[_b];
                if (range.kind === 3 /* MultiLineCommentTrivia */) {
                    if (ts.isPinnedComment(text, range.pos)) {
                        lastComment = { range: range, pinnedOrTripleSlash: true };
                        continue;
                    }
                }
                else if (ts.isRecognizedTripleSlashComment(text, range.pos, range.end)) {
                    lastComment = { range: range, pinnedOrTripleSlash: true };
                    continue;
                }
                if (lastComment) {
                    // Always insert after pinned or triple slash comments
                    if (lastComment.pinnedOrTripleSlash)
                        break;
                    // There was a blank line between the last comment and this comment.
                    // This comment is not part of the copyright comments
                    var commentLine = sourceFile.getLineAndCharacterOfPosition(range.pos).line;
                    var lastCommentEndLine = sourceFile.getLineAndCharacterOfPosition(lastComment.range.end).line;
                    if (commentLine >= lastCommentEndLine + 2)
                        break;
                }
                if (sourceFile.statements.length) {
                    if (firstNodeLine === undefined)
                        firstNodeLine = sourceFile.getLineAndCharacterOfPosition(sourceFile.statements[0].getStart()).line;
                    var commentEndLine = sourceFile.getLineAndCharacterOfPosition(range.end).line;
                    if (firstNodeLine < commentEndLine + 2)
                        break;
                }
                lastComment = { range: range, pinnedOrTripleSlash: false };
            }
            if (lastComment) {
                position = lastComment.range.end;
                advancePastLineBreak();
            }
            return position;
            function advancePastLineBreak() {
                if (position < text.length) {
                    var charCode = text.charCodeAt(position);
                    if (ts.isLineBreak(charCode)) {
                        position++;
                        if (position < text.length && charCode === 13 /* carriageReturn */ && text.charCodeAt(position) === 10 /* lineFeed */) {
                            position++;
                        }
                    }
                }
            }
        }
        function isValidLocationToAddComment(sourceFile, position) {
            return !ts.isInComment(sourceFile, position) && !ts.isInString(sourceFile, position) && !ts.isInTemplateString(sourceFile, position) && !ts.isInJSXText(sourceFile, position);
        }
        textChanges_3.isValidLocationToAddComment = isValidLocationToAddComment;
        function needSemicolonBetween(a, b) {
            return (ts.isPropertySignature(a) || ts.isPropertyDeclaration(a)) && ts.isClassOrTypeElement(b) && b.name.kind === 154 /* ComputedPropertyName */
                || ts.isStatementButNotDeclaration(a) && ts.isStatementButNotDeclaration(b); // TODO: only if b would start with a `(` or `[`
        }
        var deleteDeclaration;
        (function (deleteDeclaration_1) {
            function deleteDeclaration(changes, deletedNodesInLists, sourceFile, node) {
                switch (node.kind) {
                    case 156 /* Parameter */: {
                        var oldFunction = node.parent;
                        if (ts.isArrowFunction(oldFunction) &&
                            oldFunction.parameters.length === 1 &&
                            !ts.findChildOfKind(oldFunction, 20 /* OpenParenToken */, sourceFile)) {
                            // Lambdas with exactly one parameter are special because, after removal, there
                            // must be an empty parameter list (i.e. `()`) and this won't necessarily be the
                            // case if the parameter is simply removed (e.g. in `x => 1`).
                            changes.replaceNodeWithText(sourceFile, node, "()");
                        }
                        else {
                            deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        }
                        break;
                    }
                    case 254 /* ImportDeclaration */:
                    case 253 /* ImportEqualsDeclaration */:
                        var isFirstImport = sourceFile.imports.length && node === ts.first(sourceFile.imports).parent || node === ts.find(sourceFile.statements, ts.isAnyImportSyntax);
                        // For first import, leave header comment in place, otherwise only delete JSDoc comments
                        deleteNode(changes, sourceFile, node, { leadingTriviaOption: isFirstImport ? LeadingTriviaOption.Exclude : ts.hasJSDocNodes(node) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine });
                        break;
                    case 191 /* BindingElement */:
                        var pattern = node.parent;
                        var preserveComma = pattern.kind === 190 /* ArrayBindingPattern */ && node !== ts.last(pattern.elements);
                        if (preserveComma) {
                            deleteNode(changes, sourceFile, node);
                        }
                        else {
                            deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        }
                        break;
                    case 242 /* VariableDeclaration */:
                        deleteVariableDeclaration(changes, deletedNodesInLists, sourceFile, node);
                        break;
                    case 155 /* TypeParameter */:
                        deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        break;
                    case 258 /* ImportSpecifier */:
                        var namedImports = node.parent;
                        if (namedImports.elements.length === 1) {
                            deleteImportBinding(changes, sourceFile, namedImports);
                        }
                        else {
                            deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        }
                        break;
                    case 256 /* NamespaceImport */:
                        deleteImportBinding(changes, sourceFile, node);
                        break;
                    case 26 /* SemicolonToken */:
                        deleteNode(changes, sourceFile, node, { trailingTriviaOption: TrailingTriviaOption.Exclude });
                        break;
                    case 94 /* FunctionKeyword */:
                        deleteNode(changes, sourceFile, node, { leadingTriviaOption: LeadingTriviaOption.Exclude });
                        break;
                    case 245 /* ClassDeclaration */:
                    case 244 /* FunctionDeclaration */:
                        deleteNode(changes, sourceFile, node, { leadingTriviaOption: ts.hasJSDocNodes(node) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine });
                        break;
                    default:
                        if (ts.isImportClause(node.parent) && node.parent.name === node) {
                            deleteDefaultImport(changes, sourceFile, node.parent);
                        }
                        else if (ts.isCallExpression(node.parent) && ts.contains(node.parent.arguments, node)) {
                            deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                        }
                        else {
                            deleteNode(changes, sourceFile, node);
                        }
                }
            }
            deleteDeclaration_1.deleteDeclaration = deleteDeclaration;
            function deleteDefaultImport(changes, sourceFile, importClause) {
                if (!importClause.namedBindings) {
                    // Delete the whole import
                    deleteNode(changes, sourceFile, importClause.parent);
                }
                else {
                    // import |d,| * as ns from './file'
                    var start = importClause.name.getStart(sourceFile);
                    var nextToken = ts.getTokenAtPosition(sourceFile, importClause.name.end);
                    if (nextToken && nextToken.kind === 27 /* CommaToken */) {
                        // shift first non-whitespace position after comma to the start position of the node
                        var end = ts.skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true);
                        changes.deleteRange(sourceFile, { pos: start, end: end });
                    }
                    else {
                        deleteNode(changes, sourceFile, importClause.name);
                    }
                }
            }
            function deleteImportBinding(changes, sourceFile, node) {
                if (node.parent.name) {
                    // Delete named imports while preserving the default import
                    // import d|, * as ns| from './file'
                    // import d|, { a }| from './file'
                    var previousToken = ts.Debug.checkDefined(ts.getTokenAtPosition(sourceFile, node.pos - 1));
                    changes.deleteRange(sourceFile, { pos: previousToken.getStart(sourceFile), end: node.end });
                }
                else {
                    // Delete the entire import declaration
                    // |import * as ns from './file'|
                    // |import { a } from './file'|
                    var importDecl = ts.getAncestor(node, 254 /* ImportDeclaration */);
                    deleteNode(changes, sourceFile, importDecl);
                }
            }
            function deleteVariableDeclaration(changes, deletedNodesInLists, sourceFile, node) {
                var parent = node.parent;
                if (parent.kind === 280 /* CatchClause */) {
                    // TODO: There's currently no unused diagnostic for this, could be a suggestion
                    changes.deleteNodeRange(sourceFile, ts.findChildOfKind(parent, 20 /* OpenParenToken */, sourceFile), ts.findChildOfKind(parent, 21 /* CloseParenToken */, sourceFile));
                    return;
                }
                if (parent.declarations.length !== 1) {
                    deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
                    return;
                }
                var gp = parent.parent;
                switch (gp.kind) {
                    case 232 /* ForOfStatement */:
                    case 231 /* ForInStatement */:
                        changes.replaceNode(sourceFile, node, ts.createObjectLiteral());
                        break;
                    case 230 /* ForStatement */:
                        deleteNode(changes, sourceFile, parent);
                        break;
                    case 225 /* VariableStatement */:
                        deleteNode(changes, sourceFile, gp, { leadingTriviaOption: ts.hasJSDocNodes(gp) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine });
                        break;
                    default:
                        ts.Debug.assertNever(gp);
                }
            }
        })(deleteDeclaration || (deleteDeclaration = {}));
        /** Warning: This deletes comments too. See `copyComments` in `convertFunctionToEs6Class`. */
        // Exported for tests only! (TODO: improve tests to not need this)
        function deleteNode(changes, sourceFile, node, options) {
            if (options === void 0) { options = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }; }
            var startPosition = getAdjustedStartPosition(sourceFile, node, options);
            var endPosition = getAdjustedEndPosition(sourceFile, node, options);
            changes.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
        }
        textChanges_3.deleteNode = deleteNode;
        function deleteNodeInList(changes, deletedNodesInLists, sourceFile, node) {
            var containingList = ts.Debug.checkDefined(ts.formatting.SmartIndenter.getContainingList(node, sourceFile));
            var index = ts.indexOfNode(containingList, node);
            ts.Debug.assert(index !== -1);
            if (containingList.length === 1) {
                deleteNode(changes, sourceFile, node);
                return;
            }
            // Note: We will only delete a comma *after* a node. This will leave a trailing comma if we delete the last node.
            // That's handled in the end by `finishTrailingCommaAfterDeletingNodesInList`.
            ts.Debug.assert(!deletedNodesInLists.has(node), "Deleting a node twice");
            deletedNodesInLists.add(node);
            changes.deleteRange(sourceFile, {
                pos: startPositionToDeleteNodeInList(sourceFile, node),
                end: index === containingList.length - 1 ? getAdjustedEndPosition(sourceFile, node, {}) : startPositionToDeleteNodeInList(sourceFile, containingList[index + 1]),
            });
        }
    })(textChanges = ts.textChanges || (ts.textChanges = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodeToFixes = ts.createMultiMap();
        var fixIdToRegistration = ts.createMap();
        function diagnosticToString(diag) {
            return ts.isArray(diag)
                ? ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag[0]), diag.slice(1))
                : ts.getLocaleSpecificMessage(diag);
        }
        function createCodeFixActionWithoutFixAll(fixName, changes, description) {
            return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined);
        }
        codefix.createCodeFixActionWithoutFixAll = createCodeFixActionWithoutFixAll;
        function createCodeFixAction(fixName, changes, description, fixId, fixAllDescription, command) {
            return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, diagnosticToString(fixAllDescription), command);
        }
        codefix.createCodeFixAction = createCodeFixAction;
        function createCodeFixActionWorker(fixName, description, changes, fixId, fixAllDescription, command) {
            return { fixName: fixName, description: description, changes: changes, fixId: fixId, fixAllDescription: fixAllDescription, commands: command ? [command] : undefined };
        }
        function registerCodeFix(reg) {
            for (var _i = 0, _a = reg.errorCodes; _i < _a.length; _i++) {
                var error = _a[_i];
                errorCodeToFixes.add(String(error), reg);
            }
            if (reg.fixIds) {
                for (var _b = 0, _c = reg.fixIds; _b < _c.length; _b++) {
                    var fixId = _c[_b];
                    ts.Debug.assert(!fixIdToRegistration.has(fixId));
                    fixIdToRegistration.set(fixId, reg);
                }
            }
        }
        codefix.registerCodeFix = registerCodeFix;
        function getSupportedErrorCodes() {
            return ts.arrayFrom(errorCodeToFixes.keys());
        }
        codefix.getSupportedErrorCodes = getSupportedErrorCodes;
        function removeFixIdIfFixAllUnavailable(registration, diagnostics) {
            var errorCodes = registration.errorCodes;
            var maybeFixableDiagnostics = 0;
            for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) {
                var diag = diagnostics_1[_i];
                if (ts.contains(errorCodes, diag.code))
                    maybeFixableDiagnostics++;
                if (maybeFixableDiagnostics > 1)
                    break;
            }
            var fixAllUnavailable = maybeFixableDiagnostics < 2;
            return function (_a) {
                var fixId = _a.fixId, fixAllDescription = _a.fixAllDescription, action = __rest(_a, ["fixId", "fixAllDescription"]);
                return fixAllUnavailable ? action : __assign(__assign({}, action), { fixId: fixId, fixAllDescription: fixAllDescription });
            };
        }
        function getFixes(context) {
            var diagnostics = getDiagnostics(context);
            var registrations = errorCodeToFixes.get(String(context.errorCode));
            return ts.flatMap(registrations, function (f) { return ts.map(f.getCodeActions(context), removeFixIdIfFixAllUnavailable(f, diagnostics)); });
        }
        codefix.getFixes = getFixes;
        function getAllFixes(context) {
            // Currently fixId is always a string.
            return fixIdToRegistration.get(ts.cast(context.fixId, ts.isString)).getAllCodeActions(context);
        }
        codefix.getAllFixes = getAllFixes;
        function createCombinedCodeActions(changes, commands) {
            return { changes: changes, commands: commands };
        }
        codefix.createCombinedCodeActions = createCombinedCodeActions;
        function createFileTextChanges(fileName, textChanges) {
            return { fileName: fileName, textChanges: textChanges };
        }
        codefix.createFileTextChanges = createFileTextChanges;
        function codeFixAll(context, errorCodes, use) {
            var commands = [];
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return eachDiagnostic(context, errorCodes, function (diag) { return use(t, diag, commands); }); });
            return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands);
        }
        codefix.codeFixAll = codeFixAll;
        function eachDiagnostic(context, errorCodes, cb) {
            for (var _i = 0, _a = getDiagnostics(context); _i < _a.length; _i++) {
                var diag = _a[_i];
                if (ts.contains(errorCodes, diag.code)) {
                    cb(diag);
                }
            }
        }
        codefix.eachDiagnostic = eachDiagnostic;
        function getDiagnostics(_a) {
            var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken;
            return __spreadArrays(program.getSemanticDiagnostics(sourceFile, cancellationToken), program.getSyntacticDiagnostics(sourceFile, cancellationToken), ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor_1) {
        // A map with the refactor code as key, the refactor itself as value
        // e.g.  nonSuggestableRefactors[refactorCode] -> the refactor you want
        var refactors = ts.createMap();
        /** @param name An unique code associated with each refactor. Does not have to be human-readable. */
        function registerRefactor(name, refactor) {
            refactors.set(name, refactor);
        }
        refactor_1.registerRefactor = registerRefactor;
        function getApplicableRefactors(context) {
            return ts.arrayFrom(ts.flatMapIterator(refactors.values(), function (refactor) {
                return context.cancellationToken && context.cancellationToken.isCancellationRequested() ? undefined : refactor.getAvailableActions(context);
            }));
        }
        refactor_1.getApplicableRefactors = getApplicableRefactors;
        function getEditsForRefactor(context, refactorName, actionName) {
            var refactor = refactors.get(refactorName);
            return refactor && refactor.getEditsForAction(context, actionName);
        }
        refactor_1.getEditsForRefactor = getEditsForRefactor;
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addConvertToUnknownForNonOverlappingTypes";
        var errorCodes = [ts.Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span.start); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_unknown_conversion_for_non_overlapping_types, fixId, ts.Diagnostics.Add_unknown_to_all_conversions_of_non_overlapping_types)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag.start); }); },
        });
        function makeChange(changeTracker, sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var assertion = ts.Debug.checkDefined(ts.findAncestor(token, function (n) { return ts.isAsExpression(n) || ts.isTypeAssertion(n); }), "Expected to find an assertion expression");
            var replacement = ts.isAsExpression(assertion)
                ? ts.createAsExpression(assertion.expression, ts.createKeywordTypeNode(148 /* UnknownKeyword */))
                : ts.createTypeAssertion(ts.createKeywordTypeNode(148 /* UnknownKeyword */), assertion.expression);
            changeTracker.replaceNode(sourceFile, assertion.expression, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var changes = ts.textChanges.ChangeTracker.with(context, function (changes) {
                    var exportDeclaration = ts.createExportDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, ts.createNamedExports([]), 
                    /*moduleSpecifier*/ undefined, 
                    /*isTypeOnly*/ false);
                    changes.insertNodeAtEndOfScope(sourceFile, sourceFile, exportDeclaration);
                });
                return [codefix.createCodeFixActionWithoutFixAll("addEmptyExportDeclaration", changes, ts.Diagnostics.Add_export_to_make_this_file_into_a_module)];
            },
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addMissingAsync";
        var errorCodes = [
            ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code,
            ts.Diagnostics.Type_0_is_not_assignable_to_type_1.code,
            ts.Diagnostics.Type_0_is_not_comparable_to_type_1.code
        ];
        codefix.registerCodeFix({
            fixIds: [fixId],
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, errorCode = context.errorCode, cancellationToken = context.cancellationToken, program = context.program, span = context.span;
                var diagnostic = ts.find(program.getDiagnosticsProducingTypeChecker().getDiagnostics(sourceFile, cancellationToken), getIsMatchingAsyncError(span, errorCode));
                var directSpan = diagnostic && diagnostic.relatedInformation && ts.find(diagnostic.relatedInformation, function (r) { return r.code === ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async.code; });
                var decl = getFixableErrorSpanDeclaration(sourceFile, directSpan);
                if (!decl) {
                    return;
                }
                var trackChanges = function (cb) { return ts.textChanges.ChangeTracker.with(context, cb); };
                return [getFix(context, decl, trackChanges)];
            },
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var fixedDeclarations = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (t, diagnostic) {
                    var span = diagnostic.relatedInformation && ts.find(diagnostic.relatedInformation, function (r) { return r.code === ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async.code; });
                    var decl = getFixableErrorSpanDeclaration(sourceFile, span);
                    if (!decl) {
                        return;
                    }
                    var trackChanges = function (cb) { return (cb(t), []); };
                    return getFix(context, decl, trackChanges, fixedDeclarations);
                });
            },
        });
        function getFix(context, decl, trackChanges, fixedDeclarations) {
            var changes = trackChanges(function (t) { return makeChange(t, context.sourceFile, decl, fixedDeclarations); });
            return codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_async_modifier_to_containing_function, fixId, ts.Diagnostics.Add_all_missing_async_modifiers);
        }
        function makeChange(changeTracker, sourceFile, insertionSite, fixedDeclarations) {
            if (fixedDeclarations) {
                if (fixedDeclarations.has(ts.getNodeId(insertionSite).toString())) {
                    return;
                }
            }
            fixedDeclarations === null || fixedDeclarations === void 0 ? void 0 : fixedDeclarations.set(ts.getNodeId(insertionSite).toString(), true);
            var cloneWithModifier = ts.getSynthesizedDeepClone(insertionSite, /*includeTrivia*/ true);
            cloneWithModifier.modifiers = ts.createNodeArray(ts.createModifiersFromModifierFlags(ts.getModifierFlags(insertionSite) | 256 /* Async */));
            cloneWithModifier.modifierFlagsCache = 0;
            changeTracker.replaceNode(sourceFile, insertionSite, cloneWithModifier);
        }
        function getFixableErrorSpanDeclaration(sourceFile, span) {
            if (!span)
                return undefined;
            var token = ts.getTokenAtPosition(sourceFile, span.start);
            // Checker has already done work to determine that async might be possible, and has attached
            // related info to the node, so start by finding the signature that exactly matches up
            // with the diagnostic range.
            var decl = ts.findAncestor(token, function (node) {
                if (node.getStart(sourceFile) < span.start || node.getEnd() > ts.textSpanEnd(span)) {
                    return "quit";
                }
                return (ts.isArrowFunction(node) || ts.isMethodDeclaration(node) || ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && ts.textSpansEqual(span, ts.createTextSpanFromNode(node, sourceFile));
            });
            return decl;
        }
        function getIsMatchingAsyncError(span, errorCode) {
            return function (_a) {
                var start = _a.start, length = _a.length, relatedInformation = _a.relatedInformation, code = _a.code;
                return ts.isNumber(start) && ts.isNumber(length) && ts.textSpansEqual({ start: start, length: length }, span) &&
                    code === errorCode &&
                    !!relatedInformation &&
                    ts.some(relatedInformation, function (related) { return related.code === ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async.code; });
            };
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addMissingAwait";
        var propertyAccessCode = ts.Diagnostics.Property_0_does_not_exist_on_type_1.code;
        var callableConstructableErrorCodes = [
            ts.Diagnostics.This_expression_is_not_callable.code,
            ts.Diagnostics.This_expression_is_not_constructable.code,
        ];
        var errorCodes = __spreadArrays([
            ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type.code,
            ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type.code,
            ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type.code,
            ts.Diagnostics.Operator_0_cannot_be_applied_to_type_1.code,
            ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2.code,
            ts.Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap.code,
            ts.Diagnostics.Type_0_is_not_an_array_type.code,
            ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type.code,
            ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators.code,
            ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator.code,
            ts.Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator.code,
            ts.Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator.code,
            ts.Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator.code,
            ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code,
            propertyAccessCode
        ], callableConstructableErrorCodes);
        codefix.registerCodeFix({
            fixIds: [fixId],
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, errorCode = context.errorCode, span = context.span, cancellationToken = context.cancellationToken, program = context.program;
                var expression = getFixableErrorSpanExpression(sourceFile, errorCode, span, cancellationToken, program);
                if (!expression) {
                    return;
                }
                var checker = context.program.getTypeChecker();
                var trackChanges = function (cb) { return ts.textChanges.ChangeTracker.with(context, cb); };
                return ts.compact([
                    getDeclarationSiteFix(context, expression, errorCode, checker, trackChanges),
                    getUseSiteFix(context, expression, errorCode, checker, trackChanges)
                ]);
            },
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, cancellationToken = context.cancellationToken;
                var checker = context.program.getTypeChecker();
                var fixedDeclarations = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (t, diagnostic) {
                    var expression = getFixableErrorSpanExpression(sourceFile, diagnostic.code, diagnostic, cancellationToken, program);
                    if (!expression) {
                        return;
                    }
                    var trackChanges = function (cb) { return (cb(t), []); };
                    return getDeclarationSiteFix(context, expression, diagnostic.code, checker, trackChanges, fixedDeclarations)
                        || getUseSiteFix(context, expression, diagnostic.code, checker, trackChanges, fixedDeclarations);
                });
            },
        });
        function getDeclarationSiteFix(context, expression, errorCode, checker, trackChanges, fixedDeclarations) {
            var sourceFile = context.sourceFile, program = context.program, cancellationToken = context.cancellationToken;
            var awaitableInitializers = findAwaitableInitializers(expression, sourceFile, cancellationToken, program, checker);
            if (awaitableInitializers) {
                var initializerChanges = trackChanges(function (t) {
                    ts.forEach(awaitableInitializers.initializers, function (_a) {
                        var expression = _a.expression;
                        return makeChange(t, errorCode, sourceFile, checker, expression, fixedDeclarations);
                    });
                    if (fixedDeclarations && awaitableInitializers.needsSecondPassForFixAll) {
                        makeChange(t, errorCode, sourceFile, checker, expression, fixedDeclarations);
                    }
                });
                // No fix-all because it will already be included once with the use site fix,
                // and for simplicity the fix-all doesn‘t let the user choose between use-site and declaration-site fixes.
                return codefix.createCodeFixActionWithoutFixAll("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1
                    ? [ts.Diagnostics.Add_await_to_initializer_for_0, awaitableInitializers.initializers[0].declarationSymbol.name]
                    : ts.Diagnostics.Add_await_to_initializers);
            }
        }
        function getUseSiteFix(context, expression, errorCode, checker, trackChanges, fixedDeclarations) {
            var changes = trackChanges(function (t) { return makeChange(t, errorCode, context.sourceFile, checker, expression, fixedDeclarations); });
            return codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_await, fixId, ts.Diagnostics.Fix_all_expressions_possibly_missing_await);
        }
        function isMissingAwaitError(sourceFile, errorCode, span, cancellationToken, program) {
            var checker = program.getDiagnosticsProducingTypeChecker();
            var diagnostics = checker.getDiagnostics(sourceFile, cancellationToken);
            return ts.some(diagnostics, function (_a) {
                var start = _a.start, length = _a.length, relatedInformation = _a.relatedInformation, code = _a.code;
                return ts.isNumber(start) && ts.isNumber(length) && ts.textSpansEqual({ start: start, length: length }, span) &&
                    code === errorCode &&
                    !!relatedInformation &&
                    ts.some(relatedInformation, function (related) { return related.code === ts.Diagnostics.Did_you_forget_to_use_await.code; });
            });
        }
        function getFixableErrorSpanExpression(sourceFile, errorCode, span, cancellationToken, program) {
            var token = ts.getTokenAtPosition(sourceFile, span.start);
            // Checker has already done work to determine that await might be possible, and has attached
            // related info to the node, so start by finding the expression that exactly matches up
            // with the diagnostic range.
            var expression = ts.findAncestor(token, function (node) {
                if (node.getStart(sourceFile) < span.start || node.getEnd() > ts.textSpanEnd(span)) {
                    return "quit";
                }
                return ts.isExpression(node) && ts.textSpansEqual(span, ts.createTextSpanFromNode(node, sourceFile));
            });
            return expression
                && isMissingAwaitError(sourceFile, errorCode, span, cancellationToken, program)
                && isInsideAwaitableBody(expression) ? expression : undefined;
        }
        function findAwaitableInitializers(expression, sourceFile, cancellationToken, program, checker) {
            var identifiers = getIdentifiersFromErrorSpanExpression(expression, checker);
            if (!identifiers) {
                return;
            }
            var isCompleteFix = identifiers.isCompleteFix;
            var initializers;
            var _loop_11 = function (identifier) {
                var symbol = checker.getSymbolAtLocation(identifier);
                if (!symbol) {
                    return "continue";
                }
                var declaration = ts.tryCast(symbol.valueDeclaration, ts.isVariableDeclaration);
                var variableName = declaration && ts.tryCast(declaration.name, ts.isIdentifier);
                var variableStatement = ts.getAncestor(declaration, 225 /* VariableStatement */);
                if (!declaration || !variableStatement ||
                    declaration.type ||
                    !declaration.initializer ||
                    variableStatement.getSourceFile() !== sourceFile ||
                    ts.hasModifier(variableStatement, 1 /* Export */) ||
                    !variableName ||
                    !isInsideAwaitableBody(declaration.initializer)) {
                    isCompleteFix = false;
                    return "continue";
                }
                var diagnostics = program.getSemanticDiagnostics(sourceFile, cancellationToken);
                var isUsedElsewhere = ts.FindAllReferences.Core.eachSymbolReferenceInFile(variableName, checker, sourceFile, function (reference) {
                    return identifier !== reference && !symbolReferenceIsAlsoMissingAwait(reference, diagnostics, sourceFile, checker);
                });
                if (isUsedElsewhere) {
                    isCompleteFix = false;
                    return "continue";
                }
                (initializers || (initializers = [])).push({
                    expression: declaration.initializer,
                    declarationSymbol: symbol,
                });
            };
            for (var _i = 0, _a = identifiers.identifiers; _i < _a.length; _i++) {
                var identifier = _a[_i];
                _loop_11(identifier);
            }
            return initializers && {
                initializers: initializers,
                needsSecondPassForFixAll: !isCompleteFix,
            };
        }
        function getIdentifiersFromErrorSpanExpression(expression, checker) {
            if (ts.isPropertyAccessExpression(expression.parent) && ts.isIdentifier(expression.parent.expression)) {
                return { identifiers: [expression.parent.expression], isCompleteFix: true };
            }
            if (ts.isIdentifier(expression)) {
                return { identifiers: [expression], isCompleteFix: true };
            }
            if (ts.isBinaryExpression(expression)) {
                var sides = void 0;
                var isCompleteFix = true;
                for (var _i = 0, _a = [expression.left, expression.right]; _i < _a.length; _i++) {
                    var side = _a[_i];
                    var type = checker.getTypeAtLocation(side);
                    if (checker.getPromisedTypeOfPromise(type)) {
                        if (!ts.isIdentifier(side)) {
                            isCompleteFix = false;
                            continue;
                        }
                        (sides || (sides = [])).push(side);
                    }
                }
                return sides && { identifiers: sides, isCompleteFix: isCompleteFix };
            }
        }
        function symbolReferenceIsAlsoMissingAwait(reference, diagnostics, sourceFile, checker) {
            var errorNode = ts.isPropertyAccessExpression(reference.parent) ? reference.parent.name :
                ts.isBinaryExpression(reference.parent) ? reference.parent :
                    reference;
            var diagnostic = ts.find(diagnostics, function (diagnostic) {
                return diagnostic.start === errorNode.getStart(sourceFile) &&
                    (diagnostic.start + diagnostic.length) === errorNode.getEnd();
            });
            return diagnostic && ts.contains(errorCodes, diagnostic.code) ||
                // A Promise is usually not correct in a binary expression (it’s not valid
                // in an arithmetic expression and an equality comparison seems unusual),
                // but if the other side of the binary expression has an error, the side
                // is typed `any` which will squash the error that would identify this
                // Promise as an invalid operand. So if the whole binary expression is
                // typed `any` as a result, there is a strong likelihood that this Promise
                // is accidentally missing `await`.
                checker.getTypeAtLocation(errorNode).flags & 1 /* Any */;
        }
        function isInsideAwaitableBody(node) {
            return node.kind & 32768 /* AwaitContext */ || !!ts.findAncestor(node, function (ancestor) {
                return ancestor.parent && ts.isArrowFunction(ancestor.parent) && ancestor.parent.body === ancestor ||
                    ts.isBlock(ancestor) && (ancestor.parent.kind === 244 /* FunctionDeclaration */ ||
                        ancestor.parent.kind === 201 /* FunctionExpression */ ||
                        ancestor.parent.kind === 202 /* ArrowFunction */ ||
                        ancestor.parent.kind === 161 /* MethodDeclaration */);
            });
        }
        function makeChange(changeTracker, errorCode, sourceFile, checker, insertionSite, fixedDeclarations) {
            if (ts.isBinaryExpression(insertionSite)) {
                for (var _i = 0, _a = [insertionSite.left, insertionSite.right]; _i < _a.length; _i++) {
                    var side = _a[_i];
                    if (fixedDeclarations && ts.isIdentifier(side)) {
                        var symbol = checker.getSymbolAtLocation(side);
                        if (symbol && fixedDeclarations.has(ts.getSymbolId(symbol).toString())) {
                            continue;
                        }
                    }
                    var type = checker.getTypeAtLocation(side);
                    var newNode = checker.getPromisedTypeOfPromise(type) ? ts.createAwait(side) : side;
                    changeTracker.replaceNode(sourceFile, side, newNode);
                }
            }
            else if (errorCode === propertyAccessCode && ts.isPropertyAccessExpression(insertionSite.parent)) {
                if (fixedDeclarations && ts.isIdentifier(insertionSite.parent.expression)) {
                    var symbol = checker.getSymbolAtLocation(insertionSite.parent.expression);
                    if (symbol && fixedDeclarations.has(ts.getSymbolId(symbol).toString())) {
                        return;
                    }
                }
                changeTracker.replaceNode(sourceFile, insertionSite.parent.expression, ts.createParen(ts.createAwait(insertionSite.parent.expression)));
                insertLeadingSemicolonIfNeeded(changeTracker, insertionSite.parent.expression, sourceFile);
            }
            else if (ts.contains(callableConstructableErrorCodes, errorCode) && ts.isCallOrNewExpression(insertionSite.parent)) {
                if (fixedDeclarations && ts.isIdentifier(insertionSite)) {
                    var symbol = checker.getSymbolAtLocation(insertionSite);
                    if (symbol && fixedDeclarations.has(ts.getSymbolId(symbol).toString())) {
                        return;
                    }
                }
                changeTracker.replaceNode(sourceFile, insertionSite, ts.createParen(ts.createAwait(insertionSite)));
                insertLeadingSemicolonIfNeeded(changeTracker, insertionSite, sourceFile);
            }
            else {
                if (fixedDeclarations && ts.isVariableDeclaration(insertionSite.parent) && ts.isIdentifier(insertionSite.parent.name)) {
                    var symbol = checker.getSymbolAtLocation(insertionSite.parent.name);
                    if (symbol && !ts.addToSeen(fixedDeclarations, ts.getSymbolId(symbol))) {
                        return;
                    }
                }
                changeTracker.replaceNode(sourceFile, insertionSite, ts.createAwait(insertionSite));
            }
        }
        function insertLeadingSemicolonIfNeeded(changeTracker, beforeNode, sourceFile) {
            var precedingToken = ts.findPrecedingToken(beforeNode.pos, sourceFile);
            if (precedingToken && ts.positionIsASICandidate(precedingToken.end, precedingToken.parent, sourceFile)) {
                changeTracker.insertText(sourceFile, beforeNode.getStart(sourceFile), ";");
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addMissingConst";
        var errorCodes = [
            ts.Diagnostics.Cannot_find_name_0.code,
            ts.Diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer.code
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span.start, context.program); });
                if (changes.length > 0) {
                    return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_const_to_unresolved_variable, fixId, ts.Diagnostics.Add_const_to_all_unresolved_variables)];
                }
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var fixedNodes = new ts.NodeSet();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag.start, context.program, fixedNodes); });
            },
        });
        function makeChange(changeTracker, sourceFile, pos, program, fixedNodes) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var forInitializer = ts.findAncestor(token, function (node) {
                return ts.isForInOrOfStatement(node.parent) ? node.parent.initializer === node :
                    isPossiblyPartOfDestructuring(node) ? false : "quit";
            });
            if (forInitializer)
                return applyChange(changeTracker, forInitializer, sourceFile, fixedNodes);
            var parent = token.parent;
            if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isExpressionStatement(parent.parent)) {
                return applyChange(changeTracker, token, sourceFile, fixedNodes);
            }
            if (ts.isArrayLiteralExpression(parent)) {
                var checker_1 = program.getTypeChecker();
                if (!ts.every(parent.elements, function (element) { return arrayElementCouldBeVariableDeclaration(element, checker_1); })) {
                    return;
                }
                return applyChange(changeTracker, parent, sourceFile, fixedNodes);
            }
            var commaExpression = ts.findAncestor(token, function (node) {
                return ts.isExpressionStatement(node.parent) ? true :
                    isPossiblyPartOfCommaSeperatedInitializer(node) ? false : "quit";
            });
            if (commaExpression) {
                var checker = program.getTypeChecker();
                if (!expressionCouldBeVariableDeclaration(commaExpression, checker)) {
                    return;
                }
                return applyChange(changeTracker, commaExpression, sourceFile, fixedNodes);
            }
        }
        function applyChange(changeTracker, initializer, sourceFile, fixedNodes) {
            if (!fixedNodes || fixedNodes.tryAdd(initializer)) {
                changeTracker.insertModifierBefore(sourceFile, 81 /* ConstKeyword */, initializer);
            }
        }
        function isPossiblyPartOfDestructuring(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                case 192 /* ArrayLiteralExpression */:
                case 193 /* ObjectLiteralExpression */:
                case 281 /* PropertyAssignment */:
                case 282 /* ShorthandPropertyAssignment */:
                    return true;
                default:
                    return false;
            }
        }
        function arrayElementCouldBeVariableDeclaration(expression, checker) {
            var identifier = ts.isIdentifier(expression) ? expression :
                ts.isAssignmentExpression(expression, /*excludeCompoundAssignment*/ true) && ts.isIdentifier(expression.left) ? expression.left :
                    undefined;
            return !!identifier && !checker.getSymbolAtLocation(identifier);
        }
        function isPossiblyPartOfCommaSeperatedInitializer(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                case 209 /* BinaryExpression */:
                case 27 /* CommaToken */:
                    return true;
                default:
                    return false;
            }
        }
        function expressionCouldBeVariableDeclaration(expression, checker) {
            if (!ts.isBinaryExpression(expression)) {
                return false;
            }
            if (expression.operatorToken.kind === 27 /* CommaToken */) {
                return ts.every([expression.left, expression.right], function (expression) { return expressionCouldBeVariableDeclaration(expression, checker); });
            }
            return expression.operatorToken.kind === 62 /* EqualsToken */
                && ts.isIdentifier(expression.left)
                && !checker.getSymbolAtLocation(expression.left);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addMissingDeclareProperty";
        var errorCodes = [
            ts.Diagnostics.Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span.start); });
                if (changes.length > 0) {
                    return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Prefix_with_declare, fixId, ts.Diagnostics.Prefix_all_incorrect_property_declarations_with_declare)];
                }
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var fixedNodes = new ts.NodeSet();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag.start, fixedNodes); });
            },
        });
        function makeChange(changeTracker, sourceFile, pos, fixedNodes) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            if (!ts.isIdentifier(token)) {
                return;
            }
            var declaration = token.parent;
            if (declaration.kind === 159 /* PropertyDeclaration */ &&
                (!fixedNodes || fixedNodes.tryAdd(declaration))) {
                changeTracker.insertModifierBefore(sourceFile, 130 /* DeclareKeyword */, declaration);
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addMissingInvocationForDecorator";
        var errorCodes = [ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span.start); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Call_decorator_expression, fixId, ts.Diagnostics.Add_to_all_uncalled_decorators)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag.start); }); },
        });
        function makeChange(changeTracker, sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var decorator = ts.findAncestor(token, ts.isDecorator);
            ts.Debug.assert(!!decorator, "Expected position to be owned by a decorator.");
            var replacement = ts.createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
            changeTracker.replaceNode(sourceFile, decorator.expression, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addNameToNamelessParameter";
        var errorCodes = [ts.Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span.start); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_parameter_name, fixId, ts.Diagnostics.Add_names_to_all_parameters_without_names)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag.start); }); },
        });
        function makeChange(changeTracker, sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            if (!ts.isIdentifier(token)) {
                return ts.Debug.fail("add-name-to-nameless-parameter operates on identifiers, but got a " + ts.Debug.formatSyntaxKind(token.kind));
            }
            var param = token.parent;
            if (!ts.isParameter(param)) {
                return ts.Debug.fail("Tried to add a parameter name to a non-parameter: " + ts.Debug.formatSyntaxKind(token.kind));
            }
            var i = param.parent.parameters.indexOf(param);
            ts.Debug.assert(!param.type, "Tried to add a parameter name to a parameter that already had one.");
            ts.Debug.assert(i > -1, "Parameter not found in parent parameter list.");
            var replacement = ts.createParameter(
            /*decorators*/ undefined, param.modifiers, param.dotDotDotToken, "arg" + i, param.questionToken, ts.createTypeReferenceNode(token, /*typeArguments*/ undefined), param.initializer);
            changeTracker.replaceNode(sourceFile, token, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "annotateWithTypeFromJSDoc";
        var errorCodes = [ts.Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var decl = getDeclaration(context.sourceFile, context.span.start);
                if (!decl)
                    return;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, decl); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Annotate_with_type_from_JSDoc, fixId, ts.Diagnostics.Annotate_everything_with_types_from_JSDoc)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var decl = getDeclaration(diag.file, diag.start);
                if (decl)
                    doChange(changes, diag.file, decl);
            }); },
        });
        function getDeclaration(file, pos) {
            var name = ts.getTokenAtPosition(file, pos);
            // For an arrow function with no name, 'name' lands on the first parameter.
            return ts.tryCast(ts.isParameter(name.parent) ? name.parent.parent : name.parent, parameterShouldGetTypeFromJSDoc);
        }
        function parameterShouldGetTypeFromJSDoc(node) {
            return isDeclarationWithType(node) && hasUsableJSDoc(node);
        }
        codefix.parameterShouldGetTypeFromJSDoc = parameterShouldGetTypeFromJSDoc;
        function hasUsableJSDoc(decl) {
            return ts.isFunctionLikeDeclaration(decl)
                ? decl.parameters.some(hasUsableJSDoc) || (!decl.type && !!ts.getJSDocReturnType(decl))
                : !decl.type && !!ts.getJSDocType(decl);
        }
        function doChange(changes, sourceFile, decl) {
            if (ts.isFunctionLikeDeclaration(decl) && (ts.getJSDocReturnType(decl) || decl.parameters.some(function (p) { return !!ts.getJSDocType(p); }))) {
                if (!decl.typeParameters) {
                    var typeParameters = ts.getJSDocTypeParameterDeclarations(decl);
                    if (typeParameters.length)
                        changes.insertTypeParameters(sourceFile, decl, typeParameters);
                }
                var needParens = ts.isArrowFunction(decl) && !ts.findChildOfKind(decl, 20 /* OpenParenToken */, sourceFile);
                if (needParens)
                    changes.insertNodeBefore(sourceFile, ts.first(decl.parameters), ts.createToken(20 /* OpenParenToken */));
                for (var _i = 0, _a = decl.parameters; _i < _a.length; _i++) {
                    var param = _a[_i];
                    if (!param.type) {
                        var paramType = ts.getJSDocType(param);
                        if (paramType)
                            changes.tryInsertTypeAnnotation(sourceFile, param, transformJSDocType(paramType));
                    }
                }
                if (needParens)
                    changes.insertNodeAfter(sourceFile, ts.last(decl.parameters), ts.createToken(21 /* CloseParenToken */));
                if (!decl.type) {
                    var returnType = ts.getJSDocReturnType(decl);
                    if (returnType)
                        changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(returnType));
                }
            }
            else {
                var jsdocType = ts.Debug.checkDefined(ts.getJSDocType(decl), "A JSDocType for this declaration should exist"); // If not defined, shouldn't have been an error to fix
                ts.Debug.assert(!decl.type, "The JSDocType decl should have a type"); // If defined, shouldn't have been an error to fix.
                changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(jsdocType));
            }
        }
        function isDeclarationWithType(node) {
            return ts.isFunctionLikeDeclaration(node) ||
                node.kind === 242 /* VariableDeclaration */ ||
                node.kind === 158 /* PropertySignature */ ||
                node.kind === 159 /* PropertyDeclaration */;
        }
        function transformJSDocType(node) {
            switch (node.kind) {
                case 295 /* JSDocAllType */:
                case 296 /* JSDocUnknownType */:
                    return ts.createTypeReferenceNode("any", ts.emptyArray);
                case 299 /* JSDocOptionalType */:
                    return transformJSDocOptionalType(node);
                case 298 /* JSDocNonNullableType */:
                    return transformJSDocType(node.type);
                case 297 /* JSDocNullableType */:
                    return transformJSDocNullableType(node);
                case 301 /* JSDocVariadicType */:
                    return transformJSDocVariadicType(node);
                case 300 /* JSDocFunctionType */:
                    return transformJSDocFunctionType(node);
                case 169 /* TypeReference */:
                    return transformJSDocTypeReference(node);
                default:
                    var visited = ts.visitEachChild(node, transformJSDocType, /*context*/ undefined); // TODO: GH#18217
                    ts.setEmitFlags(visited, 1 /* SingleLine */);
                    return visited;
            }
        }
        function transformJSDocOptionalType(node) {
            return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("undefined", ts.emptyArray)]);
        }
        function transformJSDocNullableType(node) {
            return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("null", ts.emptyArray)]);
        }
        function transformJSDocVariadicType(node) {
            return ts.createArrayTypeNode(ts.visitNode(node.type, transformJSDocType));
        }
        function transformJSDocFunctionType(node) {
            return ts.createFunctionTypeNode(ts.emptyArray, node.parameters.map(transformJSDocParameter), node.type);
        }
        function transformJSDocParameter(node) {
            var index = node.parent.parameters.indexOf(node);
            var isRest = node.type.kind === 301 /* JSDocVariadicType */ && index === node.parent.parameters.length - 1; // TODO: GH#18217
            var name = node.name || (isRest ? "rest" : "arg" + index);
            var dotdotdot = isRest ? ts.createToken(25 /* DotDotDotToken */) : node.dotDotDotToken;
            return ts.createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, ts.visitNode(node.type, transformJSDocType), node.initializer);
        }
        function transformJSDocTypeReference(node) {
            var name = node.typeName;
            var args = node.typeArguments;
            if (ts.isIdentifier(node.typeName)) {
                if (ts.isJSDocIndexSignature(node)) {
                    return transformJSDocIndexSignature(node);
                }
                var text = node.typeName.text;
                switch (node.typeName.text) {
                    case "String":
                    case "Boolean":
                    case "Object":
                    case "Number":
                        text = text.toLowerCase();
                        break;
                    case "array":
                    case "date":
                    case "promise":
                        text = text[0].toUpperCase() + text.slice(1);
                        break;
                }
                name = ts.createIdentifier(text);
                if ((text === "Array" || text === "Promise") && !node.typeArguments) {
                    args = ts.createNodeArray([ts.createTypeReferenceNode("any", ts.emptyArray)]);
                }
                else {
                    args = ts.visitNodes(node.typeArguments, transformJSDocType);
                }
            }
            return ts.createTypeReferenceNode(name, args);
        }
        function transformJSDocIndexSignature(node) {
            var index = ts.createParameter(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*dotDotDotToken*/ undefined, node.typeArguments[0].kind === 140 /* NumberKeyword */ ? "n" : "s", 
            /*questionToken*/ undefined, ts.createTypeReferenceNode(node.typeArguments[0].kind === 140 /* NumberKeyword */ ? "number" : "string", []), 
            /*initializer*/ undefined);
            var indexSignature = ts.createTypeLiteralNode([ts.createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments[1])]);
            ts.setEmitFlags(indexSignature, 1 /* SingleLine */);
            return indexSignature;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "convertFunctionToEs6Class";
        var errorCodes = [ts.Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, context.span.start, context.program.getTypeChecker()); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_function_to_an_ES2015_class, fixId, ts.Diagnostics.Convert_all_constructor_functions_to_classes)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, err) { return doChange(changes, err.file, err.start, context.program.getTypeChecker()); }); },
        });
        function doChange(changes, sourceFile, position, checker) {
            var ctorSymbol = checker.getSymbolAtLocation(ts.getTokenAtPosition(sourceFile, position));
            if (!ctorSymbol || !(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) {
                // Bad input
                return undefined;
            }
            var ctorDeclaration = ctorSymbol.valueDeclaration;
            var precedingNode;
            var newClassDeclaration;
            switch (ctorDeclaration.kind) {
                case 244 /* FunctionDeclaration */:
                    precedingNode = ctorDeclaration;
                    changes.delete(sourceFile, ctorDeclaration);
                    newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration);
                    break;
                case 242 /* VariableDeclaration */:
                    precedingNode = ctorDeclaration.parent.parent;
                    newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration);
                    if (ctorDeclaration.parent.declarations.length === 1) {
                        ts.copyLeadingComments(precedingNode, newClassDeclaration, sourceFile); // TODO: GH#18217
                        changes.delete(sourceFile, precedingNode);
                    }
                    else {
                        changes.delete(sourceFile, ctorDeclaration);
                    }
                    break;
            }
            if (!newClassDeclaration) {
                return undefined;
            }
            // Deleting a declaration only deletes JSDoc style comments, so only copy those to the new node.
            if (ts.hasJSDocNodes(ctorDeclaration)) {
                ts.copyLeadingComments(ctorDeclaration, newClassDeclaration, sourceFile);
            }
            // Because the preceding node could be touched, we need to insert nodes before delete nodes.
            changes.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration);
            function createClassElementsFromSymbol(symbol) {
                var memberElements = [];
                // all instance members are stored in the "member" array of symbol
                if (symbol.members) {
                    symbol.members.forEach(function (member) {
                        var memberElement = createClassElement(member, /*modifiers*/ undefined);
                        if (memberElement) {
                            memberElements.push(memberElement);
                        }
                    });
                }
                // all static members are stored in the "exports" array of symbol
                if (symbol.exports) {
                    symbol.exports.forEach(function (member) {
                        var memberElement = createClassElement(member, [ts.createToken(120 /* StaticKeyword */)]);
                        if (memberElement) {
                            memberElements.push(memberElement);
                        }
                    });
                }
                return memberElements;
                function shouldConvertDeclaration(_target, source) {
                    // Right now the only thing we can convert are function expressions - other values shouldn't get
                    // transformed. We can update this once ES public class properties are available.
                    return ts.isFunctionLike(source);
                }
                function createClassElement(symbol, modifiers) {
                    // Right now the only thing we can convert are function expressions, which are marked as methods
                    if (!(symbol.flags & 8192 /* Method */)) {
                        return;
                    }
                    var memberDeclaration = symbol.valueDeclaration;
                    var assignmentBinaryExpression = memberDeclaration.parent;
                    if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) {
                        return;
                    }
                    // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end
                    var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 226 /* ExpressionStatement */
                        ? assignmentBinaryExpression.parent : assignmentBinaryExpression;
                    changes.delete(sourceFile, nodeToDelete);
                    if (!assignmentBinaryExpression.right) {
                        return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, 
                        /*type*/ undefined, /*initializer*/ undefined);
                    }
                    switch (assignmentBinaryExpression.right.kind) {
                        case 201 /* FunctionExpression */: {
                            var functionExpression = assignmentBinaryExpression.right;
                            var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(functionExpression, 126 /* AsyncKeyword */));
                            var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, 
                            /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body);
                            ts.copyLeadingComments(assignmentBinaryExpression, method, sourceFile);
                            return method;
                        }
                        case 202 /* ArrowFunction */: {
                            var arrowFunction = assignmentBinaryExpression.right;
                            var arrowFunctionBody = arrowFunction.body;
                            var bodyBlock = void 0;
                            // case 1: () => { return [1,2,3] }
                            if (arrowFunctionBody.kind === 223 /* Block */) {
                                bodyBlock = arrowFunctionBody;
                            }
                            // case 2: () => [1,2,3]
                            else {
                                bodyBlock = ts.createBlock([ts.createReturn(arrowFunctionBody)]);
                            }
                            var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(arrowFunction, 126 /* AsyncKeyword */));
                            var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, 
                            /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock);
                            ts.copyLeadingComments(assignmentBinaryExpression, method, sourceFile);
                            return method;
                        }
                        default: {
                            // Don't try to declare members in JavaScript files
                            if (ts.isSourceFileJS(sourceFile)) {
                                return;
                            }
                            var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, 
                            /*type*/ undefined, assignmentBinaryExpression.right);
                            ts.copyLeadingComments(assignmentBinaryExpression.parent, prop, sourceFile);
                            return prop;
                        }
                    }
                }
            }
            function createClassFromVariableDeclaration(node) {
                var initializer = node.initializer;
                if (!initializer || initializer.kind !== 201 /* FunctionExpression */) {
                    return undefined;
                }
                if (node.name.kind !== 75 /* Identifier */) {
                    return undefined;
                }
                var memberElements = createClassElementsFromSymbol(node.symbol);
                if (initializer.body) {
                    memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body));
                }
                var modifiers = getModifierKindFromSource(precedingNode, 89 /* ExportKeyword */);
                var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, 
                /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
                // Don't call copyComments here because we'll already leave them in place
                return cls;
            }
            function createClassFromFunctionDeclaration(node) {
                var memberElements = createClassElementsFromSymbol(ctorSymbol);
                if (node.body) {
                    memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body));
                }
                var modifiers = getModifierKindFromSource(node, 89 /* ExportKeyword */);
                var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, 
                /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
                // Don't call copyComments here because we'll already leave them in place
                return cls;
            }
        }
        function getModifierKindFromSource(source, kind) {
            return ts.filter(source.modifiers, function (modifier) { return modifier.kind === kind; });
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "convertToAsyncFunction";
        var errorCodes = [ts.Diagnostics.This_may_be_converted_to_an_async_function.code];
        var codeActionSucceeded = true;
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                codeActionSucceeded = true;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return convertToAsyncFunction(t, context.sourceFile, context.span.start, context.program.getTypeChecker(), context); });
                return codeActionSucceeded ? [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_to_async_function, fixId, ts.Diagnostics.Convert_all_to_async_functions)] : [];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, err) { return convertToAsyncFunction(changes, err.file, err.start, context.program.getTypeChecker(), context); }); },
        });
        var SynthBindingNameKind;
        (function (SynthBindingNameKind) {
            SynthBindingNameKind[SynthBindingNameKind["Identifier"] = 0] = "Identifier";
            SynthBindingNameKind[SynthBindingNameKind["BindingPattern"] = 1] = "BindingPattern";
        })(SynthBindingNameKind || (SynthBindingNameKind = {}));
        function convertToAsyncFunction(changes, sourceFile, position, checker, context) {
            // get the function declaration - returns a promise
            var tokenAtPosition = ts.getTokenAtPosition(sourceFile, position);
            var functionToConvert;
            // if the parent of a FunctionLikeDeclaration is a variable declaration, the convertToAsync diagnostic will be reported on the variable name
            if (ts.isIdentifier(tokenAtPosition) && ts.isVariableDeclaration(tokenAtPosition.parent) &&
                tokenAtPosition.parent.initializer && ts.isFunctionLikeDeclaration(tokenAtPosition.parent.initializer)) {
                functionToConvert = tokenAtPosition.parent.initializer;
            }
            else {
                functionToConvert = ts.tryCast(ts.getContainingFunction(ts.getTokenAtPosition(sourceFile, position)), ts.isFunctionLikeDeclaration);
            }
            if (!functionToConvert) {
                return;
            }
            var synthNamesMap = ts.createMap();
            var isInJavascript = ts.isInJSFile(functionToConvert);
            var setOfExpressionsToReturn = getAllPromiseExpressionsToReturn(functionToConvert, checker);
            var functionToConvertRenamed = renameCollidingVarNames(functionToConvert, checker, synthNamesMap, context.sourceFile);
            var returnStatements = functionToConvertRenamed.body && ts.isBlock(functionToConvertRenamed.body) ? getReturnStatementsWithPromiseHandlers(functionToConvertRenamed.body) : ts.emptyArray;
            var transformer = { checker: checker, synthNamesMap: synthNamesMap, setOfExpressionsToReturn: setOfExpressionsToReturn, isInJSFile: isInJavascript };
            if (!returnStatements.length) {
                return;
            }
            // add the async keyword
            changes.insertLastModifierBefore(sourceFile, 126 /* AsyncKeyword */, functionToConvert);
            var _loop_12 = function (returnStatement) {
                ts.forEachChild(returnStatement, function visit(node) {
                    if (ts.isCallExpression(node)) {
                        var newNodes = transformExpression(node, transformer);
                        changes.replaceNodeWithNodes(sourceFile, returnStatement, newNodes);
                    }
                    else if (!ts.isFunctionLike(node)) {
                        ts.forEachChild(node, visit);
                    }
                });
            };
            for (var _i = 0, returnStatements_1 = returnStatements; _i < returnStatements_1.length; _i++) {
                var returnStatement = returnStatements_1[_i];
                _loop_12(returnStatement);
            }
        }
        function getReturnStatementsWithPromiseHandlers(body) {
            var res = [];
            ts.forEachReturnStatement(body, function (ret) {
                if (ts.isReturnStatementWithFixablePromiseHandler(ret))
                    res.push(ret);
            });
            return res;
        }
        /*
            Finds all of the expressions of promise type that should not be saved in a variable during the refactor
        */
        function getAllPromiseExpressionsToReturn(func, checker) {
            if (!func.body) {
                return ts.createMap();
            }
            var setOfExpressionsToReturn = ts.createMap();
            ts.forEachChild(func.body, function visit(node) {
                if (isPromiseReturningCallExpression(node, checker, "then")) {
                    setOfExpressionsToReturn.set(ts.getNodeId(node).toString(), true);
                    ts.forEach(node.arguments, visit);
                }
                else if (isPromiseReturningCallExpression(node, checker, "catch")) {
                    setOfExpressionsToReturn.set(ts.getNodeId(node).toString(), true);
                    // if .catch() is the last call in the chain, move leftward in the chain until we hit something else that should be returned
                    ts.forEachChild(node, visit);
                }
                else if (isPromiseTypedExpression(node, checker)) {
                    setOfExpressionsToReturn.set(ts.getNodeId(node).toString(), true);
                    // don't recurse here, since we won't refactor any children or arguments of the expression
                }
                else {
                    ts.forEachChild(node, visit);
                }
            });
            return setOfExpressionsToReturn;
        }
        function isPromiseReturningCallExpression(node, checker, name) {
            if (!ts.isCallExpression(node))
                return false;
            var isExpressionOfName = ts.hasPropertyAccessExpressionWithName(node, name);
            var nodeType = isExpressionOfName && checker.getTypeAtLocation(node);
            return !!(nodeType && checker.getPromisedTypeOfPromise(nodeType));
        }
        function isPromiseTypedExpression(node, checker) {
            if (!ts.isExpression(node))
                return false;
            return !!checker.getPromisedTypeOfPromise(checker.getTypeAtLocation(node));
        }
        function declaredInFile(symbol, sourceFile) {
            return symbol.valueDeclaration && symbol.valueDeclaration.getSourceFile() === sourceFile;
        }
        /*
            Renaming of identifiers may be neccesary as the refactor changes scopes -
            This function collects all existing identifier names and names of identifiers that will be created in the refactor.
            It then checks for any collisions and renames them through getSynthesizedDeepClone
        */
        function renameCollidingVarNames(nodeToRename, checker, synthNamesMap, sourceFile) {
            var identsToRenameMap = ts.createMap(); // key is the symbol id
            var collidingSymbolMap = ts.createMultiMap();
            ts.forEachChild(nodeToRename, function visit(node) {
                if (!ts.isIdentifier(node)) {
                    ts.forEachChild(node, visit);
                    return;
                }
                var symbol = checker.getSymbolAtLocation(node);
                var isDefinedInFile = symbol && declaredInFile(symbol, sourceFile);
                if (symbol && isDefinedInFile) {
                    var type = checker.getTypeAtLocation(node);
                    // Note - the choice of the last call signature is arbitrary
                    var lastCallSignature = getLastCallSignature(type, checker);
                    var symbolIdString = ts.getSymbolId(symbol).toString();
                    // If the identifier refers to a function, we want to add the new synthesized variable for the declaration. Example:
                    //   fetch('...').then(response => { ... })
                    // will eventually become
                    //   const response = await fetch('...')
                    // so we push an entry for 'response'.
                    if (lastCallSignature && !ts.isFunctionLikeDeclaration(node.parent) && !synthNamesMap.has(symbolIdString)) {
                        var firstParameter = ts.firstOrUndefined(lastCallSignature.parameters);
                        var ident = firstParameter && ts.isParameter(firstParameter.valueDeclaration) && ts.tryCast(firstParameter.valueDeclaration.name, ts.isIdentifier) || ts.createOptimisticUniqueName("result");
                        var synthName = getNewNameIfConflict(ident, collidingSymbolMap);
                        synthNamesMap.set(symbolIdString, synthName);
                        collidingSymbolMap.add(ident.text, symbol);
                    }
                    // We only care about identifiers that are parameters, variable declarations, or binding elements
                    else if (node.parent && (ts.isParameter(node.parent) || ts.isVariableDeclaration(node.parent) || ts.isBindingElement(node.parent))) {
                        var originalName = node.text;
                        var collidingSymbols = collidingSymbolMap.get(originalName);
                        // if the identifier name conflicts with a different identifier that we've already seen
                        if (collidingSymbols && collidingSymbols.some(function (prevSymbol) { return prevSymbol !== symbol; })) {
                            var newName = getNewNameIfConflict(node, collidingSymbolMap);
                            identsToRenameMap.set(symbolIdString, newName.identifier);
                            synthNamesMap.set(symbolIdString, newName);
                            collidingSymbolMap.add(originalName, symbol);
                        }
                        else {
                            var identifier = ts.getSynthesizedDeepClone(node);
                            synthNamesMap.set(symbolIdString, createSynthIdentifier(identifier));
                            collidingSymbolMap.add(originalName, symbol);
                        }
                    }
                }
            });
            return ts.getSynthesizedDeepCloneWithRenames(nodeToRename, /*includeTrivia*/ true, identsToRenameMap, checker);
        }
        function getNewNameIfConflict(name, originalNames) {
            var numVarsSameName = (originalNames.get(name.text) || ts.emptyArray).length;
            var identifier = numVarsSameName === 0 ? name : ts.createIdentifier(name.text + "_" + numVarsSameName);
            return createSynthIdentifier(identifier);
        }
        function silentFail() {
            codeActionSucceeded = false;
            return ts.emptyArray;
        }
        // dispatch function to recursively build the refactoring
        // should be kept up to date with isFixablePromiseHandler in suggestionDiagnostics.ts
        function transformExpression(node, transformer, prevArgName) {
            if (isPromiseReturningCallExpression(node, transformer.checker, "then")) {
                if (node.arguments.length === 0)
                    return silentFail();
                return transformThen(node, transformer, prevArgName);
            }
            if (isPromiseReturningCallExpression(node, transformer.checker, "catch")) {
                if (node.arguments.length === 0)
                    return silentFail();
                return transformCatch(node, transformer, prevArgName);
            }
            if (ts.isPropertyAccessExpression(node)) {
                return transformExpression(node.expression, transformer, prevArgName);
            }
            var nodeType = transformer.checker.getTypeAtLocation(node);
            if (nodeType && transformer.checker.getPromisedTypeOfPromise(nodeType)) {
                ts.Debug.assertNode(node.original.parent, ts.isPropertyAccessExpression);
                return transformPromiseExpressionOfPropertyAccess(node, transformer, prevArgName);
            }
            return silentFail();
        }
        function transformCatch(node, transformer, prevArgName) {
            var func = node.arguments[0];
            var argName = getArgBindingName(func, transformer);
            var possibleNameForVarDecl;
            /*
                If there is another call in the chain after the .catch() we are transforming, we will need to save the result of both paths (try block and catch block)
                To do this, we will need to synthesize a variable that we were not aware of while we were adding identifiers to the synthNamesMap
                We will use the prevArgName and then update the synthNamesMap with a new variable name for the next transformation step
            */
            if (prevArgName && !shouldReturn(node, transformer)) {
                if (isSynthIdentifier(prevArgName)) {
                    possibleNameForVarDecl = prevArgName;
                    transformer.synthNamesMap.forEach(function (val, key) {
                        if (val.identifier.text === prevArgName.identifier.text) {
                            var newSynthName = createUniqueSynthName(prevArgName);
                            transformer.synthNamesMap.set(key, newSynthName);
                        }
                    });
                }
                else {
                    possibleNameForVarDecl = createSynthIdentifier(ts.createOptimisticUniqueName("result"), prevArgName.types);
                }
                // We are about to write a 'let' variable declaration, but `transformExpression` for both
                // the try block and catch block will assign to this name. Setting this flag indicates
                // that future assignments should be written as `name = value` instead of `const name = value`.
                possibleNameForVarDecl.hasBeenDeclared = true;
            }
            var tryBlock = ts.createBlock(transformExpression(node.expression, transformer, possibleNameForVarDecl));
            var transformationBody = getTransformationBody(func, possibleNameForVarDecl, argName, node, transformer);
            var catchArg = argName ? isSynthIdentifier(argName) ? argName.identifier.text : argName.bindingPattern : "e";
            var catchVariableDeclaration = ts.createVariableDeclaration(catchArg);
            var catchClause = ts.createCatchClause(catchVariableDeclaration, ts.createBlock(transformationBody));
            /*
                In order to avoid an implicit any, we will synthesize a type for the declaration using the unions of the types of both paths (try block and catch block)
            */
            var varDeclList;
            var varDeclIdentifier;
            if (possibleNameForVarDecl && !shouldReturn(node, transformer)) {
                varDeclIdentifier = ts.getSynthesizedDeepClone(possibleNameForVarDecl.identifier);
                var typeArray = possibleNameForVarDecl.types;
                var unionType = transformer.checker.getUnionType(typeArray, 2 /* Subtype */);
                var unionTypeNode = transformer.isInJSFile ? undefined : transformer.checker.typeToTypeNode(unionType, /*enclosingDeclaration*/ undefined, /*flags*/ undefined);
                var varDecl = [ts.createVariableDeclaration(varDeclIdentifier, unionTypeNode)];
                varDeclList = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(varDecl, 1 /* Let */));
            }
            var tryStatement = ts.createTry(tryBlock, catchClause, /*finallyBlock*/ undefined);
            var destructuredResult = prevArgName && varDeclIdentifier && isSynthBindingPattern(prevArgName)
                && ts.createVariableStatement(/* modifiers */ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.getSynthesizedDeepCloneWithRenames(prevArgName.bindingPattern), /* type */ undefined, varDeclIdentifier)], 2 /* Const */));
            return ts.compact([varDeclList, tryStatement, destructuredResult]);
        }
        function createUniqueSynthName(prevArgName) {
            var renamedPrevArg = ts.createOptimisticUniqueName(prevArgName.identifier.text);
            return createSynthIdentifier(renamedPrevArg);
        }
        function transformThen(node, transformer, prevArgName) {
            var _a = node.arguments, onFulfilled = _a[0], onRejected = _a[1];
            var onFulfilledArgumentName = getArgBindingName(onFulfilled, transformer);
            var transformationBody = getTransformationBody(onFulfilled, prevArgName, onFulfilledArgumentName, node, transformer);
            if (onRejected) {
                var onRejectedArgumentName = getArgBindingName(onRejected, transformer);
                var tryBlock = ts.createBlock(transformExpression(node.expression, transformer, onFulfilledArgumentName).concat(transformationBody));
                var transformationBody2 = getTransformationBody(onRejected, prevArgName, onRejectedArgumentName, node, transformer);
                var catchArg = onRejectedArgumentName ? isSynthIdentifier(onRejectedArgumentName) ? onRejectedArgumentName.identifier.text : onRejectedArgumentName.bindingPattern : "e";
                var catchVariableDeclaration = ts.createVariableDeclaration(catchArg);
                var catchClause = ts.createCatchClause(catchVariableDeclaration, ts.createBlock(transformationBody2));
                return [ts.createTry(tryBlock, catchClause, /* finallyBlock */ undefined)];
            }
            return transformExpression(node.expression, transformer, onFulfilledArgumentName).concat(transformationBody);
        }
        /**
         * Transforms the 'x' part of `x.then(...)`, or the 'y()' part of `y().catch(...)`, where 'x' and 'y()' are Promises.
         */
        function transformPromiseExpressionOfPropertyAccess(node, transformer, prevArgName) {
            if (shouldReturn(node, transformer)) {
                return [ts.createReturn(ts.getSynthesizedDeepClone(node))];
            }
            return createVariableOrAssignmentOrExpressionStatement(prevArgName, ts.createAwait(node), /*typeAnnotation*/ undefined);
        }
        function createVariableOrAssignmentOrExpressionStatement(variableName, rightHandSide, typeAnnotation) {
            if (!variableName || isEmptyBindingName(variableName)) {
                // if there's no argName to assign to, there still might be side effects
                return [ts.createExpressionStatement(rightHandSide)];
            }
            if (isSynthIdentifier(variableName) && variableName.hasBeenDeclared) {
                // if the variable has already been declared, we don't need "let" or "const"
                return [ts.createExpressionStatement(ts.createAssignment(ts.getSynthesizedDeepClone(variableName.identifier), rightHandSide))];
            }
            return [
                ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(ts.getSynthesizedDeepClone(getNode(variableName)), typeAnnotation, rightHandSide)
                ], 2 /* Const */))
            ];
        }
        function maybeAnnotateAndReturn(expressionToReturn, typeAnnotation) {
            if (typeAnnotation && expressionToReturn) {
                var name = ts.createOptimisticUniqueName("result");
                return __spreadArrays(createVariableOrAssignmentOrExpressionStatement(createSynthIdentifier(name), expressionToReturn, typeAnnotation), [
                    ts.createReturn(name)
                ]);
            }
            return [ts.createReturn(expressionToReturn)];
        }
        // should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts
        function getTransformationBody(func, prevArgName, argName, parent, transformer) {
            var _a, _b, _c, _d;
            switch (func.kind) {
                case 100 /* NullKeyword */:
                    // do not produce a transformed statement for a null argument
                    break;
                case 75 /* Identifier */: // identifier includes undefined
                    if (!argName) {
                        // undefined was argument passed to promise handler
                        break;
                    }
                    var synthCall = ts.createCall(ts.getSynthesizedDeepClone(func), /*typeArguments*/ undefined, isSynthIdentifier(argName) ? [argName.identifier] : []);
                    if (shouldReturn(parent, transformer)) {
                        return maybeAnnotateAndReturn(synthCall, (_a = parent.typeArguments) === null || _a === void 0 ? void 0 : _a[0]);
                    }
                    var type = transformer.checker.getTypeAtLocation(func);
                    var callSignatures = transformer.checker.getSignaturesOfType(type, 0 /* Call */);
                    if (!callSignatures.length) {
                        // if identifier in handler has no call signatures, it's invalid
                        return silentFail();
                    }
                    var returnType = callSignatures[0].getReturnType();
                    var varDeclOrAssignment = createVariableOrAssignmentOrExpressionStatement(prevArgName, ts.createAwait(synthCall), (_b = parent.typeArguments) === null || _b === void 0 ? void 0 : _b[0]);
                    if (prevArgName) {
                        prevArgName.types.push(returnType);
                    }
                    return varDeclOrAssignment;
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */: {
                    var funcBody = func.body;
                    // Arrow functions with block bodies { } will enter this control flow
                    if (ts.isBlock(funcBody)) {
                        var refactoredStmts = [];
                        var seenReturnStatement = false;
                        for (var _i = 0, _e = funcBody.statements; _i < _e.length; _i++) {
                            var statement = _e[_i];
                            if (ts.isReturnStatement(statement)) {
                                seenReturnStatement = true;
                                if (ts.isReturnStatementWithFixablePromiseHandler(statement)) {
                                    refactoredStmts = refactoredStmts.concat(getInnerTransformationBody(transformer, [statement], prevArgName));
                                }
                                else {
                                    refactoredStmts.push.apply(refactoredStmts, maybeAnnotateAndReturn(statement.expression, (_c = parent.typeArguments) === null || _c === void 0 ? void 0 : _c[0]));
                                }
                            }
                            else {
                                refactoredStmts.push(statement);
                            }
                        }
                        return shouldReturn(parent, transformer)
                            ? refactoredStmts.map(function (s) { return ts.getSynthesizedDeepClone(s); })
                            : removeReturns(refactoredStmts, prevArgName, transformer, seenReturnStatement);
                    }
                    else {
                        var innerRetStmts = ts.isFixablePromiseHandler(funcBody) ? [ts.createReturn(funcBody)] : ts.emptyArray;
                        var innerCbBody = getInnerTransformationBody(transformer, innerRetStmts, prevArgName);
                        if (innerCbBody.length > 0) {
                            return innerCbBody;
                        }
                        var type_1 = transformer.checker.getTypeAtLocation(func);
                        var returnType_1 = getLastCallSignature(type_1, transformer.checker).getReturnType();
                        var rightHandSide = ts.getSynthesizedDeepClone(funcBody);
                        var possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType_1) ? ts.createAwait(rightHandSide) : rightHandSide;
                        if (!shouldReturn(parent, transformer)) {
                            var transformedStatement = createVariableOrAssignmentOrExpressionStatement(prevArgName, possiblyAwaitedRightHandSide, /*typeAnnotation*/ undefined);
                            if (prevArgName) {
                                prevArgName.types.push(returnType_1);
                            }
                            return transformedStatement;
                        }
                        else {
                            return maybeAnnotateAndReturn(possiblyAwaitedRightHandSide, (_d = parent.typeArguments) === null || _d === void 0 ? void 0 : _d[0]);
                        }
                    }
                }
                default:
                    // If no cases apply, we've found a transformation body we don't know how to handle, so the refactoring should no-op to avoid deleting code.
                    return silentFail();
            }
            return ts.emptyArray;
        }
        function getLastCallSignature(type, checker) {
            var callSignatures = checker.getSignaturesOfType(type, 0 /* Call */);
            return ts.lastOrUndefined(callSignatures);
        }
        function removeReturns(stmts, prevArgName, transformer, seenReturnStatement) {
            var ret = [];
            for (var _i = 0, stmts_1 = stmts; _i < stmts_1.length; _i++) {
                var stmt = stmts_1[_i];
                if (ts.isReturnStatement(stmt)) {
                    if (stmt.expression) {
                        var possiblyAwaitedExpression = isPromiseTypedExpression(stmt.expression, transformer.checker) ? ts.createAwait(stmt.expression) : stmt.expression;
                        if (prevArgName === undefined) {
                            ret.push(ts.createExpressionStatement(possiblyAwaitedExpression));
                        }
                        else {
                            ret.push(ts.createVariableStatement(/*modifiers*/ undefined, (ts.createVariableDeclarationList([ts.createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, possiblyAwaitedExpression)], 2 /* Const */))));
                        }
                    }
                }
                else {
                    ret.push(ts.getSynthesizedDeepClone(stmt));
                }
            }
            // if block has no return statement, need to define prevArgName as undefined to prevent undeclared variables
            if (!seenReturnStatement && prevArgName !== undefined) {
                ret.push(ts.createVariableStatement(/*modifiers*/ undefined, (ts.createVariableDeclarationList([ts.createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, ts.createIdentifier("undefined"))], 2 /* Const */))));
            }
            return ret;
        }
        function getInnerTransformationBody(transformer, innerRetStmts, prevArgName) {
            var innerCbBody = [];
            for (var _i = 0, innerRetStmts_1 = innerRetStmts; _i < innerRetStmts_1.length; _i++) {
                var stmt = innerRetStmts_1[_i];
                ts.forEachChild(stmt, function visit(node) {
                    if (ts.isCallExpression(node)) {
                        var temp = transformExpression(node, transformer, prevArgName);
                        innerCbBody = innerCbBody.concat(temp);
                        if (innerCbBody.length > 0) {
                            return;
                        }
                    }
                    else if (!ts.isFunctionLike(node)) {
                        ts.forEachChild(node, visit);
                    }
                });
            }
            return innerCbBody;
        }
        function getArgBindingName(funcNode, transformer) {
            var types = [];
            var name;
            if (ts.isFunctionLikeDeclaration(funcNode)) {
                if (funcNode.parameters.length > 0) {
                    var param = funcNode.parameters[0].name;
                    name = getMappedBindingNameOrDefault(param);
                }
            }
            else if (ts.isIdentifier(funcNode)) {
                name = getMapEntryOrDefault(funcNode);
            }
            // return undefined argName when arg is null or undefined
            // eslint-disable-next-line no-in-operator
            if (!name || "identifier" in name && name.identifier.text === "undefined") {
                return undefined;
            }
            return name;
            function getMappedBindingNameOrDefault(bindingName) {
                if (ts.isIdentifier(bindingName))
                    return getMapEntryOrDefault(bindingName);
                var elements = ts.flatMap(bindingName.elements, function (element) {
                    if (ts.isOmittedExpression(element))
                        return [];
                    return [getMappedBindingNameOrDefault(element.name)];
                });
                return createSynthBindingPattern(bindingName, elements);
            }
            function getMapEntryOrDefault(identifier) {
                var originalNode = getOriginalNode(identifier);
                var symbol = getSymbol(originalNode);
                if (!symbol) {
                    return createSynthIdentifier(identifier, types);
                }
                var mapEntry = transformer.synthNamesMap.get(ts.getSymbolId(symbol).toString());
                return mapEntry || createSynthIdentifier(identifier, types);
            }
            function getSymbol(node) {
                return node.symbol ? node.symbol : transformer.checker.getSymbolAtLocation(node);
            }
            function getOriginalNode(node) {
                return node.original ? node.original : node;
            }
        }
        function isEmptyBindingName(bindingName) {
            if (!bindingName) {
                return true;
            }
            if (isSynthIdentifier(bindingName)) {
                return !bindingName.identifier.text;
            }
            return ts.every(bindingName.elements, isEmptyBindingName);
        }
        function getNode(bindingName) {
            return isSynthIdentifier(bindingName) ? bindingName.identifier : bindingName.bindingPattern;
        }
        function createSynthIdentifier(identifier, types) {
            if (types === void 0) { types = []; }
            return { kind: 0 /* Identifier */, identifier: identifier, types: types, hasBeenDeclared: false };
        }
        function createSynthBindingPattern(bindingPattern, elements, types) {
            if (elements === void 0) { elements = ts.emptyArray; }
            if (types === void 0) { types = []; }
            return { kind: 1 /* BindingPattern */, bindingPattern: bindingPattern, elements: elements, types: types };
        }
        function isSynthIdentifier(bindingName) {
            return bindingName.kind === 0 /* Identifier */;
        }
        function isSynthBindingPattern(bindingName) {
            return bindingName.kind === 1 /* BindingPattern */;
        }
        function shouldReturn(expression, transformer) {
            return !!expression.original && transformer.setOfExpressionsToReturn.has(ts.getNodeId(expression.original).toString());
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module.code],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, preferences = context.preferences;
                var changes = ts.textChanges.ChangeTracker.with(context, function (changes) {
                    var moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, program.getCompilerOptions().target, ts.getQuotePreference(sourceFile, preferences));
                    if (moduleExportsChangedToDefault) {
                        for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
                            var importingFile = _a[_i];
                            fixImportOfModuleExports(importingFile, sourceFile, changes, ts.getQuotePreference(importingFile, preferences));
                        }
                    }
                });
                // No support for fix-all since this applies to the whole file at once anyway.
                return [codefix.createCodeFixActionWithoutFixAll("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)];
            },
        });
        function fixImportOfModuleExports(importingFile, exportingFile, changes, quotePreference) {
            for (var _i = 0, _a = importingFile.imports; _i < _a.length; _i++) {
                var moduleSpecifier = _a[_i];
                var imported = ts.getResolvedModule(importingFile, moduleSpecifier.text);
                if (!imported || imported.resolvedFileName !== exportingFile.fileName) {
                    continue;
                }
                var importNode = ts.importFromModuleSpecifier(moduleSpecifier);
                switch (importNode.kind) {
                    case 253 /* ImportEqualsDeclaration */:
                        changes.replaceNode(importingFile, importNode, ts.makeImport(importNode.name, /*namedImports*/ undefined, moduleSpecifier, quotePreference));
                        break;
                    case 196 /* CallExpression */:
                        if (ts.isRequireCall(importNode, /*checkArgumentIsStringLiteralLike*/ false)) {
                            changes.replaceNode(importingFile, importNode, ts.createPropertyAccess(ts.getSynthesizedDeepClone(importNode), "default"));
                        }
                        break;
                }
            }
        }
        /** @returns Whether we converted a `module.exports =` to a default export. */
        function convertFileToEs6Module(sourceFile, checker, changes, target, quotePreference) {
            var identifiers = { original: collectFreeIdentifiers(sourceFile), additional: ts.createMap() };
            var exports = collectExportRenames(sourceFile, checker, identifiers);
            convertExportsAccesses(sourceFile, exports, changes);
            var moduleExportsChangedToDefault = false;
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                var moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports, quotePreference);
                moduleExportsChangedToDefault = moduleExportsChangedToDefault || moduleExportsChanged;
            }
            return moduleExportsChangedToDefault;
        }
        function collectExportRenames(sourceFile, checker, identifiers) {
            var res = ts.createMap();
            forEachExportReference(sourceFile, function (node) {
                var _a = node.name, text = _a.text, originalKeywordKind = _a.originalKeywordKind;
                if (!res.has(text) && (originalKeywordKind !== undefined && ts.isNonContextualKeyword(originalKeywordKind)
                    || checker.resolveName(text, node, 111551 /* Value */, /*excludeGlobals*/ true))) {
                    // Unconditionally add an underscore in case `text` is a keyword.
                    res.set(text, makeUniqueName("_" + text, identifiers));
                }
            });
            return res;
        }
        function convertExportsAccesses(sourceFile, exports, changes) {
            forEachExportReference(sourceFile, function (node, isAssignmentLhs) {
                if (isAssignmentLhs) {
                    return;
                }
                var text = node.name.text;
                changes.replaceNode(sourceFile, node, ts.createIdentifier(exports.get(text) || text));
            });
        }
        function forEachExportReference(sourceFile, cb) {
            sourceFile.forEachChild(function recur(node) {
                if (ts.isPropertyAccessExpression(node) && ts.isExportsOrModuleExportsOrAlias(sourceFile, node.expression) && ts.isIdentifier(node.name)) {
                    var parent = node.parent;
                    cb(node, ts.isBinaryExpression(parent) && parent.left === node && parent.operatorToken.kind === 62 /* EqualsToken */);
                }
                node.forEachChild(recur);
            });
        }
        function convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports, quotePreference) {
            switch (statement.kind) {
                case 225 /* VariableStatement */:
                    convertVariableStatement(sourceFile, statement, changes, checker, identifiers, target, quotePreference);
                    return false;
                case 226 /* ExpressionStatement */: {
                    var expression = statement.expression;
                    switch (expression.kind) {
                        case 196 /* CallExpression */: {
                            if (ts.isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true)) {
                                // For side-effecting require() call, just make a side-effecting import.
                                changes.replaceNode(sourceFile, statement, ts.makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0], quotePreference));
                            }
                            return false;
                        }
                        case 209 /* BinaryExpression */: {
                            var operatorToken = expression.operatorToken;
                            return operatorToken.kind === 62 /* EqualsToken */ && convertAssignment(sourceFile, checker, expression, changes, exports);
                        }
                    }
                }
                // falls through
                default:
                    return false;
            }
        }
        function convertVariableStatement(sourceFile, statement, changes, checker, identifiers, target, quotePreference) {
            var declarationList = statement.declarationList;
            var foundImport = false;
            var newNodes = ts.flatMap(declarationList.declarations, function (decl) {
                var name = decl.name, initializer = decl.initializer;
                if (initializer) {
                    if (ts.isExportsOrModuleExportsOrAlias(sourceFile, initializer)) {
                        // `const alias = module.exports;` can be removed.
                        foundImport = true;
                        return [];
                    }
                    else if (ts.isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
                        foundImport = true;
                        return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target, quotePreference);
                    }
                    else if (ts.isPropertyAccessExpression(initializer) && ts.isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) {
                        foundImport = true;
                        return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers, quotePreference);
                    }
                }
                // Move it out to its own variable statement. (This will not be used if `!foundImport`)
                return ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([decl], declarationList.flags));
            });
            if (foundImport) {
                // useNonAdjustedEndPosition to ensure we don't eat the newline after the statement.
                changes.replaceNodeWithNodes(sourceFile, statement, newNodes);
            }
        }
        /** Converts `const name = require("moduleSpecifier").propertyName` */
        function convertPropertyAccessImport(name, propertyName, moduleSpecifier, identifiers, quotePreference) {
            switch (name.kind) {
                case 189 /* ObjectBindingPattern */:
                case 190 /* ArrayBindingPattern */: {
                    // `const [a, b] = require("c").d` --> `import { d } from "c"; const [a, b] = d;`
                    var tmp = makeUniqueName(propertyName, identifiers);
                    return [
                        makeSingleImport(tmp, propertyName, moduleSpecifier, quotePreference),
                        makeConst(/*modifiers*/ undefined, name, ts.createIdentifier(tmp)),
                    ];
                }
                case 75 /* Identifier */:
                    // `const a = require("b").c` --> `import { c as a } from "./b";
                    return [makeSingleImport(name.text, propertyName, moduleSpecifier, quotePreference)];
                default:
                    return ts.Debug.assertNever(name, "Convert to ES6 module got invalid syntax form " + name.kind);
            }
        }
        function convertAssignment(sourceFile, checker, assignment, changes, exports) {
            var left = assignment.left, right = assignment.right;
            if (!ts.isPropertyAccessExpression(left)) {
                return false;
            }
            if (ts.isExportsOrModuleExportsOrAlias(sourceFile, left)) {
                if (ts.isExportsOrModuleExportsOrAlias(sourceFile, right)) {
                    // `const alias = module.exports;` or `module.exports = alias;` can be removed.
                    changes.delete(sourceFile, assignment.parent);
                }
                else {
                    var replacement = ts.isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right)
                        : ts.isRequireCall(right, /*checkArgumentIsStringLiteralLike*/ true) ? convertReExportAll(right.arguments[0], checker)
                            : undefined;
                    if (replacement) {
                        changes.replaceNodeWithNodes(sourceFile, assignment.parent, replacement[0]);
                        return replacement[1];
                    }
                    else {
                        changes.replaceRangeWithText(sourceFile, ts.createRange(left.getStart(sourceFile), right.pos), "export default");
                        return true;
                    }
                }
            }
            else if (ts.isExportsOrModuleExportsOrAlias(sourceFile, left.expression)) {
                convertNamedExport(sourceFile, assignment, changes, exports);
            }
            return false;
        }
        /**
         * Convert `module.exports = { ... }` to individual exports..
         * We can't always do this if the module has interesting members -- then it will be a default export instead.
         */
        function tryChangeModuleExportsObject(object) {
            var statements = ts.mapAllOrFail(object.properties, function (prop) {
                switch (prop.kind) {
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    // TODO: Maybe we should handle this? See fourslash test `refactorConvertToEs6Module_export_object_shorthand.ts`.
                    // falls through
                    case 282 /* ShorthandPropertyAssignment */:
                    case 283 /* SpreadAssignment */:
                        return undefined;
                    case 281 /* PropertyAssignment */:
                        return !ts.isIdentifier(prop.name) ? undefined : convertExportsDotXEquals_replaceNode(prop.name.text, prop.initializer);
                    case 161 /* MethodDeclaration */:
                        return !ts.isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [ts.createToken(89 /* ExportKeyword */)], prop);
                    default:
                        ts.Debug.assertNever(prop, "Convert to ES6 got invalid prop kind " + prop.kind);
                }
            });
            return statements && [statements, false];
        }
        function convertNamedExport(sourceFile, assignment, changes, exports) {
            // If "originalKeywordKind" was set, this is e.g. `exports.
            var text = assignment.left.name.text;
            var rename = exports.get(text);
            if (rename !== undefined) {
                /*
                const _class = 0;
                export { _class as class };
                */
                var newNodes = [
                    makeConst(/*modifiers*/ undefined, rename, assignment.right),
                    makeExportDeclaration([ts.createExportSpecifier(rename, text)]),
                ];
                changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes);
            }
            else {
                convertExportsPropertyAssignment(assignment, sourceFile, changes);
            }
        }
        function convertReExportAll(reExported, checker) {
            // `module.exports = require("x");` ==> `export * from "x"; export { default } from "x";`
            var moduleSpecifier = reExported.text;
            var moduleSymbol = checker.getSymbolAtLocation(reExported);
            var exports = moduleSymbol ? moduleSymbol.exports : ts.emptyUnderscoreEscapedMap;
            return exports.has("export=") ? [[reExportDefault(moduleSpecifier)], true] :
                !exports.has("default") ? [[reExportStar(moduleSpecifier)], false] :
                    // If there's some non-default export, must include both `export *` and `export default`.
                    exports.size > 1 ? [[reExportStar(moduleSpecifier), reExportDefault(moduleSpecifier)], true] : [[reExportDefault(moduleSpecifier)], true];
        }
        function reExportStar(moduleSpecifier) {
            return makeExportDeclaration(/*exportClause*/ undefined, moduleSpecifier);
        }
        function reExportDefault(moduleSpecifier) {
            return makeExportDeclaration([ts.createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier);
        }
        function convertExportsPropertyAssignment(_a, sourceFile, changes) {
            var left = _a.left, right = _a.right, parent = _a.parent;
            var name = left.name.text;
            if ((ts.isFunctionExpression(right) || ts.isArrowFunction(right) || ts.isClassExpression(right)) && (!right.name || right.name.text === name)) {
                // `exports.f = function() {}` -> `export function f() {}` -- Replace `exports.f = ` with `export `, and insert the name after `function`.
                changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, ts.createToken(89 /* ExportKeyword */), { suffix: " " });
                if (!right.name)
                    changes.insertName(sourceFile, right, name);
                var semi = ts.findChildOfKind(parent, 26 /* SemicolonToken */, sourceFile);
                if (semi)
                    changes.delete(sourceFile, semi);
            }
            else {
                // `exports.f = function g() {}` -> `export const f = function g() {}` -- just replace `exports.` with `export const `
                changes.replaceNodeRangeWithNodes(sourceFile, left.expression, ts.findChildOfKind(left, 24 /* DotToken */, sourceFile), [ts.createToken(89 /* ExportKeyword */), ts.createToken(81 /* ConstKeyword */)], { joiner: " ", suffix: " " });
            }
        }
        // TODO: GH#22492 this will cause an error if a change has been made inside the body of the node.
        function convertExportsDotXEquals_replaceNode(name, exported) {
            var modifiers = [ts.createToken(89 /* ExportKeyword */)];
            switch (exported.kind) {
                case 201 /* FunctionExpression */: {
                    var expressionName = exported.name;
                    if (expressionName && expressionName.text !== name) {
                        // `exports.f = function g() {}` -> `export const f = function g() {}`
                        return exportConst();
                    }
                }
                // falls through
                case 202 /* ArrowFunction */:
                    // `exports.f = function() {}` --> `export function f() {}`
                    return functionExpressionToDeclaration(name, modifiers, exported);
                case 214 /* ClassExpression */:
                    // `exports.C = class {}` --> `export class C {}`
                    return classExpressionToDeclaration(name, modifiers, exported);
                default:
                    return exportConst();
            }
            function exportConst() {
                // `exports.x = 0;` --> `export const x = 0;`
                return makeConst(modifiers, ts.createIdentifier(name), exported); // TODO: GH#18217
            }
        }
        /**
         * Converts `const <<name>> = require("x");`.
         * Returns nodes that will replace the variable declaration for the commonjs import.
         * May also make use `changes` to remove qualifiers at the use sites of imports, to change `mod.x` to `x`.
         */
        function convertSingleImport(file, name, moduleSpecifier, changes, checker, identifiers, target, quotePreference) {
            switch (name.kind) {
                case 189 /* ObjectBindingPattern */: {
                    var importSpecifiers = ts.mapAllOrFail(name.elements, function (e) {
                        return e.dotDotDotToken || e.initializer || e.propertyName && !ts.isIdentifier(e.propertyName) || !ts.isIdentifier(e.name)
                            ? undefined
                            // (TODO: GH#18217)
                            // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
                            : makeImportSpecifier(e.propertyName && e.propertyName.text, e.name.text);
                    });
                    if (importSpecifiers) {
                        return [ts.makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier, quotePreference)];
                    }
                }
                // falls through -- object destructuring has an interesting pattern and must be a variable declaration
                case 190 /* ArrayBindingPattern */: {
                    /*
                    import x from "x";
                    const [a, b, c] = x;
                    */
                    var tmp = makeUniqueName(codefix.moduleSpecifierToValidIdentifier(moduleSpecifier.text, target), identifiers);
                    return [
                        ts.makeImport(ts.createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, quotePreference),
                        makeConst(/*modifiers*/ undefined, ts.getSynthesizedDeepClone(name), ts.createIdentifier(tmp)),
                    ];
                }
                case 75 /* Identifier */:
                    return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, quotePreference);
                default:
                    return ts.Debug.assertNever(name, "Convert to ES6 module got invalid name kind " + name.kind);
            }
        }
        /**
         * Convert `import x = require("x").`
         * Also converts uses like `x.y()` to `y()` and uses a named import.
         */
        function convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, quotePreference) {
            var nameSymbol = checker.getSymbolAtLocation(name);
            // Maps from module property name to name actually used. (The same if there isn't shadowing.)
            var namedBindingsNames = ts.createMap();
            // True if there is some non-property use like `x()` or `f(x)`.
            var needDefaultImport = false;
            for (var _i = 0, _a = identifiers.original.get(name.text); _i < _a.length; _i++) {
                var use = _a[_i];
                if (checker.getSymbolAtLocation(use) !== nameSymbol || use === name) {
                    // This was a use of a different symbol with the same name, due to shadowing. Ignore.
                    continue;
                }
                var parent = use.parent;
                if (ts.isPropertyAccessExpression(parent)) {
                    var expression = parent.expression, propertyName = parent.name.text;
                    ts.Debug.assert(expression === use, "Didn't expect expression === use"); // Else shouldn't have been in `collectIdentifiers`
                    var idName = namedBindingsNames.get(propertyName);
                    if (idName === undefined) {
                        idName = makeUniqueName(propertyName, identifiers);
                        namedBindingsNames.set(propertyName, idName);
                    }
                    changes.replaceNode(file, parent, ts.createIdentifier(idName));
                }
                else {
                    needDefaultImport = true;
                }
            }
            var namedBindings = namedBindingsNames.size === 0 ? undefined : ts.arrayFrom(ts.mapIterator(namedBindingsNames.entries(), function (_a) {
                var propertyName = _a[0], idName = _a[1];
                return ts.createImportSpecifier(propertyName === idName ? undefined : ts.createIdentifier(propertyName), ts.createIdentifier(idName));
            }));
            if (!namedBindings) {
                // If it was unused, ensure that we at least import *something*.
                needDefaultImport = true;
            }
            return [ts.makeImport(needDefaultImport ? ts.getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier, quotePreference)];
        }
        // Identifiers helpers
        function makeUniqueName(name, identifiers) {
            while (identifiers.original.has(name) || identifiers.additional.has(name)) {
                name = "_" + name;
            }
            identifiers.additional.set(name, true);
            return name;
        }
        function collectFreeIdentifiers(file) {
            var map = ts.createMultiMap();
            forEachFreeIdentifier(file, function (id) { return map.add(id.text, id); });
            return map;
        }
        /**
         * A free identifier is an identifier that can be accessed through name lookup as a local variable.
         * In the expression `x.y`, `x` is a free identifier, but `y` is not.
         */
        function forEachFreeIdentifier(node, cb) {
            if (ts.isIdentifier(node) && isFreeIdentifier(node))
                cb(node);
            node.forEachChild(function (child) { return forEachFreeIdentifier(child, cb); });
        }
        function isFreeIdentifier(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 194 /* PropertyAccessExpression */:
                    return parent.name !== node;
                case 191 /* BindingElement */:
                    return parent.propertyName !== node;
                case 258 /* ImportSpecifier */:
                    return parent.propertyName !== node;
                default:
                    return true;
            }
        }
        // Node helpers
        function functionExpressionToDeclaration(name, additionalModifiers, fn) {
            return ts.createFunctionDeclaration(ts.getSynthesizedDeepClones(fn.decorators), // TODO: GH#19915 Don't think this is even legal.
            ts.concatenate(additionalModifiers, ts.getSynthesizedDeepClones(fn.modifiers)), ts.getSynthesizedDeepClone(fn.asteriskToken), name, ts.getSynthesizedDeepClones(fn.typeParameters), ts.getSynthesizedDeepClones(fn.parameters), ts.getSynthesizedDeepClone(fn.type), ts.convertToFunctionBody(ts.getSynthesizedDeepClone(fn.body)));
        }
        function classExpressionToDeclaration(name, additionalModifiers, cls) {
            return ts.createClassDeclaration(ts.getSynthesizedDeepClones(cls.decorators), // TODO: GH#19915 Don't think this is even legal.
            ts.concatenate(additionalModifiers, ts.getSynthesizedDeepClones(cls.modifiers)), name, ts.getSynthesizedDeepClones(cls.typeParameters), ts.getSynthesizedDeepClones(cls.heritageClauses), ts.getSynthesizedDeepClones(cls.members));
        }
        function makeSingleImport(localName, propertyName, moduleSpecifier, quotePreference) {
            return propertyName === "default"
                ? ts.makeImport(ts.createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, quotePreference)
                : ts.makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier, quotePreference);
        }
        function makeImportSpecifier(propertyName, name) {
            return ts.createImportSpecifier(propertyName !== undefined && propertyName !== name ? ts.createIdentifier(propertyName) : undefined, ts.createIdentifier(name));
        }
        function makeConst(modifiers, name, init) {
            return ts.createVariableStatement(modifiers, ts.createVariableDeclarationList([ts.createVariableDeclaration(name, /*type*/ undefined, init)], 2 /* Const */));
        }
        function makeExportDeclaration(exportSpecifiers, moduleSpecifier) {
            return ts.createExportDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, exportSpecifiers && ts.createNamedExports(exportSpecifiers), moduleSpecifier === undefined ? undefined : ts.createLiteral(moduleSpecifier));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "correctQualifiedNameToIndexedAccessType";
        var errorCodes = [ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var qualifiedName = getQualifiedName(context.sourceFile, context.span.start);
                if (!qualifiedName)
                    return undefined;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, qualifiedName); });
                var newText = qualifiedName.left.text + "[\"" + qualifiedName.right.text + "\"]";
                return [codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Rewrite_as_the_indexed_access_type_0, newText], fixId, ts.Diagnostics.Rewrite_all_as_indexed_access_types)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var q = getQualifiedName(diag.file, diag.start);
                if (q) {
                    doChange(changes, diag.file, q);
                }
            }); },
        });
        function getQualifiedName(sourceFile, pos) {
            var qualifiedName = ts.findAncestor(ts.getTokenAtPosition(sourceFile, pos), ts.isQualifiedName);
            ts.Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name.");
            return ts.isIdentifier(qualifiedName.left) ? qualifiedName : undefined;
        }
        function doChange(changeTracker, sourceFile, qualifiedName) {
            var rightText = qualifiedName.right.text;
            var replacement = ts.createIndexedAccessTypeNode(ts.createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined), ts.createLiteralTypeNode(ts.createLiteral(rightText)));
            changeTracker.replaceNode(sourceFile, qualifiedName, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodes = [ts.Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type.code];
        var fixId = "convertToTypeOnlyExport";
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return fixSingleExportDeclaration(t, getExportSpecifierForDiagnosticSpan(context.span, context.sourceFile), context); });
                if (changes.length) {
                    return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_to_type_only_export, fixId, ts.Diagnostics.Convert_all_re_exported_types_to_type_only_exports)];
                }
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var fixedExportDeclarations = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var exportSpecifier = getExportSpecifierForDiagnosticSpan(diag, context.sourceFile);
                    if (exportSpecifier && !ts.addToSeen(fixedExportDeclarations, ts.getNodeId(exportSpecifier.parent.parent))) {
                        fixSingleExportDeclaration(changes, exportSpecifier, context);
                    }
                });
            }
        });
        function getExportSpecifierForDiagnosticSpan(span, sourceFile) {
            return ts.tryCast(ts.getTokenAtPosition(sourceFile, span.start).parent, ts.isExportSpecifier);
        }
        function fixSingleExportDeclaration(changes, exportSpecifier, context) {
            if (!exportSpecifier) {
                return;
            }
            var exportClause = exportSpecifier.parent;
            var exportDeclaration = exportClause.parent;
            var typeExportSpecifiers = getTypeExportSpecifiers(exportSpecifier, context);
            if (typeExportSpecifiers.length === exportClause.elements.length) {
                changes.replaceNode(context.sourceFile, exportDeclaration, ts.updateExportDeclaration(exportDeclaration, exportDeclaration.decorators, exportDeclaration.modifiers, exportClause, exportDeclaration.moduleSpecifier, 
                /*isTypeOnly*/ true));
            }
            else {
                var valueExportDeclaration = ts.updateExportDeclaration(exportDeclaration, exportDeclaration.decorators, exportDeclaration.modifiers, ts.updateNamedExports(exportClause, ts.filter(exportClause.elements, function (e) { return !ts.contains(typeExportSpecifiers, e); })), exportDeclaration.moduleSpecifier, 
                /*isTypeOnly*/ false);
                var typeExportDeclaration = ts.createExportDeclaration(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, ts.createNamedExports(typeExportSpecifiers), exportDeclaration.moduleSpecifier, 
                /*isTypeOnly*/ true);
                changes.replaceNode(context.sourceFile, exportDeclaration, valueExportDeclaration);
                changes.insertNodeAfter(context.sourceFile, exportDeclaration, typeExportDeclaration);
            }
        }
        function getTypeExportSpecifiers(originExportSpecifier, context) {
            var exportClause = originExportSpecifier.parent;
            if (exportClause.elements.length === 1) {
                return exportClause.elements;
            }
            var diagnostics = ts.getDiagnosticsWithinSpan(ts.createTextSpanFromNode(exportClause), context.program.getSemanticDiagnostics(context.sourceFile, context.cancellationToken));
            return ts.filter(exportClause.elements, function (element) {
                var _a;
                return element === originExportSpecifier || ((_a = ts.findDiagnosticForNode(element, diagnostics)) === null || _a === void 0 ? void 0 : _a.code) === errorCodes[0];
            });
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodes = [ts.Diagnostics.This_import_is_never_used_as_a_value_and_must_use_import_type_because_the_importsNotUsedAsValues_is_set_to_error.code];
        var fixId = "convertToTypeOnlyImport";
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) {
                    var importDeclaration = getImportDeclarationForDiagnosticSpan(context.span, context.sourceFile);
                    fixSingleImportDeclaration(t, importDeclaration, context);
                });
                if (changes.length) {
                    return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_to_type_only_import, fixId, ts.Diagnostics.Convert_all_imports_not_used_as_a_value_to_type_only_imports)];
                }
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var importDeclaration = getImportDeclarationForDiagnosticSpan(diag, context.sourceFile);
                    fixSingleImportDeclaration(changes, importDeclaration, context);
                });
            }
        });
        function getImportDeclarationForDiagnosticSpan(span, sourceFile) {
            return ts.tryCast(ts.getTokenAtPosition(sourceFile, span.start).parent, ts.isImportDeclaration);
        }
        function fixSingleImportDeclaration(changes, importDeclaration, context) {
            if (!(importDeclaration === null || importDeclaration === void 0 ? void 0 : importDeclaration.importClause)) {
                return;
            }
            var importClause = importDeclaration.importClause;
            // `changes.insertModifierBefore` produces a range that might overlap further changes
            changes.insertText(context.sourceFile, importDeclaration.getStart() + "import".length, " type");
            // `import type foo, { Bar }` is not allowed, so move `foo` to new declaration
            if (importClause.name && importClause.namedBindings) {
                changes.deleteNodeRangeExcludingEnd(context.sourceFile, importClause.name, importDeclaration.importClause.namedBindings);
                changes.insertNodeBefore(context.sourceFile, importDeclaration, ts.updateImportDeclaration(importDeclaration, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, ts.createImportClause(importClause.name, 
                /*namedBindings*/ undefined, 
                /*isTypeOnly*/ true), importDeclaration.moduleSpecifier));
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodes = [
            ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code,
            ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code
        ];
        var fixId = "fixClassIncorrectlyImplementsInterface"; // TODO: share a group with fixClassDoesntImplementInheritedAbstractMember?
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var classDeclaration = getClass(sourceFile, span.start);
                return ts.mapDefined(ts.getEffectiveImplementsTypeNodes(classDeclaration), function (implementedTypeNode) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addMissingDeclarations(context, implementedTypeNode, sourceFile, classDeclaration, t, context.preferences); });
                    return changes.length === 0 ? undefined : codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Implement_interface_0, implementedTypeNode.getText(sourceFile)], fixId, ts.Diagnostics.Implement_all_unimplemented_interfaces);
                });
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var seenClassDeclarations = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var classDeclaration = getClass(diag.file, diag.start);
                    if (ts.addToSeen(seenClassDeclarations, ts.getNodeId(classDeclaration))) {
                        for (var _i = 0, _a = ts.getEffectiveImplementsTypeNodes(classDeclaration); _i < _a.length; _i++) {
                            var implementedTypeNode = _a[_i];
                            addMissingDeclarations(context, implementedTypeNode, diag.file, classDeclaration, changes, context.preferences);
                        }
                    }
                });
            },
        });
        function getClass(sourceFile, pos) {
            return ts.Debug.checkDefined(ts.getContainingClass(ts.getTokenAtPosition(sourceFile, pos)), "There should be a containing class");
        }
        function symbolPointsToNonPrivateMember(symbol) {
            return !symbol.valueDeclaration || !(ts.getModifierFlags(symbol.valueDeclaration) & 8 /* Private */);
        }
        function addMissingDeclarations(context, implementedTypeNode, sourceFile, classDeclaration, changeTracker, preferences) {
            var checker = context.program.getTypeChecker();
            var maybeHeritageClauseSymbol = getHeritageClauseSymbolTable(classDeclaration, checker);
            // Note that this is ultimately derived from a map indexed by symbol names,
            // so duplicates cannot occur.
            var implementedType = checker.getTypeAtLocation(implementedTypeNode);
            var implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
            var nonPrivateAndNotExistedInHeritageClauseMembers = implementedTypeSymbols.filter(ts.and(symbolPointsToNonPrivateMember, function (symbol) { return !maybeHeritageClauseSymbol.has(symbol.escapedName); }));
            var classType = checker.getTypeAtLocation(classDeclaration);
            var constructor = ts.find(classDeclaration.members, function (m) { return ts.isConstructorDeclaration(m); });
            if (!classType.getNumberIndexType()) {
                createMissingIndexSignatureDeclaration(implementedType, 1 /* Number */);
            }
            if (!classType.getStringIndexType()) {
                createMissingIndexSignatureDeclaration(implementedType, 0 /* String */);
            }
            var importAdder = codefix.createImportAdder(sourceFile, context.program, preferences, context.host);
            codefix.createMissingMemberNodes(classDeclaration, nonPrivateAndNotExistedInHeritageClauseMembers, context, preferences, importAdder, function (member) { return insertInterfaceMemberNode(sourceFile, classDeclaration, member); });
            importAdder.writeFixes(changeTracker);
            function createMissingIndexSignatureDeclaration(type, kind) {
                var indexInfoOfKind = checker.getIndexInfoOfType(type, kind);
                if (indexInfoOfKind) {
                    insertInterfaceMemberNode(sourceFile, classDeclaration, checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration, /*flags*/ undefined, codefix.getNoopSymbolTrackerWithResolver(context)));
                }
            }
            // Either adds the node at the top of the class, or if there's a constructor right after that
            function insertInterfaceMemberNode(sourceFile, cls, newElement) {
                if (constructor) {
                    changeTracker.insertNodeAfter(sourceFile, constructor, newElement);
                }
                else {
                    changeTracker.insertNodeAtClassStart(sourceFile, cls, newElement);
                }
            }
        }
        function getHeritageClauseSymbolTable(classDeclaration, checker) {
            var heritageClauseNode = ts.getEffectiveBaseTypeNode(classDeclaration);
            if (!heritageClauseNode)
                return ts.createSymbolTable();
            var heritageClauseType = checker.getTypeAtLocation(heritageClauseNode);
            var heritageClauseTypeSymbols = checker.getPropertiesOfType(heritageClauseType);
            return ts.createSymbolTable(heritageClauseTypeSymbols.filter(symbolPointsToNonPrivateMember));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.importFixName = "import";
        var importFixId = "fixMissingImport";
        var errorCodes = [
            ts.Diagnostics.Cannot_find_name_0.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code,
            ts.Diagnostics.Cannot_find_namespace_0.code,
            ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code,
            ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var errorCode = context.errorCode, preferences = context.preferences, sourceFile = context.sourceFile, span = context.span;
                var info = getFixesInfo(context, errorCode, span.start);
                if (!info)
                    return undefined;
                var fixes = info.fixes, symbolName = info.symbolName;
                var quotePreference = ts.getQuotePreference(sourceFile, preferences);
                return fixes.map(function (fix) { return codeActionForFix(context, sourceFile, symbolName, fix, quotePreference); });
            },
            fixIds: [importFixId],
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, preferences = context.preferences, host = context.host;
                var importAdder = createImportAdder(sourceFile, program, preferences, host);
                codefix.eachDiagnostic(context, errorCodes, function (diag) { return importAdder.addImportFromDiagnostic(diag, context); });
                return codefix.createCombinedCodeActions(ts.textChanges.ChangeTracker.with(context, importAdder.writeFixes));
            },
        });
        function createImportAdder(sourceFile, program, preferences, host) {
            var compilerOptions = program.getCompilerOptions();
            // Namespace fixes don't conflict, so just build a list.
            var addToNamespace = [];
            var importType = [];
            // Keys are import clause node IDs.
            var addToExisting = ts.createMap();
            var newImports = ts.createMap();
            return { addImportFromDiagnostic: addImportFromDiagnostic, addImportFromExportedSymbol: addImportFromExportedSymbol, writeFixes: writeFixes };
            function addImportFromDiagnostic(diagnostic, context) {
                var info = getFixesInfo(context, diagnostic.code, diagnostic.start);
                if (!info || !info.fixes.length)
                    return;
                addImport(info);
            }
            function addImportFromExportedSymbol(exportedSymbol, usageIsTypeOnly) {
                var moduleSymbol = ts.Debug.checkDefined(exportedSymbol.parent);
                var symbolName = ts.getNameForExportedSymbol(exportedSymbol, ts.getEmitScriptTarget(compilerOptions));
                var checker = program.getTypeChecker();
                var symbol = checker.getMergedSymbol(ts.skipAlias(exportedSymbol, checker));
                var exportInfos = getAllReExportingModules(sourceFile, symbol, moduleSymbol, symbolName, sourceFile, compilerOptions, checker, program.getSourceFiles());
                var preferTypeOnlyImport = !!usageIsTypeOnly && compilerOptions.importsNotUsedAsValues === 2 /* Error */;
                var useRequire = shouldUseRequire(sourceFile, compilerOptions);
                var fix = getImportFixForSymbol(sourceFile, exportInfos, moduleSymbol, symbolName, program, /*position*/ undefined, preferTypeOnlyImport, useRequire, host, preferences);
                addImport({ fixes: [fix], symbolName: symbolName });
            }
            function addImport(info) {
                var fixes = info.fixes, symbolName = info.symbolName;
                var fix = ts.first(fixes);
                switch (fix.kind) {
                    case 0 /* UseNamespace */:
                        addToNamespace.push(fix);
                        break;
                    case 1 /* ImportType */:
                        importType.push(fix);
                        break;
                    case 2 /* AddToExisting */: {
                        var importClauseOrBindingPattern = fix.importClauseOrBindingPattern, importKind = fix.importKind, canUseTypeOnlyImport = fix.canUseTypeOnlyImport;
                        var key = String(ts.getNodeId(importClauseOrBindingPattern));
                        var entry = addToExisting.get(key);
                        if (!entry) {
                            addToExisting.set(key, entry = { importClauseOrBindingPattern: importClauseOrBindingPattern, defaultImport: undefined, namedImports: [], canUseTypeOnlyImport: canUseTypeOnlyImport });
                        }
                        if (importKind === 0 /* Named */) {
                            ts.pushIfUnique(entry.namedImports, symbolName);
                        }
                        else {
                            ts.Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName, "(Add to Existing) Default import should be missing or match symbolName");
                            entry.defaultImport = symbolName;
                        }
                        break;
                    }
                    case 3 /* AddNew */: {
                        var moduleSpecifier = fix.moduleSpecifier, importKind = fix.importKind, useRequire = fix.useRequire, typeOnly = fix.typeOnly;
                        var entry = newImports.get(moduleSpecifier);
                        if (!entry) {
                            newImports.set(moduleSpecifier, entry = { namedImports: [], namespaceLikeImport: undefined, typeOnly: typeOnly, useRequire: useRequire });
                        }
                        else {
                            // An import clause can only be type-only if every import fix contributing to it can be type-only.
                            entry.typeOnly = entry.typeOnly && typeOnly;
                        }
                        switch (importKind) {
                            case 1 /* Default */:
                                ts.Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName, "(Add new) Default import should be missing or match symbolName");
                                entry.defaultImport = symbolName;
                                break;
                            case 0 /* Named */:
                                ts.pushIfUnique(entry.namedImports || (entry.namedImports = []), symbolName);
                                break;
                            case 3 /* CommonJS */:
                            case 2 /* Namespace */:
                                ts.Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName, "Namespacelike import shoudl be missing or match symbolName");
                                entry.namespaceLikeImport = { importKind: importKind, name: symbolName };
                                break;
                        }
                        break;
                    }
                    default:
                        ts.Debug.assertNever(fix, "fix wasn't never - got kind " + fix.kind);
                }
            }
            function writeFixes(changeTracker) {
                var quotePreference = ts.getQuotePreference(sourceFile, preferences);
                for (var _i = 0, addToNamespace_1 = addToNamespace; _i < addToNamespace_1.length; _i++) {
                    var fix = addToNamespace_1[_i];
                    addNamespaceQualifier(changeTracker, sourceFile, fix);
                }
                for (var _a = 0, importType_1 = importType; _a < importType_1.length; _a++) {
                    var fix = importType_1[_a];
                    addImportType(changeTracker, sourceFile, fix, quotePreference);
                }
                addToExisting.forEach(function (_a) {
                    var importClauseOrBindingPattern = _a.importClauseOrBindingPattern, defaultImport = _a.defaultImport, namedImports = _a.namedImports, canUseTypeOnlyImport = _a.canUseTypeOnlyImport;
                    doAddExistingFix(changeTracker, sourceFile, importClauseOrBindingPattern, defaultImport, namedImports, canUseTypeOnlyImport);
                });
                var newDeclarations;
                newImports.forEach(function (_a, moduleSpecifier) {
                    var useRequire = _a.useRequire, imports = __rest(_a, ["useRequire"]);
                    var getDeclarations = useRequire ? getNewRequires : getNewImports;
                    newDeclarations = ts.combine(newDeclarations, getDeclarations(moduleSpecifier, quotePreference, imports));
                });
                if (newDeclarations) {
                    ts.insertImports(changeTracker, sourceFile, newDeclarations, /*blankLineBetween*/ true);
                }
            }
        }
        codefix.createImportAdder = createImportAdder;
        // Sorted with the preferred fix coming first.
        var ImportFixKind;
        (function (ImportFixKind) {
            ImportFixKind[ImportFixKind["UseNamespace"] = 0] = "UseNamespace";
            ImportFixKind[ImportFixKind["ImportType"] = 1] = "ImportType";
            ImportFixKind[ImportFixKind["AddToExisting"] = 2] = "AddToExisting";
            ImportFixKind[ImportFixKind["AddNew"] = 3] = "AddNew";
        })(ImportFixKind || (ImportFixKind = {}));
        var ImportKind;
        (function (ImportKind) {
            ImportKind[ImportKind["Named"] = 0] = "Named";
            ImportKind[ImportKind["Default"] = 1] = "Default";
            ImportKind[ImportKind["Namespace"] = 2] = "Namespace";
            ImportKind[ImportKind["CommonJS"] = 3] = "CommonJS";
        })(ImportKind || (ImportKind = {}));
        function getImportCompletionAction(exportedSymbol, moduleSymbol, sourceFile, symbolName, host, program, formatContext, position, preferences) {
            var compilerOptions = program.getCompilerOptions();
            var exportInfos = getAllReExportingModules(sourceFile, exportedSymbol, moduleSymbol, symbolName, sourceFile, compilerOptions, program.getTypeChecker(), program.getSourceFiles());
            var useRequire = shouldUseRequire(sourceFile, compilerOptions);
            var preferTypeOnlyImport = compilerOptions.importsNotUsedAsValues === 2 /* Error */ && !ts.isSourceFileJS(sourceFile) && ts.isValidTypeOnlyAliasUseSite(ts.getTokenAtPosition(sourceFile, position));
            var moduleSpecifier = ts.first(getNewImportInfos(program, sourceFile, position, preferTypeOnlyImport, useRequire, exportInfos, host, preferences)).moduleSpecifier;
            var fix = getImportFixForSymbol(sourceFile, exportInfos, moduleSymbol, symbolName, program, position, preferTypeOnlyImport, useRequire, host, preferences);
            return { moduleSpecifier: moduleSpecifier, codeAction: codeFixActionToCodeAction(codeActionForFix({ host: host, formatContext: formatContext, preferences: preferences }, sourceFile, symbolName, fix, ts.getQuotePreference(sourceFile, preferences))) };
        }
        codefix.getImportCompletionAction = getImportCompletionAction;
        function getImportFixForSymbol(sourceFile, exportInfos, moduleSymbol, symbolName, program, position, preferTypeOnlyImport, useRequire, host, preferences) {
            ts.Debug.assert(exportInfos.some(function (info) { return info.moduleSymbol === moduleSymbol; }), "Some exportInfo should match the specified moduleSymbol");
            // We sort the best codefixes first, so taking `first` is best.
            return ts.first(getFixForImport(exportInfos, symbolName, position, preferTypeOnlyImport, useRequire, program, sourceFile, host, preferences));
        }
        function codeFixActionToCodeAction(_a) {
            var description = _a.description, changes = _a.changes, commands = _a.commands;
            return { description: description, changes: changes, commands: commands };
        }
        function getAllReExportingModules(importingFile, exportedSymbol, exportingModuleSymbol, symbolName, sourceFile, compilerOptions, checker, allSourceFiles) {
            var result = [];
            forEachExternalModule(checker, allSourceFiles, function (moduleSymbol, moduleFile) {
                // Don't import from a re-export when looking "up" like to `./index` or `../index`.
                if (moduleFile && moduleSymbol !== exportingModuleSymbol && ts.startsWith(sourceFile.fileName, ts.getDirectoryPath(moduleFile.fileName))) {
                    return;
                }
                var defaultInfo = getDefaultLikeExportInfo(importingFile, moduleSymbol, checker, compilerOptions);
                if (defaultInfo && defaultInfo.name === symbolName && ts.skipAlias(defaultInfo.symbol, checker) === exportedSymbol) {
                    result.push({ moduleSymbol: moduleSymbol, importKind: defaultInfo.kind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(defaultInfo.symbol, checker) });
                }
                for (var _i = 0, _a = checker.getExportsAndPropertiesOfModule(moduleSymbol); _i < _a.length; _i++) {
                    var exported = _a[_i];
                    if (exported.name === symbolName && ts.skipAlias(exported, checker) === exportedSymbol) {
                        result.push({ moduleSymbol: moduleSymbol, importKind: 0 /* Named */, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exported, checker) });
                    }
                }
            });
            return result;
        }
        function isTypeOnlySymbol(s, checker) {
            return !(ts.skipAlias(s, checker).flags & 111551 /* Value */);
        }
        function isTypeOnlyPosition(sourceFile, position) {
            return ts.isValidTypeOnlyAliasUseSite(ts.getTokenAtPosition(sourceFile, position));
        }
        function getFixForImport(exportInfos, symbolName, 
        /** undefined only for missing JSX namespace */
        position, preferTypeOnlyImport, useRequire, program, sourceFile, host, preferences) {
            var checker = program.getTypeChecker();
            var existingImports = ts.flatMap(exportInfos, function (info) { return getExistingImportDeclarations(info, checker, sourceFile); });
            var useNamespace = position === undefined ? undefined : tryUseExistingNamespaceImport(existingImports, symbolName, position, checker);
            var addToExisting = tryAddToExistingImport(existingImports, position !== undefined && isTypeOnlyPosition(sourceFile, position));
            // Don't bother providing an action to add a new import if we can add to an existing one.
            var addImport = addToExisting ? [addToExisting] : getFixesForAddImport(exportInfos, existingImports, program, sourceFile, position, preferTypeOnlyImport, useRequire, host, preferences);
            return __spreadArrays((useNamespace ? [useNamespace] : ts.emptyArray), addImport);
        }
        function tryUseExistingNamespaceImport(existingImports, symbolName, position, checker) {
            // It is possible that multiple import statements with the same specifier exist in the file.
            // e.g.
            //
            //     import * as ns from "foo";
            //     import { member1, member2 } from "foo";
            //
            //     member3/**/ <-- cusor here
            //
            // in this case we should provie 2 actions:
            //     1. change "member3" to "ns.member3"
            //     2. add "member3" to the second import statement's import list
            // and it is up to the user to decide which one fits best.
            return ts.firstDefined(existingImports, function (_a) {
                var declaration = _a.declaration;
                var namespacePrefix = getNamespaceLikeImportText(declaration);
                if (namespacePrefix) {
                    var moduleSymbol = getTargetModuleFromNamespaceLikeImport(declaration, checker);
                    if (moduleSymbol && moduleSymbol.exports.has(ts.escapeLeadingUnderscores(symbolName))) {
                        return { kind: 0 /* UseNamespace */, namespacePrefix: namespacePrefix, position: position };
                    }
                }
            });
        }
        function getTargetModuleFromNamespaceLikeImport(declaration, checker) {
            var _a;
            switch (declaration.kind) {
                case 242 /* VariableDeclaration */:
                    return checker.resolveExternalModuleName(declaration.initializer.arguments[0]);
                case 253 /* ImportEqualsDeclaration */:
                    return checker.getAliasedSymbol(declaration.symbol);
                case 254 /* ImportDeclaration */:
                    var namespaceImport = ts.tryCast((_a = declaration.importClause) === null || _a === void 0 ? void 0 : _a.namedBindings, ts.isNamespaceImport);
                    return namespaceImport && checker.getAliasedSymbol(namespaceImport.symbol);
                default:
                    return ts.Debug.assertNever(declaration);
            }
        }
        function getNamespaceLikeImportText(declaration) {
            var _a, _b, _c;
            switch (declaration.kind) {
                case 242 /* VariableDeclaration */:
                    return (_a = ts.tryCast(declaration.name, ts.isIdentifier)) === null || _a === void 0 ? void 0 : _a.text;
                case 253 /* ImportEqualsDeclaration */:
                    return declaration.name.text;
                case 254 /* ImportDeclaration */:
                    return (_c = ts.tryCast((_b = declaration.importClause) === null || _b === void 0 ? void 0 : _b.namedBindings, ts.isNamespaceImport)) === null || _c === void 0 ? void 0 : _c.name.text;
                default:
                    return ts.Debug.assertNever(declaration);
            }
        }
        function tryAddToExistingImport(existingImports, canUseTypeOnlyImport) {
            return ts.firstDefined(existingImports, function (_a) {
                var declaration = _a.declaration, importKind = _a.importKind;
                if (declaration.kind === 253 /* ImportEqualsDeclaration */)
                    return undefined;
                if (declaration.kind === 242 /* VariableDeclaration */) {
                    return (importKind === 0 /* Named */ || importKind === 1 /* Default */) && declaration.name.kind === 189 /* ObjectBindingPattern */
                        ? { kind: 2 /* AddToExisting */, importClauseOrBindingPattern: declaration.name, importKind: importKind, moduleSpecifier: declaration.initializer.arguments[0].text, canUseTypeOnlyImport: false }
                        : undefined;
                }
                var importClause = declaration.importClause;
                if (!importClause)
                    return undefined;
                var name = importClause.name, namedBindings = importClause.namedBindings;
                return importKind === 1 /* Default */ && !name || importKind === 0 /* Named */ && (!namedBindings || namedBindings.kind === 257 /* NamedImports */)
                    ? { kind: 2 /* AddToExisting */, importClauseOrBindingPattern: importClause, importKind: importKind, moduleSpecifier: declaration.moduleSpecifier.getText(), canUseTypeOnlyImport: canUseTypeOnlyImport }
                    : undefined;
            });
        }
        function getExistingImportDeclarations(_a, checker, sourceFile) {
            var moduleSymbol = _a.moduleSymbol, importKind = _a.importKind, exportedSymbolIsTypeOnly = _a.exportedSymbolIsTypeOnly;
            // Can't use an es6 import for a type in JS.
            return exportedSymbolIsTypeOnly && ts.isSourceFileJS(sourceFile) ? ts.emptyArray : ts.mapDefined(sourceFile.imports, function (moduleSpecifier) {
                var i = ts.importFromModuleSpecifier(moduleSpecifier);
                if (ts.isRequireVariableDeclaration(i.parent, /*requireStringLiteralLikeArgument*/ true)) {
                    return checker.resolveExternalModuleName(moduleSpecifier) === moduleSymbol ? { declaration: i.parent, importKind: importKind } : undefined;
                }
                if (i.kind === 254 /* ImportDeclaration */ || i.kind === 253 /* ImportEqualsDeclaration */) {
                    return checker.getSymbolAtLocation(moduleSpecifier) === moduleSymbol ? { declaration: i, importKind: importKind } : undefined;
                }
            });
        }
        function shouldUseRequire(sourceFile, compilerOptions) {
            return ts.isSourceFileJS(sourceFile)
                && !sourceFile.externalModuleIndicator
                && (!!sourceFile.commonJsModuleIndicator || ts.getEmitModuleKind(compilerOptions) < ts.ModuleKind.ES2015);
        }
        function getNewImportInfos(program, sourceFile, position, preferTypeOnlyImport, useRequire, moduleSymbols, host, preferences) {
            var isJs = ts.isSourceFileJS(sourceFile);
            var compilerOptions = program.getCompilerOptions();
            var allowsImportingSpecifier = createAutoImportFilter(sourceFile, program, host).allowsImportingSpecifier;
            var choicesForEachExportingModule = ts.flatMap(moduleSymbols, function (_a) {
                var moduleSymbol = _a.moduleSymbol, importKind = _a.importKind, exportedSymbolIsTypeOnly = _a.exportedSymbolIsTypeOnly;
                return ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, compilerOptions, sourceFile, ts.createModuleSpecifierResolutionHost(program, host), preferences)
                    .map(function (moduleSpecifier) {
                    // `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types.
                    return exportedSymbolIsTypeOnly && isJs
                        ? { kind: 1 /* ImportType */, moduleSpecifier: moduleSpecifier, position: ts.Debug.checkDefined(position, "position should be defined") }
                        : { kind: 3 /* AddNew */, moduleSpecifier: moduleSpecifier, importKind: importKind, useRequire: useRequire, typeOnly: preferTypeOnlyImport };
                });
            });
            // Sort by presence in package.json, then shortest paths first
            return ts.sort(choicesForEachExportingModule, function (a, b) {
                var allowsImportingA = allowsImportingSpecifier(a.moduleSpecifier);
                var allowsImportingB = allowsImportingSpecifier(b.moduleSpecifier);
                if (allowsImportingA && !allowsImportingB) {
                    return -1;
                }
                if (allowsImportingB && !allowsImportingA) {
                    return 1;
                }
                return a.moduleSpecifier.length - b.moduleSpecifier.length;
            });
        }
        function getFixesForAddImport(exportInfos, existingImports, program, sourceFile, position, preferTypeOnlyImport, useRequire, host, preferences) {
            var existingDeclaration = ts.firstDefined(existingImports, function (info) { return newImportInfoFromExistingSpecifier(info, preferTypeOnlyImport, useRequire); });
            return existingDeclaration ? [existingDeclaration] : getNewImportInfos(program, sourceFile, position, preferTypeOnlyImport, useRequire, exportInfos, host, preferences);
        }
        function newImportInfoFromExistingSpecifier(_a, preferTypeOnlyImport, useRequire) {
            var declaration = _a.declaration, importKind = _a.importKind;
            var moduleSpecifier = declaration.kind === 254 /* ImportDeclaration */ ? declaration.moduleSpecifier :
                declaration.kind === 242 /* VariableDeclaration */ ? declaration.initializer.arguments[0] :
                    declaration.moduleReference.kind === 265 /* ExternalModuleReference */ ? declaration.moduleReference.expression :
                        undefined;
            return moduleSpecifier && ts.isStringLiteral(moduleSpecifier)
                ? { kind: 3 /* AddNew */, moduleSpecifier: moduleSpecifier.text, importKind: importKind, typeOnly: preferTypeOnlyImport, useRequire: useRequire }
                : undefined;
        }
        function getFixesInfo(context, errorCode, pos) {
            var symbolToken = ts.getTokenAtPosition(context.sourceFile, pos);
            var info = errorCode === ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
                ? getFixesInfoForUMDImport(context, symbolToken)
                : ts.isIdentifier(symbolToken) ? getFixesInfoForNonUMDImport(context, symbolToken) : undefined;
            return info && __assign(__assign({}, info), { fixes: ts.sort(info.fixes, function (a, b) { return a.kind - b.kind; }) });
        }
        function getFixesInfoForUMDImport(_a, token) {
            var sourceFile = _a.sourceFile, program = _a.program, host = _a.host, preferences = _a.preferences;
            var checker = program.getTypeChecker();
            var umdSymbol = getUmdSymbol(token, checker);
            if (!umdSymbol)
                return undefined;
            var symbol = checker.getAliasedSymbol(umdSymbol);
            var symbolName = umdSymbol.name;
            var exportInfos = [{ moduleSymbol: symbol, importKind: getUmdImportKind(sourceFile, program.getCompilerOptions()), exportedSymbolIsTypeOnly: false }];
            var useRequire = shouldUseRequire(sourceFile, program.getCompilerOptions());
            var fixes = getFixForImport(exportInfos, symbolName, ts.isIdentifier(token) ? token.getStart(sourceFile) : undefined, /*preferTypeOnlyImport*/ false, useRequire, program, sourceFile, host, preferences);
            return { fixes: fixes, symbolName: symbolName };
        }
        function getUmdSymbol(token, checker) {
            // try the identifier to see if it is the umd symbol
            var umdSymbol = ts.isIdentifier(token) ? checker.getSymbolAtLocation(token) : undefined;
            if (ts.isUMDExportSymbol(umdSymbol))
                return umdSymbol;
            // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`.
            var parent = token.parent;
            return (ts.isJsxOpeningLikeElement(parent) && parent.tagName === token) || ts.isJsxOpeningFragment(parent)
                ? ts.tryCast(checker.resolveName(checker.getJsxNamespace(parent), ts.isJsxOpeningLikeElement(parent) ? token : parent, 111551 /* Value */, /*excludeGlobals*/ false), ts.isUMDExportSymbol)
                : undefined;
        }
        function getUmdImportKind(importingFile, compilerOptions) {
            // Import a synthetic `default` if enabled.
            if (ts.getAllowSyntheticDefaultImports(compilerOptions)) {
                return 1 /* Default */;
            }
            // When a synthetic `default` is unavailable, use `import..require` if the module kind supports it.
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            switch (moduleKind) {
                case ts.ModuleKind.AMD:
                case ts.ModuleKind.CommonJS:
                case ts.ModuleKind.UMD:
                    if (ts.isInJSFile(importingFile)) {
                        return ts.isExternalModule(importingFile) ? 2 /* Namespace */ : 3 /* CommonJS */;
                    }
                    return 3 /* CommonJS */;
                case ts.ModuleKind.System:
                case ts.ModuleKind.ES2015:
                case ts.ModuleKind.ES2020:
                case ts.ModuleKind.ESNext:
                case ts.ModuleKind.None:
                    // Fall back to the `import * as ns` style import.
                    return 2 /* Namespace */;
                default:
                    return ts.Debug.assertNever(moduleKind, "Unexpected moduleKind " + moduleKind);
            }
        }
        function getFixesInfoForNonUMDImport(_a, symbolToken) {
            var sourceFile = _a.sourceFile, program = _a.program, cancellationToken = _a.cancellationToken, host = _a.host, preferences = _a.preferences;
            var checker = program.getTypeChecker();
            // If we're at `<Foo/>`, we must check if `Foo` is already in scope, and if so, get an import for `React` instead.
            var symbolName = ts.isJsxOpeningLikeElement(symbolToken.parent)
                && symbolToken.parent.tagName === symbolToken
                && (ts.isIntrinsicJsxName(symbolToken.text) || checker.resolveName(symbolToken.text, symbolToken, 67108863 /* All */, /*excludeGlobals*/ false))
                ? checker.getJsxNamespace(sourceFile)
                : symbolToken.text;
            // "default" is a keyword and not a legal identifier for the import, so we don't expect it here
            ts.Debug.assert(symbolName !== "default" /* Default */, "'default' isn't a legal identifier and couldn't occur here");
            var compilerOptions = program.getCompilerOptions();
            var preferTypeOnlyImport = compilerOptions.importsNotUsedAsValues === 2 /* Error */ && ts.isValidTypeOnlyAliasUseSite(symbolToken);
            var useRequire = shouldUseRequire(sourceFile, compilerOptions);
            var exportInfos = getExportInfos(symbolName, ts.getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, checker, program, host);
            var fixes = ts.arrayFrom(ts.flatMapIterator(exportInfos.entries(), function (_a) {
                var _ = _a[0], exportInfos = _a[1];
                return getFixForImport(exportInfos, symbolName, symbolToken.getStart(sourceFile), preferTypeOnlyImport, useRequire, program, sourceFile, host, preferences);
            }));
            return { fixes: fixes, symbolName: symbolName };
        }
        // Returns a map from an exported symbol's ID to a list of every way it's (re-)exported.
        function getExportInfos(symbolName, currentTokenMeaning, cancellationToken, sourceFile, checker, program, host) {
            // For each original symbol, keep all re-exports of that symbol together so we can call `getCodeActionsForImport` on the whole group at once.
            // Maps symbol id to info for modules providing that symbol (original export + re-exports).
            var originalSymbolToExportInfos = ts.createMultiMap();
            function addSymbol(moduleSymbol, exportedSymbol, importKind) {
                originalSymbolToExportInfos.add(ts.getUniqueSymbolId(exportedSymbol, checker).toString(), { moduleSymbol: moduleSymbol, importKind: importKind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exportedSymbol, checker) });
            }
            forEachExternalModuleToImportFrom(program, host, sourceFile, /*filterByPackageJson*/ true, function (moduleSymbol) {
                cancellationToken.throwIfCancellationRequested();
                var defaultInfo = getDefaultLikeExportInfo(sourceFile, moduleSymbol, checker, program.getCompilerOptions());
                if (defaultInfo && defaultInfo.name === symbolName && symbolHasMeaning(defaultInfo.symbolForMeaning, currentTokenMeaning)) {
                    addSymbol(moduleSymbol, defaultInfo.symbol, defaultInfo.kind);
                }
                // check exports with the same name
                var exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol);
                if (exportSymbolWithIdenticalName && symbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) {
                    addSymbol(moduleSymbol, exportSymbolWithIdenticalName, 0 /* Named */);
                }
            });
            return originalSymbolToExportInfos;
        }
        function getDefaultLikeExportInfo(importingFile, moduleSymbol, checker, compilerOptions) {
            var exported = getDefaultLikeExportWorker(importingFile, moduleSymbol, checker, compilerOptions);
            if (!exported)
                return undefined;
            var symbol = exported.symbol, kind = exported.kind;
            var info = getDefaultExportInfoWorker(symbol, moduleSymbol, checker, compilerOptions);
            return info && __assign({ symbol: symbol, kind: kind }, info);
        }
        function getDefaultLikeExportWorker(importingFile, moduleSymbol, checker, compilerOptions) {
            var defaultExport = checker.tryGetMemberInModuleExports("default" /* Default */, moduleSymbol);
            if (defaultExport)
                return { symbol: defaultExport, kind: 1 /* Default */ };
            var exportEquals = checker.resolveExternalModuleSymbol(moduleSymbol);
            return exportEquals === moduleSymbol ? undefined : { symbol: exportEquals, kind: getExportEqualsImportKind(importingFile, compilerOptions) };
        }
        function getExportEqualsImportKind(importingFile, compilerOptions) {
            var allowSyntheticDefaults = ts.getAllowSyntheticDefaultImports(compilerOptions);
            // 1. 'import =' will not work in es2015+, so the decision is between a default
            //    and a namespace import, based on allowSyntheticDefaultImports/esModuleInterop.
            if (ts.getEmitModuleKind(compilerOptions) >= ts.ModuleKind.ES2015) {
                return allowSyntheticDefaults ? 1 /* Default */ : 2 /* Namespace */;
            }
            // 2. 'import =' will not work in JavaScript, so the decision is between a default
            //    and const/require.
            if (ts.isInJSFile(importingFile)) {
                return ts.isExternalModule(importingFile) ? 1 /* Default */ : 3 /* CommonJS */;
            }
            // 3. At this point the most correct choice is probably 'import =', but people
            //    really hate that, so look to see if the importing file has any precedent
            //    on how to handle it.
            for (var _i = 0, _a = importingFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (ts.isImportEqualsDeclaration(statement)) {
                    return 3 /* CommonJS */;
                }
            }
            // 4. We have no precedent to go on, so just use a default import if
            //    allowSyntheticDefaultImports/esModuleInterop is enabled.
            return allowSyntheticDefaults ? 1 /* Default */ : 3 /* CommonJS */;
        }
        function getDefaultExportInfoWorker(defaultExport, moduleSymbol, checker, compilerOptions) {
            var localSymbol = ts.getLocalSymbolForExportDefault(defaultExport);
            if (localSymbol)
                return { symbolForMeaning: localSymbol, name: localSymbol.name };
            var name = getNameForExportDefault(defaultExport);
            if (name !== undefined)
                return { symbolForMeaning: defaultExport, name: name };
            if (defaultExport.flags & 2097152 /* Alias */) {
                var aliased = checker.getImmediateAliasedSymbol(defaultExport);
                return aliased && getDefaultExportInfoWorker(aliased, ts.Debug.checkDefined(aliased.parent, "Alias targets of default exports must have a parent"), checker, compilerOptions);
            }
            if (defaultExport.escapedName !== "default" /* Default */ &&
                defaultExport.escapedName !== "export=" /* ExportEquals */) {
                return { symbolForMeaning: defaultExport, name: defaultExport.getName() };
            }
            return { symbolForMeaning: defaultExport, name: moduleSymbolToValidIdentifier(moduleSymbol, compilerOptions.target) };
        }
        function getNameForExportDefault(symbol) {
            return symbol.declarations && ts.firstDefined(symbol.declarations, function (declaration) {
                if (ts.isExportAssignment(declaration)) {
                    if (ts.isIdentifier(declaration.expression)) {
                        return declaration.expression.text;
                    }
                }
                else if (ts.isExportSpecifier(declaration)) {
                    ts.Debug.assert(declaration.name.text === "default" /* Default */, "Expected the specifier to be a default export");
                    return declaration.propertyName && declaration.propertyName.text;
                }
            });
        }
        function codeActionForFix(context, sourceFile, symbolName, fix, quotePreference) {
            var diag;
            var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) {
                diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, quotePreference);
            });
            return codefix.createCodeFixAction(codefix.importFixName, changes, diag, importFixId, ts.Diagnostics.Add_all_missing_imports);
        }
        function codeActionForFixWorker(changes, sourceFile, symbolName, fix, quotePreference) {
            switch (fix.kind) {
                case 0 /* UseNamespace */:
                    addNamespaceQualifier(changes, sourceFile, fix);
                    return [ts.Diagnostics.Change_0_to_1, symbolName, fix.namespacePrefix + "." + symbolName];
                case 1 /* ImportType */:
                    addImportType(changes, sourceFile, fix, quotePreference);
                    return [ts.Diagnostics.Change_0_to_1, symbolName, getImportTypePrefix(fix.moduleSpecifier, quotePreference) + symbolName];
                case 2 /* AddToExisting */: {
                    var importClauseOrBindingPattern = fix.importClauseOrBindingPattern, importKind = fix.importKind, canUseTypeOnlyImport = fix.canUseTypeOnlyImport, moduleSpecifier = fix.moduleSpecifier;
                    doAddExistingFix(changes, sourceFile, importClauseOrBindingPattern, importKind === 1 /* Default */ ? symbolName : undefined, importKind === 0 /* Named */ ? [symbolName] : ts.emptyArray, canUseTypeOnlyImport);
                    var moduleSpecifierWithoutQuotes = ts.stripQuotes(moduleSpecifier);
                    return [importKind === 1 /* Default */ ? ts.Diagnostics.Add_default_import_0_to_existing_import_declaration_from_1 : ts.Diagnostics.Add_0_to_existing_import_declaration_from_1, symbolName, moduleSpecifierWithoutQuotes]; // you too!
                }
                case 3 /* AddNew */: {
                    var importKind = fix.importKind, moduleSpecifier = fix.moduleSpecifier, typeOnly = fix.typeOnly, useRequire = fix.useRequire;
                    var getDeclarations = useRequire ? getNewRequires : getNewImports;
                    var importsCollection = importKind === 1 /* Default */ ? { defaultImport: symbolName, typeOnly: typeOnly } :
                        importKind === 0 /* Named */ ? { namedImports: [symbolName], typeOnly: typeOnly } :
                            { namespaceLikeImport: { importKind: importKind, name: symbolName }, typeOnly: typeOnly };
                    ts.insertImports(changes, sourceFile, getDeclarations(moduleSpecifier, quotePreference, importsCollection), /*blankLineBetween*/ true);
                    return [importKind === 1 /* Default */ ? ts.Diagnostics.Import_default_0_from_module_1 : ts.Diagnostics.Import_0_from_module_1, symbolName, moduleSpecifier];
                }
                default:
                    return ts.Debug.assertNever(fix, "Unexpected fix kind " + fix.kind);
            }
        }
        function doAddExistingFix(changes, sourceFile, clause, defaultImport, namedImports, canUseTypeOnlyImport) {
            if (clause.kind === 189 /* ObjectBindingPattern */) {
                if (defaultImport) {
                    addElementToBindingPattern(clause, defaultImport, "default");
                }
                for (var _i = 0, namedImports_1 = namedImports; _i < namedImports_1.length; _i++) {
                    var specifier = namedImports_1[_i];
                    addElementToBindingPattern(clause, specifier, /*propertyName*/ undefined);
                }
                return;
            }
            var convertTypeOnlyToRegular = !canUseTypeOnlyImport && clause.isTypeOnly;
            if (defaultImport) {
                ts.Debug.assert(!clause.name, "Cannot add a default import to an import clause that already has one");
                changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), ts.createIdentifier(defaultImport), { suffix: ", " });
            }
            if (namedImports.length) {
                var specifiers = namedImports.map(function (name) { return ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(name)); });
                if (clause.namedBindings && ts.cast(clause.namedBindings, ts.isNamedImports).elements.length) {
                    for (var _a = 0, specifiers_1 = specifiers; _a < specifiers_1.length; _a++) {
                        var spec = specifiers_1[_a];
                        changes.insertNodeInListAfter(sourceFile, ts.last(ts.cast(clause.namedBindings, ts.isNamedImports).elements), spec);
                    }
                }
                else {
                    if (specifiers.length) {
                        var namedImports_2 = ts.createNamedImports(specifiers);
                        if (clause.namedBindings) {
                            changes.replaceNode(sourceFile, clause.namedBindings, namedImports_2);
                        }
                        else {
                            changes.insertNodeAfter(sourceFile, ts.Debug.checkDefined(clause.name, "Import clause must have either named imports or a default import"), namedImports_2);
                        }
                    }
                }
            }
            if (convertTypeOnlyToRegular) {
                changes.delete(sourceFile, ts.getTypeKeywordOfTypeOnlyImport(clause, sourceFile));
            }
            function addElementToBindingPattern(bindingPattern, name, propertyName) {
                var element = ts.createBindingElement(/*dotDotDotToken*/ undefined, propertyName, name);
                if (bindingPattern.elements.length) {
                    changes.insertNodeInListAfter(sourceFile, ts.last(bindingPattern.elements), element);
                }
                else {
                    changes.replaceNode(sourceFile, bindingPattern, ts.createObjectBindingPattern([element]));
                }
            }
        }
        function addNamespaceQualifier(changes, sourceFile, _a) {
            var namespacePrefix = _a.namespacePrefix, position = _a.position;
            changes.insertText(sourceFile, position, namespacePrefix + ".");
        }
        function addImportType(changes, sourceFile, _a, quotePreference) {
            var moduleSpecifier = _a.moduleSpecifier, position = _a.position;
            changes.insertText(sourceFile, position, getImportTypePrefix(moduleSpecifier, quotePreference));
        }
        function getImportTypePrefix(moduleSpecifier, quotePreference) {
            var quote = ts.getQuoteFromPreference(quotePreference);
            return "import(" + quote + moduleSpecifier + quote + ").";
        }
        function getNewImports(moduleSpecifier, quotePreference, imports) {
            var _a, _b;
            var quotedModuleSpecifier = ts.makeStringLiteral(moduleSpecifier, quotePreference);
            var statements;
            if (imports.defaultImport !== undefined || ((_a = imports.namedImports) === null || _a === void 0 ? void 0 : _a.length)) {
                statements = ts.combine(statements, ts.makeImport(imports.defaultImport === undefined ? undefined : ts.createIdentifier(imports.defaultImport), (_b = imports.namedImports) === null || _b === void 0 ? void 0 : _b.map(function (n) { return ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(n)); }), moduleSpecifier, quotePreference, imports.typeOnly));
            }
            var namespaceLikeImport = imports.namespaceLikeImport, typeOnly = imports.typeOnly;
            if (namespaceLikeImport) {
                var declaration = namespaceLikeImport.importKind === 3 /* CommonJS */
                    ? ts.createImportEqualsDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, ts.createIdentifier(namespaceLikeImport.name), ts.createExternalModuleReference(quotedModuleSpecifier))
                    : ts.createImportDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, ts.createImportClause(
                    /*name*/ undefined, ts.createNamespaceImport(ts.createIdentifier(namespaceLikeImport.name)), typeOnly), quotedModuleSpecifier);
                statements = ts.combine(statements, declaration);
            }
            return ts.Debug.checkDefined(statements);
        }
        function getNewRequires(moduleSpecifier, quotePreference, imports) {
            var _a, _b;
            var quotedModuleSpecifier = ts.makeStringLiteral(moduleSpecifier, quotePreference);
            var statements;
            // const { default: foo, bar, etc } = require('./mod');
            if (imports.defaultImport || ((_a = imports.namedImports) === null || _a === void 0 ? void 0 : _a.length)) {
                var bindingElements = ((_b = imports.namedImports) === null || _b === void 0 ? void 0 : _b.map(function (name) { return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name); })) || [];
                if (imports.defaultImport) {
                    bindingElements.unshift(ts.createBindingElement(/*dotDotDotToken*/ undefined, "default", imports.defaultImport));
                }
                var declaration = createConstEqualsRequireDeclaration(ts.createObjectBindingPattern(bindingElements), quotedModuleSpecifier);
                statements = ts.combine(statements, declaration);
            }
            // const foo = require('./mod');
            if (imports.namespaceLikeImport) {
                var declaration = createConstEqualsRequireDeclaration(imports.namespaceLikeImport.name, quotedModuleSpecifier);
                statements = ts.combine(statements, declaration);
            }
            return ts.Debug.checkDefined(statements);
        }
        function createConstEqualsRequireDeclaration(name, quotedModuleSpecifier) {
            return ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(typeof name === "string" ? ts.createIdentifier(name) : name, 
                /*type*/ undefined, ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, [quotedModuleSpecifier]))
            ], 2 /* Const */));
        }
        function symbolHasMeaning(_a, meaning) {
            var declarations = _a.declarations;
            return ts.some(declarations, function (decl) { return !!(ts.getMeaningFromDeclaration(decl) & meaning); });
        }
        function forEachExternalModuleToImportFrom(program, host, from, filterByPackageJson, cb) {
            var filteredCount = 0;
            var moduleSpecifierResolutionHost = ts.createModuleSpecifierResolutionHost(program, host);
            var packageJson = filterByPackageJson && createAutoImportFilter(from, program, host, moduleSpecifierResolutionHost);
            forEachExternalModule(program.getTypeChecker(), program.getSourceFiles(), function (module, sourceFile) {
                if (sourceFile === undefined) {
                    if (!packageJson || packageJson.allowsImportingAmbientModule(module)) {
                        cb(module);
                    }
                    else if (packageJson) {
                        filteredCount++;
                    }
                }
                else if (sourceFile &&
                    sourceFile !== from &&
                    isImportableFile(program, from, sourceFile, moduleSpecifierResolutionHost)) {
                    if (!packageJson || packageJson.allowsImportingSourceFile(sourceFile)) {
                        cb(module);
                    }
                    else if (packageJson) {
                        filteredCount++;
                    }
                }
            });
            if (host.log) {
                host.log("forEachExternalModuleToImportFrom: filtered out " + filteredCount + " modules by package.json contents");
            }
        }
        codefix.forEachExternalModuleToImportFrom = forEachExternalModuleToImportFrom;
        function forEachExternalModule(checker, allSourceFiles, cb) {
            for (var _i = 0, _a = checker.getAmbientModules(); _i < _a.length; _i++) {
                var ambient = _a[_i];
                cb(ambient, /*sourceFile*/ undefined);
            }
            for (var _b = 0, allSourceFiles_1 = allSourceFiles; _b < allSourceFiles_1.length; _b++) {
                var sourceFile = allSourceFiles_1[_b];
                if (ts.isExternalOrCommonJsModule(sourceFile)) {
                    cb(checker.getMergedSymbol(sourceFile.symbol), sourceFile);
                }
            }
        }
        function isImportableFile(program, from, to, moduleSpecifierResolutionHost) {
            var _a;
            var getCanonicalFileName = ts.hostGetCanonicalFileName(moduleSpecifierResolutionHost);
            var globalTypingsCache = (_a = moduleSpecifierResolutionHost.getGlobalTypingsCacheLocation) === null || _a === void 0 ? void 0 : _a.call(moduleSpecifierResolutionHost);
            return !!ts.moduleSpecifiers.forEachFileNameOfModule(from.fileName, to.fileName, moduleSpecifierResolutionHost, 
            /*preferSymlinks*/ false, function (toPath) {
                var toFile = program.getSourceFile(toPath);
                // Determine to import using toPath only if toPath is what we were looking at
                // or there doesnt exist the file in the program by the symlink
                return (toFile === to || !toFile) &&
                    isImportablePath(from.fileName, toPath, getCanonicalFileName, globalTypingsCache);
            });
        }
        /**
         * Don't include something from a `node_modules` that isn't actually reachable by a global import.
         * A relative import to node_modules is usually a bad idea.
         */
        function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
            // If it's in a `node_modules` but is not reachable from here via a global import, don't bother.
            var toNodeModules = ts.forEachAncestorDirectory(toPath, function (ancestor) { return ts.getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined; });
            var toNodeModulesParent = toNodeModules && ts.getDirectoryPath(getCanonicalFileName(toNodeModules));
            return toNodeModulesParent === undefined
                || ts.startsWith(getCanonicalFileName(fromPath), toNodeModulesParent)
                || (!!globalCachePath && ts.startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent));
        }
        function moduleSymbolToValidIdentifier(moduleSymbol, target) {
            return moduleSpecifierToValidIdentifier(ts.removeFileExtension(ts.stripQuotes(moduleSymbol.name)), target);
        }
        codefix.moduleSymbolToValidIdentifier = moduleSymbolToValidIdentifier;
        function moduleSpecifierToValidIdentifier(moduleSpecifier, target) {
            var baseName = ts.getBaseFileName(ts.removeSuffix(moduleSpecifier, "/index"));
            var res = "";
            var lastCharWasValid = true;
            var firstCharCode = baseName.charCodeAt(0);
            if (ts.isIdentifierStart(firstCharCode, target)) {
                res += String.fromCharCode(firstCharCode);
            }
            else {
                lastCharWasValid = false;
            }
            for (var i = 1; i < baseName.length; i++) {
                var ch = baseName.charCodeAt(i);
                var isValid = ts.isIdentifierPart(ch, target);
                if (isValid) {
                    var char = String.fromCharCode(ch);
                    if (!lastCharWasValid) {
                        char = char.toUpperCase();
                    }
                    res += char;
                }
                lastCharWasValid = isValid;
            }
            // Need `|| "_"` to ensure result isn't empty.
            return !ts.isStringANonContextualKeyword(res) ? res || "_" : "_" + res;
        }
        codefix.moduleSpecifierToValidIdentifier = moduleSpecifierToValidIdentifier;
        function createAutoImportFilter(fromFile, program, host, moduleSpecifierResolutionHost) {
            if (moduleSpecifierResolutionHost === void 0) { moduleSpecifierResolutionHost = ts.createModuleSpecifierResolutionHost(program, host); }
            var packageJsons = host.getPackageJsonsVisibleToFile && host.getPackageJsonsVisibleToFile(fromFile.fileName) || ts.getPackageJsonsVisibleToFile(fromFile.fileName, host);
            var dependencyGroups = 1 /* Dependencies */ | 2 /* DevDependencies */ | 8 /* OptionalDependencies */;
            var usesNodeCoreModules;
            return { allowsImportingAmbientModule: allowsImportingAmbientModule, allowsImportingSourceFile: allowsImportingSourceFile, allowsImportingSpecifier: allowsImportingSpecifier, moduleSpecifierResolutionHost: moduleSpecifierResolutionHost };
            function moduleSpecifierIsCoveredByPackageJson(specifier) {
                var packageName = getNodeModuleRootSpecifier(specifier);
                for (var _i = 0, packageJsons_1 = packageJsons; _i < packageJsons_1.length; _i++) {
                    var packageJson = packageJsons_1[_i];
                    if (packageJson.has(packageName, dependencyGroups) || packageJson.has(ts.getTypesPackageName(packageName), dependencyGroups)) {
                        return true;
                    }
                }
                return false;
            }
            function allowsImportingAmbientModule(moduleSymbol) {
                if (!packageJsons.length) {
                    return true;
                }
                var declaringSourceFile = moduleSymbol.valueDeclaration.getSourceFile();
                var declaringNodeModuleName = getNodeModulesPackageNameFromFileName(declaringSourceFile.fileName);
                if (typeof declaringNodeModuleName === "undefined") {
                    return true;
                }
                var declaredModuleSpecifier = ts.stripQuotes(moduleSymbol.getName());
                if (isAllowedCoreNodeModulesImport(declaredModuleSpecifier)) {
                    return true;
                }
                return moduleSpecifierIsCoveredByPackageJson(declaringNodeModuleName)
                    || moduleSpecifierIsCoveredByPackageJson(declaredModuleSpecifier);
            }
            function allowsImportingSourceFile(sourceFile) {
                if (!packageJsons.length) {
                    return true;
                }
                var moduleSpecifier = getNodeModulesPackageNameFromFileName(sourceFile.fileName);
                if (!moduleSpecifier) {
                    return true;
                }
                return moduleSpecifierIsCoveredByPackageJson(moduleSpecifier);
            }
            /**
             * Use for a specific module specifier that has already been resolved.
             * Use `allowsImportingAmbientModule` or `allowsImportingSourceFile` to resolve
             * the best module specifier for a given module _and_ determine if it’s importable.
             */
            function allowsImportingSpecifier(moduleSpecifier) {
                if (!packageJsons.length || isAllowedCoreNodeModulesImport(moduleSpecifier)) {
                    return true;
                }
                if (ts.pathIsRelative(moduleSpecifier) || ts.isRootedDiskPath(moduleSpecifier)) {
                    return true;
                }
                return moduleSpecifierIsCoveredByPackageJson(moduleSpecifier);
            }
            function isAllowedCoreNodeModulesImport(moduleSpecifier) {
                // If we’re in JavaScript, it can be difficult to tell whether the user wants to import
                // from Node core modules or not. We can start by seeing if the user is actually using
                // any node core modules, as opposed to simply having @types/node accidentally as a
                // dependency of a dependency.
                if (ts.isSourceFileJS(fromFile) && ts.JsTyping.nodeCoreModules.has(moduleSpecifier)) {
                    if (usesNodeCoreModules === undefined) {
                        usesNodeCoreModules = ts.consumesNodeCoreModules(fromFile);
                    }
                    if (usesNodeCoreModules) {
                        return true;
                    }
                }
                return false;
            }
            function getNodeModulesPackageNameFromFileName(importedFileName) {
                if (!ts.stringContains(importedFileName, "node_modules")) {
                    return undefined;
                }
                var specifier = ts.moduleSpecifiers.getNodeModulesPackageName(host.getCompilationSettings(), fromFile.path, importedFileName, moduleSpecifierResolutionHost);
                if (!specifier) {
                    return undefined;
                }
                // Paths here are not node_modules, so we don’t care about them;
                // returning anything will trigger a lookup in package.json.
                if (!ts.pathIsRelative(specifier) && !ts.isRootedDiskPath(specifier)) {
                    return getNodeModuleRootSpecifier(specifier);
                }
            }
            function getNodeModuleRootSpecifier(fullSpecifier) {
                var components = ts.getPathComponents(ts.getPackageNameFromTypesPackageName(fullSpecifier)).slice(1);
                // Scoped packages
                if (ts.startsWith(components[0], "@")) {
                    return components[0] + "/" + components[1];
                }
                return components[0];
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixImplicitThis";
        var errorCodes = [ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, span = context.span;
                var diagnostic;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) {
                    diagnostic = doChange(t, sourceFile, span.start, program.getTypeChecker());
                });
                return diagnostic ? [codefix.createCodeFixAction(fixId, changes, diagnostic, fixId, ts.Diagnostics.Fix_all_implicit_this_errors)] : ts.emptyArray;
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                doChange(changes, diag.file, diag.start, context.program.getTypeChecker());
            }); },
        });
        function doChange(changes, sourceFile, pos, checker) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            ts.Debug.assert(token.kind === 104 /* ThisKeyword */);
            var fn = ts.getThisContainer(token, /*includeArrowFunctions*/ false);
            if (!ts.isFunctionDeclaration(fn) && !ts.isFunctionExpression(fn))
                return undefined;
            if (!ts.isSourceFile(ts.getThisContainer(fn, /*includeArrowFunctions*/ false))) { // 'this' is defined outside, convert to arrow function
                var fnKeyword = ts.Debug.assertDefined(ts.findChildOfKind(fn, 94 /* FunctionKeyword */, sourceFile));
                var name = fn.name;
                var body = ts.Debug.assertDefined(fn.body); // Should be defined because the function contained a 'this' expression
                if (ts.isFunctionExpression(fn)) {
                    if (name && ts.FindAllReferences.Core.isSymbolReferencedInFile(name, checker, sourceFile, body)) {
                        // Function expression references itself. To fix we would have to extract it to a const.
                        return undefined;
                    }
                    // `function() {}` --> `() => {}`
                    changes.delete(sourceFile, fnKeyword);
                    if (name) {
                        changes.delete(sourceFile, name);
                    }
                    changes.insertText(sourceFile, body.pos, " =>");
                    return [ts.Diagnostics.Convert_function_expression_0_to_arrow_function, name ? name.text : ts.ANONYMOUS];
                }
                else {
                    // `function f() {}` => `const f = () => {}`
                    // `name` should be defined because we only do this in inner contexts, and name is only undefined for `export default function() {}`.
                    changes.replaceNode(sourceFile, fnKeyword, ts.createToken(81 /* ConstKeyword */));
                    changes.insertText(sourceFile, name.end, " = ");
                    changes.insertText(sourceFile, body.pos, " =>");
                    return [ts.Diagnostics.Convert_function_declaration_0_to_arrow_function, name.text];
                }
            }
            // No outer 'this', add a @class tag if in a JS constructor function
            else if (ts.isSourceFileJS(sourceFile) && ts.isPropertyAccessExpression(token.parent) && ts.isAssignmentExpression(token.parent.parent)) {
                codefix.addJSDocTags(changes, sourceFile, fn, [ts.createJSDocClassTag()]);
                return ts.Diagnostics.Add_class_tag;
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixSpelling";
        var errorCodes = [
            ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code,
            ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var info = getInfo(sourceFile, context.span.start, context);
                if (!info)
                    return undefined;
                var node = info.node, suggestedSymbol = info.suggestedSymbol;
                var target = context.host.getCompilationSettings().target;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestedSymbol, target); });
                return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, ts.symbolName(suggestedSymbol)], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start, context);
                var target = context.host.getCompilationSettings().target;
                if (info)
                    doChange(changes, context.sourceFile, info.node, info.suggestedSymbol, target);
            }); },
        });
        function getInfo(sourceFile, pos, context) {
            // This is the identifier of the misspelled word. eg:
            // this.speling = 1;
            //      ^^^^^^^
            var node = ts.getTokenAtPosition(sourceFile, pos);
            var parent = node.parent;
            var checker = context.program.getTypeChecker();
            var suggestedSymbol;
            if (ts.isPropertyAccessExpression(parent) && parent.name === node) {
                ts.Debug.assert(ts.isIdentifierOrPrivateIdentifier(node), "Expected an identifier for spelling (property access)");
                var containingType = checker.getTypeAtLocation(parent.expression);
                if (parent.flags & 32 /* OptionalChain */) {
                    containingType = checker.getNonNullableType(containingType);
                }
                suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(node, containingType);
            }
            else if (ts.isImportSpecifier(parent) && parent.name === node) {
                ts.Debug.assertNode(node, ts.isIdentifier, "Expected an identifier for spelling (import)");
                var importDeclaration = ts.findAncestor(node, ts.isImportDeclaration);
                var resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration);
                if (resolvedSourceFile && resolvedSourceFile.symbol) {
                    suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(node, resolvedSourceFile.symbol);
                }
            }
            else {
                var meaning = ts.getMeaningFromLocation(node);
                var name = ts.getTextOfNode(node);
                ts.Debug.assert(name !== undefined, "name should be defined");
                suggestedSymbol = checker.getSuggestedSymbolForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning));
            }
            return suggestedSymbol === undefined ? undefined : { node: node, suggestedSymbol: suggestedSymbol };
        }
        function doChange(changes, sourceFile, node, suggestedSymbol, target) {
            var suggestion = ts.symbolName(suggestedSymbol);
            if (!ts.isIdentifierText(suggestion, target) && ts.isPropertyAccessExpression(node.parent)) {
                var valDecl = suggestedSymbol.valueDeclaration;
                if (ts.isNamedDeclaration(valDecl) && ts.isPrivateIdentifier(valDecl.name)) {
                    changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion));
                }
                else {
                    changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion)));
                }
            }
            else {
                changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion));
            }
        }
        function convertSemanticMeaningToSymbolFlags(meaning) {
            var flags = 0;
            if (meaning & 4 /* Namespace */) {
                flags |= 1920 /* Namespace */;
            }
            if (meaning & 2 /* Type */) {
                flags |= 788968 /* Type */;
            }
            if (meaning & 1 /* Value */) {
                flags |= 111551 /* Value */;
            }
            return flags;
        }
        function getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration) {
            if (!importDeclaration || !ts.isStringLiteralLike(importDeclaration.moduleSpecifier))
                return undefined;
            var resolvedModule = ts.getResolvedModule(sourceFile, importDeclaration.moduleSpecifier.text);
            if (!resolvedModule)
                return undefined;
            return context.program.getSourceFile(resolvedModule.resolvedFileName);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "returnValueCorrect";
        var fixIdAddReturnStatement = "fixAddReturnStatement";
        var fixIdRemoveBlockBodyBrace = "fixRemoveBlockBodyBrace";
        var fixIdWrapTheBlockWithParen = "fixWrapTheBlockWithParen";
        var errorCodes = [
            ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value.code,
            ts.Diagnostics.Type_0_is_not_assignable_to_type_1.code,
            ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code
        ];
        var ProblemKind;
        (function (ProblemKind) {
            ProblemKind[ProblemKind["MissingReturnStatement"] = 0] = "MissingReturnStatement";
            ProblemKind[ProblemKind["MissingParentheses"] = 1] = "MissingParentheses";
        })(ProblemKind || (ProblemKind = {}));
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            fixIds: [fixIdAddReturnStatement, fixIdRemoveBlockBodyBrace, fixIdWrapTheBlockWithParen],
            getCodeActions: function (context) {
                var program = context.program, sourceFile = context.sourceFile, start = context.span.start, errorCode = context.errorCode;
                var info = getInfo(program.getTypeChecker(), sourceFile, start, errorCode);
                if (!info)
                    return undefined;
                if (info.kind === ProblemKind.MissingReturnStatement) {
                    return ts.append([getActionForfixAddReturnStatement(context, info.expression, info.statement)], ts.isArrowFunction(info.declaration) ? getActionForfixRemoveBlockBodyBrace(context, info.declaration, info.expression, info.commentSource) : undefined);
                }
                else {
                    return [getActionForfixWrapTheBlockWithParen(context, info.declaration, info.expression)];
                }
            },
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(context.program.getTypeChecker(), diag.file, diag.start, diag.code);
                if (!info)
                    return undefined;
                switch (context.fixId) {
                    case fixIdAddReturnStatement:
                        addReturnStatement(changes, diag.file, info.expression, info.statement);
                        break;
                    case fixIdRemoveBlockBodyBrace:
                        if (!ts.isArrowFunction(info.declaration))
                            return undefined;
                        removeBlockBodyBrace(changes, diag.file, info.declaration, info.expression, info.commentSource, /* withParen */ false);
                        break;
                    case fixIdWrapTheBlockWithParen:
                        if (!ts.isArrowFunction(info.declaration))
                            return undefined;
                        wrapBlockWithParen(changes, diag.file, info.declaration, info.expression);
                        break;
                    default:
                        ts.Debug.fail(JSON.stringify(context.fixId));
                }
            }); },
        });
        function getFixInfo(checker, declaration, expectType, isFunctionType) {
            if (!declaration.body || !ts.isBlock(declaration.body) || ts.length(declaration.body.statements) !== 1)
                return undefined;
            var firstStatement = ts.first(declaration.body.statements);
            if (ts.isExpressionStatement(firstStatement) && checkFixedAssignableTo(checker, declaration, firstStatement.expression, expectType, isFunctionType)) {
                return {
                    declaration: declaration,
                    kind: ProblemKind.MissingReturnStatement,
                    expression: firstStatement.expression,
                    statement: firstStatement,
                    commentSource: firstStatement.expression
                };
            }
            else if (ts.isLabeledStatement(firstStatement) && ts.isExpressionStatement(firstStatement.statement)) {
                var node = ts.createObjectLiteral([ts.createPropertyAssignment(firstStatement.label, firstStatement.statement.expression)]);
                if (checkFixedAssignableTo(checker, declaration, node, expectType, isFunctionType)) {
                    return ts.isArrowFunction(declaration) ? {
                        declaration: declaration,
                        kind: ProblemKind.MissingParentheses,
                        expression: node,
                        statement: firstStatement,
                        commentSource: firstStatement.statement.expression
                    } : {
                        declaration: declaration,
                        kind: ProblemKind.MissingReturnStatement,
                        expression: node,
                        statement: firstStatement,
                        commentSource: firstStatement.statement.expression
                    };
                }
            }
            else if (ts.isBlock(firstStatement) && ts.length(firstStatement.statements) === 1) {
                var firstBlockStatement = ts.first(firstStatement.statements);
                if (ts.isLabeledStatement(firstBlockStatement) && ts.isExpressionStatement(firstBlockStatement.statement)) {
                    var node = ts.createObjectLiteral([ts.createPropertyAssignment(firstBlockStatement.label, firstBlockStatement.statement.expression)]);
                    if (checkFixedAssignableTo(checker, declaration, node, expectType, isFunctionType)) {
                        return {
                            declaration: declaration,
                            kind: ProblemKind.MissingReturnStatement,
                            expression: node,
                            statement: firstStatement,
                            commentSource: firstBlockStatement
                        };
                    }
                }
            }
            return undefined;
        }
        function checkFixedAssignableTo(checker, declaration, expr, type, isFunctionType) {
            return checker.isTypeAssignableTo(checker.getTypeAtLocation(isFunctionType ? ts.updateFunctionLikeBody(declaration, ts.createBlock([ts.createReturn(expr)])) : expr), type);
        }
        function getInfo(checker, sourceFile, position, errorCode) {
            var node = ts.getTokenAtPosition(sourceFile, position);
            if (!node.parent)
                return undefined;
            var declaration = ts.findAncestor(node.parent, ts.isFunctionLikeDeclaration);
            switch (errorCode) {
                case ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value.code:
                    if (!declaration || !declaration.body || !declaration.type || !ts.rangeContainsRange(declaration.type, node))
                        return undefined;
                    return getFixInfo(checker, declaration, checker.getTypeFromTypeNode(declaration.type), /* isFunctionType */ false);
                case ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code:
                    if (!declaration || !ts.isCallExpression(declaration.parent) || !declaration.body)
                        return undefined;
                    var pos = declaration.parent.arguments.indexOf(declaration);
                    var type = checker.getContextualTypeForArgumentAtIndex(declaration.parent, pos);
                    if (!type)
                        return undefined;
                    return getFixInfo(checker, declaration, type, /* isFunctionType */ true);
                case ts.Diagnostics.Type_0_is_not_assignable_to_type_1.code:
                    if (!ts.isDeclarationName(node) || !ts.isVariableLike(node.parent) && !ts.isJsxAttribute(node.parent))
                        return undefined;
                    var initializer = getVariableLikeInitializer(node.parent);
                    if (!initializer || !ts.isFunctionLikeDeclaration(initializer) || !initializer.body)
                        return undefined;
                    return getFixInfo(checker, initializer, checker.getTypeAtLocation(node.parent), /* isFunctionType */ true);
            }
            return undefined;
        }
        function getVariableLikeInitializer(declaration) {
            switch (declaration.kind) {
                case 242 /* VariableDeclaration */:
                case 156 /* Parameter */:
                case 191 /* BindingElement */:
                case 159 /* PropertyDeclaration */:
                case 281 /* PropertyAssignment */:
                    return declaration.initializer;
                case 273 /* JsxAttribute */:
                    return declaration.initializer && (ts.isJsxExpression(declaration.initializer) ? declaration.initializer.expression : undefined);
                case 282 /* ShorthandPropertyAssignment */:
                case 158 /* PropertySignature */:
                case 284 /* EnumMember */:
                case 323 /* JSDocPropertyTag */:
                case 317 /* JSDocParameterTag */:
                    return undefined;
            }
        }
        function addReturnStatement(changes, sourceFile, expression, statement) {
            ts.suppressLeadingAndTrailingTrivia(expression);
            var probablyNeedSemi = ts.probablyUsesSemicolons(sourceFile);
            changes.replaceNode(sourceFile, statement, ts.createReturn(expression), {
                leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude,
                trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude,
                suffix: probablyNeedSemi ? ";" : undefined
            });
        }
        function removeBlockBodyBrace(changes, sourceFile, declaration, expression, commentSource, withParen) {
            var newBody = (withParen || ts.needsParentheses(expression)) ? ts.createParen(expression) : expression;
            ts.suppressLeadingAndTrailingTrivia(commentSource);
            ts.copyComments(commentSource, newBody);
            changes.replaceNode(sourceFile, declaration.body, newBody);
        }
        function wrapBlockWithParen(changes, sourceFile, declaration, expression) {
            changes.replaceNode(sourceFile, declaration.body, ts.createParen(expression));
        }
        function getActionForfixAddReturnStatement(context, expression, statement) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addReturnStatement(t, context.sourceFile, expression, statement); });
            return codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_a_return_statement, fixIdAddReturnStatement, ts.Diagnostics.Add_all_missing_return_statement);
        }
        function getActionForfixRemoveBlockBodyBrace(context, declaration, expression, commentSource) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return removeBlockBodyBrace(t, context.sourceFile, declaration, expression, commentSource, /* withParen */ false); });
            return codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Remove_block_body_braces, fixIdRemoveBlockBodyBrace, ts.Diagnostics.Remove_all_incorrect_body_block_braces);
        }
        function getActionForfixWrapTheBlockWithParen(context, declaration, expression) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return wrapBlockWithParen(t, context.sourceFile, declaration, expression); });
            return codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal, fixIdWrapTheBlockWithParen, ts.Diagnostics.Wrap_all_object_literal_with_parentheses);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "addMissingMember";
        var errorCodes = [
            ts.Diagnostics.Property_0_does_not_exist_on_type_1.code,
            ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code,
            ts.Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2.code,
            ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2.code,
            ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more.code
        ];
        var fixId = "addMissingMember";
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var info = getInfo(context.sourceFile, context.span.start, context.program.getTypeChecker(), context.program);
                if (!info)
                    return undefined;
                if (info.kind === 0 /* Enum */) {
                    var token_1 = info.token, parentDeclaration_1 = info.parentDeclaration;
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addEnumMemberDeclaration(t, context.program.getTypeChecker(), token_1, parentDeclaration_1); });
                    return [codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Add_missing_enum_member_0, token_1.text], fixId, ts.Diagnostics.Add_all_missing_members)];
                }
                var parentDeclaration = info.parentDeclaration, declSourceFile = info.declSourceFile, inJs = info.inJs, makeStatic = info.makeStatic, token = info.token, call = info.call;
                var methodCodeAction = call && getActionForMethodDeclaration(context, declSourceFile, parentDeclaration, token, call, makeStatic, inJs);
                var addMember = inJs && !ts.isInterfaceDeclaration(parentDeclaration) ?
                    ts.singleElementArray(getActionsForAddMissingMemberInJavascriptFile(context, declSourceFile, parentDeclaration, token, makeStatic)) :
                    getActionsForAddMissingMemberInTypeScriptFile(context, declSourceFile, parentDeclaration, token, makeStatic);
                return ts.concatenate(ts.singleElementArray(methodCodeAction), addMember);
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var program = context.program;
                var checker = program.getTypeChecker();
                var seen = ts.createMap();
                var typeDeclToMembers = new ts.NodeMap();
                return codefix.createCombinedCodeActions(ts.textChanges.ChangeTracker.with(context, function (changes) {
                    codefix.eachDiagnostic(context, errorCodes, function (diag) {
                        var info = getInfo(diag.file, diag.start, checker, context.program);
                        if (!info || !ts.addToSeen(seen, ts.getNodeId(info.parentDeclaration) + "#" + info.token.text)) {
                            return;
                        }
                        if (info.kind === 0 /* Enum */) {
                            var token = info.token, parentDeclaration = info.parentDeclaration;
                            addEnumMemberDeclaration(changes, checker, token, parentDeclaration);
                        }
                        else {
                            var parentDeclaration = info.parentDeclaration, token_2 = info.token;
                            var infos = typeDeclToMembers.getOrUpdate(parentDeclaration, function () { return []; });
                            if (!infos.some(function (i) { return i.token.text === token_2.text; }))
                                infos.push(info);
                        }
                    });
                    typeDeclToMembers.forEach(function (infos, classDeclaration) {
                        var supers = getAllSupers(classDeclaration, checker);
                        var _loop_13 = function (info) {
                            // If some superclass added this property, don't add it again.
                            if (supers.some(function (superClassOrInterface) {
                                var superInfos = typeDeclToMembers.get(superClassOrInterface);
                                return !!superInfos && superInfos.some(function (_a) {
                                    var token = _a.token;
                                    return token.text === info.token.text;
                                });
                            }))
                                return "continue";
                            var parentDeclaration = info.parentDeclaration, declSourceFile = info.declSourceFile, inJs = info.inJs, makeStatic = info.makeStatic, token = info.token, call = info.call;
                            // Always prefer to add a method declaration if possible.
                            if (call && !ts.isPrivateIdentifier(token)) {
                                addMethodDeclaration(context, changes, declSourceFile, parentDeclaration, token, call, makeStatic, inJs);
                            }
                            else {
                                if (inJs && !ts.isInterfaceDeclaration(parentDeclaration)) {
                                    addMissingMemberInJs(changes, declSourceFile, parentDeclaration, token, makeStatic);
                                }
                                else {
                                    var typeNode = getTypeNode(program.getTypeChecker(), parentDeclaration, token);
                                    addPropertyDeclaration(changes, declSourceFile, parentDeclaration, token.text, typeNode, makeStatic ? 32 /* Static */ : 0);
                                }
                            }
                        };
                        for (var _i = 0, infos_1 = infos; _i < infos_1.length; _i++) {
                            var info = infos_1[_i];
                            _loop_13(info);
                        }
                    });
                }));
            },
        });
        function getAllSupers(decl, checker) {
            var res = [];
            while (decl) {
                var superElement = ts.getClassExtendsHeritageElement(decl);
                var superSymbol = superElement && checker.getSymbolAtLocation(superElement.expression);
                var superDecl = superSymbol && ts.find(superSymbol.declarations, ts.isClassLike);
                if (superDecl) {
                    res.push(superDecl);
                }
                decl = superDecl;
            }
            return res;
        }
        var InfoKind;
        (function (InfoKind) {
            InfoKind[InfoKind["Enum"] = 0] = "Enum";
            InfoKind[InfoKind["ClassOrInterface"] = 1] = "ClassOrInterface";
        })(InfoKind || (InfoKind = {}));
        function getInfo(tokenSourceFile, tokenPos, checker, program) {
            // The identifier of the missing property. eg:
            // this.missing = 1;
            //      ^^^^^^^
            var token = ts.getTokenAtPosition(tokenSourceFile, tokenPos);
            if (!ts.isIdentifier(token) && !ts.isPrivateIdentifier(token)) {
                return undefined;
            }
            var parent = token.parent;
            if (!ts.isPropertyAccessExpression(parent))
                return undefined;
            var leftExpressionType = ts.skipConstraint(checker.getTypeAtLocation(parent.expression));
            var symbol = leftExpressionType.symbol;
            if (!symbol || !symbol.declarations)
                return undefined;
            var classDeclaration = ts.find(symbol.declarations, ts.isClassLike);
            // Don't suggest adding private identifiers to anything other than a class.
            if (!classDeclaration && ts.isPrivateIdentifier(token)) {
                return undefined;
            }
            // Prefer to change the class instead of the interface if they are merged
            var classOrInterface = classDeclaration || ts.find(symbol.declarations, ts.isInterfaceDeclaration);
            if (classOrInterface && !program.isSourceFileFromExternalLibrary(classOrInterface.getSourceFile())) {
                var makeStatic = (leftExpressionType.target || leftExpressionType) !== checker.getDeclaredTypeOfSymbol(symbol);
                if (makeStatic && (ts.isPrivateIdentifier(token) || ts.isInterfaceDeclaration(classOrInterface))) {
                    return undefined;
                }
                var declSourceFile = classOrInterface.getSourceFile();
                var inJs = ts.isSourceFileJS(declSourceFile);
                var call = ts.tryCast(parent.parent, ts.isCallExpression);
                return { kind: 1 /* ClassOrInterface */, token: token, parentDeclaration: classOrInterface, makeStatic: makeStatic, declSourceFile: declSourceFile, inJs: inJs, call: call };
            }
            var enumDeclaration = ts.find(symbol.declarations, ts.isEnumDeclaration);
            if (enumDeclaration && !ts.isPrivateIdentifier(token) && !program.isSourceFileFromExternalLibrary(enumDeclaration.getSourceFile())) {
                return { kind: 0 /* Enum */, token: token, parentDeclaration: enumDeclaration };
            }
            return undefined;
        }
        function getActionsForAddMissingMemberInJavascriptFile(context, declSourceFile, classDeclaration, token, makeStatic) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addMissingMemberInJs(t, declSourceFile, classDeclaration, token, makeStatic); });
            if (changes.length === 0) {
                return undefined;
            }
            var diagnostic = makeStatic ? ts.Diagnostics.Initialize_static_property_0 :
                ts.isPrivateIdentifier(token) ? ts.Diagnostics.Declare_a_private_field_named_0 : ts.Diagnostics.Initialize_property_0_in_the_constructor;
            return codefix.createCodeFixAction(fixName, changes, [diagnostic, token.text], fixId, ts.Diagnostics.Add_all_missing_members);
        }
        function addMissingMemberInJs(changeTracker, declSourceFile, classDeclaration, token, makeStatic) {
            var tokenName = token.text;
            if (makeStatic) {
                if (classDeclaration.kind === 214 /* ClassExpression */) {
                    return;
                }
                var className = classDeclaration.name.getText();
                var staticInitialization = initializePropertyToUndefined(ts.createIdentifier(className), tokenName);
                changeTracker.insertNodeAfter(declSourceFile, classDeclaration, staticInitialization);
            }
            else if (ts.isPrivateIdentifier(token)) {
                var property = ts.createProperty(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, tokenName, 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined);
                var lastProp = getNodeToInsertPropertyAfter(classDeclaration);
                if (lastProp) {
                    changeTracker.insertNodeAfter(declSourceFile, lastProp, property);
                }
                else {
                    changeTracker.insertNodeAtClassStart(declSourceFile, classDeclaration, property);
                }
            }
            else {
                var classConstructor = ts.getFirstConstructorWithBody(classDeclaration);
                if (!classConstructor) {
                    return;
                }
                var propertyInitialization = initializePropertyToUndefined(ts.createThis(), tokenName);
                changeTracker.insertNodeAtConstructorEnd(declSourceFile, classConstructor, propertyInitialization);
            }
        }
        function initializePropertyToUndefined(obj, propertyName) {
            return ts.createStatement(ts.createAssignment(ts.createPropertyAccess(obj, propertyName), ts.createIdentifier("undefined")));
        }
        function getActionsForAddMissingMemberInTypeScriptFile(context, declSourceFile, classDeclaration, token, makeStatic) {
            var typeNode = getTypeNode(context.program.getTypeChecker(), classDeclaration, token);
            var actions = [createAddPropertyDeclarationAction(context, declSourceFile, classDeclaration, token.text, typeNode, makeStatic ? 32 /* Static */ : 0)];
            if (makeStatic || ts.isPrivateIdentifier(token)) {
                return actions;
            }
            if (ts.startsWithUnderscore(token.text)) {
                actions.unshift(createAddPropertyDeclarationAction(context, declSourceFile, classDeclaration, token.text, typeNode, 8 /* Private */));
            }
            actions.push(createAddIndexSignatureAction(context, declSourceFile, classDeclaration, token.text, typeNode));
            return actions;
        }
        function getTypeNode(checker, classDeclaration, token) {
            var typeNode;
            if (token.parent.parent.kind === 209 /* BinaryExpression */) {
                var binaryExpression = token.parent.parent;
                var otherExpression = token.parent === binaryExpression.left ? binaryExpression.right : binaryExpression.left;
                var widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression)));
                typeNode = checker.typeToTypeNode(widenedType, classDeclaration, /*flags*/ undefined);
            }
            else {
                var contextualType = checker.getContextualType(token.parent);
                typeNode = contextualType ? checker.typeToTypeNode(contextualType, /*enclosingDeclaration*/ undefined, /*flags*/ undefined) : undefined;
            }
            return typeNode || ts.createKeywordTypeNode(125 /* AnyKeyword */);
        }
        function createAddPropertyDeclarationAction(context, declSourceFile, classDeclaration, tokenName, typeNode, modifierFlags) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addPropertyDeclaration(t, declSourceFile, classDeclaration, tokenName, typeNode, modifierFlags); });
            if (modifierFlags & 8 /* Private */) {
                return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Declare_private_property_0, tokenName]);
            }
            return codefix.createCodeFixAction(fixName, changes, [modifierFlags & 32 /* Static */ ? ts.Diagnostics.Declare_static_property_0 : ts.Diagnostics.Declare_property_0, tokenName], fixId, ts.Diagnostics.Add_all_missing_members);
        }
        function addPropertyDeclaration(changeTracker, declSourceFile, classDeclaration, tokenName, typeNode, modifierFlags) {
            var property = ts.createProperty(
            /*decorators*/ undefined, 
            /*modifiers*/ modifierFlags ? ts.createNodeArray(ts.createModifiersFromModifierFlags(modifierFlags)) : undefined, tokenName, 
            /*questionToken*/ undefined, typeNode, 
            /*initializer*/ undefined);
            var lastProp = getNodeToInsertPropertyAfter(classDeclaration);
            if (lastProp) {
                changeTracker.insertNodeAfter(declSourceFile, lastProp, property);
            }
            else {
                changeTracker.insertNodeAtClassStart(declSourceFile, classDeclaration, property);
            }
        }
        // Gets the last of the first run of PropertyDeclarations, or undefined if the class does not start with a PropertyDeclaration.
        function getNodeToInsertPropertyAfter(cls) {
            var res;
            for (var _i = 0, _a = cls.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (!ts.isPropertyDeclaration(member))
                    break;
                res = member;
            }
            return res;
        }
        function createAddIndexSignatureAction(context, declSourceFile, classDeclaration, tokenName, typeNode) {
            // Index signatures cannot have the static modifier.
            var stringTypeNode = ts.createKeywordTypeNode(143 /* StringKeyword */);
            var indexingParameter = ts.createParameter(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*dotDotDotToken*/ undefined, "x", 
            /*questionToken*/ undefined, stringTypeNode, 
            /*initializer*/ undefined);
            var indexSignature = ts.createIndexSignature(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, [indexingParameter], typeNode);
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.insertNodeAtClassStart(declSourceFile, classDeclaration, indexSignature); });
            // No fixId here because code-fix-all currently only works on adding individual named properties.
            return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]);
        }
        function getActionForMethodDeclaration(context, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs) {
            // Private methods are not implemented yet.
            if (ts.isPrivateIdentifier(token)) {
                return undefined;
            }
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addMethodDeclaration(context, t, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs); });
            return codefix.createCodeFixAction(fixName, changes, [makeStatic ? ts.Diagnostics.Declare_static_method_0 : ts.Diagnostics.Declare_method_0, token.text], fixId, ts.Diagnostics.Add_all_missing_members);
        }
        function addMethodDeclaration(context, changeTracker, declSourceFile, typeDecl, token, callExpression, makeStatic, inJs) {
            var importAdder = codefix.createImportAdder(declSourceFile, context.program, context.preferences, context.host);
            var methodDeclaration = codefix.createMethodFromCallExpression(context, callExpression, token.text, inJs, makeStatic, typeDecl, importAdder);
            var containingMethodDeclaration = ts.getAncestor(callExpression, 161 /* MethodDeclaration */);
            if (containingMethodDeclaration && containingMethodDeclaration.parent === typeDecl) {
                changeTracker.insertNodeAfter(declSourceFile, containingMethodDeclaration, methodDeclaration);
            }
            else {
                changeTracker.insertNodeAtClassStart(declSourceFile, typeDecl, methodDeclaration);
            }
            importAdder.writeFixes(changeTracker);
        }
        function addEnumMemberDeclaration(changes, checker, token, enumDeclaration) {
            /**
             * create initializer only literal enum that has string initializer.
             * value of initializer is a string literal that equal to name of enum member.
             * numeric enum or empty enum will not create initializer.
             */
            var hasStringInitializer = ts.some(enumDeclaration.members, function (member) {
                var type = checker.getTypeAtLocation(member);
                return !!(type && type.flags & 132 /* StringLike */);
            });
            var enumMember = ts.createEnumMember(token, hasStringInitializer ? ts.createStringLiteral(token.text) : undefined);
            changes.replaceNode(enumDeclaration.getSourceFile(), enumDeclaration, ts.updateEnumDeclaration(enumDeclaration, enumDeclaration.decorators, enumDeclaration.modifiers, enumDeclaration.name, ts.concatenate(enumDeclaration.members, ts.singleElementArray(enumMember))), {
                leadingTriviaOption: ts.textChanges.LeadingTriviaOption.IncludeAll,
                trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude
            });
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "addMissingNewOperator";
        var errorCodes = [ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addMissingNewOperator(t, sourceFile, span); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_missing_new_operator_to_call, fixId, ts.Diagnostics.Add_missing_new_operator_to_all_calls)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                return addMissingNewOperator(changes, context.sourceFile, diag);
            }); },
        });
        function addMissingNewOperator(changes, sourceFile, span) {
            var call = ts.cast(findAncestorMatchingSpan(sourceFile, span), ts.isCallExpression);
            var newExpression = ts.createNew(call.expression, call.typeArguments, call.arguments);
            changes.replaceNode(sourceFile, call, newExpression);
        }
        function findAncestorMatchingSpan(sourceFile, span) {
            var token = ts.getTokenAtPosition(sourceFile, span.start);
            var end = ts.textSpanEnd(span);
            while (token.end < end) {
                token = token.parent;
            }
            return token;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "fixCannotFindModule";
        var fixIdInstallTypesPackage = "installTypesPackage";
        var errorCodeCannotFindModule = ts.Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations.code;
        var errorCodes = [
            errorCodeCannotFindModule,
            ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var host = context.host, sourceFile = context.sourceFile, start = context.span.start;
                var packageName = tryGetImportedPackageName(sourceFile, start);
                if (packageName === undefined)
                    return undefined;
                var typesPackageName = getTypesPackageNameToInstall(packageName, host, context.errorCode);
                return typesPackageName === undefined
                    ? []
                    : [codefix.createCodeFixAction(fixName, /*changes*/ [], [ts.Diagnostics.Install_0, typesPackageName], fixIdInstallTypesPackage, ts.Diagnostics.Install_all_missing_types_packages, getInstallCommand(sourceFile.fileName, typesPackageName))];
            },
            fixIds: [fixIdInstallTypesPackage],
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (_changes, diag, commands) {
                    var packageName = tryGetImportedPackageName(diag.file, diag.start);
                    if (packageName === undefined)
                        return undefined;
                    switch (context.fixId) {
                        case fixIdInstallTypesPackage: {
                            var pkg = getTypesPackageNameToInstall(packageName, context.host, diag.code);
                            if (pkg) {
                                commands.push(getInstallCommand(diag.file.fileName, pkg));
                            }
                            break;
                        }
                        default:
                            ts.Debug.fail("Bad fixId: " + context.fixId);
                    }
                });
            },
        });
        function getInstallCommand(fileName, packageName) {
            return { type: "install package", file: fileName, packageName: packageName };
        }
        function tryGetImportedPackageName(sourceFile, pos) {
            var moduleName = ts.cast(ts.getTokenAtPosition(sourceFile, pos), ts.isStringLiteral).text;
            var packageName = ts.parsePackageName(moduleName).packageName;
            return ts.isExternalModuleNameRelative(packageName) ? undefined : packageName;
        }
        function getTypesPackageNameToInstall(packageName, host, diagCode) {
            return diagCode === errorCodeCannotFindModule
                ? (ts.JsTyping.nodeCoreModules.has(packageName) ? "@types/node" : undefined)
                : (host.isKnownTypesPackageName(packageName) ? ts.getTypesPackageName(packageName) : undefined); // TODO: GH#18217
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodes = [
            ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code,
            ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1.code,
        ];
        var fixId = "fixClassDoesntImplementInheritedAbstractMember";
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) {
                    return addMissingMembers(getClass(sourceFile, span.start), sourceFile, context, t, context.preferences);
                });
                return changes.length === 0 ? undefined : [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Implement_inherited_abstract_class, fixId, ts.Diagnostics.Implement_all_inherited_abstract_classes)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var seenClassDeclarations = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var classDeclaration = getClass(diag.file, diag.start);
                    if (ts.addToSeen(seenClassDeclarations, ts.getNodeId(classDeclaration))) {
                        addMissingMembers(classDeclaration, context.sourceFile, context, changes, context.preferences);
                    }
                });
            },
        });
        function getClass(sourceFile, pos) {
            // Token is the identifier in the case of a class declaration
            // or the class keyword token in the case of a class expression.
            var token = ts.getTokenAtPosition(sourceFile, pos);
            return ts.cast(token.parent, ts.isClassLike);
        }
        function addMissingMembers(classDeclaration, sourceFile, context, changeTracker, preferences) {
            var extendsNode = ts.getEffectiveBaseTypeNode(classDeclaration);
            var checker = context.program.getTypeChecker();
            var instantiatedExtendsType = checker.getTypeAtLocation(extendsNode);
            // Note that this is ultimately derived from a map indexed by symbol names,
            // so duplicates cannot occur.
            var abstractAndNonPrivateExtendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType).filter(symbolPointsToNonPrivateAndAbstractMember);
            var importAdder = codefix.createImportAdder(sourceFile, context.program, preferences, context.host);
            codefix.createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, context, preferences, importAdder, function (member) { return changeTracker.insertNodeAtClassStart(sourceFile, classDeclaration, member); });
            importAdder.writeFixes(changeTracker);
        }
        function symbolPointsToNonPrivateAndAbstractMember(symbol) {
            // See `codeFixClassExtendAbstractProtectedProperty.ts` in https://github.com/Microsoft/TypeScript/pull/11547/files
            // (now named `codeFixClassExtendAbstractPrivateProperty.ts`)
            var flags = ts.getModifierFlags(ts.first(symbol.getDeclarations()));
            return !(flags & 8 /* Private */) && !!(flags & 128 /* Abstract */);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "classSuperMustPrecedeThisAccess";
        var errorCodes = [ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var nodes = getNodes(sourceFile, span.start);
                if (!nodes)
                    return undefined;
                var constructor = nodes.constructor, superCall = nodes.superCall;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, constructor, superCall); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Make_super_call_the_first_statement_in_the_constructor, fixId, ts.Diagnostics.Make_all_super_calls_the_first_statement_in_their_constructor)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var seenClasses = ts.createMap(); // Ensure we only do this once per class.
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var nodes = getNodes(diag.file, diag.start);
                    if (!nodes)
                        return;
                    var constructor = nodes.constructor, superCall = nodes.superCall;
                    if (ts.addToSeen(seenClasses, ts.getNodeId(constructor.parent))) {
                        doChange(changes, sourceFile, constructor, superCall);
                    }
                });
            },
        });
        function doChange(changes, sourceFile, constructor, superCall) {
            changes.insertNodeAtConstructorStart(sourceFile, constructor, superCall);
            changes.delete(sourceFile, superCall);
        }
        function getNodes(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            if (token.kind !== 104 /* ThisKeyword */)
                return undefined;
            var constructor = ts.getContainingFunction(token);
            var superCall = findSuperCall(constructor.body);
            // figure out if the `this` access is actually inside the supercall
            // i.e. super(this.a), since in that case we won't suggest a fix
            return superCall && !superCall.expression.arguments.some(function (arg) { return ts.isPropertyAccessExpression(arg) && arg.expression === token; }) ? { constructor: constructor, superCall: superCall } : undefined;
        }
        function findSuperCall(n) {
            return ts.isExpressionStatement(n) && ts.isSuperCall(n.expression)
                ? n
                : ts.isFunctionLike(n)
                    ? undefined
                    : ts.forEachChild(n, findSuperCall);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "constructorForDerivedNeedSuperCall";
        var errorCodes = [ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var ctr = getNode(sourceFile, span.start);
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, ctr); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_missing_super_call, fixId, ts.Diagnostics.Add_all_missing_super_calls)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                return doChange(changes, context.sourceFile, getNode(diag.file, diag.start));
            }); },
        });
        function getNode(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            ts.Debug.assert(ts.isConstructorDeclaration(token.parent), "token should be at the constructor declaration");
            return token.parent;
        }
        function doChange(changes, sourceFile, ctr) {
            var superCall = ts.createStatement(ts.createCall(ts.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ ts.emptyArray));
            changes.insertNodeAtConstructorStart(sourceFile, ctr, superCall);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "enableExperimentalDecorators";
        var errorCodes = [
            ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning.code
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var configFile = context.program.getCompilerOptions().configFile;
                if (configFile === undefined) {
                    return undefined;
                }
                var changes = ts.textChanges.ChangeTracker.with(context, function (changeTracker) { return doChange(changeTracker, configFile); });
                return [codefix.createCodeFixActionWithoutFixAll(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes) {
                var configFile = context.program.getCompilerOptions().configFile;
                if (configFile === undefined) {
                    return undefined;
                }
                doChange(changes, configFile);
            }); },
        });
        function doChange(changeTracker, configFile) {
            codefix.setJsonCompilerOptionValue(changeTracker, configFile, "experimentalDecorators", ts.createTrue());
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixID = "fixEnableJsxFlag";
        var errorCodes = [ts.Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var configFile = context.program.getCompilerOptions().configFile;
                if (configFile === undefined) {
                    return undefined;
                }
                var changes = ts.textChanges.ChangeTracker.with(context, function (changeTracker) {
                    return doChange(changeTracker, configFile);
                });
                return [
                    codefix.createCodeFixActionWithoutFixAll(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file)
                ];
            },
            fixIds: [fixID],
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (changes) {
                    var configFile = context.program.getCompilerOptions().configFile;
                    if (configFile === undefined) {
                        return undefined;
                    }
                    doChange(changes, configFile);
                });
            }
        });
        function doChange(changeTracker, configFile) {
            codefix.setJsonCompilerOptionValue(changeTracker, configFile, "jsx", ts.createStringLiteral("react"));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        codefix.registerCodeFix({
            errorCodes: [ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code],
            getCodeActions: function (context) {
                var compilerOptions = context.program.getCompilerOptions();
                var configFile = compilerOptions.configFile;
                if (configFile === undefined) {
                    return undefined;
                }
                var codeFixes = [];
                var moduleKind = ts.getEmitModuleKind(compilerOptions);
                var moduleOutOfRange = moduleKind >= ts.ModuleKind.ES2015 && moduleKind < ts.ModuleKind.ESNext;
                if (moduleOutOfRange) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (changes) {
                        codefix.setJsonCompilerOptionValue(changes, configFile, "module", ts.createStringLiteral("esnext"));
                    });
                    codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixModuleOption", changes, [ts.Diagnostics.Set_the_module_option_in_your_configuration_file_to_0, "esnext"]));
                }
                var target = ts.getEmitScriptTarget(compilerOptions);
                var targetOutOfRange = target < 4 /* ES2017 */ || target > 99 /* ESNext */;
                if (targetOutOfRange) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) {
                        var configObject = ts.getTsConfigObjectLiteralExpression(configFile);
                        if (!configObject)
                            return;
                        var options = [["target", ts.createStringLiteral("es2017")]];
                        if (moduleKind === ts.ModuleKind.CommonJS) {
                            // Ensure we preserve the default module kind (commonjs), as targets >= ES2015 have a default module kind of es2015.
                            options.push(["module", ts.createStringLiteral("commonjs")]);
                        }
                        codefix.setJsonCompilerOptionValues(tracker, configFile, options);
                    });
                    codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixTargetOption", changes, [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0, "es2017"]));
                }
                return codeFixes.length ? codeFixes : undefined;
            }
        });
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "extendsInterfaceBecomesImplements";
        var errorCodes = [ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var nodes = getNodes(sourceFile, context.span.start);
                if (!nodes)
                    return undefined;
                var extendsToken = nodes.extendsToken, heritageClauses = nodes.heritageClauses;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChanges(t, sourceFile, extendsToken, heritageClauses); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Change_extends_to_implements, fixId, ts.Diagnostics.Change_all_extended_interfaces_to_implements)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var nodes = getNodes(diag.file, diag.start);
                if (nodes)
                    doChanges(changes, diag.file, nodes.extendsToken, nodes.heritageClauses);
            }); },
        });
        function getNodes(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var heritageClauses = ts.getContainingClass(token).heritageClauses;
            var extendsToken = heritageClauses[0].getFirstToken();
            return extendsToken.kind === 90 /* ExtendsKeyword */ ? { extendsToken: extendsToken, heritageClauses: heritageClauses } : undefined;
        }
        function doChanges(changes, sourceFile, extendsToken, heritageClauses) {
            changes.replaceNode(sourceFile, extendsToken, ts.createToken(113 /* ImplementsKeyword */));
            // If there is already an implements clause, replace the implements keyword with a comma.
            if (heritageClauses.length === 2 &&
                heritageClauses[0].token === 90 /* ExtendsKeyword */ &&
                heritageClauses[1].token === 113 /* ImplementsKeyword */) {
                var implementsToken = heritageClauses[1].getFirstToken();
                var implementsFullStart = implementsToken.getFullStart();
                changes.replaceRange(sourceFile, { pos: implementsFullStart, end: implementsFullStart }, ts.createToken(27 /* CommaToken */));
                // Rough heuristic: delete trailing whitespace after keyword so that it's not excessive.
                // (Trailing because leading might be indentation, which is more sensitive.)
                var text = sourceFile.text;
                var end = implementsToken.end;
                while (end < text.length && ts.isWhiteSpaceSingleLine(text.charCodeAt(end))) {
                    end++;
                }
                changes.deleteRange(sourceFile, { pos: implementsToken.getStart(), end: end });
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "forgottenThisPropertyAccess";
        var didYouMeanStaticMemberCode = ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code;
        var errorCodes = [
            ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
            ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies.code,
            didYouMeanStaticMemberCode,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var info = getInfo(sourceFile, context.span.start, context.errorCode);
                if (!info) {
                    return undefined;
                }
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, info); });
                return [codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Add_0_to_unresolved_variable, info.className || "this"], fixId, ts.Diagnostics.Add_qualifier_to_all_unresolved_variables_matching_a_member_name)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start, diag.code);
                if (info)
                    doChange(changes, context.sourceFile, info);
            }); },
        });
        function getInfo(sourceFile, pos, diagCode) {
            var node = ts.getTokenAtPosition(sourceFile, pos);
            if (ts.isIdentifier(node)) {
                return { node: node, className: diagCode === didYouMeanStaticMemberCode ? ts.getContainingClass(node).name.text : undefined };
            }
        }
        function doChange(changes, sourceFile, _a) {
            var node = _a.node, className = _a.className;
            // TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper
            ts.suppressLeadingAndTrailingTrivia(node);
            changes.replaceNode(sourceFile, node, ts.createPropertyAccess(className ? ts.createIdentifier(className) : ts.createThis(), node));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixIdExpression = "fixInvalidJsxCharacters_expression";
        var fixIdHtmlEntity = "fixInvalidJsxCharacters_htmlEntity";
        var errorCodes = [
            ts.Diagnostics.Unexpected_token_Did_you_mean_or_gt.code,
            ts.Diagnostics.Unexpected_token_Did_you_mean_or_rbrace.code
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            fixIds: [fixIdExpression, fixIdHtmlEntity],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, preferences = context.preferences, span = context.span;
                var changeToExpression = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, preferences, sourceFile, span.start, /* useHtmlEntity */ false); });
                var changeToHtmlEntity = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, preferences, sourceFile, span.start, /* useHtmlEntity */ true); });
                return [
                    codefix.createCodeFixAction(fixIdExpression, changeToExpression, ts.Diagnostics.Wrap_invalid_character_in_an_expression_container, fixIdExpression, ts.Diagnostics.Wrap_all_invalid_characters_in_an_expression_container),
                    codefix.createCodeFixAction(fixIdHtmlEntity, changeToHtmlEntity, ts.Diagnostics.Convert_invalid_character_to_its_html_entity_code, fixIdHtmlEntity, ts.Diagnostics.Convert_all_invalid_characters_to_HTML_entity_code)
                ];
            },
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (changes, diagnostic) { return doChange(changes, context.preferences, diagnostic.file, diagnostic.start, context.fixId === fixIdHtmlEntity); });
            }
        });
        var htmlEntity = {
            ">": "&gt;",
            "}": "&rbrace;",
        };
        function isValidCharacter(character) {
            return ts.hasProperty(htmlEntity, character);
        }
        function doChange(changes, preferences, sourceFile, start, useHtmlEntity) {
            var character = sourceFile.getText()[start];
            // sanity check
            if (!isValidCharacter(character)) {
                return;
            }
            var replacement = useHtmlEntity ? htmlEntity[character] : "{" + ts.quote(character, preferences) + "}";
            changes.replaceRangeWithText(sourceFile, { pos: start, end: start + 1 }, replacement);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "unusedIdentifier";
        var fixIdPrefix = "unusedIdentifier_prefix";
        var fixIdDelete = "unusedIdentifier_delete";
        var fixIdInfer = "unusedIdentifier_infer";
        var errorCodes = [
            ts.Diagnostics._0_is_declared_but_its_value_is_never_read.code,
            ts.Diagnostics._0_is_declared_but_never_used.code,
            ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code,
            ts.Diagnostics.All_imports_in_import_declaration_are_unused.code,
            ts.Diagnostics.All_destructured_elements_are_unused.code,
            ts.Diagnostics.All_variables_are_unused.code,
            ts.Diagnostics.All_type_parameters_are_unused.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var errorCode = context.errorCode, sourceFile = context.sourceFile, program = context.program;
                var checker = program.getTypeChecker();
                var sourceFiles = program.getSourceFiles();
                var token = ts.getTokenAtPosition(sourceFile, context.span.start);
                if (ts.isJSDocTemplateTag(token)) {
                    return [createDeleteFix(ts.textChanges.ChangeTracker.with(context, function (t) { return t.delete(sourceFile, token); }), ts.Diagnostics.Remove_template_tag)];
                }
                if (token.kind === 29 /* LessThanToken */) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return deleteTypeParameters(t, sourceFile, token); });
                    return [createDeleteFix(changes, ts.Diagnostics.Remove_type_parameters)];
                }
                var importDecl = tryGetFullImport(token);
                if (importDecl) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.delete(sourceFile, importDecl); });
                    return [createDeleteFix(changes, [ts.Diagnostics.Remove_import_from_0, ts.showModuleSpecifier(importDecl)])];
                }
                var delDestructure = ts.textChanges.ChangeTracker.with(context, function (t) {
                    return tryDeleteFullDestructure(token, t, sourceFile, checker, sourceFiles, /*isFixAll*/ false);
                });
                if (delDestructure.length) {
                    return [createDeleteFix(delDestructure, ts.Diagnostics.Remove_destructuring)];
                }
                var delVar = ts.textChanges.ChangeTracker.with(context, function (t) { return tryDeleteFullVariableStatement(sourceFile, token, t); });
                if (delVar.length) {
                    return [createDeleteFix(delVar, ts.Diagnostics.Remove_variable_statement)];
                }
                var result = [];
                if (token.kind === 132 /* InferKeyword */) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return changeInferToUnknown(t, sourceFile, token); });
                    var name = ts.cast(token.parent, ts.isInferTypeNode).typeParameter.name.text;
                    result.push(codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Replace_infer_0_with_unknown, name], fixIdInfer, ts.Diagnostics.Replace_all_unused_infer_with_unknown));
                }
                else {
                    var deletion = ts.textChanges.ChangeTracker.with(context, function (t) {
                        return tryDeleteDeclaration(sourceFile, token, t, checker, sourceFiles, /*isFixAll*/ false);
                    });
                    if (deletion.length) {
                        var name = ts.isComputedPropertyName(token.parent) ? token.parent : token;
                        result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_unused_declaration_for_Colon_0, name.getText(sourceFile)]));
                    }
                }
                var prefix = ts.textChanges.ChangeTracker.with(context, function (t) { return tryPrefixDeclaration(t, errorCode, sourceFile, token); });
                if (prefix.length) {
                    result.push(codefix.createCodeFixAction(fixName, prefix, [ts.Diagnostics.Prefix_0_with_an_underscore, token.getText(sourceFile)], fixIdPrefix, ts.Diagnostics.Prefix_all_unused_declarations_with_where_possible));
                }
                return result;
            },
            fixIds: [fixIdPrefix, fixIdDelete, fixIdInfer],
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program;
                var checker = program.getTypeChecker();
                var sourceFiles = program.getSourceFiles();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var token = ts.getTokenAtPosition(sourceFile, diag.start);
                    switch (context.fixId) {
                        case fixIdPrefix:
                            tryPrefixDeclaration(changes, diag.code, sourceFile, token);
                            break;
                        case fixIdDelete: {
                            if (token.kind === 132 /* InferKeyword */)
                                break; // Can't delete
                            var importDecl = tryGetFullImport(token);
                            if (importDecl) {
                                changes.delete(sourceFile, importDecl);
                            }
                            else if (ts.isJSDocTemplateTag(token)) {
                                changes.delete(sourceFile, token);
                            }
                            else if (token.kind === 29 /* LessThanToken */) {
                                deleteTypeParameters(changes, sourceFile, token);
                            }
                            else if (!tryDeleteFullDestructure(token, changes, sourceFile, checker, sourceFiles, /*isFixAll*/ true) &&
                                !tryDeleteFullVariableStatement(sourceFile, token, changes)) {
                                tryDeleteDeclaration(sourceFile, token, changes, checker, sourceFiles, /*isFixAll*/ true);
                            }
                            break;
                        }
                        case fixIdInfer:
                            if (token.kind === 132 /* InferKeyword */) {
                                changeInferToUnknown(changes, sourceFile, token);
                            }
                            break;
                        default:
                            ts.Debug.fail(JSON.stringify(context.fixId));
                    }
                });
            },
        });
        function changeInferToUnknown(changes, sourceFile, token) {
            changes.replaceNode(sourceFile, token.parent, ts.createKeywordTypeNode(148 /* UnknownKeyword */));
        }
        function createDeleteFix(changes, diag) {
            return codefix.createCodeFixAction(fixName, changes, diag, fixIdDelete, ts.Diagnostics.Delete_all_unused_declarations);
        }
        function deleteTypeParameters(changes, sourceFile, token) {
            changes.delete(sourceFile, ts.Debug.checkDefined(ts.cast(token.parent, ts.isDeclarationWithTypeParameterChildren).typeParameters, "The type parameter to delete should exist"));
        }
        // Sometimes the diagnostic span is an entire ImportDeclaration, so we should remove the whole thing.
        function tryGetFullImport(token) {
            return token.kind === 96 /* ImportKeyword */ ? ts.tryCast(token.parent, ts.isImportDeclaration) : undefined;
        }
        function tryDeleteFullDestructure(token, changes, sourceFile, checker, sourceFiles, isFixAll) {
            if (token.kind !== 18 /* OpenBraceToken */ || !ts.isObjectBindingPattern(token.parent))
                return false;
            var decl = token.parent.parent;
            if (decl.kind === 156 /* Parameter */) {
                tryDeleteParameter(changes, sourceFile, decl, checker, sourceFiles, isFixAll);
            }
            else {
                changes.delete(sourceFile, decl);
            }
            return true;
        }
        function tryDeleteFullVariableStatement(sourceFile, token, changes) {
            var declarationList = ts.tryCast(token.parent, ts.isVariableDeclarationList);
            if (declarationList && declarationList.getChildren(sourceFile)[0] === token) {
                changes.delete(sourceFile, declarationList.parent.kind === 225 /* VariableStatement */ ? declarationList.parent : declarationList);
                return true;
            }
            return false;
        }
        function tryPrefixDeclaration(changes, errorCode, sourceFile, token) {
            // Don't offer to prefix a property.
            if (errorCode === ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code)
                return;
            if (token.kind === 132 /* InferKeyword */) {
                token = ts.cast(token.parent, ts.isInferTypeNode).typeParameter.name;
            }
            if (ts.isIdentifier(token) && canPrefix(token)) {
                changes.replaceNode(sourceFile, token, ts.createIdentifier("_" + token.text));
                if (ts.isParameter(token.parent)) {
                    ts.getJSDocParameterTags(token.parent).forEach(function (tag) {
                        if (ts.isIdentifier(tag.name)) {
                            changes.replaceNode(sourceFile, tag.name, ts.createIdentifier("_" + tag.name.text));
                        }
                    });
                }
            }
        }
        function canPrefix(token) {
            switch (token.parent.kind) {
                case 156 /* Parameter */:
                case 155 /* TypeParameter */:
                    return true;
                case 242 /* VariableDeclaration */: {
                    var varDecl = token.parent;
                    switch (varDecl.parent.parent.kind) {
                        case 232 /* ForOfStatement */:
                        case 231 /* ForInStatement */:
                            return true;
                    }
                }
            }
            return false;
        }
        function tryDeleteDeclaration(sourceFile, token, changes, checker, sourceFiles, isFixAll) {
            tryDeleteDeclarationWorker(token, changes, sourceFile, checker, sourceFiles, isFixAll);
            if (ts.isIdentifier(token))
                deleteAssignments(changes, sourceFile, token, checker);
        }
        function deleteAssignments(changes, sourceFile, token, checker) {
            ts.FindAllReferences.Core.eachSymbolReferenceInFile(token, checker, sourceFile, function (ref) {
                if (ts.isPropertyAccessExpression(ref.parent) && ref.parent.name === ref)
                    ref = ref.parent;
                if (ts.isBinaryExpression(ref.parent) && ts.isExpressionStatement(ref.parent.parent) && ref.parent.left === ref) {
                    changes.delete(sourceFile, ref.parent.parent);
                }
            });
        }
        function tryDeleteDeclarationWorker(token, changes, sourceFile, checker, sourceFiles, isFixAll) {
            var parent = token.parent;
            if (ts.isParameter(parent)) {
                tryDeleteParameter(changes, sourceFile, parent, checker, sourceFiles, isFixAll);
            }
            else {
                changes.delete(sourceFile, ts.isImportClause(parent) ? token : ts.isComputedPropertyName(parent) ? parent.parent : parent);
            }
        }
        function tryDeleteParameter(changes, sourceFile, p, checker, sourceFiles, isFixAll) {
            if (mayDeleteParameter(p, checker, isFixAll)) {
                if (p.modifiers && p.modifiers.length > 0
                    && (!ts.isIdentifier(p.name) || ts.FindAllReferences.Core.isSymbolReferencedInFile(p.name, checker, sourceFile))) {
                    p.modifiers.forEach(function (modifier) {
                        changes.deleteModifier(sourceFile, modifier);
                    });
                }
                else {
                    changes.delete(sourceFile, p);
                    deleteUnusedArguments(changes, sourceFile, p, sourceFiles, checker);
                }
            }
        }
        function mayDeleteParameter(p, checker, isFixAll) {
            var parent = p.parent;
            switch (parent.kind) {
                case 161 /* MethodDeclaration */:
                    // Don't remove a parameter if this overrides something.
                    var symbol = checker.getSymbolAtLocation(parent.name);
                    if (ts.isMemberSymbolInBaseType(symbol, checker))
                        return false;
                // falls through
                case 162 /* Constructor */:
                case 244 /* FunctionDeclaration */:
                    return true;
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */: {
                    // Can't remove a non-last parameter in a callback. Can remove a parameter in code-fix-all if future parameters are also unused.
                    var parameters = parent.parameters;
                    var index = parameters.indexOf(p);
                    ts.Debug.assert(index !== -1, "The parameter should already be in the list");
                    return isFixAll
                        ? parameters.slice(index + 1).every(function (p) { return p.name.kind === 75 /* Identifier */ && !p.symbol.isReferenced; })
                        : index === parameters.length - 1;
                }
                case 164 /* SetAccessor */:
                    // Setter must have a parameter
                    return false;
                default:
                    return ts.Debug.failBadSyntaxKind(parent);
            }
        }
        function deleteUnusedArguments(changes, sourceFile, deletedParameter, sourceFiles, checker) {
            ts.FindAllReferences.Core.eachSignatureCall(deletedParameter.parent, sourceFiles, checker, function (call) {
                var index = deletedParameter.parent.parameters.indexOf(deletedParameter);
                if (call.arguments.length > index) { // Just in case the call didn't provide enough arguments.
                    changes.delete(sourceFile, call.arguments[index]);
                }
            });
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixUnreachableCode";
        var errorCodes = [ts.Diagnostics.Unreachable_code_detected.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, context.span.start, context.span.length, context.errorCode); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Remove_unreachable_code, fixId, ts.Diagnostics.Remove_all_unreachable_code)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return doChange(changes, diag.file, diag.start, diag.length, diag.code); }); },
        });
        function doChange(changes, sourceFile, start, length, errorCode) {
            var token = ts.getTokenAtPosition(sourceFile, start);
            var statement = ts.findAncestor(token, ts.isStatement);
            if (statement.getStart(sourceFile) !== token.getStart(sourceFile)) {
                var logData = JSON.stringify({
                    statementKind: ts.Debug.formatSyntaxKind(statement.kind),
                    tokenKind: ts.Debug.formatSyntaxKind(token.kind),
                    errorCode: errorCode,
                    start: start,
                    length: length
                });
                ts.Debug.fail("Token and statement should start at the same point. " + logData);
            }
            var container = (ts.isBlock(statement.parent) ? statement.parent : statement).parent;
            if (!ts.isBlock(statement.parent) || statement === ts.first(statement.parent.statements)) {
                switch (container.kind) {
                    case 227 /* IfStatement */:
                        if (container.elseStatement) {
                            if (ts.isBlock(statement.parent)) {
                                break;
                            }
                            else {
                                changes.replaceNode(sourceFile, statement, ts.createBlock(ts.emptyArray));
                            }
                            return;
                        }
                    // falls through
                    case 229 /* WhileStatement */:
                    case 230 /* ForStatement */:
                        changes.delete(sourceFile, container);
                        return;
                }
            }
            if (ts.isBlock(statement.parent)) {
                var end_3 = start + length;
                var lastStatement = ts.Debug.checkDefined(lastWhere(ts.sliceAfter(statement.parent.statements, statement), function (s) { return s.pos < end_3; }), "Some statement should be last");
                changes.deleteNodeRange(sourceFile, statement, lastStatement);
            }
            else {
                changes.delete(sourceFile, statement);
            }
        }
        function lastWhere(a, pred) {
            var last;
            for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
                var value = a_1[_i];
                if (!pred(value))
                    break;
                last = value;
            }
            return last;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixUnusedLabel";
        var errorCodes = [ts.Diagnostics.Unused_label.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, context.span.start); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Remove_unused_label, fixId, ts.Diagnostics.Remove_all_unused_labels)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return doChange(changes, diag.file, diag.start); }); },
        });
        function doChange(changes, sourceFile, start) {
            var token = ts.getTokenAtPosition(sourceFile, start);
            var labeledStatement = ts.cast(token.parent, ts.isLabeledStatement);
            var pos = token.getStart(sourceFile);
            var statementPos = labeledStatement.statement.getStart(sourceFile);
            // If label is on a separate line, just delete the rest of that line, but not the indentation of the labeled statement.
            var end = ts.positionsAreOnSameLine(pos, statementPos, sourceFile) ? statementPos
                : ts.skipTrivia(sourceFile.text, ts.findChildOfKind(labeledStatement, 58 /* ColonToken */, sourceFile).end, /*stopAfterLineBreak*/ true);
            changes.deleteRange(sourceFile, { pos: pos, end: end });
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixIdPlain = "fixJSDocTypes_plain";
        var fixIdNullable = "fixJSDocTypes_nullable";
        var errorCodes = [ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var checker = context.program.getTypeChecker();
                var info = getInfo(sourceFile, context.span.start, checker);
                if (!info)
                    return undefined;
                var typeNode = info.typeNode, type = info.type;
                var original = typeNode.getText(sourceFile);
                var actions = [fix(type, fixIdPlain, ts.Diagnostics.Change_all_jsdoc_style_types_to_TypeScript)];
                if (typeNode.kind === 297 /* JSDocNullableType */) {
                    // for nullable types, suggest the flow-compatible `T | null | undefined`
                    // in addition to the jsdoc/closure-compatible `T | null`
                    actions.push(fix(checker.getNullableType(type, 32768 /* Undefined */), fixIdNullable, ts.Diagnostics.Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types));
                }
                return actions;
                function fix(type, fixId, fixAllDescription) {
                    var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, typeNode, type, checker); });
                    return codefix.createCodeFixAction("jdocTypes", changes, [ts.Diagnostics.Change_0_to_1, original, checker.typeToString(type)], fixId, fixAllDescription);
                }
            },
            fixIds: [fixIdPlain, fixIdNullable],
            getAllCodeActions: function (context) {
                var fixId = context.fixId, program = context.program, sourceFile = context.sourceFile;
                var checker = program.getTypeChecker();
                return codefix.codeFixAll(context, errorCodes, function (changes, err) {
                    var info = getInfo(err.file, err.start, checker);
                    if (!info)
                        return;
                    var typeNode = info.typeNode, type = info.type;
                    var fixedType = typeNode.kind === 297 /* JSDocNullableType */ && fixId === fixIdNullable ? checker.getNullableType(type, 32768 /* Undefined */) : type;
                    doChange(changes, sourceFile, typeNode, fixedType, checker);
                });
            }
        });
        function doChange(changes, sourceFile, oldTypeNode, newType, checker) {
            changes.replaceNode(sourceFile, oldTypeNode, checker.typeToTypeNode(newType, /*enclosingDeclaration*/ oldTypeNode, /*flags*/ undefined)); // TODO: GH#18217
        }
        function getInfo(sourceFile, pos, checker) {
            var decl = ts.findAncestor(ts.getTokenAtPosition(sourceFile, pos), isTypeContainer);
            var typeNode = decl && decl.type;
            return typeNode && { typeNode: typeNode, type: checker.getTypeFromTypeNode(typeNode) };
        }
        function isTypeContainer(node) {
            // NOTE: Some locations are not handled yet:
            // MappedTypeNode.typeParameters and SignatureDeclaration.typeParameters, as well as CallExpression.typeArguments
            switch (node.kind) {
                case 217 /* AsExpression */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 244 /* FunctionDeclaration */:
                case 163 /* GetAccessor */:
                case 167 /* IndexSignature */:
                case 186 /* MappedType */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 156 /* Parameter */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 164 /* SetAccessor */:
                case 247 /* TypeAliasDeclaration */:
                case 199 /* TypeAssertionExpression */:
                case 242 /* VariableDeclaration */:
                    return true;
                default:
                    return false;
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixMissingCallParentheses";
        var errorCodes = [
            ts.Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            fixIds: [fixId],
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var callName = getCallName(sourceFile, span.start);
                if (!callName)
                    return;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, callName); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_missing_call_parentheses, fixId, ts.Diagnostics.Add_all_missing_call_parentheses)];
            },
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var callName = getCallName(diag.file, diag.start);
                if (callName)
                    doChange(changes, diag.file, callName);
            }); }
        });
        function doChange(changes, sourceFile, name) {
            changes.replaceNodeWithText(sourceFile, name, name.text + "()");
        }
        function getCallName(sourceFile, start) {
            var token = ts.getTokenAtPosition(sourceFile, start);
            if (ts.isPropertyAccessExpression(token.parent)) {
                var current = token.parent;
                while (ts.isPropertyAccessExpression(current.parent)) {
                    current = current.parent;
                }
                return current.name;
            }
            if (ts.isIdentifier(token)) {
                return token;
            }
            return undefined;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixAwaitInSyncFunction";
        var errorCodes = [
            ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code,
            ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var nodes = getNodes(sourceFile, span.start);
                if (!nodes)
                    return undefined;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, nodes); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_async_modifier_to_containing_function, fixId, ts.Diagnostics.Add_all_missing_async_modifiers)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var seen = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var nodes = getNodes(diag.file, diag.start);
                    if (!nodes || !ts.addToSeen(seen, ts.getNodeId(nodes.insertBefore)))
                        return;
                    doChange(changes, context.sourceFile, nodes);
                });
            },
        });
        function getReturnType(expr) {
            if (expr.type) {
                return expr.type;
            }
            if (ts.isVariableDeclaration(expr.parent) &&
                expr.parent.type &&
                ts.isFunctionTypeNode(expr.parent.type)) {
                return expr.parent.type.type;
            }
        }
        function getNodes(sourceFile, start) {
            var token = ts.getTokenAtPosition(sourceFile, start);
            var containingFunction = ts.getContainingFunction(token);
            if (!containingFunction) {
                return;
            }
            var insertBefore;
            switch (containingFunction.kind) {
                case 161 /* MethodDeclaration */:
                    insertBefore = containingFunction.name;
                    break;
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                    insertBefore = ts.findChildOfKind(containingFunction, 94 /* FunctionKeyword */, sourceFile);
                    break;
                case 202 /* ArrowFunction */:
                    insertBefore = ts.findChildOfKind(containingFunction, 20 /* OpenParenToken */, sourceFile) || ts.first(containingFunction.parameters);
                    break;
                default:
                    return;
            }
            return insertBefore && {
                insertBefore: insertBefore,
                returnType: getReturnType(containingFunction)
            };
        }
        function doChange(changes, sourceFile, _a) {
            var insertBefore = _a.insertBefore, returnType = _a.returnType;
            if (returnType) {
                var entityName = ts.getEntityNameFromTypeNode(returnType);
                if (!entityName || entityName.kind !== 75 /* Identifier */ || entityName.text !== "Promise") {
                    changes.replaceNode(sourceFile, returnType, ts.createTypeReferenceNode("Promise", ts.createNodeArray([returnType])));
                }
            }
            changes.insertModifierBefore(sourceFile, 126 /* AsyncKeyword */, insertBefore);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "inferFromUsage";
        var errorCodes = [
            // Variable declarations
            ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code,
            // Variable uses
            ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code,
            // Parameter declarations
            ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code,
            ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code,
            // Get Accessor declarations
            ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code,
            ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code,
            // Set Accessor declarations
            ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code,
            // Property declarations
            ts.Diagnostics.Member_0_implicitly_has_an_1_type.code,
            //// Suggestions
            // Variable declarations
            ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage.code,
            // Variable uses
            ts.Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code,
            // Parameter declarations
            ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code,
            ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage.code,
            // Get Accessor declarations
            ts.Diagnostics.Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage.code,
            ts.Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage.code,
            // Set Accessor declarations
            ts.Diagnostics.Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage.code,
            // Property declarations
            ts.Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code,
            // Function expressions and declarations
            ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, start = context.span.start, errorCode = context.errorCode, cancellationToken = context.cancellationToken, host = context.host, preferences = context.preferences;
                var token = ts.getTokenAtPosition(sourceFile, start);
                var declaration;
                var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeen*/ ts.returnTrue, host, preferences); });
                var name = declaration && ts.getNameOfDeclaration(declaration);
                return !name || changes.length === 0 ? undefined
                    : [codefix.createCodeFixAction(fixId, changes, [getDiagnostic(errorCode, token), name.getText(sourceFile)], fixId, ts.Diagnostics.Infer_all_types_from_usage)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, cancellationToken = context.cancellationToken, host = context.host, preferences = context.preferences;
                var markSeen = ts.nodeSeenTracker();
                return codefix.codeFixAll(context, errorCodes, function (changes, err) {
                    doChange(changes, sourceFile, ts.getTokenAtPosition(err.file, err.start), err.code, program, cancellationToken, markSeen, host, preferences);
                });
            },
        });
        function getDiagnostic(errorCode, token) {
            switch (errorCode) {
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.isSetAccessorDeclaration(ts.getContainingFunction(token)) ? ts.Diagnostics.Infer_type_of_0_from_usage : ts.Diagnostics.Infer_parameter_types_from_usage; // TODO: GH#18217
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Infer_parameter_types_from_usage;
                case ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation.code:
                    return ts.Diagnostics.Infer_this_type_of_0_from_usage;
                default:
                    return ts.Diagnostics.Infer_type_of_0_from_usage;
            }
        }
        /** Map suggestion code to error code */
        function mapSuggestionDiagnostic(errorCode) {
            switch (errorCode) {
                case ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code;
                case ts.Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code;
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code;
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code;
                case ts.Diagnostics.Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code;
                case ts.Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code;
                case ts.Diagnostics.Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code;
                case ts.Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
                    return ts.Diagnostics.Member_0_implicitly_has_an_1_type.code;
            }
            return errorCode;
        }
        function doChange(changes, sourceFile, token, errorCode, program, cancellationToken, markSeen, host, preferences) {
            if (!ts.isParameterPropertyModifier(token.kind) && token.kind !== 75 /* Identifier */ && token.kind !== 25 /* DotDotDotToken */ && token.kind !== 104 /* ThisKeyword */) {
                return undefined;
            }
            var parent = token.parent;
            var importAdder = codefix.createImportAdder(sourceFile, program, preferences, host);
            errorCode = mapSuggestionDiagnostic(errorCode);
            switch (errorCode) {
                // Variable and Property declarations
                case ts.Diagnostics.Member_0_implicitly_has_an_1_type.code:
                case ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code:
                    if ((ts.isVariableDeclaration(parent) && markSeen(parent)) || ts.isPropertyDeclaration(parent) || ts.isPropertySignature(parent)) { // handle bad location
                        annotateVariableDeclaration(changes, importAdder, sourceFile, parent, program, host, cancellationToken);
                        importAdder.writeFixes(changes);
                        return parent;
                    }
                    if (ts.isPropertyAccessExpression(parent)) {
                        var type = inferTypeForVariableFromUsage(parent.name, program, cancellationToken);
                        var typeNode = ts.getTypeNodeIfAccessible(type, parent, program, host);
                        if (typeNode) {
                            // Note that the codefix will never fire with an existing `@type` tag, so there is no need to merge tags
                            var typeTag = ts.createJSDocTypeTag(ts.createJSDocTypeExpression(typeNode), /*comment*/ "");
                            addJSDocTags(changes, sourceFile, ts.cast(parent.parent.parent, ts.isExpressionStatement), [typeTag]);
                        }
                        importAdder.writeFixes(changes);
                        return parent;
                    }
                    return undefined;
                case ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code: {
                    var symbol = program.getTypeChecker().getSymbolAtLocation(token);
                    if (symbol && symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) && markSeen(symbol.valueDeclaration)) {
                        annotateVariableDeclaration(changes, importAdder, sourceFile, symbol.valueDeclaration, program, host, cancellationToken);
                        importAdder.writeFixes(changes);
                        return symbol.valueDeclaration;
                    }
                    return undefined;
                }
            }
            var containingFunction = ts.getContainingFunction(token);
            if (containingFunction === undefined) {
                return undefined;
            }
            var declaration;
            switch (errorCode) {
                // Parameter declarations
                case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
                    if (ts.isSetAccessorDeclaration(containingFunction)) {
                        annotateSetAccessor(changes, importAdder, sourceFile, containingFunction, program, host, cancellationToken);
                        declaration = containingFunction;
                        break;
                    }
                // falls through
                case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
                    if (markSeen(containingFunction)) {
                        var param = ts.cast(parent, ts.isParameter);
                        annotateParameters(changes, importAdder, sourceFile, param, containingFunction, program, host, cancellationToken);
                        declaration = param;
                    }
                    break;
                // Get Accessor declarations
                case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code:
                case ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code:
                    if (ts.isGetAccessorDeclaration(containingFunction) && ts.isIdentifier(containingFunction.name)) {
                        annotate(changes, importAdder, sourceFile, containingFunction, inferTypeForVariableFromUsage(containingFunction.name, program, cancellationToken), program, host);
                        declaration = containingFunction;
                    }
                    break;
                // Set Accessor declarations
                case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code:
                    if (ts.isSetAccessorDeclaration(containingFunction)) {
                        annotateSetAccessor(changes, importAdder, sourceFile, containingFunction, program, host, cancellationToken);
                        declaration = containingFunction;
                    }
                    break;
                // Function 'this'
                case ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation.code:
                    if (ts.textChanges.isThisTypeAnnotatable(containingFunction) && markSeen(containingFunction)) {
                        annotateThis(changes, sourceFile, containingFunction, program, host, cancellationToken);
                        declaration = containingFunction;
                    }
                    break;
                default:
                    return ts.Debug.fail(String(errorCode));
            }
            importAdder.writeFixes(changes);
            return declaration;
        }
        function annotateVariableDeclaration(changes, importAdder, sourceFile, declaration, program, host, cancellationToken) {
            if (ts.isIdentifier(declaration.name)) {
                annotate(changes, importAdder, sourceFile, declaration, inferTypeForVariableFromUsage(declaration.name, program, cancellationToken), program, host);
            }
        }
        function annotateParameters(changes, importAdder, sourceFile, parameterDeclaration, containingFunction, program, host, cancellationToken) {
            if (!ts.isIdentifier(parameterDeclaration.name)) {
                return;
            }
            var parameterInferences = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken);
            ts.Debug.assert(containingFunction.parameters.length === parameterInferences.length, "Parameter count and inference count should match");
            if (ts.isInJSFile(containingFunction)) {
                annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host);
            }
            else {
                var needParens = ts.isArrowFunction(containingFunction) && !ts.findChildOfKind(containingFunction, 20 /* OpenParenToken */, sourceFile);
                if (needParens)
                    changes.insertNodeBefore(sourceFile, ts.first(containingFunction.parameters), ts.createToken(20 /* OpenParenToken */));
                for (var _i = 0, parameterInferences_1 = parameterInferences; _i < parameterInferences_1.length; _i++) {
                    var _a = parameterInferences_1[_i], declaration = _a.declaration, type = _a.type;
                    if (declaration && !declaration.type && !declaration.initializer) {
                        annotate(changes, importAdder, sourceFile, declaration, type, program, host);
                    }
                }
                if (needParens)
                    changes.insertNodeAfter(sourceFile, ts.last(containingFunction.parameters), ts.createToken(21 /* CloseParenToken */));
            }
        }
        function annotateThis(changes, sourceFile, containingFunction, program, host, cancellationToken) {
            var references = getFunctionReferences(containingFunction, sourceFile, program, cancellationToken);
            if (!references || !references.length) {
                return;
            }
            var thisInference = inferTypeFromReferences(program, references, cancellationToken).thisParameter();
            var typeNode = ts.getTypeNodeIfAccessible(thisInference, containingFunction, program, host);
            if (!typeNode) {
                return;
            }
            if (ts.isInJSFile(containingFunction)) {
                annotateJSDocThis(changes, sourceFile, containingFunction, typeNode);
            }
            else {
                changes.tryInsertThisTypeAnnotation(sourceFile, containingFunction, typeNode);
            }
        }
        function annotateJSDocThis(changes, sourceFile, containingFunction, typeNode) {
            addJSDocTags(changes, sourceFile, containingFunction, [
                ts.createJSDocThisTag(ts.createJSDocTypeExpression(typeNode)),
            ]);
        }
        function annotateSetAccessor(changes, importAdder, sourceFile, setAccessorDeclaration, program, host, cancellationToken) {
            var param = ts.firstOrUndefined(setAccessorDeclaration.parameters);
            if (param && ts.isIdentifier(setAccessorDeclaration.name) && ts.isIdentifier(param.name)) {
                var type = inferTypeForVariableFromUsage(setAccessorDeclaration.name, program, cancellationToken);
                if (type === program.getTypeChecker().getAnyType()) {
                    type = inferTypeForVariableFromUsage(param.name, program, cancellationToken);
                }
                if (ts.isInJSFile(setAccessorDeclaration)) {
                    annotateJSDocParameters(changes, sourceFile, [{ declaration: param, type: type }], program, host);
                }
                else {
                    annotate(changes, importAdder, sourceFile, param, type, program, host);
                }
            }
        }
        function annotate(changes, importAdder, sourceFile, declaration, type, program, host) {
            var typeNode = ts.getTypeNodeIfAccessible(type, declaration, program, host);
            if (typeNode) {
                if (ts.isInJSFile(sourceFile) && declaration.kind !== 158 /* PropertySignature */) {
                    var parent = ts.isVariableDeclaration(declaration) ? ts.tryCast(declaration.parent.parent, ts.isVariableStatement) : declaration;
                    if (!parent) {
                        return;
                    }
                    var typeExpression = ts.createJSDocTypeExpression(typeNode);
                    var typeTag = ts.isGetAccessorDeclaration(declaration) ? ts.createJSDocReturnTag(typeExpression, "") : ts.createJSDocTypeTag(typeExpression, "");
                    addJSDocTags(changes, sourceFile, parent, [typeTag]);
                }
                else if (!tryReplaceImportTypeNodeWithAutoImport(typeNode, declaration, type, sourceFile, changes, importAdder, ts.getEmitScriptTarget(program.getCompilerOptions()))) {
                    changes.tryInsertTypeAnnotation(sourceFile, declaration, typeNode);
                }
            }
        }
        function tryReplaceImportTypeNodeWithAutoImport(typeNode, declaration, type, sourceFile, changes, importAdder, scriptTarget) {
            var importableReference = codefix.tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, scriptTarget);
            if (importableReference && changes.tryInsertTypeAnnotation(sourceFile, declaration, importableReference.typeReference)) {
                ts.forEach(importableReference.symbols, function (s) { return importAdder.addImportFromExportedSymbol(s, /*usageIsTypeOnly*/ true); });
                return true;
            }
            return false;
        }
        function annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host) {
            var signature = parameterInferences.length && parameterInferences[0].declaration.parent;
            if (!signature) {
                return;
            }
            var paramTags = ts.mapDefined(parameterInferences, function (inference) {
                var param = inference.declaration;
                // only infer parameters that have (1) no type and (2) an accessible inferred type
                if (param.initializer || ts.getJSDocType(param) || !ts.isIdentifier(param.name))
                    return;
                var typeNode = inference.type && ts.getTypeNodeIfAccessible(inference.type, param, program, host);
                var name = ts.getSynthesizedClone(param.name);
                ts.setEmitFlags(name, 1536 /* NoComments */ | 2048 /* NoNestedComments */);
                return typeNode && ts.createJSDocParamTag(name, !!inference.isOptional, ts.createJSDocTypeExpression(typeNode), "");
            });
            addJSDocTags(changes, sourceFile, signature, paramTags);
        }
        function addJSDocTags(changes, sourceFile, parent, newTags) {
            var comments = ts.mapDefined(parent.jsDoc, function (j) { return j.comment; });
            var oldTags = ts.flatMapToMutable(parent.jsDoc, function (j) { return j.tags; });
            var unmergedNewTags = newTags.filter(function (newTag) { return !oldTags || !oldTags.some(function (tag, i) {
                var merged = tryMergeJsdocTags(tag, newTag);
                if (merged)
                    oldTags[i] = merged;
                return !!merged;
            }); });
            var tag = ts.createJSDocComment(comments.join("\n"), ts.createNodeArray(__spreadArrays((oldTags || ts.emptyArray), unmergedNewTags)));
            var jsDocNode = parent.kind === 202 /* ArrowFunction */ ? getJsDocNodeForArrowFunction(parent) : parent;
            jsDocNode.jsDoc = parent.jsDoc;
            jsDocNode.jsDocCache = parent.jsDocCache;
            changes.insertJsdocCommentBefore(sourceFile, jsDocNode, tag);
        }
        codefix.addJSDocTags = addJSDocTags;
        function getJsDocNodeForArrowFunction(signature) {
            if (signature.parent.kind === 159 /* PropertyDeclaration */) {
                return signature.parent;
            }
            return signature.parent.parent;
        }
        function tryMergeJsdocTags(oldTag, newTag) {
            if (oldTag.kind !== newTag.kind) {
                return undefined;
            }
            switch (oldTag.kind) {
                case 317 /* JSDocParameterTag */: {
                    var oldParam = oldTag;
                    var newParam = newTag;
                    return ts.isIdentifier(oldParam.name) && ts.isIdentifier(newParam.name) && oldParam.name.escapedText === newParam.name.escapedText
                        ? ts.createJSDocParamTag(newParam.name, newParam.isBracketed, newParam.typeExpression, oldParam.comment)
                        : undefined;
                }
                case 318 /* JSDocReturnTag */:
                    return ts.createJSDocReturnTag(newTag.typeExpression, oldTag.comment);
            }
        }
        function getReferences(token, program, cancellationToken) {
            // Position shouldn't matter since token is not a SourceFile.
            return ts.mapDefined(ts.FindAllReferences.getReferenceEntriesForNode(-1, token, program, program.getSourceFiles(), cancellationToken), function (entry) {
                return entry.kind !== 0 /* Span */ ? ts.tryCast(entry.node, ts.isIdentifier) : undefined;
            });
        }
        function inferTypeForVariableFromUsage(token, program, cancellationToken) {
            var references = getReferences(token, program, cancellationToken);
            return inferTypeFromReferences(program, references, cancellationToken).single();
        }
        function inferTypeForParametersFromUsage(func, sourceFile, program, cancellationToken) {
            var references = getFunctionReferences(func, sourceFile, program, cancellationToken);
            return references && inferTypeFromReferences(program, references, cancellationToken).parameters(func) ||
                func.parameters.map(function (p) { return ({
                    declaration: p,
                    type: ts.isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : program.getTypeChecker().getAnyType()
                }); });
        }
        function getFunctionReferences(containingFunction, sourceFile, program, cancellationToken) {
            var searchToken;
            switch (containingFunction.kind) {
                case 162 /* Constructor */:
                    searchToken = ts.findChildOfKind(containingFunction, 129 /* ConstructorKeyword */, sourceFile);
                    break;
                case 202 /* ArrowFunction */:
                case 201 /* FunctionExpression */:
                    var parent = containingFunction.parent;
                    searchToken = ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name) ?
                        parent.name :
                        containingFunction.name;
                    break;
                case 244 /* FunctionDeclaration */:
                case 161 /* MethodDeclaration */:
                    searchToken = containingFunction.name;
                    break;
            }
            if (!searchToken) {
                return undefined;
            }
            return getReferences(searchToken, program, cancellationToken);
        }
        function inferTypeFromReferences(program, references, cancellationToken) {
            var checker = program.getTypeChecker();
            var builtinConstructors = {
                string: function () { return checker.getStringType(); },
                number: function () { return checker.getNumberType(); },
                Array: function (t) { return checker.createArrayType(t); },
                Promise: function (t) { return checker.createPromiseType(t); },
            };
            var builtins = [
                checker.getStringType(),
                checker.getNumberType(),
                checker.createArrayType(checker.getAnyType()),
                checker.createPromiseType(checker.getAnyType()),
            ];
            return {
                single: single,
                parameters: parameters,
                thisParameter: thisParameter,
            };
            function createEmptyUsage() {
                return {
                    isNumber: undefined,
                    isString: undefined,
                    isNumberOrString: undefined,
                    candidateTypes: undefined,
                    properties: undefined,
                    calls: undefined,
                    constructs: undefined,
                    numberIndex: undefined,
                    stringIndex: undefined,
                    candidateThisTypes: undefined,
                    inferredTypes: undefined,
                };
            }
            function combineUsages(usages) {
                var combinedProperties = ts.createUnderscoreEscapedMap();
                for (var _i = 0, usages_1 = usages; _i < usages_1.length; _i++) {
                    var u = usages_1[_i];
                    if (u.properties) {
                        u.properties.forEach(function (p, name) {
                            if (!combinedProperties.has(name)) {
                                combinedProperties.set(name, []);
                            }
                            combinedProperties.get(name).push(p);
                        });
                    }
                }
                var properties = ts.createUnderscoreEscapedMap();
                combinedProperties.forEach(function (ps, name) {
                    properties.set(name, combineUsages(ps));
                });
                return {
                    isNumber: usages.some(function (u) { return u.isNumber; }),
                    isString: usages.some(function (u) { return u.isString; }),
                    isNumberOrString: usages.some(function (u) { return u.isNumberOrString; }),
                    candidateTypes: ts.flatMap(usages, function (u) { return u.candidateTypes; }),
                    properties: properties,
                    calls: ts.flatMap(usages, function (u) { return u.calls; }),
                    constructs: ts.flatMap(usages, function (u) { return u.constructs; }),
                    numberIndex: ts.forEach(usages, function (u) { return u.numberIndex; }),
                    stringIndex: ts.forEach(usages, function (u) { return u.stringIndex; }),
                    candidateThisTypes: ts.flatMap(usages, function (u) { return u.candidateThisTypes; }),
                    inferredTypes: undefined,
                };
            }
            function single() {
                return combineTypes(inferTypesFromReferencesSingle(references));
            }
            function parameters(declaration) {
                if (references.length === 0 || !declaration.parameters) {
                    return undefined;
                }
                var usage = createEmptyUsage();
                for (var _i = 0, references_2 = references; _i < references_2.length; _i++) {
                    var reference = references_2[_i];
                    cancellationToken.throwIfCancellationRequested();
                    calculateUsageOfNode(reference, usage);
                }
                var calls = __spreadArrays(usage.constructs || [], usage.calls || []);
                return declaration.parameters.map(function (parameter, parameterIndex) {
                    var types = [];
                    var isRest = ts.isRestParameter(parameter);
                    var isOptional = false;
                    for (var _i = 0, calls_1 = calls; _i < calls_1.length; _i++) {
                        var call = calls_1[_i];
                        if (call.argumentTypes.length <= parameterIndex) {
                            isOptional = ts.isInJSFile(declaration);
                            types.push(checker.getUndefinedType());
                        }
                        else if (isRest) {
                            for (var i = parameterIndex; i < call.argumentTypes.length; i++) {
                                types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[i]));
                            }
                        }
                        else {
                            types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[parameterIndex]));
                        }
                    }
                    if (ts.isIdentifier(parameter.name)) {
                        var inferred = inferTypesFromReferencesSingle(getReferences(parameter.name, program, cancellationToken));
                        types.push.apply(types, (isRest ? ts.mapDefined(inferred, checker.getElementTypeOfArrayType) : inferred));
                    }
                    var type = combineTypes(types);
                    return {
                        type: isRest ? checker.createArrayType(type) : type,
                        isOptional: isOptional && !isRest,
                        declaration: parameter
                    };
                });
            }
            function thisParameter() {
                var usage = createEmptyUsage();
                for (var _i = 0, references_3 = references; _i < references_3.length; _i++) {
                    var reference = references_3[_i];
                    cancellationToken.throwIfCancellationRequested();
                    calculateUsageOfNode(reference, usage);
                }
                return combineTypes(usage.candidateThisTypes || ts.emptyArray);
            }
            function inferTypesFromReferencesSingle(references) {
                var usage = createEmptyUsage();
                for (var _i = 0, references_4 = references; _i < references_4.length; _i++) {
                    var reference = references_4[_i];
                    cancellationToken.throwIfCancellationRequested();
                    calculateUsageOfNode(reference, usage);
                }
                return inferTypes(usage);
            }
            function calculateUsageOfNode(node, usage) {
                while (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
                    node = node.parent;
                }
                switch (node.parent.kind) {
                    case 226 /* ExpressionStatement */:
                        inferTypeFromExpressionStatement(node, usage);
                        break;
                    case 208 /* PostfixUnaryExpression */:
                        usage.isNumber = true;
                        break;
                    case 207 /* PrefixUnaryExpression */:
                        inferTypeFromPrefixUnaryExpression(node.parent, usage);
                        break;
                    case 209 /* BinaryExpression */:
                        inferTypeFromBinaryExpression(node, node.parent, usage);
                        break;
                    case 277 /* CaseClause */:
                    case 278 /* DefaultClause */:
                        inferTypeFromSwitchStatementLabel(node.parent, usage);
                        break;
                    case 196 /* CallExpression */:
                    case 197 /* NewExpression */:
                        if (node.parent.expression === node) {
                            inferTypeFromCallExpression(node.parent, usage);
                        }
                        else {
                            inferTypeFromContextualType(node, usage);
                        }
                        break;
                    case 194 /* PropertyAccessExpression */:
                        inferTypeFromPropertyAccessExpression(node.parent, usage);
                        break;
                    case 195 /* ElementAccessExpression */:
                        inferTypeFromPropertyElementExpression(node.parent, node, usage);
                        break;
                    case 281 /* PropertyAssignment */:
                    case 282 /* ShorthandPropertyAssignment */:
                        inferTypeFromPropertyAssignment(node.parent, usage);
                        break;
                    case 159 /* PropertyDeclaration */:
                        inferTypeFromPropertyDeclaration(node.parent, usage);
                        break;
                    case 242 /* VariableDeclaration */: {
                        var _a = node.parent, name = _a.name, initializer = _a.initializer;
                        if (node === name) {
                            if (initializer) { // This can happen for `let x = null;` which still has an implicit-any error.
                                addCandidateType(usage, checker.getTypeAtLocation(initializer));
                            }
                            break;
                        }
                    }
                    // falls through
                    default:
                        return inferTypeFromContextualType(node, usage);
                }
            }
            function inferTypeFromContextualType(node, usage) {
                if (ts.isExpressionNode(node)) {
                    addCandidateType(usage, checker.getContextualType(node));
                }
            }
            function inferTypeFromExpressionStatement(node, usage) {
                addCandidateType(usage, ts.isCallExpression(node) ? checker.getVoidType() : checker.getAnyType());
            }
            function inferTypeFromPrefixUnaryExpression(node, usage) {
                switch (node.operator) {
                    case 45 /* PlusPlusToken */:
                    case 46 /* MinusMinusToken */:
                    case 40 /* MinusToken */:
                    case 54 /* TildeToken */:
                        usage.isNumber = true;
                        break;
                    case 39 /* PlusToken */:
                        usage.isNumberOrString = true;
                        break;
                    // case SyntaxKind.ExclamationToken:
                    // no inferences here;
                }
            }
            function inferTypeFromBinaryExpression(node, parent, usage) {
                switch (parent.operatorToken.kind) {
                    // ExponentiationOperator
                    case 42 /* AsteriskAsteriskToken */:
                    // MultiplicativeOperator
                    // falls through
                    case 41 /* AsteriskToken */:
                    case 43 /* SlashToken */:
                    case 44 /* PercentToken */:
                    // ShiftOperator
                    // falls through
                    case 47 /* LessThanLessThanToken */:
                    case 48 /* GreaterThanGreaterThanToken */:
                    case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                    // BitwiseOperator
                    // falls through
                    case 50 /* AmpersandToken */:
                    case 51 /* BarToken */:
                    case 52 /* CaretToken */:
                    // CompoundAssignmentOperator
                    // falls through
                    case 64 /* MinusEqualsToken */:
                    case 66 /* AsteriskAsteriskEqualsToken */:
                    case 65 /* AsteriskEqualsToken */:
                    case 67 /* SlashEqualsToken */:
                    case 68 /* PercentEqualsToken */:
                    case 72 /* AmpersandEqualsToken */:
                    case 73 /* BarEqualsToken */:
                    case 74 /* CaretEqualsToken */:
                    case 69 /* LessThanLessThanEqualsToken */:
                    case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 70 /* GreaterThanGreaterThanEqualsToken */:
                    // AdditiveOperator
                    // falls through
                    case 40 /* MinusToken */:
                    // RelationalOperator
                    // falls through
                    case 29 /* LessThanToken */:
                    case 32 /* LessThanEqualsToken */:
                    case 31 /* GreaterThanToken */:
                    case 33 /* GreaterThanEqualsToken */:
                        var operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
                        if (operandType.flags & 1056 /* EnumLike */) {
                            addCandidateType(usage, operandType);
                        }
                        else {
                            usage.isNumber = true;
                        }
                        break;
                    case 63 /* PlusEqualsToken */:
                    case 39 /* PlusToken */:
                        var otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
                        if (otherOperandType.flags & 1056 /* EnumLike */) {
                            addCandidateType(usage, otherOperandType);
                        }
                        else if (otherOperandType.flags & 296 /* NumberLike */) {
                            usage.isNumber = true;
                        }
                        else if (otherOperandType.flags & 132 /* StringLike */) {
                            usage.isString = true;
                        }
                        else if (otherOperandType.flags & 1 /* Any */) {
                            // do nothing, maybe we'll learn something elsewhere
                        }
                        else {
                            usage.isNumberOrString = true;
                        }
                        break;
                    //  AssignmentOperators
                    case 62 /* EqualsToken */:
                    case 34 /* EqualsEqualsToken */:
                    case 36 /* EqualsEqualsEqualsToken */:
                    case 37 /* ExclamationEqualsEqualsToken */:
                    case 35 /* ExclamationEqualsToken */:
                        addCandidateType(usage, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left));
                        break;
                    case 97 /* InKeyword */:
                        if (node === parent.left) {
                            usage.isString = true;
                        }
                        break;
                    // LogicalOperator Or NullishCoalescing
                    case 56 /* BarBarToken */:
                    case 60 /* QuestionQuestionToken */:
                        if (node === parent.left &&
                            (node.parent.parent.kind === 242 /* VariableDeclaration */ || ts.isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) {
                            // var x = x || {};
                            // TODO: use getFalsyflagsOfType
                            addCandidateType(usage, checker.getTypeAtLocation(parent.right));
                        }
                        break;
                    case 55 /* AmpersandAmpersandToken */:
                    case 27 /* CommaToken */:
                    case 98 /* InstanceOfKeyword */:
                        // nothing to infer here
                        break;
                }
            }
            function inferTypeFromSwitchStatementLabel(parent, usage) {
                addCandidateType(usage, checker.getTypeAtLocation(parent.parent.parent.expression));
            }
            function inferTypeFromCallExpression(parent, usage) {
                var call = {
                    argumentTypes: [],
                    return_: createEmptyUsage()
                };
                if (parent.arguments) {
                    for (var _i = 0, _a = parent.arguments; _i < _a.length; _i++) {
                        var argument = _a[_i];
                        call.argumentTypes.push(checker.getTypeAtLocation(argument));
                    }
                }
                calculateUsageOfNode(parent, call.return_);
                if (parent.kind === 196 /* CallExpression */) {
                    (usage.calls || (usage.calls = [])).push(call);
                }
                else {
                    (usage.constructs || (usage.constructs = [])).push(call);
                }
            }
            function inferTypeFromPropertyAccessExpression(parent, usage) {
                var name = ts.escapeLeadingUnderscores(parent.name.text);
                if (!usage.properties) {
                    usage.properties = ts.createUnderscoreEscapedMap();
                }
                var propertyUsage = usage.properties.get(name) || createEmptyUsage();
                calculateUsageOfNode(parent, propertyUsage);
                usage.properties.set(name, propertyUsage);
            }
            function inferTypeFromPropertyElementExpression(parent, node, usage) {
                if (node === parent.argumentExpression) {
                    usage.isNumberOrString = true;
                    return;
                }
                else {
                    var indexType = checker.getTypeAtLocation(parent.argumentExpression);
                    var indexUsage = createEmptyUsage();
                    calculateUsageOfNode(parent, indexUsage);
                    if (indexType.flags & 296 /* NumberLike */) {
                        usage.numberIndex = indexUsage;
                    }
                    else {
                        usage.stringIndex = indexUsage;
                    }
                }
            }
            function inferTypeFromPropertyAssignment(assignment, usage) {
                var nodeWithRealType = ts.isVariableDeclaration(assignment.parent.parent) ?
                    assignment.parent.parent :
                    assignment.parent;
                addCandidateThisType(usage, checker.getTypeAtLocation(nodeWithRealType));
            }
            function inferTypeFromPropertyDeclaration(declaration, usage) {
                addCandidateThisType(usage, checker.getTypeAtLocation(declaration.parent));
            }
            function removeLowPriorityInferences(inferences, priorities) {
                var toRemove = [];
                for (var _i = 0, inferences_1 = inferences; _i < inferences_1.length; _i++) {
                    var i = inferences_1[_i];
                    for (var _a = 0, priorities_1 = priorities; _a < priorities_1.length; _a++) {
                        var _b = priorities_1[_a], high = _b.high, low = _b.low;
                        if (high(i)) {
                            ts.Debug.assert(!low(i), "Priority can't have both low and high");
                            toRemove.push(low);
                        }
                    }
                }
                return inferences.filter(function (i) { return toRemove.every(function (f) { return !f(i); }); });
            }
            function combineFromUsage(usage) {
                return combineTypes(inferTypes(usage));
            }
            function combineTypes(inferences) {
                if (!inferences.length)
                    return checker.getAnyType();
                // 1. string or number individually override string | number
                // 2. non-any, non-void overrides any or void
                // 3. non-nullable, non-any, non-void, non-anonymous overrides anonymous types
                var stringNumber = checker.getUnionType([checker.getStringType(), checker.getNumberType()]);
                var priorities = [
                    {
                        high: function (t) { return t === checker.getStringType() || t === checker.getNumberType(); },
                        low: function (t) { return t === stringNumber; }
                    },
                    {
                        high: function (t) { return !(t.flags & (1 /* Any */ | 16384 /* Void */)); },
                        low: function (t) { return !!(t.flags & (1 /* Any */ | 16384 /* Void */)); }
                    },
                    {
                        high: function (t) { return !(t.flags & (98304 /* Nullable */ | 1 /* Any */ | 16384 /* Void */)) && !(ts.getObjectFlags(t) & 16 /* Anonymous */); },
                        low: function (t) { return !!(ts.getObjectFlags(t) & 16 /* Anonymous */); }
                    }
                ];
                var good = removeLowPriorityInferences(inferences, priorities);
                var anons = good.filter(function (i) { return ts.getObjectFlags(i) & 16 /* Anonymous */; });
                if (anons.length) {
                    good = good.filter(function (i) { return !(ts.getObjectFlags(i) & 16 /* Anonymous */); });
                    good.push(combineAnonymousTypes(anons));
                }
                return checker.getWidenedType(checker.getUnionType(good.map(checker.getBaseTypeOfLiteralType), 2 /* Subtype */));
            }
            function combineAnonymousTypes(anons) {
                if (anons.length === 1) {
                    return anons[0];
                }
                var calls = [];
                var constructs = [];
                var stringIndices = [];
                var numberIndices = [];
                var stringIndexReadonly = false;
                var numberIndexReadonly = false;
                var props = ts.createMultiMap();
                for (var _i = 0, anons_1 = anons; _i < anons_1.length; _i++) {
                    var anon = anons_1[_i];
                    for (var _a = 0, _b = checker.getPropertiesOfType(anon); _a < _b.length; _a++) {
                        var p = _b[_a];
                        props.add(p.name, checker.getTypeOfSymbolAtLocation(p, p.valueDeclaration));
                    }
                    calls.push.apply(calls, checker.getSignaturesOfType(anon, 0 /* Call */));
                    constructs.push.apply(constructs, checker.getSignaturesOfType(anon, 1 /* Construct */));
                    if (anon.stringIndexInfo) {
                        stringIndices.push(anon.stringIndexInfo.type);
                        stringIndexReadonly = stringIndexReadonly || anon.stringIndexInfo.isReadonly;
                    }
                    if (anon.numberIndexInfo) {
                        numberIndices.push(anon.numberIndexInfo.type);
                        numberIndexReadonly = numberIndexReadonly || anon.numberIndexInfo.isReadonly;
                    }
                }
                var members = ts.mapEntries(props, function (name, types) {
                    var isOptional = types.length < anons.length ? 16777216 /* Optional */ : 0;
                    var s = checker.createSymbol(4 /* Property */ | isOptional, name);
                    s.type = checker.getUnionType(types);
                    return [name, s];
                });
                return checker.createAnonymousType(anons[0].symbol, members, calls, constructs, stringIndices.length ? checker.createIndexInfo(checker.getUnionType(stringIndices), stringIndexReadonly) : undefined, numberIndices.length ? checker.createIndexInfo(checker.getUnionType(numberIndices), numberIndexReadonly) : undefined);
            }
            function inferTypes(usage) {
                var _a, _b, _c;
                var types = [];
                if (usage.isNumber) {
                    types.push(checker.getNumberType());
                }
                if (usage.isString) {
                    types.push(checker.getStringType());
                }
                if (usage.isNumberOrString) {
                    types.push(checker.getUnionType([checker.getStringType(), checker.getNumberType()]));
                }
                if (usage.numberIndex) {
                    types.push(checker.createArrayType(combineFromUsage(usage.numberIndex)));
                }
                if (((_a = usage.properties) === null || _a === void 0 ? void 0 : _a.size) || ((_b = usage.calls) === null || _b === void 0 ? void 0 : _b.length) || ((_c = usage.constructs) === null || _c === void 0 ? void 0 : _c.length) || usage.stringIndex) {
                    types.push(inferStructuralType(usage));
                }
                types.push.apply(types, (usage.candidateTypes || []).map(function (t) { return checker.getBaseTypeOfLiteralType(t); }));
                types.push.apply(types, inferNamedTypesFromProperties(usage));
                return types;
            }
            function inferStructuralType(usage) {
                var members = ts.createUnderscoreEscapedMap();
                if (usage.properties) {
                    usage.properties.forEach(function (u, name) {
                        var symbol = checker.createSymbol(4 /* Property */, name);
                        symbol.type = combineFromUsage(u);
                        members.set(name, symbol);
                    });
                }
                var callSignatures = usage.calls ? [getSignatureFromCalls(usage.calls)] : [];
                var constructSignatures = usage.constructs ? [getSignatureFromCalls(usage.constructs)] : [];
                var stringIndexInfo = usage.stringIndex && checker.createIndexInfo(combineFromUsage(usage.stringIndex), /*isReadonly*/ false);
                return checker.createAnonymousType(/*symbol*/ undefined, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined);
            }
            function inferNamedTypesFromProperties(usage) {
                if (!usage.properties || !usage.properties.size)
                    return [];
                var types = builtins.filter(function (t) { return allPropertiesAreAssignableToUsage(t, usage); });
                if (0 < types.length && types.length < 3) {
                    return types.map(function (t) { return inferInstantiationFromUsage(t, usage); });
                }
                return [];
            }
            function allPropertiesAreAssignableToUsage(type, usage) {
                if (!usage.properties)
                    return false;
                return !ts.forEachEntry(usage.properties, function (propUsage, name) {
                    var source = checker.getTypeOfPropertyOfType(type, name);
                    if (!source) {
                        return true;
                    }
                    if (propUsage.calls) {
                        var sigs = checker.getSignaturesOfType(source, 0 /* Call */);
                        return !sigs.length || !checker.isTypeAssignableTo(source, getFunctionFromCalls(propUsage.calls));
                    }
                    else {
                        return !checker.isTypeAssignableTo(source, combineFromUsage(propUsage));
                    }
                });
            }
            /**
             * inference is limited to
             * 1. generic types with a single parameter
             * 2. inference to/from calls with a single signature
             */
            function inferInstantiationFromUsage(type, usage) {
                if (!(ts.getObjectFlags(type) & 4 /* Reference */) || !usage.properties) {
                    return type;
                }
                var generic = type.target;
                var singleTypeParameter = ts.singleOrUndefined(generic.typeParameters);
                if (!singleTypeParameter)
                    return type;
                var types = [];
                usage.properties.forEach(function (propUsage, name) {
                    var genericPropertyType = checker.getTypeOfPropertyOfType(generic, name);
                    ts.Debug.assert(!!genericPropertyType, "generic should have all the properties of its reference.");
                    types.push.apply(types, inferTypeParameters(genericPropertyType, combineFromUsage(propUsage), singleTypeParameter));
                });
                return builtinConstructors[type.symbol.escapedName](combineTypes(types));
            }
            function inferTypeParameters(genericType, usageType, typeParameter) {
                if (genericType === typeParameter) {
                    return [usageType];
                }
                else if (genericType.flags & 3145728 /* UnionOrIntersection */) {
                    return ts.flatMap(genericType.types, function (t) { return inferTypeParameters(t, usageType, typeParameter); });
                }
                else if (ts.getObjectFlags(genericType) & 4 /* Reference */ && ts.getObjectFlags(usageType) & 4 /* Reference */) {
                    // this is wrong because we need a reference to the targetType to, so we can check that it's also a reference
                    var genericArgs = checker.getTypeArguments(genericType);
                    var usageArgs = checker.getTypeArguments(usageType);
                    var types = [];
                    if (genericArgs && usageArgs) {
                        for (var i = 0; i < genericArgs.length; i++) {
                            if (usageArgs[i]) {
                                types.push.apply(types, inferTypeParameters(genericArgs[i], usageArgs[i], typeParameter));
                            }
                        }
                    }
                    return types;
                }
                var genericSigs = checker.getSignaturesOfType(genericType, 0 /* Call */);
                var usageSigs = checker.getSignaturesOfType(usageType, 0 /* Call */);
                if (genericSigs.length === 1 && usageSigs.length === 1) {
                    return inferFromSignatures(genericSigs[0], usageSigs[0], typeParameter);
                }
                return [];
            }
            function inferFromSignatures(genericSig, usageSig, typeParameter) {
                var types = [];
                for (var i = 0; i < genericSig.parameters.length; i++) {
                    var genericParam = genericSig.parameters[i];
                    var usageParam = usageSig.parameters[i];
                    var isRest = genericSig.declaration && ts.isRestParameter(genericSig.declaration.parameters[i]);
                    if (!usageParam) {
                        break;
                    }
                    var genericParamType = checker.getTypeOfSymbolAtLocation(genericParam, genericParam.valueDeclaration);
                    var elementType = isRest && checker.getElementTypeOfArrayType(genericParamType);
                    if (elementType) {
                        genericParamType = elementType;
                    }
                    var targetType = usageParam.type || checker.getTypeOfSymbolAtLocation(usageParam, usageParam.valueDeclaration);
                    types.push.apply(types, inferTypeParameters(genericParamType, targetType, typeParameter));
                }
                var genericReturn = checker.getReturnTypeOfSignature(genericSig);
                var usageReturn = checker.getReturnTypeOfSignature(usageSig);
                types.push.apply(types, inferTypeParameters(genericReturn, usageReturn, typeParameter));
                return types;
            }
            function getFunctionFromCalls(calls) {
                return checker.createAnonymousType(/*symbol*/ undefined, ts.createSymbolTable(), [getSignatureFromCalls(calls)], ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
            }
            function getSignatureFromCalls(calls) {
                var parameters = [];
                var length = Math.max.apply(Math, calls.map(function (c) { return c.argumentTypes.length; }));
                var _loop_14 = function (i) {
                    var symbol = checker.createSymbol(1 /* FunctionScopedVariable */, ts.escapeLeadingUnderscores("arg" + i));
                    symbol.type = combineTypes(calls.map(function (call) { return call.argumentTypes[i] || checker.getUndefinedType(); }));
                    if (calls.some(function (call) { return call.argumentTypes[i] === undefined; })) {
                        symbol.flags |= 16777216 /* Optional */;
                    }
                    parameters.push(symbol);
                };
                for (var i = 0; i < length; i++) {
                    _loop_14(i);
                }
                var returnType = combineFromUsage(combineUsages(calls.map(function (call) { return call.return_; })));
                // TODO: GH#18217
                return checker.createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, length, 0 /* None */);
            }
            function addCandidateType(usage, type) {
                if (type && !(type.flags & 1 /* Any */) && !(type.flags & 131072 /* Never */)) {
                    (usage.candidateTypes || (usage.candidateTypes = [])).push(type);
                }
            }
            function addCandidateThisType(usage, type) {
                if (type && !(type.flags & 1 /* Any */) && !(type.flags & 131072 /* Never */)) {
                    (usage.candidateThisTypes || (usage.candidateThisTypes = [])).push(type);
                }
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "disableJsDiagnostics";
        var fixId = "disableJsDiagnostics";
        var errorCodes = ts.mapDefined(Object.keys(ts.Diagnostics), function (key) {
            var diag = ts.Diagnostics[key];
            return diag.category === ts.DiagnosticCategory.Error ? diag.code : undefined;
        });
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, program = context.program, span = context.span, host = context.host, formatContext = context.formatContext;
                if (!ts.isInJSFile(sourceFile) || !ts.isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
                    return undefined;
                }
                var newLineCharacter = sourceFile.checkJsDirective ? "" : ts.getNewLineOrDefaultFromHost(host, formatContext.options);
                var fixes = [
                    // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file.
                    codefix.createCodeFixActionWithoutFixAll(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [
                            ts.createTextChange(sourceFile.checkJsDirective
                                ? ts.createTextSpanFromBounds(sourceFile.checkJsDirective.pos, sourceFile.checkJsDirective.end)
                                : ts.createTextSpan(0, 0), "// @ts-nocheck" + newLineCharacter),
                        ])], ts.Diagnostics.Disable_checking_for_this_file),
                ];
                if (ts.textChanges.isValidLocationToAddComment(sourceFile, span.start)) {
                    fixes.unshift(codefix.createCodeFixAction(fixName, ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, sourceFile, span.start); }), ts.Diagnostics.Ignore_this_error_message, fixId, ts.Diagnostics.Add_ts_ignore_to_all_error_messages));
                }
                return fixes;
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                var seenLines = ts.createMap();
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    if (ts.textChanges.isValidLocationToAddComment(diag.file, diag.start)) {
                        makeChange(changes, diag.file, diag.start, seenLines);
                    }
                });
            },
        });
        function makeChange(changes, sourceFile, position, seenLines) {
            var lineNumber = ts.getLineAndCharacterOfPosition(sourceFile, position).line;
            // Only need to add `// @ts-ignore` for a line once.
            if (!seenLines || ts.addToSeen(seenLines, lineNumber)) {
                changes.insertCommentBeforeLine(sourceFile, lineNumber, position, " @ts-ignore");
            }
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        /**
         * Finds members of the resolved type that are missing in the class pointed to by class decl
         * and generates source code for the missing members.
         * @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
         * @param importAdder If provided, type annotations will use identifier type references instead of ImportTypeNodes, and the missing imports will be added to the importAdder.
         * @returns Empty string iff there are no member insertions.
         */
        function createMissingMemberNodes(classDeclaration, possiblyMissingSymbols, context, preferences, importAdder, addClassElement) {
            var classMembers = classDeclaration.symbol.members;
            for (var _i = 0, possiblyMissingSymbols_1 = possiblyMissingSymbols; _i < possiblyMissingSymbols_1.length; _i++) {
                var symbol = possiblyMissingSymbols_1[_i];
                if (!classMembers.has(symbol.escapedName)) {
                    addNewNodeForMemberSymbol(symbol, classDeclaration, context, preferences, importAdder, addClassElement);
                }
            }
        }
        codefix.createMissingMemberNodes = createMissingMemberNodes;
        function getNoopSymbolTrackerWithResolver(context) {
            return {
                trackSymbol: ts.noop,
                moduleResolverHost: ts.getModuleSpecifierResolverHost(context.program, context.host),
            };
        }
        codefix.getNoopSymbolTrackerWithResolver = getNoopSymbolTrackerWithResolver;
        /**
         * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
         */
        function addNewNodeForMemberSymbol(symbol, enclosingDeclaration, context, preferences, importAdder, addClassElement) {
            var declarations = symbol.getDeclarations();
            if (!(declarations && declarations.length)) {
                return undefined;
            }
            var checker = context.program.getTypeChecker();
            var scriptTarget = ts.getEmitScriptTarget(context.program.getCompilerOptions());
            var declaration = declarations[0];
            var name = ts.getSynthesizedDeepClone(ts.getNameOfDeclaration(declaration), /*includeTrivia*/ false);
            var visibilityModifier = createVisibilityModifier(ts.getModifierFlags(declaration));
            var modifiers = visibilityModifier ? ts.createNodeArray([visibilityModifier]) : undefined;
            var type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration));
            var optional = !!(symbol.flags & 16777216 /* Optional */);
            var ambient = !!(enclosingDeclaration.flags & 8388608 /* Ambient */);
            switch (declaration.kind) {
                case 158 /* PropertySignature */:
                case 159 /* PropertyDeclaration */:
                    var flags = preferences.quotePreference === "single" ? 268435456 /* UseSingleQuotesForStringLiteralType */ : undefined;
                    var typeNode = checker.typeToTypeNode(type, enclosingDeclaration, flags, getNoopSymbolTrackerWithResolver(context));
                    if (importAdder) {
                        var importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, scriptTarget);
                        if (importableReference) {
                            typeNode = importableReference.typeReference;
                            importSymbols(importAdder, importableReference.symbols);
                        }
                    }
                    addClassElement(ts.createProperty(
                    /*decorators*/ undefined, modifiers, name, optional ? ts.createToken(57 /* QuestionToken */) : undefined, typeNode, 
                    /*initializer*/ undefined));
                    break;
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */: {
                    var typeNode_1 = checker.typeToTypeNode(type, enclosingDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context));
                    var allAccessors = ts.getAllAccessorDeclarations(declarations, declaration);
                    var orderedAccessors = allAccessors.secondAccessor
                        ? [allAccessors.firstAccessor, allAccessors.secondAccessor]
                        : [allAccessors.firstAccessor];
                    if (importAdder) {
                        var importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode_1, type, scriptTarget);
                        if (importableReference) {
                            typeNode_1 = importableReference.typeReference;
                            importSymbols(importAdder, importableReference.symbols);
                        }
                    }
                    for (var _i = 0, orderedAccessors_1 = orderedAccessors; _i < orderedAccessors_1.length; _i++) {
                        var accessor = orderedAccessors_1[_i];
                        if (ts.isGetAccessorDeclaration(accessor)) {
                            addClassElement(ts.createGetAccessor(
                            /*decorators*/ undefined, modifiers, name, ts.emptyArray, typeNode_1, ambient ? undefined : createStubbedMethodBody(preferences)));
                        }
                        else {
                            ts.Debug.assertNode(accessor, ts.isSetAccessorDeclaration, "The counterpart to a getter should be a setter");
                            var parameter = ts.getSetAccessorValueParameter(accessor);
                            var parameterName = parameter && ts.isIdentifier(parameter.name) ? ts.idText(parameter.name) : undefined;
                            addClassElement(ts.createSetAccessor(
                            /*decorators*/ undefined, modifiers, name, createDummyParameters(1, [parameterName], [typeNode_1], 1, /*inJs*/ false), ambient ? undefined : createStubbedMethodBody(preferences)));
                        }
                    }
                    break;
                }
                case 160 /* MethodSignature */:
                case 161 /* MethodDeclaration */:
                    // The signature for the implementation appears as an entry in `signatures` iff
                    // there is only one signature.
                    // If there are overloads and an implementation signature, it appears as an
                    // extra declaration that isn't a signature for `type`.
                    // If there is more than one overload but no implementation signature
                    // (eg: an abstract method or interface declaration), there is a 1-1
                    // correspondence of declarations and signatures.
                    var signatures = checker.getSignaturesOfType(type, 0 /* Call */);
                    if (!ts.some(signatures)) {
                        break;
                    }
                    if (declarations.length === 1) {
                        ts.Debug.assert(signatures.length === 1, "One declaration implies one signature");
                        var signature = signatures[0];
                        outputMethod(signature, modifiers, name, ambient ? undefined : createStubbedMethodBody(preferences));
                        break;
                    }
                    for (var _a = 0, signatures_1 = signatures; _a < signatures_1.length; _a++) {
                        var signature = signatures_1[_a];
                        // Need to ensure nodes are fresh each time so they can have different positions.
                        outputMethod(signature, ts.getSynthesizedDeepClones(modifiers, /*includeTrivia*/ false), ts.getSynthesizedDeepClone(name, /*includeTrivia*/ false));
                    }
                    if (!ambient) {
                        if (declarations.length > signatures.length) {
                            var signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1]);
                            outputMethod(signature, modifiers, name, createStubbedMethodBody(preferences));
                        }
                        else {
                            ts.Debug.assert(declarations.length === signatures.length, "Declarations and signatures should match count");
                            addClassElement(createMethodImplementingSignatures(signatures, name, optional, modifiers, preferences));
                        }
                    }
                    break;
            }
            function outputMethod(signature, modifiers, name, body) {
                var method = signatureToMethodDeclaration(context, signature, enclosingDeclaration, modifiers, name, optional, body, importAdder);
                if (method)
                    addClassElement(method);
            }
        }
        function signatureToMethodDeclaration(context, signature, enclosingDeclaration, modifiers, name, optional, body, importAdder) {
            var program = context.program;
            var checker = program.getTypeChecker();
            var scriptTarget = ts.getEmitScriptTarget(program.getCompilerOptions());
            var signatureDeclaration = checker.signatureToSignatureDeclaration(signature, 161 /* MethodDeclaration */, enclosingDeclaration, 1 /* NoTruncation */ | 256 /* SuppressAnyReturnType */, getNoopSymbolTrackerWithResolver(context));
            if (!signatureDeclaration) {
                return undefined;
            }
            if (importAdder) {
                if (signatureDeclaration.typeParameters) {
                    ts.forEach(signatureDeclaration.typeParameters, function (typeParameterDecl, i) {
                        var typeParameter = signature.typeParameters[i];
                        if (typeParameterDecl.constraint) {
                            var importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeParameterDecl.constraint, typeParameter.constraint, scriptTarget);
                            if (importableReference) {
                                typeParameterDecl.constraint = importableReference.typeReference;
                                importSymbols(importAdder, importableReference.symbols);
                            }
                        }
                        if (typeParameterDecl.default) {
                            var importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeParameterDecl.default, typeParameter.default, scriptTarget);
                            if (importableReference) {
                                typeParameterDecl.default = importableReference.typeReference;
                                importSymbols(importAdder, importableReference.symbols);
                            }
                        }
                    });
                }
                ts.forEach(signatureDeclaration.parameters, function (parameterDecl, i) {
                    var parameter = signature.parameters[i];
                    var importableReference = tryGetAutoImportableReferenceFromImportTypeNode(parameterDecl.type, checker.getTypeAtLocation(parameter.valueDeclaration), scriptTarget);
                    if (importableReference) {
                        parameterDecl.type = importableReference.typeReference;
                        importSymbols(importAdder, importableReference.symbols);
                    }
                });
                if (signatureDeclaration.type) {
                    var importableReference = tryGetAutoImportableReferenceFromImportTypeNode(signatureDeclaration.type, signature.resolvedReturnType, scriptTarget);
                    if (importableReference) {
                        signatureDeclaration.type = importableReference.typeReference;
                        importSymbols(importAdder, importableReference.symbols);
                    }
                }
            }
            signatureDeclaration.decorators = undefined;
            signatureDeclaration.modifiers = modifiers;
            signatureDeclaration.name = name;
            signatureDeclaration.questionToken = optional ? ts.createToken(57 /* QuestionToken */) : undefined;
            signatureDeclaration.body = body;
            return signatureDeclaration;
        }
        function createMethodFromCallExpression(context, call, methodName, inJs, makeStatic, contextNode, importAdder) {
            var body = !ts.isInterfaceDeclaration(contextNode);
            var typeArguments = call.typeArguments, args = call.arguments, parent = call.parent;
            var scriptTarget = ts.getEmitScriptTarget(context.program.getCompilerOptions());
            var checker = context.program.getTypeChecker();
            var tracker = getNoopSymbolTrackerWithResolver(context);
            var types = ts.map(args, function (arg) {
                return typeToAutoImportableTypeNode(checker, importAdder, checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg)), contextNode, scriptTarget, /*flags*/ undefined, tracker);
            });
            var names = ts.map(args, function (arg) {
                return ts.isIdentifier(arg) ? arg.text : ts.isPropertyAccessExpression(arg) && ts.isIdentifier(arg.name) ? arg.name.text : undefined;
            });
            var contextualType = checker.getContextualType(call);
            var returnType = (inJs || !contextualType) ? undefined : checker.typeToTypeNode(contextualType, contextNode, /*flags*/ undefined, tracker);
            return ts.createMethod(
            /*decorators*/ undefined, 
            /*modifiers*/ makeStatic ? [ts.createToken(120 /* StaticKeyword */)] : undefined, 
            /*asteriskToken*/ ts.isYieldExpression(parent) ? ts.createToken(41 /* AsteriskToken */) : undefined, methodName, 
            /*questionToken*/ undefined, 
            /*typeParameters*/ inJs ? undefined : ts.map(typeArguments, function (_, i) {
                return ts.createTypeParameterDeclaration(84 /* T */ + typeArguments.length - 1 <= 90 /* Z */ ? String.fromCharCode(84 /* T */ + i) : "T" + i);
            }), 
            /*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs), 
            /*type*/ returnType, body ? createStubbedMethodBody(context.preferences) : undefined);
        }
        codefix.createMethodFromCallExpression = createMethodFromCallExpression;
        function typeToAutoImportableTypeNode(checker, importAdder, type, contextNode, scriptTarget, flags, tracker) {
            var typeNode = checker.typeToTypeNode(type, contextNode, flags, tracker);
            if (typeNode && ts.isImportTypeNode(typeNode)) {
                var importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, scriptTarget);
                if (importableReference) {
                    importSymbols(importAdder, importableReference.symbols);
                    return importableReference.typeReference;
                }
            }
            return typeNode;
        }
        codefix.typeToAutoImportableTypeNode = typeToAutoImportableTypeNode;
        function createDummyParameters(argCount, names, types, minArgumentCount, inJs) {
            var parameters = [];
            for (var i = 0; i < argCount; i++) {
                var newParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, 
                /*name*/ names && names[i] || "arg" + i, 
                /*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? ts.createToken(57 /* QuestionToken */) : undefined, 
                /*type*/ inJs ? undefined : types && types[i] || ts.createKeywordTypeNode(125 /* AnyKeyword */), 
                /*initializer*/ undefined);
                parameters.push(newParameter);
            }
            return parameters;
        }
        function createMethodImplementingSignatures(signatures, name, optional, modifiers, preferences) {
            /** This is *a* signature with the maximal number of arguments,
             * such that if there is a "maximal" signature without rest arguments,
             * this is one of them.
             */
            var maxArgsSignature = signatures[0];
            var minArgumentCount = signatures[0].minArgumentCount;
            var someSigHasRestParameter = false;
            for (var _i = 0, signatures_2 = signatures; _i < signatures_2.length; _i++) {
                var sig = signatures_2[_i];
                minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount);
                if (ts.signatureHasRestParameter(sig)) {
                    someSigHasRestParameter = true;
                }
                if (sig.parameters.length >= maxArgsSignature.parameters.length && (!ts.signatureHasRestParameter(sig) || ts.signatureHasRestParameter(maxArgsSignature))) {
                    maxArgsSignature = sig;
                }
            }
            var maxNonRestArgs = maxArgsSignature.parameters.length - (ts.signatureHasRestParameter(maxArgsSignature) ? 1 : 0);
            var maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(function (symbol) { return symbol.name; });
            var parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, /* types */ undefined, minArgumentCount, /*inJs*/ false);
            if (someSigHasRestParameter) {
                var anyArrayType = ts.createArrayTypeNode(ts.createKeywordTypeNode(125 /* AnyKeyword */));
                var restParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, ts.createToken(25 /* DotDotDotToken */), maxArgsParameterSymbolNames[maxNonRestArgs] || "rest", 
                /*questionToken*/ maxNonRestArgs >= minArgumentCount ? ts.createToken(57 /* QuestionToken */) : undefined, anyArrayType, 
                /*initializer*/ undefined);
                parameters.push(restParameter);
            }
            return createStubbedMethod(modifiers, name, optional, 
            /*typeParameters*/ undefined, parameters, 
            /*returnType*/ undefined, preferences);
        }
        function createStubbedMethod(modifiers, name, optional, typeParameters, parameters, returnType, preferences) {
            return ts.createMethod(
            /*decorators*/ undefined, modifiers, 
            /*asteriskToken*/ undefined, name, optional ? ts.createToken(57 /* QuestionToken */) : undefined, typeParameters, parameters, returnType, createStubbedMethodBody(preferences));
        }
        function createStubbedMethodBody(preferences) {
            return ts.createBlock([ts.createThrow(ts.createNew(ts.createIdentifier("Error"), 
                /*typeArguments*/ undefined, 
                // TODO Handle auto quote preference.
                [ts.createLiteral("Method not implemented.", /*isSingleQuote*/ preferences.quotePreference === "single")]))], 
            /*multiline*/ true);
        }
        function createVisibilityModifier(flags) {
            if (flags & 4 /* Public */) {
                return ts.createToken(119 /* PublicKeyword */);
            }
            else if (flags & 16 /* Protected */) {
                return ts.createToken(118 /* ProtectedKeyword */);
            }
            return undefined;
        }
        function setJsonCompilerOptionValues(changeTracker, configFile, options) {
            var tsconfigObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile);
            if (!tsconfigObjectLiteral)
                return undefined;
            var compilerOptionsProperty = findJsonProperty(tsconfigObjectLiteral, "compilerOptions");
            if (compilerOptionsProperty === undefined) {
                changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral(options.map(function (_a) {
                    var optionName = _a[0], optionValue = _a[1];
                    return createJsonPropertyAssignment(optionName, optionValue);
                }), /*multiLine*/ true)));
                return;
            }
            var compilerOptions = compilerOptionsProperty.initializer;
            if (!ts.isObjectLiteralExpression(compilerOptions)) {
                return;
            }
            for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
                var _a = options_1[_i], optionName = _a[0], optionValue = _a[1];
                var optionProperty = findJsonProperty(compilerOptions, optionName);
                if (optionProperty === undefined) {
                    changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue));
                }
                else {
                    changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue);
                }
            }
        }
        codefix.setJsonCompilerOptionValues = setJsonCompilerOptionValues;
        function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) {
            setJsonCompilerOptionValues(changeTracker, configFile, [[optionName, optionValue]]);
        }
        codefix.setJsonCompilerOptionValue = setJsonCompilerOptionValue;
        function createJsonPropertyAssignment(name, initializer) {
            return ts.createPropertyAssignment(ts.createStringLiteral(name), initializer);
        }
        codefix.createJsonPropertyAssignment = createJsonPropertyAssignment;
        function findJsonProperty(obj, name) {
            return ts.find(obj.properties, function (p) { return ts.isPropertyAssignment(p) && !!p.name && ts.isStringLiteral(p.name) && p.name.text === name; });
        }
        codefix.findJsonProperty = findJsonProperty;
        /**
         * Given an ImportTypeNode 'import("./a").SomeType<import("./b").OtherType<...>>',
         * returns an equivalent type reference node with any nested ImportTypeNodes also replaced
         * with type references, and a list of symbols that must be imported to use the type reference.
         */
        function tryGetAutoImportableReferenceFromImportTypeNode(importTypeNode, type, scriptTarget) {
            if (importTypeNode && ts.isLiteralImportTypeNode(importTypeNode) && importTypeNode.qualifier && (!type || type.symbol)) {
                // Symbol for the left-most thing after the dot
                var firstIdentifier = ts.getFirstIdentifier(importTypeNode.qualifier);
                var name = ts.getNameForExportedSymbol(firstIdentifier.symbol, scriptTarget);
                var qualifier = name !== firstIdentifier.text
                    ? replaceFirstIdentifierOfEntityName(importTypeNode.qualifier, ts.createIdentifier(name))
                    : importTypeNode.qualifier;
                var symbols_4 = [firstIdentifier.symbol];
                var typeArguments_1 = [];
                if (importTypeNode.typeArguments) {
                    importTypeNode.typeArguments.forEach(function (arg) {
                        var ref = tryGetAutoImportableReferenceFromImportTypeNode(arg, /*undefined*/ type, scriptTarget);
                        if (ref) {
                            symbols_4.push.apply(symbols_4, ref.symbols);
                            typeArguments_1.push(ref.typeReference);
                        }
                        else {
                            typeArguments_1.push(arg);
                        }
                    });
                }
                return {
                    symbols: symbols_4,
                    typeReference: ts.createTypeReferenceNode(qualifier, typeArguments_1)
                };
            }
        }
        codefix.tryGetAutoImportableReferenceFromImportTypeNode = tryGetAutoImportableReferenceFromImportTypeNode;
        function replaceFirstIdentifierOfEntityName(name, newIdentifier) {
            if (name.kind === 75 /* Identifier */) {
                return newIdentifier;
            }
            return ts.createQualifiedName(replaceFirstIdentifierOfEntityName(name.left, newIdentifier), name.right);
        }
        function importSymbols(importAdder, symbols) {
            symbols.forEach(function (s) { return importAdder.addImportFromExportedSymbol(s, /*usageIsTypeOnly*/ true); });
        }
        codefix.importSymbols = importSymbols;
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "invalidImportSyntax";
        function getCodeFixesForImportDeclaration(context, node) {
            var sourceFile = ts.getSourceFileOfNode(node);
            var namespace = ts.getNamespaceDeclarationNode(node);
            var opts = context.program.getCompilerOptions();
            var variations = [];
            // import Bluebird from "bluebird";
            variations.push(createAction(context, sourceFile, node, ts.makeImport(namespace.name, /*namedImports*/ undefined, node.moduleSpecifier, ts.getQuotePreference(sourceFile, context.preferences))));
            if (ts.getEmitModuleKind(opts) === ts.ModuleKind.CommonJS) {
                // import Bluebird = require("bluebird");
                variations.push(createAction(context, sourceFile, node, ts.createImportEqualsDeclaration(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, namespace.name, ts.createExternalModuleReference(node.moduleSpecifier))));
            }
            return variations;
        }
        function createAction(context, sourceFile, node, replacement) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, node, replacement); });
            return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]);
        }
        codefix.registerCodeFix({
            errorCodes: [
                ts.Diagnostics.This_expression_is_not_callable.code,
                ts.Diagnostics.This_expression_is_not_constructable.code,
            ],
            getCodeActions: getActionsForUsageOfInvalidImport
        });
        function getActionsForUsageOfInvalidImport(context) {
            var sourceFile = context.sourceFile;
            var targetKind = ts.Diagnostics.This_expression_is_not_callable.code === context.errorCode ? 196 /* CallExpression */ : 197 /* NewExpression */;
            var node = ts.findAncestor(ts.getTokenAtPosition(sourceFile, context.span.start), function (a) { return a.kind === targetKind; });
            if (!node) {
                return [];
            }
            var expr = node.expression;
            return getImportCodeFixesForExpression(context, expr);
        }
        codefix.registerCodeFix({
            errorCodes: [
                // The following error codes cover pretty much all assignability errors that could involve an expression
                ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code,
                ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1.code,
                ts.Diagnostics.Type_0_is_not_assignable_to_type_1.code,
                ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated.code,
                ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1.code,
                ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2.code,
                ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2.code,
                ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1.code,
                ts.Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2.code,
                ts.Diagnostics.Property_0_in_type_1_is_not_assignable_to_type_2.code,
                ts.Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property.code,
                ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1.code,
            ],
            getCodeActions: getActionsForInvalidImportLocation
        });
        function getActionsForInvalidImportLocation(context) {
            var sourceFile = context.sourceFile;
            var node = ts.findAncestor(ts.getTokenAtPosition(sourceFile, context.span.start), function (a) { return a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length); });
            if (!node) {
                return [];
            }
            return getImportCodeFixesForExpression(context, node);
        }
        function getImportCodeFixesForExpression(context, expr) {
            var type = context.program.getTypeChecker().getTypeAtLocation(expr);
            if (!(type.symbol && type.symbol.originatingImport)) {
                return [];
            }
            var fixes = [];
            var relatedImport = type.symbol.originatingImport; // TODO: GH#18217
            if (!ts.isImportCall(relatedImport)) {
                ts.addRange(fixes, getCodeFixesForImportDeclaration(context, relatedImport));
            }
            if (ts.isExpression(expr) && !(ts.isNamedDeclaration(expr.parent) && expr.parent.name === expr)) {
                var sourceFile_1 = context.sourceFile;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile_1, expr, ts.createPropertyAccess(expr, "default"), {}); });
                fixes.push(codefix.createCodeFixActionWithoutFixAll(fixName, changes, ts.Diagnostics.Use_synthetic_default_member));
            }
            return fixes;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixName = "strictClassInitialization";
        var fixIdAddDefiniteAssignmentAssertions = "addMissingPropertyDefiniteAssignmentAssertions";
        var fixIdAddUndefinedType = "addMissingPropertyUndefinedType";
        var fixIdAddInitializer = "addMissingPropertyInitializer";
        var errorCodes = [ts.Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var propertyDeclaration = getPropertyDeclaration(context.sourceFile, context.span.start);
                if (!propertyDeclaration)
                    return;
                var result = [
                    getActionForAddMissingUndefinedType(context, propertyDeclaration),
                    getActionForAddMissingDefiniteAssignmentAssertion(context, propertyDeclaration)
                ];
                ts.append(result, getActionForAddMissingInitializer(context, propertyDeclaration));
                return result;
            },
            fixIds: [fixIdAddDefiniteAssignmentAssertions, fixIdAddUndefinedType, fixIdAddInitializer],
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                    var propertyDeclaration = getPropertyDeclaration(diag.file, diag.start);
                    if (!propertyDeclaration)
                        return;
                    switch (context.fixId) {
                        case fixIdAddDefiniteAssignmentAssertions:
                            addDefiniteAssignmentAssertion(changes, diag.file, propertyDeclaration);
                            break;
                        case fixIdAddUndefinedType:
                            addUndefinedType(changes, diag.file, propertyDeclaration);
                            break;
                        case fixIdAddInitializer:
                            var checker = context.program.getTypeChecker();
                            var initializer = getInitializer(checker, propertyDeclaration);
                            if (!initializer)
                                return;
                            addInitializer(changes, diag.file, propertyDeclaration, initializer);
                            break;
                        default:
                            ts.Debug.fail(JSON.stringify(context.fixId));
                    }
                });
            },
        });
        function getPropertyDeclaration(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            return ts.isIdentifier(token) ? ts.cast(token.parent, ts.isPropertyDeclaration) : undefined;
        }
        function getActionForAddMissingDefiniteAssignmentAssertion(context, propertyDeclaration) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addDefiniteAssignmentAssertion(t, context.sourceFile, propertyDeclaration); });
            return codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Add_definite_assignment_assertion_to_property_0, propertyDeclaration.getText()], fixIdAddDefiniteAssignmentAssertions, ts.Diagnostics.Add_definite_assignment_assertions_to_all_uninitialized_properties);
        }
        function addDefiniteAssignmentAssertion(changeTracker, propertyDeclarationSourceFile, propertyDeclaration) {
            var property = ts.updateProperty(propertyDeclaration, propertyDeclaration.decorators, propertyDeclaration.modifiers, propertyDeclaration.name, ts.createToken(53 /* ExclamationToken */), propertyDeclaration.type, propertyDeclaration.initializer);
            changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration, property);
        }
        function getActionForAddMissingUndefinedType(context, propertyDeclaration) {
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addUndefinedType(t, context.sourceFile, propertyDeclaration); });
            return codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Add_undefined_type_to_property_0, propertyDeclaration.name.getText()], fixIdAddUndefinedType, ts.Diagnostics.Add_undefined_type_to_all_uninitialized_properties);
        }
        function addUndefinedType(changeTracker, propertyDeclarationSourceFile, propertyDeclaration) {
            var undefinedTypeNode = ts.createKeywordTypeNode(146 /* UndefinedKeyword */);
            var type = propertyDeclaration.type; // TODO: GH#18217
            var types = ts.isUnionTypeNode(type) ? type.types.concat(undefinedTypeNode) : [type, undefinedTypeNode];
            changeTracker.replaceNode(propertyDeclarationSourceFile, type, ts.createUnionTypeNode(types));
        }
        function getActionForAddMissingInitializer(context, propertyDeclaration) {
            var checker = context.program.getTypeChecker();
            var initializer = getInitializer(checker, propertyDeclaration);
            if (!initializer)
                return undefined;
            var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return addInitializer(t, context.sourceFile, propertyDeclaration, initializer); });
            return codefix.createCodeFixAction(fixName, changes, [ts.Diagnostics.Add_initializer_to_property_0, propertyDeclaration.name.getText()], fixIdAddInitializer, ts.Diagnostics.Add_initializers_to_all_uninitialized_properties);
        }
        function addInitializer(changeTracker, propertyDeclarationSourceFile, propertyDeclaration, initializer) {
            var property = ts.updateProperty(propertyDeclaration, propertyDeclaration.decorators, propertyDeclaration.modifiers, propertyDeclaration.name, propertyDeclaration.questionToken, propertyDeclaration.type, initializer);
            changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration, property);
        }
        function getInitializer(checker, propertyDeclaration) {
            return getDefaultValueFromType(checker, checker.getTypeFromTypeNode(propertyDeclaration.type)); // TODO: GH#18217
        }
        function getDefaultValueFromType(checker, type) {
            if (type.flags & 512 /* BooleanLiteral */) {
                return (type === checker.getFalseType() || type === checker.getFalseType(/*fresh*/ true)) ? ts.createFalse() : ts.createTrue();
            }
            else if (type.isLiteral()) {
                return ts.createLiteral(type.value);
            }
            else if (type.isUnion()) {
                return ts.firstDefined(type.types, function (t) { return getDefaultValueFromType(checker, t); });
            }
            else if (type.isClass()) {
                var classDeclaration = ts.getClassLikeDeclarationOfSymbol(type.symbol);
                if (!classDeclaration || ts.hasModifier(classDeclaration, 128 /* Abstract */))
                    return undefined;
                var constructorDeclaration = ts.getFirstConstructorWithBody(classDeclaration);
                if (constructorDeclaration && constructorDeclaration.parameters.length)
                    return undefined;
                return ts.createNew(ts.createIdentifier(type.symbol.name), /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
            }
            else if (checker.isArrayLikeType(type)) {
                return ts.createArrayLiteral();
            }
            return undefined;
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "requireInTs";
        var errorCodes = [ts.Diagnostics.require_call_may_be_converted_to_an_import.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, context.sourceFile, context.span.start, context.program); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_require_to_import, fixId, ts.Diagnostics.Convert_all_require_to_import)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return doChange(changes, diag.file, diag.start, context.program); }); },
        });
        function doChange(changes, sourceFile, pos, program) {
            var _a = getInfo(sourceFile, pos), statement = _a.statement, name = _a.name, required = _a.required;
            changes.replaceNode(sourceFile, statement, ts.getAllowSyntheticDefaultImports(program.getCompilerOptions())
                ? ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(name, /*namedBindings*/ undefined), required)
                : ts.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, name, ts.createExternalModuleReference(required)));
        }
        function getInfo(sourceFile, pos) {
            var parent = ts.getTokenAtPosition(sourceFile, pos).parent;
            if (!ts.isRequireCall(parent, /*checkArgumentIsStringLiteralLike*/ true))
                throw ts.Debug.failBadSyntaxKind(parent);
            var decl = ts.cast(parent.parent, ts.isVariableDeclaration);
            return { statement: ts.cast(decl.parent.parent, ts.isVariableStatement), name: ts.cast(decl.name, ts.isIdentifier), required: parent.arguments[0] };
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "useDefaultImport";
        var errorCodes = [ts.Diagnostics.Import_may_be_converted_to_a_default_import.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, start = context.span.start;
                var info = getInfo(sourceFile, start);
                if (!info)
                    return undefined;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, info, context.preferences); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_to_default_import, fixId, ts.Diagnostics.Convert_all_to_default_imports)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start);
                if (info)
                    doChange(changes, diag.file, info, context.preferences);
            }); },
        });
        function getInfo(sourceFile, pos) {
            var name = ts.getTokenAtPosition(sourceFile, pos);
            if (!ts.isIdentifier(name))
                return undefined; // bad input
            var parent = name.parent;
            if (ts.isImportEqualsDeclaration(parent) && ts.isExternalModuleReference(parent.moduleReference)) {
                return { importNode: parent, name: name, moduleSpecifier: parent.moduleReference.expression };
            }
            else if (ts.isNamespaceImport(parent)) {
                var importNode = parent.parent.parent;
                return { importNode: importNode, name: name, moduleSpecifier: importNode.moduleSpecifier };
            }
        }
        function doChange(changes, sourceFile, info, preferences) {
            changes.replaceNode(sourceFile, info.importNode, ts.makeImport(info.name, /*namedImports*/ undefined, info.moduleSpecifier, ts.getQuotePreference(sourceFile, preferences)));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "useBigintLiteral";
        var errorCodes = [
            ts.Diagnostics.Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span); });
                if (changes.length > 0) {
                    return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_to_a_bigint_numeric_literal, fixId, ts.Diagnostics.Convert_all_to_bigint_numeric_literals)];
                }
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag); });
            },
        });
        function makeChange(changeTracker, sourceFile, span) {
            var numericLiteral = ts.tryCast(ts.getTokenAtPosition(sourceFile, span.start), ts.isNumericLiteral);
            if (!numericLiteral) {
                return;
            }
            // We use .getText to overcome parser inaccuracies: https://github.com/microsoft/TypeScript/issues/33298
            var newText = numericLiteral.getText(sourceFile) + "n";
            changeTracker.replaceNode(sourceFile, numericLiteral, ts.createBigIntLiteral(newText));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixIdAddMissingTypeof = "fixAddModuleReferTypeMissingTypeof";
        var fixId = fixIdAddMissingTypeof;
        var errorCodes = [ts.Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var importType = getImportTypeNode(sourceFile, span.start);
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, importType); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Add_missing_typeof, fixId, ts.Diagnostics.Add_missing_typeof)];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                return doChange(changes, context.sourceFile, getImportTypeNode(diag.file, diag.start));
            }); },
        });
        function getImportTypeNode(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            ts.Debug.assert(token.kind === 96 /* ImportKeyword */, "This token should be an ImportKeyword");
            ts.Debug.assert(token.parent.kind === 188 /* ImportType */, "Token parent should be an ImportType");
            return token.parent;
        }
        function doChange(changes, sourceFile, importType) {
            var newTypeNode = ts.updateImportTypeNode(importType, importType.argument, importType.qualifier, importType.typeArguments, /* isTypeOf */ true);
            changes.replaceNode(sourceFile, importType, newTypeNode);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixIdAddMissingTypeof = "fixConvertToMappedObjectType";
        var fixId = fixIdAddMissingTypeof;
        var errorCodes = [ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span;
                var info = getInfo(sourceFile, span.start);
                if (!info)
                    return undefined;
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, info); });
                var name = ts.idText(info.container.name);
                return [codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Convert_0_to_mapped_object_type, name], fixId, [ts.Diagnostics.Convert_0_to_mapped_object_type, name])];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start);
                if (info)
                    doChange(changes, diag.file, info);
            }); }
        });
        function getInfo(sourceFile, pos) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var indexSignature = ts.cast(token.parent.parent, ts.isIndexSignatureDeclaration);
            if (ts.isClassDeclaration(indexSignature.parent))
                return undefined;
            var container = ts.isInterfaceDeclaration(indexSignature.parent) ? indexSignature.parent : ts.cast(indexSignature.parent.parent, ts.isTypeAliasDeclaration);
            return { indexSignature: indexSignature, container: container };
        }
        function createTypeAliasFromInterface(declaration, type) {
            return ts.createTypeAliasDeclaration(declaration.decorators, declaration.modifiers, declaration.name, declaration.typeParameters, type);
        }
        function doChange(changes, sourceFile, _a) {
            var indexSignature = _a.indexSignature, container = _a.container;
            var members = ts.isInterfaceDeclaration(container) ? container.members : container.type.members;
            var otherMembers = members.filter(function (member) { return !ts.isIndexSignatureDeclaration(member); });
            var parameter = ts.first(indexSignature.parameters);
            var mappedTypeParameter = ts.createTypeParameterDeclaration(ts.cast(parameter.name, ts.isIdentifier), parameter.type);
            var mappedIntersectionType = ts.createMappedTypeNode(ts.hasReadonlyModifier(indexSignature) ? ts.createModifier(138 /* ReadonlyKeyword */) : undefined, mappedTypeParameter, indexSignature.questionToken, indexSignature.type);
            var intersectionType = ts.createIntersectionTypeNode(__spreadArrays(ts.getAllSuperTypeNodes(container), [
                mappedIntersectionType
            ], (otherMembers.length ? [ts.createTypeLiteralNode(otherMembers)] : ts.emptyArray)));
            changes.replaceNode(sourceFile, container, createTypeAliasFromInterface(container, intersectionType));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "removeUnnecessaryAwait";
        var errorCodes = [
            ts.Diagnostics.await_has_no_effect_on_the_type_of_this_expression.code,
        ];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return makeChange(t, context.sourceFile, context.span); });
                if (changes.length > 0) {
                    return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Remove_unnecessary_await, fixId, ts.Diagnostics.Remove_all_unnecessary_uses_of_await)];
                }
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) {
                return codefix.codeFixAll(context, errorCodes, function (changes, diag) { return makeChange(changes, diag.file, diag); });
            },
        });
        function makeChange(changeTracker, sourceFile, span) {
            var awaitKeyword = ts.tryCast(ts.getTokenAtPosition(sourceFile, span.start), function (node) { return node.kind === 127 /* AwaitKeyword */; });
            var awaitExpression = awaitKeyword && ts.tryCast(awaitKeyword.parent, ts.isAwaitExpression);
            if (!awaitExpression) {
                return;
            }
            var expressionToReplace = awaitExpression;
            var hasSurroundingParens = ts.isParenthesizedExpression(awaitExpression.parent);
            if (hasSurroundingParens) {
                var leftMostExpression = ts.getLeftmostExpression(awaitExpression.expression, /*stopAtCallExpressions*/ false);
                if (ts.isIdentifier(leftMostExpression)) {
                    var precedingToken = ts.findPrecedingToken(awaitExpression.parent.pos, sourceFile);
                    if (precedingToken && precedingToken.kind !== 99 /* NewKeyword */) {
                        expressionToReplace = awaitExpression.parent;
                    }
                }
            }
            changeTracker.replaceNode(sourceFile, expressionToReplace, awaitExpression.expression);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var errorCodes = [ts.Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both.code];
        var fixId = "splitTypeOnlyImport";
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            fixIds: [fixId],
            getCodeActions: function (context) {
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) {
                    return splitTypeOnlyImport(t, getImportDeclaration(context.sourceFile, context.span), context);
                });
                if (changes.length) {
                    return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Split_into_two_separate_import_declarations, fixId, ts.Diagnostics.Split_all_invalid_type_only_imports)];
                }
            },
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, error) {
                splitTypeOnlyImport(changes, getImportDeclaration(context.sourceFile, error), context);
            }); },
        });
        function getImportDeclaration(sourceFile, span) {
            return ts.findAncestor(ts.getTokenAtPosition(sourceFile, span.start), ts.isImportDeclaration);
        }
        function splitTypeOnlyImport(changes, importDeclaration, context) {
            if (!importDeclaration) {
                return;
            }
            var importClause = ts.Debug.checkDefined(importDeclaration.importClause);
            changes.replaceNode(context.sourceFile, importDeclaration, ts.updateImportDeclaration(importDeclaration, importDeclaration.decorators, importDeclaration.modifiers, ts.updateImportClause(importClause, importClause.name, /*namedBindings*/ undefined, importClause.isTypeOnly), importDeclaration.moduleSpecifier));
            changes.insertNodeAfter(context.sourceFile, importDeclaration, ts.createImportDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, ts.updateImportClause(importClause, /*name*/ undefined, importClause.namedBindings, importClause.isTypeOnly), importDeclaration.moduleSpecifier));
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixConvertConstToLet";
        var errorCodes = [ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant.code];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile, span = context.span, program = context.program;
                var variableStatement = getVariableStatement(sourceFile, span.start, program);
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, variableStatement); });
                return [codefix.createCodeFixAction(fixId, changes, ts.Diagnostics.Convert_const_to_let, fixId, ts.Diagnostics.Convert_const_to_let)];
            },
            fixIds: [fixId]
        });
        function getVariableStatement(sourceFile, pos, program) {
            var token = ts.getTokenAtPosition(sourceFile, pos);
            var checker = program.getTypeChecker();
            var symbol = checker.getSymbolAtLocation(token);
            if (symbol) {
                return symbol.valueDeclaration.parent.parent;
            }
        }
        function doChange(changes, sourceFile, variableStatement) {
            if (!variableStatement) {
                return;
            }
            var start = variableStatement.getStart();
            changes.replaceRangeWithText(sourceFile, { pos: start, end: start + 5 }, "let");
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var codefix;
    (function (codefix) {
        var fixId = "fixExpectedComma";
        var expectedErrorCode = ts.Diagnostics._0_expected.code;
        var errorCodes = [expectedErrorCode];
        codefix.registerCodeFix({
            errorCodes: errorCodes,
            getCodeActions: function (context) {
                var sourceFile = context.sourceFile;
                var info = getInfo(sourceFile, context.span.start, context.errorCode);
                if (!info) {
                    return undefined;
                }
                var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, info); });
                return [codefix.createCodeFixAction(fixId, changes, [ts.Diagnostics.Change_0_to_1, ";", ","], fixId, [ts.Diagnostics.Change_0_to_1, ";", ","])];
            },
            fixIds: [fixId],
            getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) {
                var info = getInfo(diag.file, diag.start, diag.code);
                if (info)
                    doChange(changes, context.sourceFile, info);
            }); },
        });
        function getInfo(sourceFile, pos, _) {
            var node = ts.getTokenAtPosition(sourceFile, pos);
            return (node.kind === 26 /* SemicolonToken */ &&
                node.parent &&
                (ts.isObjectLiteralExpression(node.parent) ||
                    ts.isArrayLiteralExpression(node.parent))) ? { node: node } : undefined;
        }
        function doChange(changes, sourceFile, _a) {
            var node = _a.node;
            var newNode = ts.createNode(27 /* CommaToken */);
            changes.replaceNode(sourceFile, node, newNode);
        }
    })(codefix = ts.codefix || (ts.codefix = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var refactorName = "Convert export";
        var actionNameDefaultToNamed = "Convert default export to named export";
        var actionNameNamedToDefault = "Convert named export to default export";
        refactor.registerRefactor(refactorName, {
            getAvailableActions: function (context) {
                var info = getInfo(context);
                if (!info)
                    return ts.emptyArray;
                var description = info.wasDefault ? ts.Diagnostics.Convert_default_export_to_named_export.message : ts.Diagnostics.Convert_named_export_to_default_export.message;
                var actionName = info.wasDefault ? actionNameDefaultToNamed : actionNameNamedToDefault;
                return [{ name: refactorName, description: description, actions: [{ name: actionName, description: description }] }];
            },
            getEditsForAction: function (context, actionName) {
                ts.Debug.assert(actionName === actionNameDefaultToNamed || actionName === actionNameNamedToDefault, "Unexpected action name");
                var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(context.file, context.program, ts.Debug.checkDefined(getInfo(context), "context must have info"), t, context.cancellationToken); });
                return { edits: edits, renameFilename: undefined, renameLocation: undefined };
            },
        });
        function getInfo(context) {
            var file = context.file;
            var span = ts.getRefactorContextSpan(context);
            var token = ts.getTokenAtPosition(file, span.start);
            var exportNode = ts.getParentNodeInSpan(token, file, span);
            if (!exportNode || (!ts.isSourceFile(exportNode.parent) && !(ts.isModuleBlock(exportNode.parent) && ts.isAmbientModule(exportNode.parent.parent)))) {
                return undefined;
            }
            var exportingModuleSymbol = ts.isSourceFile(exportNode.parent) ? exportNode.parent.symbol : exportNode.parent.parent.symbol;
            var flags = ts.getModifierFlags(exportNode);
            var wasDefault = !!(flags & 512 /* Default */);
            // If source file already has a default export, don't offer refactor.
            if (!(flags & 1 /* Export */) || !wasDefault && exportingModuleSymbol.exports.has("default" /* Default */)) {
                return undefined;
            }
            switch (exportNode.kind) {
                case 244 /* FunctionDeclaration */:
                case 245 /* ClassDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 248 /* EnumDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 249 /* ModuleDeclaration */: {
                    var node = exportNode;
                    return node.name && ts.isIdentifier(node.name) ? { exportNode: node, exportName: node.name, wasDefault: wasDefault, exportingModuleSymbol: exportingModuleSymbol } : undefined;
                }
                case 225 /* VariableStatement */: {
                    var vs = exportNode;
                    // Must be `export const x = something;`.
                    if (!(vs.declarationList.flags & 2 /* Const */) || vs.declarationList.declarations.length !== 1) {
                        return undefined;
                    }
                    var decl = ts.first(vs.declarationList.declarations);
                    if (!decl.initializer)
                        return undefined;
                    ts.Debug.assert(!wasDefault, "Can't have a default flag here");
                    return ts.isIdentifier(decl.name) ? { exportNode: vs, exportName: decl.name, wasDefault: wasDefault, exportingModuleSymbol: exportingModuleSymbol } : undefined;
                }
                default:
                    return undefined;
            }
        }
        function doChange(exportingSourceFile, program, info, changes, cancellationToken) {
            changeExport(exportingSourceFile, info, changes, program.getTypeChecker());
            changeImports(program, info, changes, cancellationToken);
        }
        function changeExport(exportingSourceFile, _a, changes, checker) {
            var wasDefault = _a.wasDefault, exportNode = _a.exportNode, exportName = _a.exportName;
            if (wasDefault) {
                changes.delete(exportingSourceFile, ts.Debug.checkDefined(ts.findModifier(exportNode, 84 /* DefaultKeyword */), "Should find a default keyword in modifier list"));
            }
            else {
                var exportKeyword = ts.Debug.checkDefined(ts.findModifier(exportNode, 89 /* ExportKeyword */), "Should find an export keyword in modifier list");
                switch (exportNode.kind) {
                    case 244 /* FunctionDeclaration */:
                    case 245 /* ClassDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                        changes.insertNodeAfter(exportingSourceFile, exportKeyword, ts.createToken(84 /* DefaultKeyword */));
                        break;
                    case 225 /* VariableStatement */:
                        // If 'x' isn't used in this file, `export const x = 0;` --> `export default 0;`
                        if (!ts.FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile)) {
                            // We checked in `getInfo` that an initializer exists.
                            changes.replaceNode(exportingSourceFile, exportNode, ts.createExportDefault(ts.Debug.checkDefined(ts.first(exportNode.declarationList.declarations).initializer, "Initializer was previously known to be present")));
                            break;
                        }
                    // falls through
                    case 248 /* EnumDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                    case 249 /* ModuleDeclaration */:
                        // `export type T = number;` -> `type T = number; export default T;`
                        changes.deleteModifier(exportingSourceFile, exportKeyword);
                        changes.insertNodeAfter(exportingSourceFile, exportNode, ts.createExportDefault(ts.createIdentifier(exportName.text)));
                        break;
                    default:
                        ts.Debug.assertNever(exportNode, "Unexpected exportNode kind " + exportNode.kind);
                }
            }
        }
        function changeImports(program, _a, changes, cancellationToken) {
            var wasDefault = _a.wasDefault, exportName = _a.exportName, exportingModuleSymbol = _a.exportingModuleSymbol;
            var checker = program.getTypeChecker();
            var exportSymbol = ts.Debug.checkDefined(checker.getSymbolAtLocation(exportName), "Export name should resolve to a symbol");
            ts.FindAllReferences.Core.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, wasDefault, function (ref) {
                var importingSourceFile = ref.getSourceFile();
                if (wasDefault) {
                    changeDefaultToNamedImport(importingSourceFile, ref, changes, exportName.text);
                }
                else {
                    changeNamedToDefaultImport(importingSourceFile, ref, changes);
                }
            });
        }
        function changeDefaultToNamedImport(importingSourceFile, ref, changes, exportName) {
            var parent = ref.parent;
            switch (parent.kind) {
                case 194 /* PropertyAccessExpression */:
                    // `a.default` --> `a.foo`
                    changes.replaceNode(importingSourceFile, ref, ts.createIdentifier(exportName));
                    break;
                case 258 /* ImportSpecifier */:
                case 263 /* ExportSpecifier */: {
                    var spec = parent;
                    // `default as foo` --> `foo`, `default as bar` --> `foo as bar`
                    changes.replaceNode(importingSourceFile, spec, makeImportSpecifier(exportName, spec.name.text));
                    break;
                }
                case 255 /* ImportClause */: {
                    var clause = parent;
                    ts.Debug.assert(clause.name === ref, "Import clause name should match provided ref");
                    var spec = makeImportSpecifier(exportName, ref.text);
                    var namedBindings = clause.namedBindings;
                    if (!namedBindings) {
                        // `import foo from "./a";` --> `import { foo } from "./a";`
                        changes.replaceNode(importingSourceFile, ref, ts.createNamedImports([spec]));
                    }
                    else if (namedBindings.kind === 256 /* NamespaceImport */) {
                        // `import foo, * as a from "./a";` --> `import * as a from ".a/"; import { foo } from "./a";`
                        changes.deleteRange(importingSourceFile, { pos: ref.getStart(importingSourceFile), end: namedBindings.getStart(importingSourceFile) });
                        var quotePreference = ts.isStringLiteral(clause.parent.moduleSpecifier) ? ts.quotePreferenceFromString(clause.parent.moduleSpecifier, importingSourceFile) : 1 /* Double */;
                        var newImport = ts.makeImport(/*default*/ undefined, [makeImportSpecifier(exportName, ref.text)], clause.parent.moduleSpecifier, quotePreference);
                        changes.insertNodeAfter(importingSourceFile, clause.parent, newImport);
                    }
                    else {
                        // `import foo, { bar } from "./a"` --> `import { bar, foo } from "./a";`
                        changes.delete(importingSourceFile, ref);
                        changes.insertNodeAtEndOfList(importingSourceFile, namedBindings.elements, spec);
                    }
                    break;
                }
                default:
                    ts.Debug.failBadSyntaxKind(parent);
            }
        }
        function changeNamedToDefaultImport(importingSourceFile, ref, changes) {
            var parent = ref.parent;
            switch (parent.kind) {
                case 194 /* PropertyAccessExpression */:
                    // `a.foo` --> `a.default`
                    changes.replaceNode(importingSourceFile, ref, ts.createIdentifier("default"));
                    break;
                case 258 /* ImportSpecifier */: {
                    // `import { foo } from "./a";` --> `import foo from "./a";`
                    // `import { foo as bar } from "./a";` --> `import bar from "./a";`
                    var defaultImport = ts.createIdentifier(parent.name.text);
                    if (parent.parent.elements.length === 1) {
                        changes.replaceNode(importingSourceFile, parent.parent, defaultImport);
                    }
                    else {
                        changes.delete(importingSourceFile, parent);
                        changes.insertNodeBefore(importingSourceFile, parent.parent, defaultImport);
                    }
                    break;
                }
                case 263 /* ExportSpecifier */: {
                    // `export { foo } from "./a";` --> `export { default as foo } from "./a";`
                    // `export { foo as bar } from "./a";` --> `export { default as bar } from "./a";`
                    // `export { foo as default } from "./a";` --> `export { default } from "./a";`
                    // (Because `export foo from "./a";` isn't valid syntax.)
                    changes.replaceNode(importingSourceFile, parent, makeExportSpecifier("default", parent.name.text));
                    break;
                }
                default:
                    ts.Debug.assertNever(parent, "Unexpected parent kind " + parent.kind);
            }
        }
        function makeImportSpecifier(propertyName, name) {
            return ts.createImportSpecifier(propertyName === name ? undefined : ts.createIdentifier(propertyName), ts.createIdentifier(name));
        }
        function makeExportSpecifier(propertyName, name) {
            return ts.createExportSpecifier(propertyName === name ? undefined : ts.createIdentifier(propertyName), ts.createIdentifier(name));
        }
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var refactorName = "Convert import";
        var actionNameNamespaceToNamed = "Convert namespace import to named imports";
        var actionNameNamedToNamespace = "Convert named imports to namespace import";
        refactor.registerRefactor(refactorName, {
            getAvailableActions: function (context) {
                var i = getImportToConvert(context);
                if (!i)
                    return ts.emptyArray;
                var description = i.kind === 256 /* NamespaceImport */ ? ts.Diagnostics.Convert_namespace_import_to_named_imports.message : ts.Diagnostics.Convert_named_imports_to_namespace_import.message;
                var actionName = i.kind === 256 /* NamespaceImport */ ? actionNameNamespaceToNamed : actionNameNamedToNamespace;
                return [{ name: refactorName, description: description, actions: [{ name: actionName, description: description }] }];
            },
            getEditsForAction: function (context, actionName) {
                ts.Debug.assert(actionName === actionNameNamespaceToNamed || actionName === actionNameNamedToNamespace, "Unexpected action name");
                var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(context.file, context.program, t, ts.Debug.checkDefined(getImportToConvert(context), "Context must provide an import to convert")); });
                return { edits: edits, renameFilename: undefined, renameLocation: undefined };
            }
        });
        // Can convert imports of the form `import * as m from "m";` or `import d, { x, y } from "m";`.
        function getImportToConvert(context) {
            var file = context.file;
            var span = ts.getRefactorContextSpan(context);
            var token = ts.getTokenAtPosition(file, span.start);
            var importDecl = ts.getParentNodeInSpan(token, file, span);
            if (!importDecl || !ts.isImportDeclaration(importDecl))
                return undefined;
            var importClause = importDecl.importClause;
            return importClause && importClause.namedBindings;
        }
        function doChange(sourceFile, program, changes, toConvert) {
            var checker = program.getTypeChecker();
            if (toConvert.kind === 256 /* NamespaceImport */) {
                doChangeNamespaceToNamed(sourceFile, checker, changes, toConvert, ts.getAllowSyntheticDefaultImports(program.getCompilerOptions()));
            }
            else {
                doChangeNamedToNamespace(sourceFile, checker, changes, toConvert);
            }
        }
        function doChangeNamespaceToNamed(sourceFile, checker, changes, toConvert, allowSyntheticDefaultImports) {
            var usedAsNamespaceOrDefault = false;
            var nodesToReplace = [];
            var conflictingNames = ts.createMap();
            ts.FindAllReferences.Core.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, function (id) {
                if (!ts.isPropertyAccessExpression(id.parent)) {
                    usedAsNamespaceOrDefault = true;
                }
                else {
                    var parent = ts.cast(id.parent, ts.isPropertyAccessExpression);
                    var exportName = parent.name.text;
                    if (checker.resolveName(exportName, id, 67108863 /* All */, /*excludeGlobals*/ true)) {
                        conflictingNames.set(exportName, true);
                    }
                    ts.Debug.assert(parent.expression === id, "Parent expression should match id");
                    nodesToReplace.push(parent);
                }
            });
            // We may need to change `mod.x` to `_x` to avoid a name conflict.
            var exportNameToImportName = ts.createMap();
            for (var _i = 0, nodesToReplace_1 = nodesToReplace; _i < nodesToReplace_1.length; _i++) {
                var propertyAccess = nodesToReplace_1[_i];
                var exportName = propertyAccess.name.text;
                var importName = exportNameToImportName.get(exportName);
                if (importName === undefined) {
                    exportNameToImportName.set(exportName, importName = conflictingNames.has(exportName) ? ts.getUniqueName(exportName, sourceFile) : exportName);
                }
                changes.replaceNode(sourceFile, propertyAccess, ts.createIdentifier(importName));
            }
            var importSpecifiers = [];
            exportNameToImportName.forEach(function (name, propertyName) {
                importSpecifiers.push(ts.createImportSpecifier(name === propertyName ? undefined : ts.createIdentifier(propertyName), ts.createIdentifier(name)));
            });
            var importDecl = toConvert.parent.parent;
            if (usedAsNamespaceOrDefault && !allowSyntheticDefaultImports) {
                // Need to leave the namespace import alone
                changes.insertNodeAfter(sourceFile, importDecl, updateImport(importDecl, /*defaultImportName*/ undefined, importSpecifiers));
            }
            else {
                changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, usedAsNamespaceOrDefault ? ts.createIdentifier(toConvert.name.text) : undefined, importSpecifiers));
            }
        }
        function doChangeNamedToNamespace(sourceFile, checker, changes, toConvert) {
            var importDecl = toConvert.parent.parent;
            var moduleSpecifier = importDecl.moduleSpecifier;
            var preferredName = moduleSpecifier && ts.isStringLiteral(moduleSpecifier) ? ts.codefix.moduleSpecifierToValidIdentifier(moduleSpecifier.text, 99 /* ESNext */) : "module";
            var namespaceNameConflicts = toConvert.elements.some(function (element) {
                return ts.FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, function (id) {
                    return !!checker.resolveName(preferredName, id, 67108863 /* All */, /*excludeGlobals*/ true);
                }) || false;
            });
            var namespaceImportName = namespaceNameConflicts ? ts.getUniqueName(preferredName, sourceFile) : preferredName;
            var neededNamedImports = [];
            var _loop_15 = function (element) {
                var propertyName = (element.propertyName || element.name).text;
                ts.FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, function (id) {
                    var access = ts.createPropertyAccess(ts.createIdentifier(namespaceImportName), propertyName);
                    if (ts.isShorthandPropertyAssignment(id.parent)) {
                        changes.replaceNode(sourceFile, id.parent, ts.createPropertyAssignment(id.text, access));
                    }
                    else if (ts.isExportSpecifier(id.parent) && !id.parent.propertyName) {
                        if (!neededNamedImports.some(function (n) { return n.name === element.name; })) {
                            neededNamedImports.push(ts.createImportSpecifier(element.propertyName && ts.createIdentifier(element.propertyName.text), ts.createIdentifier(element.name.text)));
                        }
                    }
                    else {
                        changes.replaceNode(sourceFile, id, access);
                    }
                });
            };
            for (var _i = 0, _a = toConvert.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                _loop_15(element);
            }
            changes.replaceNode(sourceFile, toConvert, ts.createNamespaceImport(ts.createIdentifier(namespaceImportName)));
            if (neededNamedImports.length) {
                changes.insertNodeAfter(sourceFile, toConvert.parent.parent, updateImport(importDecl, /*defaultImportName*/ undefined, neededNamedImports));
            }
        }
        function updateImport(old, defaultImportName, elements) {
            return ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(defaultImportName, elements && elements.length ? ts.createNamedImports(elements) : undefined), old.moduleSpecifier);
        }
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var extractSymbol;
        (function (extractSymbol) {
            var refactorName = "Extract Symbol";
            refactor.registerRefactor(refactorName, { getAvailableActions: getAvailableActions, getEditsForAction: getEditsForAction });
            /**
             * Compute the associated code actions
             * Exported for tests.
             */
            function getAvailableActions(context) {
                var rangeToExtract = getRangeToExtract(context.file, ts.getRefactorContextSpan(context));
                var targetRange = rangeToExtract.targetRange;
                if (targetRange === undefined) {
                    return ts.emptyArray;
                }
                var extractions = getPossibleExtractions(targetRange, context);
                if (extractions === undefined) {
                    // No extractions possible
                    return ts.emptyArray;
                }
                var functionActions = [];
                var usedFunctionNames = ts.createMap();
                var constantActions = [];
                var usedConstantNames = ts.createMap();
                var i = 0;
                for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) {
                    var _a = extractions_1[_i], functionExtraction = _a.functionExtraction, constantExtraction = _a.constantExtraction;
                    // Skip these since we don't have a way to report errors yet
                    if (functionExtraction.errors.length === 0) {
                        // Don't issue refactorings with duplicated names.
                        // Scopes come back in "innermost first" order, so extractions will
                        // preferentially go into nearer scopes
                        var description = functionExtraction.description;
                        if (!usedFunctionNames.has(description)) {
                            usedFunctionNames.set(description, true);
                            functionActions.push({
                                description: description,
                                name: "function_scope_" + i
                            });
                        }
                    }
                    // Skip these since we don't have a way to report errors yet
                    if (constantExtraction.errors.length === 0) {
                        // Don't issue refactorings with duplicated names.
                        // Scopes come back in "innermost first" order, so extractions will
                        // preferentially go into nearer scopes
                        var description = constantExtraction.description;
                        if (!usedConstantNames.has(description)) {
                            usedConstantNames.set(description, true);
                            constantActions.push({
                                description: description,
                                name: "constant_scope_" + i
                            });
                        }
                    }
                    // *do* increment i anyway because we'll look for the i-th scope
                    // later when actually doing the refactoring if the user requests it
                    i++;
                }
                var infos = [];
                if (constantActions.length) {
                    infos.push({
                        name: refactorName,
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_constant),
                        actions: constantActions
                    });
                }
                if (functionActions.length) {
                    infos.push({
                        name: refactorName,
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_function),
                        actions: functionActions
                    });
                }
                return infos.length ? infos : ts.emptyArray;
            }
            extractSymbol.getAvailableActions = getAvailableActions;
            /* Exported for tests */
            function getEditsForAction(context, actionName) {
                var rangeToExtract = getRangeToExtract(context.file, ts.getRefactorContextSpan(context));
                var targetRange = rangeToExtract.targetRange; // TODO:GH#18217
                var parsedFunctionIndexMatch = /^function_scope_(\d+)$/.exec(actionName);
                if (parsedFunctionIndexMatch) {
                    var index = +parsedFunctionIndexMatch[1];
                    ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the function scope index");
                    return getFunctionExtractionAtIndex(targetRange, context, index);
                }
                var parsedConstantIndexMatch = /^constant_scope_(\d+)$/.exec(actionName);
                if (parsedConstantIndexMatch) {
                    var index = +parsedConstantIndexMatch[1];
                    ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the constant scope index");
                    return getConstantExtractionAtIndex(targetRange, context, index);
                }
                ts.Debug.fail("Unrecognized action name");
            }
            extractSymbol.getEditsForAction = getEditsForAction;
            // Move these into diagnostic messages if they become user-facing
            var Messages;
            (function (Messages) {
                function createMessage(message) {
                    return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message };
                }
                Messages.cannotExtractRange = createMessage("Cannot extract range.");
                Messages.cannotExtractImport = createMessage("Cannot extract import statement.");
                Messages.cannotExtractSuper = createMessage("Cannot extract super call.");
                Messages.cannotExtractJSDoc = createMessage("Cannot extract JSDoc.");
                Messages.cannotExtractEmpty = createMessage("Cannot extract empty range.");
                Messages.expressionExpected = createMessage("expression expected.");
                Messages.uselessConstantType = createMessage("No reason to extract constant of type.");
                Messages.statementOrExpressionExpected = createMessage("Statement or expression expected.");
                Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements.");
                Messages.cannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement.");
                Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range.");
                Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators.");
                Messages.typeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope.");
                Messages.functionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope.");
                Messages.cannotExtractIdentifier = createMessage("Select more than a single identifier.");
                Messages.cannotExtractExportedEntity = createMessage("Cannot extract exported declaration");
                Messages.cannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression");
                Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor");
                Messages.cannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts");
                Messages.cannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes");
                Messages.cannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function");
                Messages.cannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS");
                Messages.cannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block");
            })(Messages = extractSymbol.Messages || (extractSymbol.Messages = {}));
            var RangeFacts;
            (function (RangeFacts) {
                RangeFacts[RangeFacts["None"] = 0] = "None";
                RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn";
                RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator";
                RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction";
                RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis";
                /**
                 * The range is in a function which needs the 'static' modifier in a class
                 */
                RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion";
            })(RangeFacts || (RangeFacts = {}));
            /**
             * getRangeToExtract takes a span inside a text file and returns either an expression or an array
             * of statements representing the minimum set of nodes needed to extract the entire span. This
             * process may fail, in which case a set of errors is returned instead (these are currently
             * not shown to the user, but can be used by us diagnostically)
             */
            // exported only for tests
            function getRangeToExtract(sourceFile, span) {
                var length = span.length;
                if (length === 0) {
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractEmpty)] };
                }
                // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
                // This may fail (e.g. you select two statements in the root of a source file)
                var start = ts.getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start), sourceFile, span);
                // Do the same for the ending position
                var end = ts.getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span);
                var declarations = [];
                // We'll modify these flags as we walk the tree to collect data
                // about what things need to be done as part of the extraction.
                var rangeFacts = RangeFacts.None;
                if (!start || !end) {
                    // cannot find either start or end node
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                }
                if (start.parent !== end.parent) {
                    // start and end nodes belong to different subtrees
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                }
                if (start !== end) {
                    // start and end should be statements and parent should be either block or a source file
                    if (!isBlockLike(start.parent)) {
                        return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                    }
                    var statements = [];
                    var start2 = start; // TODO: GH#18217 Need to alias `start` to get this to compile. See https://github.com/Microsoft/TypeScript/issues/19955#issuecomment-344118248
                    for (var _i = 0, _a = start2.parent.statements; _i < _a.length; _i++) {
                        var statement = _a[_i];
                        if (statement === start || statements.length) {
                            var errors_1 = checkNode(statement);
                            if (errors_1) {
                                return { errors: errors_1 };
                            }
                            statements.push(statement);
                        }
                        if (statement === end) {
                            break;
                        }
                    }
                    if (!statements.length) {
                        // https://github.com/Microsoft/TypeScript/issues/20559
                        // Ranges like [|case 1: break;|] will fail to populate `statements` because
                        // they will never find `start` in `start.parent.statements`.
                        // Consider: We could support ranges like [|case 1:|] by refining them to just
                        // the expression.
                        return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                    }
                    return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } };
                }
                if (ts.isJSDoc(start)) {
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractJSDoc)] };
                }
                if (ts.isReturnStatement(start) && !start.expression) {
                    // Makes no sense to extract an expression-less return statement.
                    return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
                }
                // We have a single node (start)
                var node = refineNode(start);
                var errors = checkRootNode(node) || checkNode(node);
                if (errors) {
                    return { errors: errors };
                }
                return { targetRange: { range: getStatementOrExpressionRange(node), facts: rangeFacts, declarations: declarations } }; // TODO: GH#18217
                /**
                 * Attempt to refine the extraction node (generally, by shrinking it) to produce better results.
                 * @param node The unrefined extraction node.
                 */
                function refineNode(node) {
                    if (ts.isReturnStatement(node)) {
                        if (node.expression) {
                            return node.expression;
                        }
                    }
                    else if (ts.isVariableStatement(node)) {
                        var numInitializers = 0;
                        var lastInitializer = void 0;
                        for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                            var declaration = _a[_i];
                            if (declaration.initializer) {
                                numInitializers++;
                                lastInitializer = declaration.initializer;
                            }
                        }
                        if (numInitializers === 1) {
                            return lastInitializer;
                        }
                        // No special handling if there are multiple initializers.
                    }
                    else if (ts.isVariableDeclaration(node)) {
                        if (node.initializer) {
                            return node.initializer;
                        }
                    }
                    return node;
                }
                function checkRootNode(node) {
                    if (ts.isIdentifier(ts.isExpressionStatement(node) ? node.expression : node)) {
                        return [ts.createDiagnosticForNode(node, Messages.cannotExtractIdentifier)];
                    }
                    return undefined;
                }
                function checkForStaticContext(nodeToCheck, containingClass) {
                    var current = nodeToCheck;
                    while (current !== containingClass) {
                        if (current.kind === 159 /* PropertyDeclaration */) {
                            if (ts.hasModifier(current, 32 /* Static */)) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                            break;
                        }
                        else if (current.kind === 156 /* Parameter */) {
                            var ctorOrMethod = ts.getContainingFunction(current);
                            if (ctorOrMethod.kind === 162 /* Constructor */) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                            break;
                        }
                        else if (current.kind === 161 /* MethodDeclaration */) {
                            if (ts.hasModifier(current, 32 /* Static */)) {
                                rangeFacts |= RangeFacts.InStaticRegion;
                            }
                        }
                        current = current.parent;
                    }
                }
                // Verifies whether we can actually extract this node or not.
                function checkNode(nodeToCheck) {
                    var PermittedJumps;
                    (function (PermittedJumps) {
                        PermittedJumps[PermittedJumps["None"] = 0] = "None";
                        PermittedJumps[PermittedJumps["Break"] = 1] = "Break";
                        PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue";
                        PermittedJumps[PermittedJumps["Return"] = 4] = "Return";
                    })(PermittedJumps || (PermittedJumps = {}));
                    // We believe it's true because the node is from the (unmodified) tree.
                    ts.Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (1)");
                    // For understanding how skipTrivia functioned:
                    ts.Debug.assert(!ts.positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (2)");
                    if (!ts.isStatement(nodeToCheck) && !(ts.isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
                        return [ts.createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)];
                    }
                    if (nodeToCheck.flags & 8388608 /* Ambient */) {
                        return [ts.createDiagnosticForNode(nodeToCheck, Messages.cannotExtractAmbientBlock)];
                    }
                    // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default)
                    var containingClass = ts.getContainingClass(nodeToCheck);
                    if (containingClass) {
                        checkForStaticContext(nodeToCheck, containingClass);
                    }
                    var errors;
                    var permittedJumps = 4 /* Return */;
                    var seenLabels;
                    visit(nodeToCheck);
                    return errors;
                    function visit(node) {
                        if (errors) {
                            // already found an error - can stop now
                            return true;
                        }
                        if (ts.isDeclaration(node)) {
                            var declaringNode = (node.kind === 242 /* VariableDeclaration */) ? node.parent.parent : node;
                            if (ts.hasModifier(declaringNode, 1 /* Export */)) {
                                // TODO: GH#18217 Silly to use `errors ||` since it's definitely not defined (see top of `visit`)
                                // Also, if we're only pushing one error, just use `let error: Diagnostic | undefined`!
                                // Also TODO: GH#19956
                                (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractExportedEntity));
                                return true;
                            }
                            declarations.push(node.symbol);
                        }
                        // Some things can't be extracted in certain situations
                        switch (node.kind) {
                            case 254 /* ImportDeclaration */:
                                (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractImport));
                                return true;
                            case 102 /* SuperKeyword */:
                                // For a super *constructor call*, we have to be extracting the entire class,
                                // but a super *method call* simply implies a 'this' reference
                                if (node.parent.kind === 196 /* CallExpression */) {
                                    // Super constructor call
                                    var containingClass_1 = ts.getContainingClass(node); // TODO:GH#18217
                                    if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) {
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractSuper));
                                        return true;
                                    }
                                }
                                else {
                                    rangeFacts |= RangeFacts.UsesThis;
                                }
                                break;
                        }
                        if (ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node)) {
                            switch (node.kind) {
                                case 244 /* FunctionDeclaration */:
                                case 245 /* ClassDeclaration */:
                                    if (ts.isSourceFile(node.parent) && node.parent.externalModuleIndicator === undefined) {
                                        // You cannot extract global declarations
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.functionWillNotBeVisibleInTheNewScope));
                                    }
                                    break;
                            }
                            // do not dive into functions or classes
                            return false;
                        }
                        var savedPermittedJumps = permittedJumps;
                        switch (node.kind) {
                            case 227 /* IfStatement */:
                                permittedJumps = 0 /* None */;
                                break;
                            case 240 /* TryStatement */:
                                // forbid all jumps inside try blocks
                                permittedJumps = 0 /* None */;
                                break;
                            case 223 /* Block */:
                                if (node.parent && node.parent.kind === 240 /* TryStatement */ && node.parent.finallyBlock === node) {
                                    // allow unconditional returns from finally blocks
                                    permittedJumps = 4 /* Return */;
                                }
                                break;
                            case 278 /* DefaultClause */:
                            case 277 /* CaseClause */:
                                // allow unlabeled break inside case clauses
                                permittedJumps |= 1 /* Break */;
                                break;
                            default:
                                if (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false)) {
                                    // allow unlabeled break/continue inside loops
                                    permittedJumps |= 1 /* Break */ | 2 /* Continue */;
                                }
                                break;
                        }
                        switch (node.kind) {
                            case 183 /* ThisType */:
                            case 104 /* ThisKeyword */:
                                rangeFacts |= RangeFacts.UsesThis;
                                break;
                            case 238 /* LabeledStatement */: {
                                var label = node.label;
                                (seenLabels || (seenLabels = [])).push(label.escapedText);
                                ts.forEachChild(node, visit);
                                seenLabels.pop();
                                break;
                            }
                            case 234 /* BreakStatement */:
                            case 233 /* ContinueStatement */: {
                                var label = node.label;
                                if (label) {
                                    if (!ts.contains(seenLabels, label.escapedText)) {
                                        // attempts to jump to label that is not in range to be extracted
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange));
                                    }
                                }
                                else {
                                    if (!(permittedJumps & (node.kind === 234 /* BreakStatement */ ? 1 /* Break */ : 2 /* Continue */))) {
                                        // attempt to break or continue in a forbidden context
                                        (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements));
                                    }
                                }
                                break;
                            }
                            case 206 /* AwaitExpression */:
                                rangeFacts |= RangeFacts.IsAsyncFunction;
                                break;
                            case 212 /* YieldExpression */:
                                rangeFacts |= RangeFacts.IsGenerator;
                                break;
                            case 235 /* ReturnStatement */:
                                if (permittedJumps & 4 /* Return */) {
                                    rangeFacts |= RangeFacts.HasReturn;
                                }
                                else {
                                    (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalReturnStatement));
                                }
                                break;
                            default:
                                ts.forEachChild(node, visit);
                                break;
                        }
                        permittedJumps = savedPermittedJumps;
                    }
                }
            }
            extractSymbol.getRangeToExtract = getRangeToExtract;
            function getStatementOrExpressionRange(node) {
                if (ts.isStatement(node)) {
                    return [node];
                }
                else if (ts.isExpressionNode(node)) {
                    // If our selection is the expression in an ExpressionStatement, expand
                    // the selection to include the enclosing Statement (this stops us
                    // from trying to care about the return value of the extracted function
                    // and eliminates double semicolon insertion in certain scenarios)
                    return ts.isExpressionStatement(node.parent) ? [node.parent] : node;
                }
                return undefined;
            }
            function isScope(node) {
                return ts.isFunctionLikeDeclaration(node) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node);
            }
            /**
             * Computes possible places we could extract the function into. For example,
             * you may be able to extract into a class method *or* local closure *or* namespace function,
             * depending on what's in the extracted body.
             */
            function collectEnclosingScopes(range) {
                var current = isReadonlyArray(range.range) ? ts.first(range.range) : range.range;
                if (range.facts & RangeFacts.UsesThis) {
                    // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class
                    var containingClass = ts.getContainingClass(current);
                    if (containingClass) {
                        var containingFunction = ts.findAncestor(current, ts.isFunctionLikeDeclaration);
                        return containingFunction
                            ? [containingFunction, containingClass]
                            : [containingClass];
                    }
                }
                var scopes = [];
                while (true) {
                    current = current.parent;
                    // A function parameter's initializer is actually in the outer scope, not the function declaration
                    if (current.kind === 156 /* Parameter */) {
                        // Skip all the way to the outer scope of the function that declared this parameter
                        current = ts.findAncestor(current, function (parent) { return ts.isFunctionLikeDeclaration(parent); }).parent;
                    }
                    // We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of.
                    // Walk up to the closest parent of a place where we can logically put a sibling:
                    //  * Function declaration
                    //  * Class declaration or expression
                    //  * Module/namespace or source file
                    if (isScope(current)) {
                        scopes.push(current);
                        if (current.kind === 290 /* SourceFile */) {
                            return scopes;
                        }
                    }
                }
            }
            function getFunctionExtractionAtIndex(targetRange, context, requestedChangesIndex) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, functionErrorsPerScope = _b.functionErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations;
                ts.Debug.assert(!functionErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?");
                context.cancellationToken.throwIfCancellationRequested(); // TODO: GH#18217
                return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], exposedVariableDeclarations, targetRange, context);
            }
            function getConstantExtractionAtIndex(targetRange, context, requestedChangesIndex) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, constantErrorsPerScope = _b.constantErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations;
                ts.Debug.assert(!constantErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?");
                ts.Debug.assert(exposedVariableDeclarations.length === 0, "Extract constant accepted a range containing a variable declaration?");
                context.cancellationToken.throwIfCancellationRequested();
                var expression = ts.isExpression(target)
                    ? target
                    : target.statements[0].expression;
                return extractConstantInScope(expression, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange.facts, context);
            }
            /**
             * Given a piece of text to extract ('targetRange'), computes a list of possible extractions.
             * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes
             * or an error explaining why we can't extract into that scope.
             */
            function getPossibleExtractions(targetRange, context) {
                var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, functionErrorsPerScope = _b.functionErrorsPerScope, constantErrorsPerScope = _b.constantErrorsPerScope;
                // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547
                var extractions = scopes.map(function (scope, i) {
                    var functionDescriptionPart = getDescriptionForFunctionInScope(scope);
                    var constantDescriptionPart = getDescriptionForConstantInScope(scope);
                    var scopeDescription = ts.isFunctionLikeDeclaration(scope)
                        ? getDescriptionForFunctionLikeDeclaration(scope)
                        : ts.isClassLike(scope)
                            ? getDescriptionForClassLikeDeclaration(scope)
                            : getDescriptionForModuleLikeDeclaration(scope);
                    var functionDescription;
                    var constantDescription;
                    if (scopeDescription === 1 /* Global */) {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "global"]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "global"]);
                    }
                    else if (scopeDescription === 0 /* Module */) {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "module"]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "module"]);
                    }
                    else {
                        functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [functionDescriptionPart, scopeDescription]);
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [constantDescriptionPart, scopeDescription]);
                    }
                    // Customize the phrasing for the innermost scope to increase clarity.
                    if (i === 0 && !ts.isClassLike(scope)) {
                        constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_enclosing_scope), [constantDescriptionPart]);
                    }
                    return {
                        functionExtraction: {
                            description: functionDescription,
                            errors: functionErrorsPerScope[i],
                        },
                        constantExtraction: {
                            description: constantDescription,
                            errors: constantErrorsPerScope[i],
                        },
                    };
                });
                return extractions;
            }
            function getPossibleExtractionsWorker(targetRange, context) {
                var sourceFile = context.file;
                var scopes = collectEnclosingScopes(targetRange);
                var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile);
                var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker(), context.cancellationToken);
                return { scopes: scopes, readsAndWrites: readsAndWrites };
            }
            function getDescriptionForFunctionInScope(scope) {
                return ts.isFunctionLikeDeclaration(scope)
                    ? "inner function"
                    : ts.isClassLike(scope)
                        ? "method"
                        : "function";
            }
            function getDescriptionForConstantInScope(scope) {
                return ts.isClassLike(scope)
                    ? "readonly field"
                    : "constant";
            }
            function getDescriptionForFunctionLikeDeclaration(scope) {
                switch (scope.kind) {
                    case 162 /* Constructor */:
                        return "constructor";
                    case 201 /* FunctionExpression */:
                    case 244 /* FunctionDeclaration */:
                        return scope.name
                            ? "function '" + scope.name.text + "'"
                            : ts.ANONYMOUS;
                    case 202 /* ArrowFunction */:
                        return "arrow function";
                    case 161 /* MethodDeclaration */:
                        return "method '" + scope.name.getText() + "'";
                    case 163 /* GetAccessor */:
                        return "'get " + scope.name.getText() + "'";
                    case 164 /* SetAccessor */:
                        return "'set " + scope.name.getText() + "'";
                    default:
                        throw ts.Debug.assertNever(scope, "Unexpected scope kind " + scope.kind);
                }
            }
            function getDescriptionForClassLikeDeclaration(scope) {
                return scope.kind === 245 /* ClassDeclaration */
                    ? scope.name ? "class '" + scope.name.text + "'" : "anonymous class declaration"
                    : scope.name ? "class expression '" + scope.name.text + "'" : "anonymous class expression";
            }
            function getDescriptionForModuleLikeDeclaration(scope) {
                return scope.kind === 250 /* ModuleBlock */
                    ? "namespace '" + scope.parent.name.getText() + "'"
                    : scope.externalModuleIndicator ? 0 /* Module */ : 1 /* Global */;
            }
            var SpecialScope;
            (function (SpecialScope) {
                SpecialScope[SpecialScope["Module"] = 0] = "Module";
                SpecialScope[SpecialScope["Global"] = 1] = "Global";
            })(SpecialScope || (SpecialScope = {}));
            /**
             * Result of 'extractRange' operation for a specific scope.
             * Stores either a list of changes that should be applied to extract a range or a list of errors
             */
            function extractFunctionInScope(node, scope, _a, exposedVariableDeclarations, range, context) {
                var usagesInScope = _a.usages, typeParameterUsages = _a.typeParameterUsages, substitutions = _a.substitutions;
                var checker = context.program.getTypeChecker();
                var scriptTarget = ts.getEmitScriptTarget(context.program.getCompilerOptions());
                var importAdder = ts.codefix.createImportAdder(context.file, context.program, context.preferences, context.host);
                // Make a unique name for the extracted function
                var file = scope.getSourceFile();
                var functionNameText = ts.getUniqueName(ts.isClassLike(scope) ? "newMethod" : "newFunction", file);
                var isJS = ts.isInJSFile(scope);
                var functionName = ts.createIdentifier(functionNameText);
                var returnType;
                var parameters = [];
                var callArguments = [];
                var writes;
                usagesInScope.forEach(function (usage, name) {
                    var typeNode;
                    if (!isJS) {
                        var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node);
                        // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
                        type = checker.getBaseTypeOfLiteralType(type);
                        typeNode = ts.codefix.typeToAutoImportableTypeNode(checker, importAdder, type, scope, scriptTarget, 1 /* NoTruncation */);
                    }
                    var paramDecl = ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, 
                    /*name*/ name, 
                    /*questionToken*/ undefined, typeNode);
                    parameters.push(paramDecl);
                    if (usage.usage === 2 /* Write */) {
                        (writes || (writes = [])).push(usage);
                    }
                    callArguments.push(ts.createIdentifier(name));
                });
                var typeParametersAndDeclarations = ts.arrayFrom(typeParameterUsages.values()).map(function (type) { return ({ type: type, declaration: getFirstDeclaration(type) }); });
                var sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder);
                var typeParameters = sortedTypeParametersAndDeclarations.length === 0
                    ? undefined
                    : sortedTypeParametersAndDeclarations.map(function (t) { return t.declaration; });
                // Strictly speaking, we should check whether each name actually binds to the appropriate type
                // parameter.  In cases of shadowing, they may not.
                var callTypeArguments = typeParameters !== undefined
                    ? typeParameters.map(function (decl) { return ts.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined); })
                    : undefined;
                // Provide explicit return types for contextually-typed functions
                // to avoid problems when there are literal types present
                if (ts.isExpression(node) && !isJS) {
                    var contextualType = checker.getContextualType(node);
                    returnType = checker.typeToTypeNode(contextualType, scope, 1 /* NoTruncation */); // TODO: GH#18217
                }
                var _b = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty;
                ts.suppressLeadingAndTrailingTrivia(body);
                var newFunction;
                if (ts.isClassLike(scope)) {
                    // always create private method in TypeScript files
                    var modifiers = isJS ? [] : [ts.createToken(117 /* PrivateKeyword */)];
                    if (range.facts & RangeFacts.InStaticRegion) {
                        modifiers.push(ts.createToken(120 /* StaticKeyword */));
                    }
                    if (range.facts & RangeFacts.IsAsyncFunction) {
                        modifiers.push(ts.createToken(126 /* AsyncKeyword */));
                    }
                    newFunction = ts.createMethod(
                    /*decorators*/ undefined, modifiers.length ? modifiers : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(41 /* AsteriskToken */) : undefined, functionName, 
                    /*questionToken*/ undefined, typeParameters, parameters, returnType, body);
                }
                else {
                    newFunction = ts.createFunctionDeclaration(
                    /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(126 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(41 /* AsteriskToken */) : undefined, functionName, typeParameters, parameters, returnType, body);
                }
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var minInsertionPos = (isReadonlyArray(range.range) ? ts.last(range.range) : range.range).end;
                var nodeToInsertBefore = getNodeToInsertFunctionBefore(minInsertionPos, scope);
                if (nodeToInsertBefore) {
                    changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newFunction, /*blankLineBetween*/ true);
                }
                else {
                    changeTracker.insertNodeAtEndOfScope(context.file, scope, newFunction);
                }
                importAdder.writeFixes(changeTracker);
                var newNodes = [];
                // replace range with function call
                var called = getCalledExpression(scope, range, functionNameText);
                var call = ts.createCall(called, callTypeArguments, // Note that no attempt is made to take advantage of type argument inference
                callArguments);
                if (range.facts & RangeFacts.IsGenerator) {
                    call = ts.createYield(ts.createToken(41 /* AsteriskToken */), call);
                }
                if (range.facts & RangeFacts.IsAsyncFunction) {
                    call = ts.createAwait(call);
                }
                if (exposedVariableDeclarations.length && !writes) {
                    // No need to mix declarations and writes.
                    // How could any variables be exposed if there's a return statement?
                    ts.Debug.assert(!returnValueProperty, "Expected no returnValueProperty");
                    ts.Debug.assert(!(range.facts & RangeFacts.HasReturn), "Expected RangeFacts.HasReturn flag to be unset");
                    if (exposedVariableDeclarations.length === 1) {
                        // Declaring exactly one variable: let x = newFunction();
                        var variableDeclaration = exposedVariableDeclarations[0];
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.getSynthesizedDeepClone(variableDeclaration.name), /*type*/ ts.getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns
                        variableDeclaration.parent.flags)));
                    }
                    else {
                        // Declaring multiple variables / return properties:
                        //   let {x, y} = newFunction();
                        var bindingElements = [];
                        var typeElements = [];
                        var commonNodeFlags = exposedVariableDeclarations[0].parent.flags;
                        var sawExplicitType = false;
                        for (var _i = 0, exposedVariableDeclarations_1 = exposedVariableDeclarations; _i < exposedVariableDeclarations_1.length; _i++) {
                            var variableDeclaration = exposedVariableDeclarations_1[_i];
                            bindingElements.push(ts.createBindingElement(
                            /*dotDotDotToken*/ undefined, 
                            /*propertyName*/ undefined, 
                            /*name*/ ts.getSynthesizedDeepClone(variableDeclaration.name)));
                            // Being returned through an object literal will have widened the type.
                            var variableType = checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), scope, 1 /* NoTruncation */);
                            typeElements.push(ts.createPropertySignature(
                            /*modifiers*/ undefined, 
                            /*name*/ variableDeclaration.symbol.name, 
                            /*questionToken*/ undefined, 
                            /*type*/ variableType, 
                            /*initializer*/ undefined));
                            sawExplicitType = sawExplicitType || variableDeclaration.type !== undefined;
                            commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags;
                        }
                        var typeLiteral = sawExplicitType ? ts.createTypeLiteralNode(typeElements) : undefined;
                        if (typeLiteral) {
                            ts.setEmitFlags(typeLiteral, 1 /* SingleLine */);
                        }
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createObjectBindingPattern(bindingElements), 
                            /*type*/ typeLiteral, 
                            /*initializer*/ call)], commonNodeFlags)));
                    }
                }
                else if (exposedVariableDeclarations.length || writes) {
                    if (exposedVariableDeclarations.length) {
                        // CONSIDER: we're going to create one statement per variable, but we could actually preserve their original grouping.
                        for (var _c = 0, exposedVariableDeclarations_2 = exposedVariableDeclarations; _c < exposedVariableDeclarations_2.length; _c++) {
                            var variableDeclaration = exposedVariableDeclarations_2[_c];
                            var flags = variableDeclaration.parent.flags;
                            if (flags & 2 /* Const */) {
                                flags = (flags & ~2 /* Const */) | 1 /* Let */;
                            }
                            newNodes.push(ts.createVariableStatement(
                            /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], flags)));
                        }
                    }
                    if (returnValueProperty) {
                        // has both writes and return, need to create variable declaration to hold return value;
                        newNodes.push(ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))], 1 /* Let */)));
                    }
                    var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                    if (returnValueProperty) {
                        assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty));
                    }
                    // propagate writes back
                    if (assignments.length === 1) {
                        // We would only have introduced a return value property if there had been
                        // other assignments to make.
                        ts.Debug.assert(!returnValueProperty, "Shouldn't have returnValueProperty here");
                        newNodes.push(ts.createStatement(ts.createAssignment(assignments[0].name, call)));
                        if (range.facts & RangeFacts.HasReturn) {
                            newNodes.push(ts.createReturn());
                        }
                    }
                    else {
                        // emit e.g.
                        //   { a, b, __return } = newFunction(a, b);
                        //   return __return;
                        newNodes.push(ts.createStatement(ts.createAssignment(ts.createObjectLiteral(assignments), call)));
                        if (returnValueProperty) {
                            newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty)));
                        }
                    }
                }
                else {
                    if (range.facts & RangeFacts.HasReturn) {
                        newNodes.push(ts.createReturn(call));
                    }
                    else if (isReadonlyArray(range.range)) {
                        newNodes.push(ts.createStatement(call));
                    }
                    else {
                        newNodes.push(call);
                    }
                }
                if (isReadonlyArray(range.range)) {
                    changeTracker.replaceNodeRangeWithNodes(context.file, ts.first(range.range), ts.last(range.range), newNodes);
                }
                else {
                    changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes);
                }
                var edits = changeTracker.getChanges();
                var renameRange = isReadonlyArray(range.range) ? ts.first(range.range) : range.range;
                var renameFilename = renameRange.getSourceFile().fileName;
                var renameLocation = ts.getRenameLocation(edits, renameFilename, functionNameText, /*isDeclaredBeforeUse*/ false);
                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
                function getTypeDeepCloneUnionUndefined(typeNode) {
                    if (typeNode === undefined) {
                        return undefined;
                    }
                    var clone = ts.getSynthesizedDeepClone(typeNode);
                    var withoutParens = clone;
                    while (ts.isParenthesizedTypeNode(withoutParens)) {
                        withoutParens = withoutParens.type;
                    }
                    return ts.isUnionTypeNode(withoutParens) && ts.find(withoutParens.types, function (t) { return t.kind === 146 /* UndefinedKeyword */; })
                        ? clone
                        : ts.createUnionTypeNode([clone, ts.createKeywordTypeNode(146 /* UndefinedKeyword */)]);
                }
            }
            /**
             * Result of 'extractRange' operation for a specific scope.
             * Stores either a list of changes that should be applied to extract a range or a list of errors
             */
            function extractConstantInScope(node, scope, _a, rangeFacts, context) {
                var _b;
                var substitutions = _a.substitutions;
                var checker = context.program.getTypeChecker();
                // Make a unique name for the extracted variable
                var file = scope.getSourceFile();
                var localNameText = ts.getUniqueName(ts.isClassLike(scope) ? "newProperty" : "newLocal", file);
                var isJS = ts.isInJSFile(scope);
                var variableType = isJS || !checker.isContextSensitive(node)
                    ? undefined
                    : checker.typeToTypeNode(checker.getContextualType(node), scope, 1 /* NoTruncation */); // TODO: GH#18217
                var initializer = transformConstantInitializer(node, substitutions);
                (_b = transformFunctionInitializerAndType(variableType, initializer), variableType = _b.variableType, initializer = _b.initializer);
                ts.suppressLeadingAndTrailingTrivia(initializer);
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                if (ts.isClassLike(scope)) {
                    ts.Debug.assert(!isJS, "Cannot extract to a JS class"); // See CannotExtractToJSClass
                    var modifiers = [];
                    modifiers.push(ts.createToken(117 /* PrivateKeyword */));
                    if (rangeFacts & RangeFacts.InStaticRegion) {
                        modifiers.push(ts.createToken(120 /* StaticKeyword */));
                    }
                    modifiers.push(ts.createToken(138 /* ReadonlyKeyword */));
                    var newVariable = ts.createProperty(
                    /*decorators*/ undefined, modifiers, localNameText, 
                    /*questionToken*/ undefined, variableType, initializer);
                    var localReference = ts.createPropertyAccess(rangeFacts & RangeFacts.InStaticRegion
                        ? ts.createIdentifier(scope.name.getText()) // TODO: GH#18217
                        : ts.createThis(), ts.createIdentifier(localNameText));
                    // Declare
                    var maxInsertionPos = node.pos;
                    var nodeToInsertBefore = getNodeToInsertPropertyBefore(maxInsertionPos, scope);
                    changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, /*blankLineBetween*/ true);
                    // Consume
                    changeTracker.replaceNode(context.file, node, localReference);
                }
                else {
                    var newVariableDeclaration = ts.createVariableDeclaration(localNameText, variableType, initializer);
                    // If the node is part of an initializer in a list of variable declarations, insert a new
                    // variable declaration into the list (in case it depends on earlier ones).
                    // CONSIDER: If the declaration list isn't const, we might want to split it into multiple
                    // lists so that the newly extracted one can be const.
                    var oldVariableDeclaration = getContainingVariableDeclarationIfInList(node, scope);
                    if (oldVariableDeclaration) {
                        // Declare
                        // CONSIDER: could detect that each is on a separate line (See `extractConstant_VariableList_MultipleLines` in `extractConstants.ts`)
                        changeTracker.insertNodeBefore(context.file, oldVariableDeclaration, newVariableDeclaration);
                        // Consume
                        var localReference = ts.createIdentifier(localNameText);
                        changeTracker.replaceNode(context.file, node, localReference);
                    }
                    else if (node.parent.kind === 226 /* ExpressionStatement */ && scope === ts.findAncestor(node, isScope)) {
                        // If the parent is an expression statement and the target scope is the immediately enclosing one,
                        // replace the statement with the declaration.
                        var newVariableStatement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */));
                        changeTracker.replaceNode(context.file, node.parent, newVariableStatement);
                    }
                    else {
                        var newVariableStatement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */));
                        // Declare
                        var nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope);
                        if (nodeToInsertBefore.pos === 0) {
                            changeTracker.insertNodeAtTopOfFile(context.file, newVariableStatement, /*blankLineBetween*/ false);
                        }
                        else {
                            changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariableStatement, /*blankLineBetween*/ false);
                        }
                        // Consume
                        if (node.parent.kind === 226 /* ExpressionStatement */) {
                            // If the parent is an expression statement, delete it.
                            changeTracker.delete(context.file, node.parent);
                        }
                        else {
                            var localReference = ts.createIdentifier(localNameText);
                            changeTracker.replaceNode(context.file, node, localReference);
                        }
                    }
                }
                var edits = changeTracker.getChanges();
                var renameFilename = node.getSourceFile().fileName;
                var renameLocation = ts.getRenameLocation(edits, renameFilename, localNameText, /*isDeclaredBeforeUse*/ true);
                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
                function transformFunctionInitializerAndType(variableType, initializer) {
                    // If no contextual type exists there is nothing to transfer to the function signature
                    if (variableType === undefined)
                        return { variableType: variableType, initializer: initializer };
                    // Only do this for function expressions and arrow functions that are not generic
                    if (!ts.isFunctionExpression(initializer) && !ts.isArrowFunction(initializer) || !!initializer.typeParameters)
                        return { variableType: variableType, initializer: initializer };
                    var functionType = checker.getTypeAtLocation(node);
                    var functionSignature = ts.singleOrUndefined(checker.getSignaturesOfType(functionType, 0 /* Call */));
                    // If no function signature, maybe there was an error, do nothing
                    if (!functionSignature)
                        return { variableType: variableType, initializer: initializer };
                    // If the function signature has generic type parameters we don't attempt to move the parameters
                    if (!!functionSignature.getTypeParameters())
                        return { variableType: variableType, initializer: initializer };
                    // We add parameter types if needed
                    var parameters = [];
                    var hasAny = false;
                    for (var _i = 0, _a = initializer.parameters; _i < _a.length; _i++) {
                        var p = _a[_i];
                        if (p.type) {
                            parameters.push(p);
                        }
                        else {
                            var paramType = checker.getTypeAtLocation(p);
                            if (paramType === checker.getAnyType())
                                hasAny = true;
                            parameters.push(ts.updateParameter(p, p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, p.type || checker.typeToTypeNode(paramType, scope, 1 /* NoTruncation */), p.initializer));
                        }
                    }
                    // If a parameter was inferred as any we skip adding function parameters at all.
                    // Turning an implicit any (which under common settings is a error) to an explicit
                    // is probably actually a worse refactor outcome.
                    if (hasAny)
                        return { variableType: variableType, initializer: initializer };
                    variableType = undefined;
                    if (ts.isArrowFunction(initializer)) {
                        initializer = ts.updateArrowFunction(initializer, node.modifiers, initializer.typeParameters, parameters, initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, 1 /* NoTruncation */), initializer.equalsGreaterThanToken, initializer.body);
                    }
                    else {
                        if (functionSignature && !!functionSignature.thisParameter) {
                            var firstParameter = ts.firstOrUndefined(parameters);
                            // If the function signature has a this parameter and if the first defined parameter is not the this parameter, we must add it
                            // Note: If this parameter was already there, it would have been previously updated with the type if not type was present
                            if ((!firstParameter || (ts.isIdentifier(firstParameter.name) && firstParameter.name.escapedText !== "this"))) {
                                var thisType = checker.getTypeOfSymbolAtLocation(functionSignature.thisParameter, node);
                                parameters.splice(0, 0, ts.createParameter(
                                /* decorators */ undefined, 
                                /* modifiers */ undefined, 
                                /* dotDotDotToken */ undefined, "this", 
                                /* questionToken */ undefined, checker.typeToTypeNode(thisType, scope, 1 /* NoTruncation */)));
                            }
                        }
                        initializer = ts.updateFunctionExpression(initializer, node.modifiers, initializer.asteriskToken, initializer.name, initializer.typeParameters, parameters, initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, 1 /* NoTruncation */), initializer.body);
                    }
                    return { variableType: variableType, initializer: initializer };
                }
            }
            function getContainingVariableDeclarationIfInList(node, scope) {
                var prevNode;
                while (node !== undefined && node !== scope) {
                    if (ts.isVariableDeclaration(node) &&
                        node.initializer === prevNode &&
                        ts.isVariableDeclarationList(node.parent) &&
                        node.parent.declarations.length > 1) {
                        return node;
                    }
                    prevNode = node;
                    node = node.parent;
                }
            }
            function getFirstDeclaration(type) {
                var firstDeclaration;
                var symbol = type.symbol;
                if (symbol && symbol.declarations) {
                    for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                        var declaration = _a[_i];
                        if (firstDeclaration === undefined || declaration.pos < firstDeclaration.pos) {
                            firstDeclaration = declaration;
                        }
                    }
                }
                return firstDeclaration;
            }
            function compareTypesByDeclarationOrder(_a, _b) {
                var type1 = _a.type, declaration1 = _a.declaration;
                var type2 = _b.type, declaration2 = _b.declaration;
                return ts.compareProperties(declaration1, declaration2, "pos", ts.compareValues)
                    || ts.compareStringsCaseSensitive(type1.symbol ? type1.symbol.getName() : "", type2.symbol ? type2.symbol.getName() : "")
                    || ts.compareValues(type1.id, type2.id);
            }
            function getCalledExpression(scope, range, functionNameText) {
                var functionReference = ts.createIdentifier(functionNameText);
                if (ts.isClassLike(scope)) {
                    var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis(); // TODO: GH#18217
                    return ts.createPropertyAccess(lhs, functionReference);
                }
                else {
                    return functionReference;
                }
            }
            function transformFunctionBody(body, exposedVariableDeclarations, writes, substitutions, hasReturn) {
                var hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0;
                if (ts.isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) {
                    // already block, no declarations or writes to propagate back, no substitutions - can use node as is
                    return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined };
                }
                var returnValueProperty;
                var ignoreReturns = false;
                var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]);
                // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions
                if (hasWritesOrVariableDeclarations || substitutions.size) {
                    var rewrittenStatements = ts.visitNodes(statements, visitor).slice();
                    if (hasWritesOrVariableDeclarations && !hasReturn && ts.isStatement(body)) {
                        // add return at the end to propagate writes back in case if control flow falls out of the function body
                        // it is ok to know that range has at least one return since it we only allow unconditional returns
                        var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                        if (assignments.length === 1) {
                            rewrittenStatements.push(ts.createReturn(assignments[0].name));
                        }
                        else {
                            rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments)));
                        }
                    }
                    return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty };
                }
                else {
                    return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined };
                }
                function visitor(node) {
                    if (!ignoreReturns && node.kind === 235 /* ReturnStatement */ && hasWritesOrVariableDeclarations) {
                        var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
                        if (node.expression) {
                            if (!returnValueProperty) {
                                returnValueProperty = "__return";
                            }
                            assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor)));
                        }
                        if (assignments.length === 1) {
                            return ts.createReturn(assignments[0].name);
                        }
                        else {
                            return ts.createReturn(ts.createObjectLiteral(assignments));
                        }
                    }
                    else {
                        var oldIgnoreReturns = ignoreReturns;
                        ignoreReturns = ignoreReturns || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node);
                        var substitution = substitutions.get(ts.getNodeId(node).toString());
                        var result = substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext);
                        ignoreReturns = oldIgnoreReturns;
                        return result;
                    }
                }
            }
            function transformConstantInitializer(initializer, substitutions) {
                return substitutions.size
                    ? visitor(initializer)
                    : initializer;
                function visitor(node) {
                    var substitution = substitutions.get(ts.getNodeId(node).toString());
                    return substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext);
                }
            }
            function getStatementsOrClassElements(scope) {
                if (ts.isFunctionLikeDeclaration(scope)) {
                    var body = scope.body; // TODO: GH#18217
                    if (ts.isBlock(body)) {
                        return body.statements;
                    }
                }
                else if (ts.isModuleBlock(scope) || ts.isSourceFile(scope)) {
                    return scope.statements;
                }
                else if (ts.isClassLike(scope)) {
                    return scope.members;
                }
                else {
                    ts.assertType(scope);
                }
                return ts.emptyArray;
            }
            /**
             * If `scope` contains a function after `minPos`, then return the first such function.
             * Otherwise, return `undefined`.
             */
            function getNodeToInsertFunctionBefore(minPos, scope) {
                return ts.find(getStatementsOrClassElements(scope), function (child) {
                    return child.pos >= minPos && ts.isFunctionLikeDeclaration(child) && !ts.isConstructorDeclaration(child);
                });
            }
            function getNodeToInsertPropertyBefore(maxPos, scope) {
                var members = scope.members;
                ts.Debug.assert(members.length > 0, "Found no members"); // There must be at least one child, since we extracted from one.
                var prevMember;
                var allProperties = true;
                for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
                    var member = members_1[_i];
                    if (member.pos > maxPos) {
                        return prevMember || members[0];
                    }
                    if (allProperties && !ts.isPropertyDeclaration(member)) {
                        // If it is non-vacuously true that all preceding members are properties,
                        // insert before the current member (i.e. at the end of the list of properties).
                        if (prevMember !== undefined) {
                            return member;
                        }
                        allProperties = false;
                    }
                    prevMember = member;
                }
                if (prevMember === undefined)
                    return ts.Debug.fail(); // If the loop didn't return, then it did set prevMember.
                return prevMember;
            }
            function getNodeToInsertConstantBefore(node, scope) {
                ts.Debug.assert(!ts.isClassLike(scope));
                var prevScope;
                for (var curr = node; curr !== scope; curr = curr.parent) {
                    if (isScope(curr)) {
                        prevScope = curr;
                    }
                }
                for (var curr = (prevScope || node).parent;; curr = curr.parent) {
                    if (isBlockLike(curr)) {
                        var prevStatement = void 0;
                        for (var _i = 0, _a = curr.statements; _i < _a.length; _i++) {
                            var statement = _a[_i];
                            if (statement.pos > node.pos) {
                                break;
                            }
                            prevStatement = statement;
                        }
                        if (!prevStatement && ts.isCaseClause(curr)) {
                            // We must have been in the expression of the case clause.
                            ts.Debug.assert(ts.isSwitchStatement(curr.parent.parent), "Grandparent isn't a switch statement");
                            return curr.parent.parent;
                        }
                        // There must be at least one statement since we started in one.
                        return ts.Debug.checkDefined(prevStatement, "prevStatement failed to get set");
                    }
                    ts.Debug.assert(curr !== scope, "Didn't encounter a block-like before encountering scope");
                }
            }
            function getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes) {
                var variableAssignments = ts.map(exposedVariableDeclarations, function (v) { return ts.createShorthandPropertyAssignment(v.symbol.name); });
                var writeAssignments = ts.map(writes, function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); });
                // TODO: GH#18217 `variableAssignments` not possibly undefined!
                return variableAssignments === undefined
                    ? writeAssignments
                    : writeAssignments === undefined
                        ? variableAssignments
                        : variableAssignments.concat(writeAssignments);
            }
            function isReadonlyArray(v) {
                return ts.isArray(v);
            }
            /**
             * Produces a range that spans the entirety of nodes, given a selection
             * that might start/end in the middle of nodes.
             *
             * For example, when the user makes a selection like this
             *                     v---v
             *   var someThing = foo + bar;
             *  this returns     ^-------^
             */
            function getEnclosingTextRange(targetRange, sourceFile) {
                return isReadonlyArray(targetRange.range)
                    ? { pos: ts.first(targetRange.range).getStart(sourceFile), end: ts.last(targetRange.range).getEnd() }
                    : targetRange.range;
            }
            var Usage;
            (function (Usage) {
                // value should be passed to extracted method
                Usage[Usage["Read"] = 1] = "Read";
                // value should be passed to extracted method and propagated back
                Usage[Usage["Write"] = 2] = "Write";
            })(Usage || (Usage = {}));
            function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker, cancellationToken) {
                var allTypeParameterUsages = ts.createMap(); // Key is type ID
                var usagesPerScope = [];
                var substitutionsPerScope = [];
                var functionErrorsPerScope = [];
                var constantErrorsPerScope = [];
                var visibleDeclarationsInExtractedRange = [];
                var exposedVariableSymbolSet = ts.createMap(); // Key is symbol ID
                var exposedVariableDeclarations = [];
                var firstExposedNonVariableDeclaration;
                var expression = !isReadonlyArray(targetRange.range)
                    ? targetRange.range
                    : targetRange.range.length === 1 && ts.isExpressionStatement(targetRange.range[0])
                        ? targetRange.range[0].expression
                        : undefined;
                var expressionDiagnostic;
                if (expression === undefined) {
                    var statements = targetRange.range;
                    var start = ts.first(statements).getStart();
                    var end = ts.last(statements).end;
                    expressionDiagnostic = ts.createFileDiagnostic(sourceFile, start, end - start, Messages.expressionExpected);
                }
                else if (checker.getTypeAtLocation(expression).flags & (16384 /* Void */ | 131072 /* Never */)) {
                    expressionDiagnostic = ts.createDiagnosticForNode(expression, Messages.uselessConstantType);
                }
                // initialize results
                for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) {
                    var scope = scopes_1[_i];
                    usagesPerScope.push({ usages: ts.createMap(), typeParameterUsages: ts.createMap(), substitutions: ts.createMap() });
                    substitutionsPerScope.push(ts.createMap());
                    functionErrorsPerScope.push(ts.isFunctionLikeDeclaration(scope) && scope.kind !== 244 /* FunctionDeclaration */
                        ? [ts.createDiagnosticForNode(scope, Messages.cannotExtractToOtherFunctionLike)]
                        : []);
                    var constantErrors = [];
                    if (expressionDiagnostic) {
                        constantErrors.push(expressionDiagnostic);
                    }
                    if (ts.isClassLike(scope) && ts.isInJSFile(scope)) {
                        constantErrors.push(ts.createDiagnosticForNode(scope, Messages.cannotExtractToJSClass));
                    }
                    if (ts.isArrowFunction(scope) && !ts.isBlock(scope.body)) {
                        // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this
                        constantErrors.push(ts.createDiagnosticForNode(scope, Messages.cannotExtractToExpressionArrowFunction));
                    }
                    constantErrorsPerScope.push(constantErrors);
                }
                var seenUsages = ts.createMap();
                var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range;
                var unmodifiedNode = isReadonlyArray(targetRange.range) ? ts.first(targetRange.range) : targetRange.range;
                var inGenericContext = isInGenericContext(unmodifiedNode);
                collectUsages(target);
                // Unfortunately, this code takes advantage of the knowledge that the generated method
                // will use the contextual type of an expression as the return type of the extracted
                // method (and will therefore "use" all the types involved).
                if (inGenericContext && !isReadonlyArray(targetRange.range)) {
                    var contextualType = checker.getContextualType(targetRange.range); // TODO: GH#18217
                    recordTypeParameterUsages(contextualType);
                }
                if (allTypeParameterUsages.size > 0) {
                    var seenTypeParameterUsages = ts.createMap(); // Key is type ID
                    var i_1 = 0;
                    for (var curr = unmodifiedNode; curr !== undefined && i_1 < scopes.length; curr = curr.parent) {
                        if (curr === scopes[i_1]) {
                            // Copy current contents of seenTypeParameterUsages into scope.
                            seenTypeParameterUsages.forEach(function (typeParameter, id) {
                                usagesPerScope[i_1].typeParameterUsages.set(id, typeParameter);
                            });
                            i_1++;
                        }
                        // Note that we add the current node's type parameters *after* updating the corresponding scope.
                        if (ts.isDeclarationWithTypeParameters(curr)) {
                            for (var _a = 0, _b = ts.getEffectiveTypeParameterDeclarations(curr); _a < _b.length; _a++) {
                                var typeParameterDecl = _b[_a];
                                var typeParameter = checker.getTypeAtLocation(typeParameterDecl);
                                if (allTypeParameterUsages.has(typeParameter.id.toString())) {
                                    seenTypeParameterUsages.set(typeParameter.id.toString(), typeParameter);
                                }
                            }
                        }
                    }
                    // If we didn't get through all the scopes, then there were some that weren't in our
                    // parent chain (impossible at time of writing).  A conservative solution would be to
                    // copy allTypeParameterUsages into all remaining scopes.
                    ts.Debug.assert(i_1 === scopes.length, "Should have iterated all scopes");
                }
                // If there are any declarations in the extracted block that are used in the same enclosing
                // lexical scope, we can't move the extraction "up" as those declarations will become unreachable
                if (visibleDeclarationsInExtractedRange.length) {
                    var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent)
                        ? scopes[0]
                        : ts.getEnclosingBlockScopeContainer(scopes[0]);
                    ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations);
                }
                var _loop_16 = function (i) {
                    var scopeUsages = usagesPerScope[i];
                    // Special case: in the innermost scope, all usages are available.
                    // (The computed value reflects the value at the top-level of the scope, but the
                    // local will actually be declared at the same level as the extracted expression).
                    if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) {
                        var errorNode = isReadonlyArray(targetRange.range) ? targetRange.range[0] : targetRange.range;
                        constantErrorsPerScope[i].push(ts.createDiagnosticForNode(errorNode, Messages.cannotAccessVariablesFromNestedScopes));
                    }
                    var hasWrite = false;
                    var readonlyClassPropertyWrite;
                    usagesPerScope[i].usages.forEach(function (value) {
                        if (value.usage === 2 /* Write */) {
                            hasWrite = true;
                            if (value.symbol.flags & 106500 /* ClassMember */ &&
                                value.symbol.valueDeclaration &&
                                ts.hasModifier(value.symbol.valueDeclaration, 64 /* Readonly */)) {
                                readonlyClassPropertyWrite = value.symbol.valueDeclaration;
                            }
                        }
                    });
                    // If an expression was extracted, then there shouldn't have been any variable declarations.
                    ts.Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0, "No variable declarations expected if something was extracted");
                    if (hasWrite && !isReadonlyArray(targetRange.range)) {
                        var diag = ts.createDiagnosticForNode(targetRange.range, Messages.cannotWriteInExpression);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                    else if (readonlyClassPropertyWrite && i > 0) {
                        var diag = ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                    else if (firstExposedNonVariableDeclaration) {
                        var diag = ts.createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.cannotExtractExportedEntity);
                        functionErrorsPerScope[i].push(diag);
                        constantErrorsPerScope[i].push(diag);
                    }
                };
                for (var i = 0; i < scopes.length; i++) {
                    _loop_16(i);
                }
                return { target: target, usagesPerScope: usagesPerScope, functionErrorsPerScope: functionErrorsPerScope, constantErrorsPerScope: constantErrorsPerScope, exposedVariableDeclarations: exposedVariableDeclarations };
                function isInGenericContext(node) {
                    return !!ts.findAncestor(node, function (n) { return ts.isDeclarationWithTypeParameters(n) && ts.getEffectiveTypeParameterDeclarations(n).length !== 0; });
                }
                function recordTypeParameterUsages(type) {
                    // PERF: This is potentially very expensive.  `type` could be a library type with
                    // a lot of properties, each of which the walker will visit.  Unfortunately, the
                    // solution isn't as trivial as filtering to user types because of (e.g.) Array.
                    var symbolWalker = checker.getSymbolWalker(function () { return (cancellationToken.throwIfCancellationRequested(), true); });
                    var visitedTypes = symbolWalker.walkType(type).visitedTypes;
                    for (var _i = 0, visitedTypes_1 = visitedTypes; _i < visitedTypes_1.length; _i++) {
                        var visitedType = visitedTypes_1[_i];
                        if (visitedType.isTypeParameter()) {
                            allTypeParameterUsages.set(visitedType.id.toString(), visitedType);
                        }
                    }
                }
                function collectUsages(node, valueUsage) {
                    if (valueUsage === void 0) { valueUsage = 1 /* Read */; }
                    if (inGenericContext) {
                        var type = checker.getTypeAtLocation(node);
                        recordTypeParameterUsages(type);
                    }
                    if (ts.isDeclaration(node) && node.symbol) {
                        visibleDeclarationsInExtractedRange.push(node);
                    }
                    if (ts.isAssignmentExpression(node)) {
                        // use 'write' as default usage for values
                        collectUsages(node.left, 2 /* Write */);
                        collectUsages(node.right);
                    }
                    else if (ts.isUnaryExpressionWithWrite(node)) {
                        collectUsages(node.operand, 2 /* Write */);
                    }
                    else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
                        // use 'write' as default usage for values
                        ts.forEachChild(node, collectUsages);
                    }
                    else if (ts.isIdentifier(node)) {
                        if (!node.parent) {
                            return;
                        }
                        if (ts.isQualifiedName(node.parent) && node !== node.parent.left) {
                            return;
                        }
                        if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) {
                            return;
                        }
                        recordUsage(node, valueUsage, /*isTypeNode*/ ts.isPartOfTypeNode(node));
                    }
                    else {
                        ts.forEachChild(node, collectUsages);
                    }
                }
                function recordUsage(n, usage, isTypeNode) {
                    var symbolId = recordUsagebySymbol(n, usage, isTypeNode);
                    if (symbolId) {
                        for (var i = 0; i < scopes.length; i++) {
                            // push substitution from map<symbolId, subst> to map<nodeId, subst> to simplify rewriting
                            var substitution = substitutionsPerScope[i].get(symbolId);
                            if (substitution) {
                                usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitution);
                            }
                        }
                    }
                }
                function recordUsagebySymbol(identifier, usage, isTypeName) {
                    var symbol = getSymbolReferencedByIdentifier(identifier);
                    if (!symbol) {
                        // cannot find symbol - do nothing
                        return undefined;
                    }
                    var symbolId = ts.getSymbolId(symbol).toString();
                    var lastUsage = seenUsages.get(symbolId);
                    // there are two kinds of value usages
                    // - reads - if range contains a read from the value located outside of the range then value should be passed as a parameter
                    // - writes - if range contains a write to a value located outside the range the value should be passed as a parameter and
                    //   returned as a return value
                    // 'write' case is a superset of 'read' so if we already have processed 'write' of some symbol there is not need to handle 'read'
                    // since all information is already recorded
                    if (lastUsage && lastUsage >= usage) {
                        return symbolId;
                    }
                    seenUsages.set(symbolId, usage);
                    if (lastUsage) {
                        // if we get here this means that we are trying to handle 'write' and 'read' was already processed
                        // walk scopes and update existing records.
                        for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) {
                            var perScope = usagesPerScope_1[_i];
                            var prevEntry = perScope.usages.get(identifier.text);
                            if (prevEntry) {
                                perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier });
                            }
                        }
                        return symbolId;
                    }
                    // find first declaration in this file
                    var decls = symbol.getDeclarations();
                    var declInFile = decls && ts.find(decls, function (d) { return d.getSourceFile() === sourceFile; });
                    if (!declInFile) {
                        return undefined;
                    }
                    if (ts.rangeContainsStartEnd(enclosingTextRange, declInFile.getStart(), declInFile.end)) {
                        // declaration is located in range to be extracted - do nothing
                        return undefined;
                    }
                    if (targetRange.facts & RangeFacts.IsGenerator && usage === 2 /* Write */) {
                        // this is write to a reference located outside of the target scope and range is extracted into generator
                        // currently this is unsupported scenario
                        var diag = ts.createDiagnosticForNode(identifier, Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators);
                        for (var _a = 0, functionErrorsPerScope_1 = functionErrorsPerScope; _a < functionErrorsPerScope_1.length; _a++) {
                            var errors = functionErrorsPerScope_1[_a];
                            errors.push(diag);
                        }
                        for (var _b = 0, constantErrorsPerScope_1 = constantErrorsPerScope; _b < constantErrorsPerScope_1.length; _b++) {
                            var errors = constantErrorsPerScope_1[_b];
                            errors.push(diag);
                        }
                    }
                    for (var i = 0; i < scopes.length; i++) {
                        var scope = scopes[i];
                        var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags, /*excludeGlobals*/ false);
                        if (resolvedSymbol === symbol) {
                            continue;
                        }
                        if (!substitutionsPerScope[i].has(symbolId)) {
                            var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName);
                            if (substitution) {
                                substitutionsPerScope[i].set(symbolId, substitution);
                            }
                            else if (isTypeName) {
                                // If the symbol is a type parameter that won't be in scope, we'll pass it as a type argument
                                // so there's no problem.
                                if (!(symbol.flags & 262144 /* TypeParameter */)) {
                                    var diag = ts.createDiagnosticForNode(identifier, Messages.typeWillNotBeVisibleInTheNewScope);
                                    functionErrorsPerScope[i].push(diag);
                                    constantErrorsPerScope[i].push(diag);
                                }
                            }
                            else {
                                usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier });
                            }
                        }
                    }
                    return symbolId;
                }
                function checkForUsedDeclarations(node) {
                    // If this node is entirely within the original extraction range, we don't need to do anything.
                    if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) {
                        return;
                    }
                    // Otherwise check and recurse.
                    var sym = ts.isIdentifier(node)
                        ? getSymbolReferencedByIdentifier(node)
                        : checker.getSymbolAtLocation(node);
                    if (sym) {
                        var decl = ts.find(visibleDeclarationsInExtractedRange, function (d) { return d.symbol === sym; });
                        if (decl) {
                            if (ts.isVariableDeclaration(decl)) {
                                var idString = decl.symbol.id.toString();
                                if (!exposedVariableSymbolSet.has(idString)) {
                                    exposedVariableDeclarations.push(decl);
                                    exposedVariableSymbolSet.set(idString, true);
                                }
                            }
                            else {
                                // CONSIDER: this includes binding elements, which we could
                                // expose in the same way as variables.
                                firstExposedNonVariableDeclaration = firstExposedNonVariableDeclaration || decl;
                            }
                        }
                    }
                    ts.forEachChild(node, checkForUsedDeclarations);
                }
                /**
                 * Return the symbol referenced by an identifier (even if it declares a different symbol).
                 */
                function getSymbolReferencedByIdentifier(identifier) {
                    // If the identifier is both a property name and its value, we're only interested in its value
                    // (since the name is a declaration and will be included in the extracted range).
                    return identifier.parent && ts.isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier
                        ? checker.getShorthandAssignmentValueSymbol(identifier.parent)
                        : checker.getSymbolAtLocation(identifier);
                }
                function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) {
                    if (!symbol) {
                        return undefined;
                    }
                    var decls = symbol.getDeclarations();
                    if (decls && decls.some(function (d) { return d.parent === scopeDecl; })) {
                        return ts.createIdentifier(symbol.name);
                    }
                    var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode);
                    if (prefix === undefined) {
                        return undefined;
                    }
                    return isTypeNode
                        ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name))
                        : ts.createPropertyAccess(prefix, symbol.name);
                }
            }
            /**
             * Computes whether or not a node represents an expression in a position where it could
             * be extracted.
             * The isExpression() in utilities.ts returns some false positives we need to handle,
             * such as `import x from 'y'` -- the 'y' is a StringLiteral but is *not* an expression
             * in the sense of something that you could extract on
             */
            function isExtractableExpression(node) {
                var parent = node.parent;
                switch (parent.kind) {
                    case 284 /* EnumMember */:
                        return false;
                }
                switch (node.kind) {
                    case 10 /* StringLiteral */:
                        return parent.kind !== 254 /* ImportDeclaration */ &&
                            parent.kind !== 258 /* ImportSpecifier */;
                    case 213 /* SpreadElement */:
                    case 189 /* ObjectBindingPattern */:
                    case 191 /* BindingElement */:
                        return false;
                    case 75 /* Identifier */:
                        return parent.kind !== 191 /* BindingElement */ &&
                            parent.kind !== 258 /* ImportSpecifier */ &&
                            parent.kind !== 263 /* ExportSpecifier */;
                }
                return true;
            }
            function isBlockLike(node) {
                switch (node.kind) {
                    case 223 /* Block */:
                    case 290 /* SourceFile */:
                    case 250 /* ModuleBlock */:
                    case 277 /* CaseClause */:
                        return true;
                    default:
                        return false;
                }
            }
        })(extractSymbol = refactor.extractSymbol || (refactor.extractSymbol = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var refactorName = "Extract type";
        var extractToTypeAlias = "Extract to type alias";
        var extractToInterface = "Extract to interface";
        var extractToTypeDef = "Extract to typedef";
        refactor.registerRefactor(refactorName, {
            getAvailableActions: function (context) {
                var info = getRangeToExtract(context);
                if (!info)
                    return ts.emptyArray;
                return [{
                        name: refactorName,
                        description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_type),
                        actions: info.isJS ? [{
                                name: extractToTypeDef, description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_typedef)
                            }] : ts.append([{
                                name: extractToTypeAlias, description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_type_alias)
                            }], info.typeElements && {
                            name: extractToInterface, description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_interface)
                        })
                    }];
            },
            getEditsForAction: function (context, actionName) {
                var file = context.file;
                var info = ts.Debug.checkDefined(getRangeToExtract(context), "Expected to find a range to extract");
                var name = ts.getUniqueName("NewType", file);
                var edits = ts.textChanges.ChangeTracker.with(context, function (changes) {
                    switch (actionName) {
                        case extractToTypeAlias:
                            ts.Debug.assert(!info.isJS, "Invalid actionName/JS combo");
                            return doTypeAliasChange(changes, file, name, info);
                        case extractToTypeDef:
                            ts.Debug.assert(info.isJS, "Invalid actionName/JS combo");
                            return doTypedefChange(changes, file, name, info);
                        case extractToInterface:
                            ts.Debug.assert(!info.isJS && !!info.typeElements, "Invalid actionName/JS combo");
                            return doInterfaceChange(changes, file, name, info);
                        default:
                            ts.Debug.fail("Unexpected action name");
                    }
                });
                var renameFilename = file.fileName;
                var renameLocation = ts.getRenameLocation(edits, renameFilename, name, /*preferLastLocation*/ false);
                return { edits: edits, renameFilename: renameFilename, renameLocation: renameLocation };
            }
        });
        function getRangeToExtract(context) {
            var file = context.file, startPosition = context.startPosition;
            var isJS = ts.isSourceFileJS(file);
            var current = ts.getTokenAtPosition(file, startPosition);
            var range = ts.createTextRangeFromSpan(ts.getRefactorContextSpan(context));
            var selection = ts.findAncestor(current, (function (node) { return node.parent && rangeContainsSkipTrivia(range, node, file) && !rangeContainsSkipTrivia(range, node.parent, file); }));
            if (!selection || !ts.isTypeNode(selection))
                return undefined;
            var checker = context.program.getTypeChecker();
            var firstStatement = ts.Debug.checkDefined(ts.findAncestor(selection, ts.isStatement), "Should find a statement");
            var typeParameters = collectTypeParameters(checker, selection, firstStatement, file);
            if (!typeParameters)
                return undefined;
            var typeElements = flattenTypeLiteralNodeReference(checker, selection);
            return { isJS: isJS, selection: selection, firstStatement: firstStatement, typeParameters: typeParameters, typeElements: typeElements };
        }
        function flattenTypeLiteralNodeReference(checker, node) {
            if (!node)
                return undefined;
            if (ts.isIntersectionTypeNode(node)) {
                var result = [];
                var seen_1 = ts.createMap();
                for (var _i = 0, _a = node.types; _i < _a.length; _i++) {
                    var type = _a[_i];
                    var flattenedTypeMembers = flattenTypeLiteralNodeReference(checker, type);
                    if (!flattenedTypeMembers || !flattenedTypeMembers.every(function (type) { return type.name && ts.addToSeen(seen_1, ts.getNameFromPropertyName(type.name)); })) {
                        return undefined;
                    }
                    ts.addRange(result, flattenedTypeMembers);
                }
                return result;
            }
            else if (ts.isParenthesizedTypeNode(node)) {
                return flattenTypeLiteralNodeReference(checker, node.type);
            }
            else if (ts.isTypeLiteralNode(node)) {
                return node.members;
            }
            return undefined;
        }
        function rangeContainsSkipTrivia(r1, node, file) {
            return ts.rangeContainsStartEnd(r1, ts.skipTrivia(file.text, node.pos), node.end);
        }
        function collectTypeParameters(checker, selection, statement, file) {
            var result = [];
            return visitor(selection) ? undefined : result;
            function visitor(node) {
                if (ts.isTypeReferenceNode(node)) {
                    if (ts.isIdentifier(node.typeName)) {
                        var symbol = checker.resolveName(node.typeName.text, node.typeName, 262144 /* TypeParameter */, /* excludeGlobals */ true);
                        if (symbol) {
                            var declaration = ts.cast(ts.first(symbol.declarations), ts.isTypeParameterDeclaration);
                            if (rangeContainsSkipTrivia(statement, declaration, file) && !rangeContainsSkipTrivia(selection, declaration, file)) {
                                result.push(declaration);
                            }
                        }
                    }
                }
                else if (ts.isInferTypeNode(node)) {
                    var conditionalTypeNode = ts.findAncestor(node, function (n) { return ts.isConditionalTypeNode(n) && rangeContainsSkipTrivia(n.extendsType, node, file); });
                    if (!conditionalTypeNode || !rangeContainsSkipTrivia(selection, conditionalTypeNode, file)) {
                        return true;
                    }
                }
                else if ((ts.isTypePredicateNode(node) || ts.isThisTypeNode(node))) {
                    var functionLikeNode = ts.findAncestor(node.parent, ts.isFunctionLike);
                    if (functionLikeNode && functionLikeNode.type && rangeContainsSkipTrivia(functionLikeNode.type, node, file) && !rangeContainsSkipTrivia(selection, functionLikeNode, file)) {
                        return true;
                    }
                }
                else if (ts.isTypeQueryNode(node)) {
                    if (ts.isIdentifier(node.exprName)) {
                        var symbol = checker.resolveName(node.exprName.text, node.exprName, 111551 /* Value */, /* excludeGlobals */ false);
                        if (symbol && rangeContainsSkipTrivia(statement, symbol.valueDeclaration, file) && !rangeContainsSkipTrivia(selection, symbol.valueDeclaration, file)) {
                            return true;
                        }
                    }
                    else {
                        if (ts.isThisIdentifier(node.exprName.left) && !rangeContainsSkipTrivia(selection, node.parent, file)) {
                            return true;
                        }
                    }
                }
                return ts.forEachChild(node, visitor);
            }
        }
        function doTypeAliasChange(changes, file, name, info) {
            var firstStatement = info.firstStatement, selection = info.selection, typeParameters = info.typeParameters;
            var newTypeNode = ts.createTypeAliasDeclaration(
            /* decorators */ undefined, 
            /* modifiers */ undefined, name, typeParameters.map(function (id) { return ts.updateTypeParameterDeclaration(id, id.name, id.constraint, /* defaultType */ undefined); }), selection);
            changes.insertNodeBefore(file, firstStatement, ts.ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true);
            changes.replaceNode(file, selection, ts.createTypeReferenceNode(name, typeParameters.map(function (id) { return ts.createTypeReferenceNode(id.name, /* typeArguments */ undefined); })));
        }
        function doInterfaceChange(changes, file, name, info) {
            var firstStatement = info.firstStatement, selection = info.selection, typeParameters = info.typeParameters, typeElements = info.typeElements;
            var newTypeNode = ts.createInterfaceDeclaration(
            /* decorators */ undefined, 
            /* modifiers */ undefined, name, typeParameters, 
            /* heritageClauses */ undefined, typeElements);
            changes.insertNodeBefore(file, firstStatement, ts.ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true);
            changes.replaceNode(file, selection, ts.createTypeReferenceNode(name, typeParameters.map(function (id) { return ts.createTypeReferenceNode(id.name, /* typeArguments */ undefined); })));
        }
        function doTypedefChange(changes, file, name, info) {
            var firstStatement = info.firstStatement, selection = info.selection, typeParameters = info.typeParameters;
            var node = ts.createNode(322 /* JSDocTypedefTag */);
            node.tagName = ts.createIdentifier("typedef"); // TODO: jsdoc factory https://github.com/Microsoft/TypeScript/pull/29539
            node.fullName = ts.createIdentifier(name);
            node.name = node.fullName;
            node.typeExpression = ts.createJSDocTypeExpression(selection);
            var templates = [];
            ts.forEach(typeParameters, function (typeParameter) {
                var constraint = ts.getEffectiveConstraintOfTypeParameter(typeParameter);
                var template = ts.createNode(321 /* JSDocTemplateTag */);
                template.tagName = ts.createIdentifier("template");
                template.constraint = constraint && ts.cast(constraint, ts.isJSDocTypeExpression);
                var parameter = ts.createNode(155 /* TypeParameter */);
                parameter.name = typeParameter.name;
                template.typeParameters = ts.createNodeArray([parameter]);
                templates.push(template);
            });
            changes.insertNodeBefore(file, firstStatement, ts.createJSDocComment(/* comment */ undefined, ts.createNodeArray(ts.concatenate(templates, [node]))), /* blankLineBetween */ true);
            changes.replaceNode(file, selection, ts.createTypeReferenceNode(name, typeParameters.map(function (id) { return ts.createTypeReferenceNode(id.name, /* typeArguments */ undefined); })));
        }
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var generateGetAccessorAndSetAccessor;
        (function (generateGetAccessorAndSetAccessor) {
            var actionName = "Generate 'get' and 'set' accessors";
            var actionDescription = ts.Diagnostics.Generate_get_and_set_accessors.message;
            refactor.registerRefactor(actionName, { getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions });
            function getAvailableActions(context) {
                if (!getConvertibleFieldAtPosition(context))
                    return ts.emptyArray;
                return [{
                        name: actionName,
                        description: actionDescription,
                        actions: [
                            {
                                name: actionName,
                                description: actionDescription
                            }
                        ]
                    }];
            }
            function getEditsForAction(context, _actionName) {
                var file = context.file;
                var fieldInfo = getConvertibleFieldAtPosition(context);
                if (!fieldInfo)
                    return undefined;
                var isJS = ts.isSourceFileJS(file);
                var changeTracker = ts.textChanges.ChangeTracker.fromContext(context);
                var isStatic = fieldInfo.isStatic, isReadonly = fieldInfo.isReadonly, fieldName = fieldInfo.fieldName, accessorName = fieldInfo.accessorName, originalName = fieldInfo.originalName, type = fieldInfo.type, container = fieldInfo.container, declaration = fieldInfo.declaration, renameAccessor = fieldInfo.renameAccessor;
                ts.suppressLeadingAndTrailingTrivia(fieldName);
                ts.suppressLeadingAndTrailingTrivia(accessorName);
                ts.suppressLeadingAndTrailingTrivia(declaration);
                ts.suppressLeadingAndTrailingTrivia(container);
                var isInClassLike = ts.isClassLike(container);
                // avoid Readonly modifier because it will convert to get accessor
                var modifierFlags = ts.getModifierFlags(declaration) & ~64 /* Readonly */;
                var accessorModifiers = isInClassLike
                    ? !modifierFlags || modifierFlags & 8 /* Private */
                        ? getModifiers(isJS, isStatic, 119 /* PublicKeyword */)
                        : ts.createNodeArray(ts.createModifiersFromModifierFlags(modifierFlags))
                    : undefined;
                var fieldModifiers = isInClassLike ? getModifiers(isJS, isStatic, 117 /* PrivateKeyword */) : undefined;
                updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers);
                var getAccessor = generateGetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container);
                ts.suppressLeadingAndTrailingTrivia(getAccessor);
                insertAccessor(changeTracker, file, getAccessor, declaration, container);
                if (isReadonly) {
                    // readonly modifier only existed in classLikeDeclaration
                    var constructor = ts.getFirstConstructorWithBody(container);
                    if (constructor) {
                        updateReadonlyPropertyInitializerStatementConstructor(changeTracker, file, constructor, fieldName.text, originalName);
                    }
                }
                else {
                    var setAccessor = generateSetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container);
                    ts.suppressLeadingAndTrailingTrivia(setAccessor);
                    insertAccessor(changeTracker, file, setAccessor, declaration, container);
                }
                var edits = changeTracker.getChanges();
                var renameFilename = file.fileName;
                var nameNeedRename = renameAccessor ? accessorName : fieldName;
                var renameLocationOffset = ts.isIdentifier(nameNeedRename) ? 0 : -1;
                var renameLocation = renameLocationOffset + ts.getRenameLocation(edits, renameFilename, nameNeedRename.text, /*preferLastLocation*/ ts.isParameter(declaration));
                return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits };
            }
            function isConvertibleName(name) {
                return ts.isIdentifier(name) || ts.isStringLiteral(name);
            }
            function isAcceptedDeclaration(node) {
                return ts.isParameterPropertyDeclaration(node, node.parent) || ts.isPropertyDeclaration(node) || ts.isPropertyAssignment(node);
            }
            function createPropertyName(name, originalName) {
                return ts.isIdentifier(originalName) ? ts.createIdentifier(name) : ts.createLiteral(name);
            }
            function createAccessorAccessExpression(fieldName, isStatic, container) {
                var leftHead = isStatic ? container.name : ts.createThis(); // TODO: GH#18217
                return ts.isIdentifier(fieldName) ? ts.createPropertyAccess(leftHead, fieldName) : ts.createElementAccess(leftHead, ts.createLiteral(fieldName));
            }
            function getModifiers(isJS, isStatic, accessModifier) {
                var modifiers = ts.append(!isJS ? [ts.createToken(accessModifier)] : undefined, isStatic ? ts.createToken(120 /* StaticKeyword */) : undefined);
                return modifiers && ts.createNodeArray(modifiers);
            }
            function getConvertibleFieldAtPosition(context) {
                var file = context.file, startPosition = context.startPosition, endPosition = context.endPosition;
                var node = ts.getTokenAtPosition(file, startPosition);
                var declaration = ts.findAncestor(node.parent, isAcceptedDeclaration);
                // make sure declaration have AccessibilityModifier or Static Modifier or Readonly Modifier
                var meaning = 28 /* AccessibilityModifier */ | 32 /* Static */ | 64 /* Readonly */;
                if (!declaration || !ts.nodeOverlapsWithStartEnd(declaration.name, file, startPosition, endPosition) // TODO: GH#18217
                    || !isConvertibleName(declaration.name) || (ts.getModifierFlags(declaration) | meaning) !== meaning)
                    return undefined;
                var name = declaration.name.text;
                var startWithUnderscore = ts.startsWithUnderscore(name);
                var fieldName = createPropertyName(startWithUnderscore ? name : ts.getUniqueName("_" + name, file), declaration.name);
                var accessorName = createPropertyName(startWithUnderscore ? ts.getUniqueName(name.substring(1), file) : name, declaration.name);
                return {
                    isStatic: ts.hasStaticModifier(declaration),
                    isReadonly: ts.hasReadonlyModifier(declaration),
                    type: ts.getTypeAnnotationNode(declaration),
                    container: declaration.kind === 156 /* Parameter */ ? declaration.parent.parent : declaration.parent,
                    originalName: declaration.name.text,
                    declaration: declaration,
                    fieldName: fieldName,
                    accessorName: accessorName,
                    renameAccessor: startWithUnderscore
                };
            }
            function generateGetAccessor(fieldName, accessorName, type, modifiers, isStatic, container) {
                return ts.createGetAccessor(
                /*decorators*/ undefined, modifiers, accessorName, 
                /*parameters*/ undefined, // TODO: GH#18217
                type, ts.createBlock([
                    ts.createReturn(createAccessorAccessExpression(fieldName, isStatic, container))
                ], /*multiLine*/ true));
            }
            function generateSetAccessor(fieldName, accessorName, type, modifiers, isStatic, container) {
                return ts.createSetAccessor(
                /*decorators*/ undefined, modifiers, accessorName, [ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, ts.createIdentifier("value"), 
                    /*questionToken*/ undefined, type)], ts.createBlock([
                    ts.createStatement(ts.createAssignment(createAccessorAccessExpression(fieldName, isStatic, container), ts.createIdentifier("value")))
                ], /*multiLine*/ true));
            }
            function updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers) {
                var property = ts.updateProperty(declaration, declaration.decorators, modifiers, fieldName, declaration.questionToken || declaration.exclamationToken, declaration.type, declaration.initializer);
                changeTracker.replaceNode(file, declaration, property);
            }
            function updatePropertyAssignmentDeclaration(changeTracker, file, declaration, fieldName) {
                var assignment = ts.updatePropertyAssignment(declaration, fieldName, declaration.initializer);
                changeTracker.replacePropertyAssignment(file, declaration, assignment);
            }
            function updateFieldDeclaration(changeTracker, file, declaration, fieldName, modifiers) {
                if (ts.isPropertyDeclaration(declaration)) {
                    updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers);
                }
                else if (ts.isPropertyAssignment(declaration)) {
                    updatePropertyAssignmentDeclaration(changeTracker, file, declaration, fieldName);
                }
                else {
                    changeTracker.replaceNode(file, declaration, ts.updateParameter(declaration, declaration.decorators, modifiers, declaration.dotDotDotToken, ts.cast(fieldName, ts.isIdentifier), declaration.questionToken, declaration.type, declaration.initializer));
                }
            }
            function insertAccessor(changeTracker, file, accessor, declaration, container) {
                ts.isParameterPropertyDeclaration(declaration, declaration.parent) ? changeTracker.insertNodeAtClassStart(file, container, accessor) :
                    ts.isPropertyAssignment(declaration) ? changeTracker.insertNodeAfterComma(file, declaration, accessor) :
                        changeTracker.insertNodeAfter(file, declaration, accessor);
            }
            function updateReadonlyPropertyInitializerStatementConstructor(changeTracker, file, constructor, fieldName, originalName) {
                if (!constructor.body)
                    return;
                constructor.body.forEachChild(function recur(node) {
                    if (ts.isElementAccessExpression(node) &&
                        node.expression.kind === 104 /* ThisKeyword */ &&
                        ts.isStringLiteral(node.argumentExpression) &&
                        node.argumentExpression.text === originalName &&
                        ts.isWriteAccess(node)) {
                        changeTracker.replaceNode(file, node.argumentExpression, ts.createStringLiteral(fieldName));
                    }
                    if (ts.isPropertyAccessExpression(node) && node.expression.kind === 104 /* ThisKeyword */ && node.name.text === originalName && ts.isWriteAccess(node)) {
                        changeTracker.replaceNode(file, node.name, ts.createIdentifier(fieldName));
                    }
                    if (!ts.isFunctionLike(node) && !ts.isClassLike(node)) {
                        node.forEachChild(recur);
                    }
                });
            }
        })(generateGetAccessorAndSetAccessor = refactor.generateGetAccessorAndSetAccessor || (refactor.generateGetAccessorAndSetAccessor = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var refactorName = "Move to a new file";
        refactor.registerRefactor(refactorName, {
            getAvailableActions: function (context) {
                if (!context.preferences.allowTextChangesInNewFiles || getStatementsToMove(context) === undefined)
                    return ts.emptyArray;
                var description = ts.getLocaleSpecificMessage(ts.Diagnostics.Move_to_a_new_file);
                return [{ name: refactorName, description: description, actions: [{ name: refactorName, description: description }] }];
            },
            getEditsForAction: function (context, actionName) {
                ts.Debug.assert(actionName === refactorName, "Wrong refactor invoked");
                var statements = ts.Debug.checkDefined(getStatementsToMove(context));
                var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(context.file, context.program, statements, t, context.host, context.preferences); });
                return { edits: edits, renameFilename: undefined, renameLocation: undefined };
            }
        });
        function getRangeToMove(context) {
            var file = context.file;
            var range = ts.createTextRangeFromSpan(ts.getRefactorContextSpan(context));
            var statements = file.statements;
            var startNodeIndex = ts.findIndex(statements, function (s) { return s.end > range.pos; });
            if (startNodeIndex === -1)
                return undefined;
            var startStatement = statements[startNodeIndex];
            if (ts.isNamedDeclaration(startStatement) && startStatement.name && ts.rangeContainsRange(startStatement.name, range)) {
                return { toMove: [statements[startNodeIndex]], afterLast: statements[startNodeIndex + 1] };
            }
            // Can't only partially include the start node or be partially into the next node
            if (range.pos > startStatement.getStart(file))
                return undefined;
            var afterEndNodeIndex = ts.findIndex(statements, function (s) { return s.end > range.end; }, startNodeIndex);
            // Can't be partially into the next node
            if (afterEndNodeIndex !== -1 && (afterEndNodeIndex === 0 || statements[afterEndNodeIndex].getStart(file) < range.end))
                return undefined;
            return {
                toMove: statements.slice(startNodeIndex, afterEndNodeIndex === -1 ? statements.length : afterEndNodeIndex),
                afterLast: afterEndNodeIndex === -1 ? undefined : statements[afterEndNodeIndex],
            };
        }
        function doChange(oldFile, program, toMove, changes, host, preferences) {
            var checker = program.getTypeChecker();
            var usage = getUsageInfo(oldFile, toMove.all, checker);
            var currentDirectory = ts.getDirectoryPath(oldFile.fileName);
            var extension = ts.extensionFromPath(oldFile.fileName);
            var newModuleName = makeUniqueModuleName(getNewModuleName(usage.movedSymbols), extension, currentDirectory, host);
            var newFileNameWithExtension = newModuleName + extension;
            // If previous file was global, this is easy.
            changes.createNewFile(oldFile, ts.combinePaths(currentDirectory, newFileNameWithExtension), getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, newModuleName, preferences));
            addNewFileToTsconfig(program, changes, oldFile.fileName, newFileNameWithExtension, ts.hostGetCanonicalFileName(host));
        }
        // Filters imports out of the range of statements to move. Imports will be copied to the new file anyway, and may still be needed in the old file.
        function getStatementsToMove(context) {
            var rangeToMove = getRangeToMove(context);
            if (rangeToMove === undefined)
                return undefined;
            var all = [];
            var ranges = [];
            var toMove = rangeToMove.toMove, afterLast = rangeToMove.afterLast;
            ts.getRangesWhere(toMove, function (s) { return !isPureImport(s); }, function (start, afterEndIndex) {
                for (var i = start; i < afterEndIndex; i++)
                    all.push(toMove[i]);
                ranges.push({ first: toMove[start], afterLast: afterLast });
            });
            return all.length === 0 ? undefined : { all: all, ranges: ranges };
        }
        function isPureImport(node) {
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return true;
                case 253 /* ImportEqualsDeclaration */:
                    return !ts.hasModifier(node, 1 /* Export */);
                case 225 /* VariableStatement */:
                    return node.declarationList.declarations.every(function (d) { return !!d.initializer && ts.isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ true); });
                default:
                    return false;
            }
        }
        function addNewFileToTsconfig(program, changes, oldFileName, newFileNameWithExtension, getCanonicalFileName) {
            var cfg = program.getCompilerOptions().configFile;
            if (!cfg)
                return;
            var newFileAbsolutePath = ts.normalizePath(ts.combinePaths(oldFileName, "..", newFileNameWithExtension));
            var newFilePath = ts.getRelativePathFromFile(cfg.fileName, newFileAbsolutePath, getCanonicalFileName);
            var cfgObject = cfg.statements[0] && ts.tryCast(cfg.statements[0].expression, ts.isObjectLiteralExpression);
            var filesProp = cfgObject && ts.find(cfgObject.properties, function (prop) {
                return ts.isPropertyAssignment(prop) && ts.isStringLiteral(prop.name) && prop.name.text === "files";
            });
            if (filesProp && ts.isArrayLiteralExpression(filesProp.initializer)) {
                changes.insertNodeInListAfter(cfg, ts.last(filesProp.initializer.elements), ts.createLiteral(newFilePath), filesProp.initializer.elements);
            }
        }
        function getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, newModuleName, preferences) {
            var checker = program.getTypeChecker();
            if (!oldFile.externalModuleIndicator && !oldFile.commonJsModuleIndicator) {
                deleteMovedStatements(oldFile, toMove.ranges, changes);
                return toMove.all;
            }
            var useEs6ModuleSyntax = !!oldFile.externalModuleIndicator;
            var quotePreference = ts.getQuotePreference(oldFile, preferences);
            var importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEs6ModuleSyntax, quotePreference);
            if (importsFromNewFile) {
                ts.insertImports(changes, oldFile, importsFromNewFile, /*blankLineBetween*/ true);
            }
            deleteUnusedOldImports(oldFile, toMove.all, changes, usage.unusedImportsFromOldFile, checker);
            deleteMovedStatements(oldFile, toMove.ranges, changes);
            updateImportsInOtherFiles(changes, program, oldFile, usage.movedSymbols, newModuleName);
            return __spreadArrays(getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, quotePreference), addExports(oldFile, toMove.all, usage.oldFileImportsFromNewFile, useEs6ModuleSyntax));
        }
        function deleteMovedStatements(sourceFile, moved, changes) {
            for (var _i = 0, moved_1 = moved; _i < moved_1.length; _i++) {
                var _a = moved_1[_i], first_1 = _a.first, afterLast = _a.afterLast;
                changes.deleteNodeRangeExcludingEnd(sourceFile, first_1, afterLast);
            }
        }
        function deleteUnusedOldImports(oldFile, toMove, changes, toDelete, checker) {
            for (var _i = 0, _a = oldFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (ts.contains(toMove, statement))
                    continue;
                forEachImportInStatement(statement, function (i) { return deleteUnusedImports(oldFile, i, changes, function (name) { return toDelete.has(checker.getSymbolAtLocation(name)); }); });
            }
        }
        function updateImportsInOtherFiles(changes, program, oldFile, movedSymbols, newModuleName) {
            var checker = program.getTypeChecker();
            var _loop_17 = function (sourceFile) {
                if (sourceFile === oldFile)
                    return "continue";
                var _loop_18 = function (statement) {
                    forEachImportInStatement(statement, function (importNode) {
                        if (checker.getSymbolAtLocation(moduleSpecifierFromImport(importNode)) !== oldFile.symbol)
                            return;
                        var shouldMove = function (name) {
                            var symbol = ts.isBindingElement(name.parent)
                                ? ts.getPropertySymbolFromBindingElement(checker, name.parent)
                                : ts.skipAlias(checker.getSymbolAtLocation(name), checker); // TODO: GH#18217
                            return !!symbol && movedSymbols.has(symbol);
                        };
                        deleteUnusedImports(sourceFile, importNode, changes, shouldMove); // These will be changed to imports from the new file
                        var newModuleSpecifier = ts.combinePaths(ts.getDirectoryPath(moduleSpecifierFromImport(importNode).text), newModuleName);
                        var newImportDeclaration = filterImport(importNode, ts.createLiteral(newModuleSpecifier), shouldMove);
                        if (newImportDeclaration)
                            changes.insertNodeAfter(sourceFile, statement, newImportDeclaration);
                        var ns = getNamespaceLikeImport(importNode);
                        if (ns)
                            updateNamespaceLikeImport(changes, sourceFile, checker, movedSymbols, newModuleName, newModuleSpecifier, ns, importNode);
                    });
                };
                for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                    var statement = _a[_i];
                    _loop_18(statement);
                }
            };
            for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                _loop_17(sourceFile);
            }
        }
        function getNamespaceLikeImport(node) {
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return node.importClause && node.importClause.namedBindings && node.importClause.namedBindings.kind === 256 /* NamespaceImport */ ?
                        node.importClause.namedBindings.name : undefined;
                case 253 /* ImportEqualsDeclaration */:
                    return node.name;
                case 242 /* VariableDeclaration */:
                    return ts.tryCast(node.name, ts.isIdentifier);
                default:
                    return ts.Debug.assertNever(node, "Unexpected node kind " + node.kind);
            }
        }
        function updateNamespaceLikeImport(changes, sourceFile, checker, movedSymbols, newModuleName, newModuleSpecifier, oldImportId, oldImportNode) {
            var preferredNewNamespaceName = ts.codefix.moduleSpecifierToValidIdentifier(newModuleName, 99 /* ESNext */);
            var needUniqueName = false;
            var toChange = [];
            ts.FindAllReferences.Core.eachSymbolReferenceInFile(oldImportId, checker, sourceFile, function (ref) {
                if (!ts.isPropertyAccessExpression(ref.parent))
                    return;
                needUniqueName = needUniqueName || !!checker.resolveName(preferredNewNamespaceName, ref, 67108863 /* All */, /*excludeGlobals*/ true);
                if (movedSymbols.has(checker.getSymbolAtLocation(ref.parent.name))) {
                    toChange.push(ref);
                }
            });
            if (toChange.length) {
                var newNamespaceName = needUniqueName ? ts.getUniqueName(preferredNewNamespaceName, sourceFile) : preferredNewNamespaceName;
                for (var _i = 0, toChange_1 = toChange; _i < toChange_1.length; _i++) {
                    var ref = toChange_1[_i];
                    changes.replaceNode(sourceFile, ref, ts.createIdentifier(newNamespaceName));
                }
                changes.insertNodeAfter(sourceFile, oldImportNode, updateNamespaceLikeImportNode(oldImportNode, newModuleName, newModuleSpecifier));
            }
        }
        function updateNamespaceLikeImportNode(node, newNamespaceName, newModuleSpecifier) {
            var newNamespaceId = ts.createIdentifier(newNamespaceName);
            var newModuleString = ts.createLiteral(newModuleSpecifier);
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return ts.createImportDeclaration(
                    /*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(newNamespaceId)), newModuleString);
                case 253 /* ImportEqualsDeclaration */:
                    return ts.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newNamespaceId, ts.createExternalModuleReference(newModuleString));
                case 242 /* VariableDeclaration */:
                    return ts.createVariableDeclaration(newNamespaceId, /*type*/ undefined, createRequireCall(newModuleString));
                default:
                    return ts.Debug.assertNever(node, "Unexpected node kind " + node.kind);
            }
        }
        function moduleSpecifierFromImport(i) {
            return (i.kind === 254 /* ImportDeclaration */ ? i.moduleSpecifier
                : i.kind === 253 /* ImportEqualsDeclaration */ ? i.moduleReference.expression
                    : i.initializer.arguments[0]);
        }
        function forEachImportInStatement(statement, cb) {
            if (ts.isImportDeclaration(statement)) {
                if (ts.isStringLiteral(statement.moduleSpecifier))
                    cb(statement);
            }
            else if (ts.isImportEqualsDeclaration(statement)) {
                if (ts.isExternalModuleReference(statement.moduleReference) && ts.isStringLiteralLike(statement.moduleReference.expression)) {
                    cb(statement);
                }
            }
            else if (ts.isVariableStatement(statement)) {
                for (var _i = 0, _a = statement.declarationList.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    if (decl.initializer && ts.isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
                        cb(decl);
                    }
                }
            }
        }
        function createOldFileImportsFromNewFile(newFileNeedExport, newFileNameWithExtension, useEs6Imports, quotePreference) {
            var defaultImport;
            var imports = [];
            newFileNeedExport.forEach(function (symbol) {
                if (symbol.escapedName === "default" /* Default */) {
                    defaultImport = ts.createIdentifier(ts.symbolNameNoDefault(symbol)); // TODO: GH#18217
                }
                else {
                    imports.push(symbol.name);
                }
            });
            return makeImportOrRequire(defaultImport, imports, newFileNameWithExtension, useEs6Imports, quotePreference);
        }
        function makeImportOrRequire(defaultImport, imports, path, useEs6Imports, quotePreference) {
            path = ts.ensurePathIsNonModuleName(path);
            if (useEs6Imports) {
                var specifiers = imports.map(function (i) { return ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(i)); });
                return ts.makeImportIfNecessary(defaultImport, specifiers, path, quotePreference);
            }
            else {
                ts.Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module.
                var bindingElements = imports.map(function (i) { return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i); });
                return bindingElements.length
                    ? makeVariableStatement(ts.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(ts.createLiteral(path)))
                    : undefined;
            }
        }
        function makeVariableStatement(name, type, initializer, flags) {
            if (flags === void 0) { flags = 2 /* Const */; }
            return ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(name, type, initializer)], flags));
        }
        function createRequireCall(moduleSpecifier) {
            return ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, [moduleSpecifier]);
        }
        function addExports(sourceFile, toMove, needExport, useEs6Exports) {
            return ts.flatMap(toMove, function (statement) {
                if (isTopLevelDeclarationStatement(statement) &&
                    !isExported(sourceFile, statement, useEs6Exports) &&
                    forEachTopLevelDeclaration(statement, function (d) { return needExport.has(ts.Debug.checkDefined(d.symbol)); })) {
                    var exports = addExport(statement, useEs6Exports);
                    if (exports)
                        return exports;
                }
                return statement;
            });
        }
        function deleteUnusedImports(sourceFile, importDecl, changes, isUnused) {
            switch (importDecl.kind) {
                case 254 /* ImportDeclaration */:
                    deleteUnusedImportsInDeclaration(sourceFile, importDecl, changes, isUnused);
                    break;
                case 253 /* ImportEqualsDeclaration */:
                    if (isUnused(importDecl.name)) {
                        changes.delete(sourceFile, importDecl);
                    }
                    break;
                case 242 /* VariableDeclaration */:
                    deleteUnusedImportsInVariableDeclaration(sourceFile, importDecl, changes, isUnused);
                    break;
                default:
                    ts.Debug.assertNever(importDecl, "Unexpected import decl kind " + importDecl.kind);
            }
        }
        function deleteUnusedImportsInDeclaration(sourceFile, importDecl, changes, isUnused) {
            if (!importDecl.importClause)
                return;
            var _a = importDecl.importClause, name = _a.name, namedBindings = _a.namedBindings;
            var defaultUnused = !name || isUnused(name);
            var namedBindingsUnused = !namedBindings ||
                (namedBindings.kind === 256 /* NamespaceImport */ ? isUnused(namedBindings.name) : namedBindings.elements.length !== 0 && namedBindings.elements.every(function (e) { return isUnused(e.name); }));
            if (defaultUnused && namedBindingsUnused) {
                changes.delete(sourceFile, importDecl);
            }
            else {
                if (name && defaultUnused) {
                    changes.delete(sourceFile, name);
                }
                if (namedBindings) {
                    if (namedBindingsUnused) {
                        changes.replaceNode(sourceFile, importDecl.importClause, ts.updateImportClause(importDecl.importClause, name, /*namedBindings*/ undefined, importDecl.importClause.isTypeOnly));
                    }
                    else if (namedBindings.kind === 257 /* NamedImports */) {
                        for (var _i = 0, _b = namedBindings.elements; _i < _b.length; _i++) {
                            var element = _b[_i];
                            if (isUnused(element.name))
                                changes.delete(sourceFile, element);
                        }
                    }
                }
            }
        }
        function deleteUnusedImportsInVariableDeclaration(sourceFile, varDecl, changes, isUnused) {
            var name = varDecl.name;
            switch (name.kind) {
                case 75 /* Identifier */:
                    if (isUnused(name)) {
                        changes.delete(sourceFile, name);
                    }
                    break;
                case 190 /* ArrayBindingPattern */:
                    break;
                case 189 /* ObjectBindingPattern */:
                    if (name.elements.every(function (e) { return ts.isIdentifier(e.name) && isUnused(e.name); })) {
                        changes.delete(sourceFile, ts.isVariableDeclarationList(varDecl.parent) && varDecl.parent.declarations.length === 1 ? varDecl.parent.parent : varDecl);
                    }
                    else {
                        for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                            var element = _a[_i];
                            if (ts.isIdentifier(element.name) && isUnused(element.name)) {
                                changes.delete(sourceFile, element.name);
                            }
                        }
                    }
                    break;
            }
        }
        function getNewFileImportsAndAddExportInOldFile(oldFile, importsToCopy, newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, quotePreference) {
            var copiedOldImports = [];
            for (var _i = 0, _a = oldFile.statements; _i < _a.length; _i++) {
                var oldStatement = _a[_i];
                forEachImportInStatement(oldStatement, function (i) {
                    ts.append(copiedOldImports, filterImport(i, moduleSpecifierFromImport(i), function (name) { return importsToCopy.has(checker.getSymbolAtLocation(name)); }));
                });
            }
            // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file.
            var oldFileDefault;
            var oldFileNamedImports = [];
            var markSeenTop = ts.nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`.
            newFileImportsFromOldFile.forEach(function (symbol) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    if (!isTopLevelDeclaration(decl))
                        continue;
                    var name = nameOfTopLevelDeclaration(decl);
                    if (!name)
                        continue;
                    var top = getTopLevelDeclarationStatement(decl);
                    if (markSeenTop(top)) {
                        addExportToChanges(oldFile, top, changes, useEs6ModuleSyntax);
                    }
                    if (ts.hasModifier(decl, 512 /* Default */)) {
                        oldFileDefault = name;
                    }
                    else {
                        oldFileNamedImports.push(name.text);
                    }
                }
            });
            ts.append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, ts.removeFileExtension(ts.getBaseFileName(oldFile.fileName)), useEs6ModuleSyntax, quotePreference));
            return copiedOldImports;
        }
        function makeUniqueModuleName(moduleName, extension, inDirectory, host) {
            var newModuleName = moduleName;
            for (var i = 1;; i++) {
                var name = ts.combinePaths(inDirectory, newModuleName + extension);
                if (!host.fileExists(name))
                    return newModuleName; // TODO: GH#18217
                newModuleName = moduleName + "." + i;
            }
        }
        function getNewModuleName(movedSymbols) {
            return movedSymbols.forEachEntry(ts.symbolNameNoDefault) || "newFile";
        }
        function getUsageInfo(oldFile, toMove, checker) {
            var movedSymbols = new SymbolSet();
            var oldImportsNeededByNewFile = new SymbolSet();
            var newFileImportsFromOldFile = new SymbolSet();
            var containsJsx = ts.find(toMove, function (statement) { return !!(statement.transformFlags & 2 /* ContainsJsx */); });
            var jsxNamespaceSymbol = getJsxNamespaceSymbol(containsJsx);
            if (jsxNamespaceSymbol) { // Might not exist (e.g. in non-compiling code)
                oldImportsNeededByNewFile.add(jsxNamespaceSymbol);
            }
            for (var _i = 0, toMove_1 = toMove; _i < toMove_1.length; _i++) {
                var statement = toMove_1[_i];
                forEachTopLevelDeclaration(statement, function (decl) {
                    movedSymbols.add(ts.Debug.checkDefined(ts.isExpressionStatement(decl) ? checker.getSymbolAtLocation(decl.expression.left) : decl.symbol, "Need a symbol here"));
                });
            }
            for (var _a = 0, toMove_2 = toMove; _a < toMove_2.length; _a++) {
                var statement = toMove_2[_a];
                forEachReference(statement, checker, function (symbol) {
                    if (!symbol.declarations)
                        return;
                    for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        if (isInImport(decl)) {
                            oldImportsNeededByNewFile.add(symbol);
                        }
                        else if (isTopLevelDeclaration(decl) && sourceFileOfTopLevelDeclaration(decl) === oldFile && !movedSymbols.has(symbol)) {
                            newFileImportsFromOldFile.add(symbol);
                        }
                    }
                });
            }
            var unusedImportsFromOldFile = oldImportsNeededByNewFile.clone();
            var oldFileImportsFromNewFile = new SymbolSet();
            for (var _b = 0, _c = oldFile.statements; _b < _c.length; _b++) {
                var statement = _c[_b];
                if (ts.contains(toMove, statement))
                    continue;
                // jsxNamespaceSymbol will only be set iff it is in oldImportsNeededByNewFile.
                if (jsxNamespaceSymbol && !!(statement.transformFlags & 2 /* ContainsJsx */)) {
                    unusedImportsFromOldFile.delete(jsxNamespaceSymbol);
                }
                forEachReference(statement, checker, function (symbol) {
                    if (movedSymbols.has(symbol))
                        oldFileImportsFromNewFile.add(symbol);
                    unusedImportsFromOldFile.delete(symbol);
                });
            }
            return { movedSymbols: movedSymbols, newFileImportsFromOldFile: newFileImportsFromOldFile, oldFileImportsFromNewFile: oldFileImportsFromNewFile, oldImportsNeededByNewFile: oldImportsNeededByNewFile, unusedImportsFromOldFile: unusedImportsFromOldFile };
            function getJsxNamespaceSymbol(containsJsx) {
                if (containsJsx === undefined) {
                    return undefined;
                }
                var jsxNamespace = checker.getJsxNamespace(containsJsx);
                // Strictly speaking, this could resolve to a symbol other than the JSX namespace.
                // This will produce erroneous output (probably, an incorrectly copied import) but
                // is expected to be very rare and easily reversible.
                var jsxNamespaceSymbol = checker.resolveName(jsxNamespace, containsJsx, 1920 /* Namespace */, /*excludeGlobals*/ true);
                return !!jsxNamespaceSymbol && ts.some(jsxNamespaceSymbol.declarations, isInImport)
                    ? jsxNamespaceSymbol
                    : undefined;
            }
        }
        // Below should all be utilities
        function isInImport(decl) {
            switch (decl.kind) {
                case 253 /* ImportEqualsDeclaration */:
                case 258 /* ImportSpecifier */:
                case 255 /* ImportClause */:
                case 256 /* NamespaceImport */:
                    return true;
                case 242 /* VariableDeclaration */:
                    return isVariableDeclarationInImport(decl);
                case 191 /* BindingElement */:
                    return ts.isVariableDeclaration(decl.parent.parent) && isVariableDeclarationInImport(decl.parent.parent);
                default:
                    return false;
            }
        }
        function isVariableDeclarationInImport(decl) {
            return ts.isSourceFile(decl.parent.parent.parent) &&
                !!decl.initializer && ts.isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true);
        }
        function filterImport(i, moduleSpecifier, keep) {
            switch (i.kind) {
                case 254 /* ImportDeclaration */: {
                    var clause = i.importClause;
                    if (!clause)
                        return undefined;
                    var defaultImport = clause.name && keep(clause.name) ? clause.name : undefined;
                    var namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep);
                    return defaultImport || namedBindings
                        ? ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(defaultImport, namedBindings), moduleSpecifier)
                        : undefined;
                }
                case 253 /* ImportEqualsDeclaration */:
                    return keep(i.name) ? i : undefined;
                case 242 /* VariableDeclaration */: {
                    var name = filterBindingName(i.name, keep);
                    return name ? makeVariableStatement(name, i.type, createRequireCall(moduleSpecifier), i.parent.flags) : undefined;
                }
                default:
                    return ts.Debug.assertNever(i, "Unexpected import kind " + i.kind);
            }
        }
        function filterNamedBindings(namedBindings, keep) {
            if (namedBindings.kind === 256 /* NamespaceImport */) {
                return keep(namedBindings.name) ? namedBindings : undefined;
            }
            else {
                var newElements = namedBindings.elements.filter(function (e) { return keep(e.name); });
                return newElements.length ? ts.createNamedImports(newElements) : undefined;
            }
        }
        function filterBindingName(name, keep) {
            switch (name.kind) {
                case 75 /* Identifier */:
                    return keep(name) ? name : undefined;
                case 190 /* ArrayBindingPattern */:
                    return name;
                case 189 /* ObjectBindingPattern */: {
                    // We can't handle nested destructurings or property names well here, so just copy them all.
                    var newElements = name.elements.filter(function (prop) { return prop.propertyName || !ts.isIdentifier(prop.name) || keep(prop.name); });
                    return newElements.length ? ts.createObjectBindingPattern(newElements) : undefined;
                }
            }
        }
        function forEachReference(node, checker, onReference) {
            node.forEachChild(function cb(node) {
                if (ts.isIdentifier(node) && !ts.isDeclarationName(node)) {
                    var sym = checker.getSymbolAtLocation(node);
                    if (sym)
                        onReference(sym);
                }
                else {
                    node.forEachChild(cb);
                }
            });
        }
        var SymbolSet = /** @class */ (function () {
            function SymbolSet() {
                this.map = ts.createMap();
            }
            SymbolSet.prototype.add = function (symbol) {
                this.map.set(String(ts.getSymbolId(symbol)), symbol);
            };
            SymbolSet.prototype.has = function (symbol) {
                return this.map.has(String(ts.getSymbolId(symbol)));
            };
            SymbolSet.prototype.delete = function (symbol) {
                this.map.delete(String(ts.getSymbolId(symbol)));
            };
            SymbolSet.prototype.forEach = function (cb) {
                this.map.forEach(cb);
            };
            SymbolSet.prototype.forEachEntry = function (cb) {
                return ts.forEachEntry(this.map, cb);
            };
            SymbolSet.prototype.clone = function () {
                var clone = new SymbolSet();
                ts.copyEntries(this.map, clone.map);
                return clone;
            };
            return SymbolSet;
        }());
        function isTopLevelDeclaration(node) {
            return isNonVariableTopLevelDeclaration(node) && ts.isSourceFile(node.parent) || ts.isVariableDeclaration(node) && ts.isSourceFile(node.parent.parent.parent);
        }
        function sourceFileOfTopLevelDeclaration(node) {
            return ts.isVariableDeclaration(node) ? node.parent.parent.parent : node.parent;
        }
        function isTopLevelDeclarationStatement(node) {
            ts.Debug.assert(ts.isSourceFile(node.parent), "Node parent should be a SourceFile");
            return isNonVariableTopLevelDeclaration(node) || ts.isVariableStatement(node);
        }
        function isNonVariableTopLevelDeclaration(node) {
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                case 245 /* ClassDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 248 /* EnumDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 253 /* ImportEqualsDeclaration */:
                    return true;
                default:
                    return false;
            }
        }
        function forEachTopLevelDeclaration(statement, cb) {
            switch (statement.kind) {
                case 244 /* FunctionDeclaration */:
                case 245 /* ClassDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 248 /* EnumDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 253 /* ImportEqualsDeclaration */:
                    return cb(statement);
                case 225 /* VariableStatement */:
                    return ts.firstDefined(statement.declarationList.declarations, function (decl) { return forEachTopLevelDeclarationInBindingName(decl.name, cb); });
                case 226 /* ExpressionStatement */: {
                    var expression = statement.expression;
                    return ts.isBinaryExpression(expression) && ts.getAssignmentDeclarationKind(expression) === 1 /* ExportsProperty */
                        ? cb(statement)
                        : undefined;
                }
            }
        }
        function forEachTopLevelDeclarationInBindingName(name, cb) {
            switch (name.kind) {
                case 75 /* Identifier */:
                    return cb(ts.cast(name.parent, function (x) { return ts.isVariableDeclaration(x) || ts.isBindingElement(x); }));
                case 190 /* ArrayBindingPattern */:
                case 189 /* ObjectBindingPattern */:
                    return ts.firstDefined(name.elements, function (em) { return ts.isOmittedExpression(em) ? undefined : forEachTopLevelDeclarationInBindingName(em.name, cb); });
                default:
                    return ts.Debug.assertNever(name, "Unexpected name kind " + name.kind);
            }
        }
        function nameOfTopLevelDeclaration(d) {
            return ts.isExpressionStatement(d) ? ts.tryCast(d.expression.left.name, ts.isIdentifier) : ts.tryCast(d.name, ts.isIdentifier);
        }
        function getTopLevelDeclarationStatement(d) {
            switch (d.kind) {
                case 242 /* VariableDeclaration */:
                    return d.parent.parent;
                case 191 /* BindingElement */:
                    return getTopLevelDeclarationStatement(ts.cast(d.parent.parent, function (p) { return ts.isVariableDeclaration(p) || ts.isBindingElement(p); }));
                default:
                    return d;
            }
        }
        function addExportToChanges(sourceFile, decl, changes, useEs6Exports) {
            if (isExported(sourceFile, decl, useEs6Exports))
                return;
            if (useEs6Exports) {
                if (!ts.isExpressionStatement(decl))
                    changes.insertExportModifier(sourceFile, decl);
            }
            else {
                var names = getNamesToExportInCommonJS(decl);
                if (names.length !== 0)
                    changes.insertNodesAfter(sourceFile, decl, names.map(createExportAssignment));
            }
        }
        function isExported(sourceFile, decl, useEs6Exports) {
            if (useEs6Exports) {
                return !ts.isExpressionStatement(decl) && ts.hasModifier(decl, 1 /* Export */);
            }
            else {
                return getNamesToExportInCommonJS(decl).some(function (name) { return sourceFile.symbol.exports.has(ts.escapeLeadingUnderscores(name)); });
            }
        }
        function addExport(decl, useEs6Exports) {
            return useEs6Exports ? [addEs6Export(decl)] : addCommonjsExport(decl);
        }
        function addEs6Export(d) {
            var modifiers = ts.concatenate([ts.createModifier(89 /* ExportKeyword */)], d.modifiers);
            switch (d.kind) {
                case 244 /* FunctionDeclaration */:
                    return ts.updateFunctionDeclaration(d, d.decorators, modifiers, d.asteriskToken, d.name, d.typeParameters, d.parameters, d.type, d.body);
                case 245 /* ClassDeclaration */:
                    return ts.updateClassDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members);
                case 225 /* VariableStatement */:
                    return ts.updateVariableStatement(d, modifiers, d.declarationList);
                case 249 /* ModuleDeclaration */:
                    return ts.updateModuleDeclaration(d, d.decorators, modifiers, d.name, d.body);
                case 248 /* EnumDeclaration */:
                    return ts.updateEnumDeclaration(d, d.decorators, modifiers, d.name, d.members);
                case 247 /* TypeAliasDeclaration */:
                    return ts.updateTypeAliasDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.type);
                case 246 /* InterfaceDeclaration */:
                    return ts.updateInterfaceDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members);
                case 253 /* ImportEqualsDeclaration */:
                    return ts.updateImportEqualsDeclaration(d, d.decorators, modifiers, d.name, d.moduleReference);
                case 226 /* ExpressionStatement */:
                    return ts.Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...`
                default:
                    return ts.Debug.assertNever(d, "Unexpected declaration kind " + d.kind);
            }
        }
        function addCommonjsExport(decl) {
            return __spreadArrays([decl], getNamesToExportInCommonJS(decl).map(createExportAssignment));
        }
        function getNamesToExportInCommonJS(decl) {
            switch (decl.kind) {
                case 244 /* FunctionDeclaration */:
                case 245 /* ClassDeclaration */:
                    return [decl.name.text]; // TODO: GH#18217
                case 225 /* VariableStatement */:
                    return ts.mapDefined(decl.declarationList.declarations, function (d) { return ts.isIdentifier(d.name) ? d.name.text : undefined; });
                case 249 /* ModuleDeclaration */:
                case 248 /* EnumDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 253 /* ImportEqualsDeclaration */:
                    return ts.emptyArray;
                case 226 /* ExpressionStatement */:
                    return ts.Debug.fail("Can't export an ExpressionStatement"); // Shouldn't try to add 'export' keyword to `exports.x = ...`
                default:
                    return ts.Debug.assertNever(decl, "Unexpected decl kind " + decl.kind);
            }
        }
        /** Creates `exports.x = x;` */
        function createExportAssignment(name) {
            return ts.createExpressionStatement(ts.createBinary(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.createIdentifier(name)), 62 /* EqualsToken */, ts.createIdentifier(name)));
        }
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var addOrRemoveBracesToArrowFunction;
        (function (addOrRemoveBracesToArrowFunction) {
            var refactorName = "Add or remove braces in an arrow function";
            var refactorDescription = ts.Diagnostics.Add_or_remove_braces_in_an_arrow_function.message;
            var addBracesActionName = "Add braces to arrow function";
            var removeBracesActionName = "Remove braces from arrow function";
            var addBracesActionDescription = ts.Diagnostics.Add_braces_to_arrow_function.message;
            var removeBracesActionDescription = ts.Diagnostics.Remove_braces_from_arrow_function.message;
            refactor.registerRefactor(refactorName, { getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions });
            function getAvailableActions(context) {
                var file = context.file, startPosition = context.startPosition;
                var info = getConvertibleArrowFunctionAtPosition(file, startPosition);
                if (!info)
                    return ts.emptyArray;
                return [{
                        name: refactorName,
                        description: refactorDescription,
                        actions: [
                            info.addBraces ?
                                {
                                    name: addBracesActionName,
                                    description: addBracesActionDescription
                                } : {
                                name: removeBracesActionName,
                                description: removeBracesActionDescription
                            }
                        ]
                    }];
            }
            function getEditsForAction(context, actionName) {
                var file = context.file, startPosition = context.startPosition;
                var info = getConvertibleArrowFunctionAtPosition(file, startPosition);
                if (!info)
                    return undefined;
                var expression = info.expression, returnStatement = info.returnStatement, func = info.func;
                var body;
                if (actionName === addBracesActionName) {
                    var returnStatement_1 = ts.createReturn(expression);
                    body = ts.createBlock([returnStatement_1], /* multiLine */ true);
                    ts.suppressLeadingAndTrailingTrivia(body);
                    ts.copyLeadingComments(expression, returnStatement_1, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ true);
                }
                else if (actionName === removeBracesActionName && returnStatement) {
                    var actualExpression = expression || ts.createVoidZero();
                    body = ts.needsParentheses(actualExpression) ? ts.createParen(actualExpression) : actualExpression;
                    ts.suppressLeadingAndTrailingTrivia(body);
                    ts.copyTrailingAsLeadingComments(returnStatement, body, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ false);
                    ts.copyLeadingComments(returnStatement, body, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ false);
                    ts.copyTrailingComments(returnStatement, body, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ false);
                }
                else {
                    ts.Debug.fail("invalid action");
                }
                var edits = ts.textChanges.ChangeTracker.with(context, function (t) {
                    t.replaceNode(file, func.body, body);
                });
                return { renameFilename: undefined, renameLocation: undefined, edits: edits };
            }
            function getConvertibleArrowFunctionAtPosition(file, startPosition) {
                var node = ts.getTokenAtPosition(file, startPosition);
                var func = ts.getContainingFunction(node);
                if (!func || !ts.isArrowFunction(func) || (!ts.rangeContainsRange(func, node) || ts.rangeContainsRange(func.body, node)))
                    return undefined;
                if (ts.isExpression(func.body)) {
                    return {
                        func: func,
                        addBraces: true,
                        expression: func.body
                    };
                }
                else if (func.body.statements.length === 1) {
                    var firstStatement = ts.first(func.body.statements);
                    if (ts.isReturnStatement(firstStatement)) {
                        return {
                            func: func,
                            addBraces: false,
                            expression: firstStatement.expression,
                            returnStatement: firstStatement
                        };
                    }
                }
                return undefined;
            }
        })(addOrRemoveBracesToArrowFunction = refactor.addOrRemoveBracesToArrowFunction || (refactor.addOrRemoveBracesToArrowFunction = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var convertParamsToDestructuredObject;
        (function (convertParamsToDestructuredObject) {
            var refactorName = "Convert parameters to destructured object";
            var minimumParameterLength = 2;
            refactor.registerRefactor(refactorName, { getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions });
            function getAvailableActions(context) {
                var file = context.file, startPosition = context.startPosition;
                var isJSFile = ts.isSourceFileJS(file);
                if (isJSFile)
                    return ts.emptyArray; // TODO: GH#30113
                var functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, context.program.getTypeChecker());
                if (!functionDeclaration)
                    return ts.emptyArray;
                var description = ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_parameters_to_destructured_object);
                return [{
                        name: refactorName,
                        description: description,
                        actions: [{
                                name: refactorName,
                                description: description
                            }]
                    }];
            }
            function getEditsForAction(context, actionName) {
                ts.Debug.assert(actionName === refactorName, "Unexpected action name");
                var file = context.file, startPosition = context.startPosition, program = context.program, cancellationToken = context.cancellationToken, host = context.host;
                var functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, program.getTypeChecker());
                if (!functionDeclaration || !cancellationToken)
                    return undefined;
                var groupedReferences = getGroupedReferences(functionDeclaration, program, cancellationToken);
                if (groupedReferences.valid) {
                    var edits = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(file, program, host, t, functionDeclaration, groupedReferences); });
                    return { renameFilename: undefined, renameLocation: undefined, edits: edits };
                }
                return { edits: [] }; // TODO: GH#30113
            }
            function doChange(sourceFile, program, host, changes, functionDeclaration, groupedReferences) {
                var newParamDeclaration = ts.map(createNewParameters(functionDeclaration, program, host), function (param) { return ts.getSynthesizedDeepClone(param); });
                changes.replaceNodeRangeWithNodes(sourceFile, ts.first(functionDeclaration.parameters), ts.last(functionDeclaration.parameters), newParamDeclaration, { joiner: ", ",
                    // indentation is set to 0 because otherwise the object parameter will be indented if there is a `this` parameter
                    indentation: 0,
                    leadingTriviaOption: ts.textChanges.LeadingTriviaOption.IncludeAll,
                    trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include
                });
                var functionCalls = ts.sortAndDeduplicate(groupedReferences.functionCalls, /*comparer*/ function (a, b) { return ts.compareValues(a.pos, b.pos); });
                for (var _i = 0, functionCalls_1 = functionCalls; _i < functionCalls_1.length; _i++) {
                    var call = functionCalls_1[_i];
                    if (call.arguments && call.arguments.length) {
                        var newArgument = ts.getSynthesizedDeepClone(createNewArgument(functionDeclaration, call.arguments), /*includeTrivia*/ true);
                        changes.replaceNodeRange(ts.getSourceFileOfNode(call), ts.first(call.arguments), ts.last(call.arguments), newArgument, { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.IncludeAll, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include });
                    }
                }
            }
            function getGroupedReferences(functionDeclaration, program, cancellationToken) {
                var functionNames = getFunctionNames(functionDeclaration);
                var classNames = ts.isConstructorDeclaration(functionDeclaration) ? getClassNames(functionDeclaration) : [];
                var names = ts.deduplicate(__spreadArrays(functionNames, classNames), ts.equateValues);
                var checker = program.getTypeChecker();
                var references = ts.flatMap(names, /*mapfn*/ function (/*mapfn*/ name) { return ts.FindAllReferences.getReferenceEntriesForNode(-1, name, program, program.getSourceFiles(), cancellationToken); });
                var groupedReferences = groupReferences(references);
                if (!ts.every(groupedReferences.declarations, /*callback*/ function (/*callback*/ decl) { return ts.contains(names, decl); })) {
                    groupedReferences.valid = false;
                }
                return groupedReferences;
                function groupReferences(referenceEntries) {
                    var classReferences = { accessExpressions: [], typeUsages: [] };
                    var groupedReferences = { functionCalls: [], declarations: [], classReferences: classReferences, valid: true };
                    var functionSymbols = ts.map(functionNames, getSymbolTargetAtLocation);
                    var classSymbols = ts.map(classNames, getSymbolTargetAtLocation);
                    var isConstructor = ts.isConstructorDeclaration(functionDeclaration);
                    for (var _i = 0, referenceEntries_1 = referenceEntries; _i < referenceEntries_1.length; _i++) {
                        var entry = referenceEntries_1[_i];
                        if (entry.kind !== 1 /* Node */) {
                            groupedReferences.valid = false;
                            continue;
                        }
                        /* We compare symbols because in some cases find all references wil return a reference that may or may not be to the refactored function.
                        Example from the refactorConvertParamsToDestructuredObject_methodCallUnion.ts test:
                            class A { foo(a: number, b: number) { return a + b; } }
                            class B { foo(c: number, d: number) { return c + d; } }
                            declare const ab: A | B;
                            ab.foo(1, 2);
                        Find all references will return `ab.foo(1, 2)` as a reference to A's `foo` but we could be calling B's `foo`.
                        When looking for constructor calls, however, the symbol on the constructor call reference is going to be the corresponding class symbol.
                        So we need to add a special case for this because when calling a constructor of a class through one of its subclasses,
                        the symbols are going to be different.
                        */
                        if (ts.contains(functionSymbols, getSymbolTargetAtLocation(entry.node)) || ts.isNewExpressionTarget(entry.node)) {
                            var importOrExportReference = entryToImportOrExport(entry);
                            if (importOrExportReference) {
                                continue;
                            }
                            var decl = entryToDeclaration(entry);
                            if (decl) {
                                groupedReferences.declarations.push(decl);
                                continue;
                            }
                            var call = entryToFunctionCall(entry);
                            if (call) {
                                groupedReferences.functionCalls.push(call);
                                continue;
                            }
                        }
                        // if the refactored function is a constructor, we must also check if the references to its class are valid
                        if (isConstructor && ts.contains(classSymbols, getSymbolTargetAtLocation(entry.node))) {
                            var importOrExportReference = entryToImportOrExport(entry);
                            if (importOrExportReference) {
                                continue;
                            }
                            var decl = entryToDeclaration(entry);
                            if (decl) {
                                groupedReferences.declarations.push(decl);
                                continue;
                            }
                            var accessExpression = entryToAccessExpression(entry);
                            if (accessExpression) {
                                classReferences.accessExpressions.push(accessExpression);
                                continue;
                            }
                            // Only class declarations are allowed to be used as a type (in a heritage clause),
                            // otherwise `findAllReferences` might not be able to track constructor calls.
                            if (ts.isClassDeclaration(functionDeclaration.parent)) {
                                var type = entryToType(entry);
                                if (type) {
                                    classReferences.typeUsages.push(type);
                                    continue;
                                }
                            }
                        }
                        groupedReferences.valid = false;
                    }
                    return groupedReferences;
                }
                function getSymbolTargetAtLocation(node) {
                    var symbol = checker.getSymbolAtLocation(node);
                    return symbol && ts.getSymbolTarget(symbol, checker);
                }
            }
            function entryToImportOrExport(entry) {
                var node = entry.node;
                if (ts.isImportSpecifier(node.parent)
                    || ts.isImportClause(node.parent)
                    || ts.isImportEqualsDeclaration(node.parent)
                    || ts.isNamespaceImport(node.parent)) {
                    return node;
                }
                if (ts.isExportSpecifier(node.parent) || ts.isExportAssignment(node.parent)) {
                    return node;
                }
                return undefined;
            }
            function entryToDeclaration(entry) {
                if (ts.isDeclaration(entry.node.parent)) {
                    return entry.node;
                }
                return undefined;
            }
            function entryToFunctionCall(entry) {
                if (entry.node.parent) {
                    var functionReference = entry.node;
                    var parent = functionReference.parent;
                    switch (parent.kind) {
                        // foo(...) or super(...) or new Foo(...)
                        case 196 /* CallExpression */:
                        case 197 /* NewExpression */:
                            var callOrNewExpression = ts.tryCast(parent, ts.isCallOrNewExpression);
                            if (callOrNewExpression && callOrNewExpression.expression === functionReference) {
                                return callOrNewExpression;
                            }
                            break;
                        // x.foo(...)
                        case 194 /* PropertyAccessExpression */:
                            var propertyAccessExpression = ts.tryCast(parent, ts.isPropertyAccessExpression);
                            if (propertyAccessExpression && propertyAccessExpression.parent && propertyAccessExpression.name === functionReference) {
                                var callOrNewExpression_1 = ts.tryCast(propertyAccessExpression.parent, ts.isCallOrNewExpression);
                                if (callOrNewExpression_1 && callOrNewExpression_1.expression === propertyAccessExpression) {
                                    return callOrNewExpression_1;
                                }
                            }
                            break;
                        // x["foo"](...)
                        case 195 /* ElementAccessExpression */:
                            var elementAccessExpression = ts.tryCast(parent, ts.isElementAccessExpression);
                            if (elementAccessExpression && elementAccessExpression.parent && elementAccessExpression.argumentExpression === functionReference) {
                                var callOrNewExpression_2 = ts.tryCast(elementAccessExpression.parent, ts.isCallOrNewExpression);
                                if (callOrNewExpression_2 && callOrNewExpression_2.expression === elementAccessExpression) {
                                    return callOrNewExpression_2;
                                }
                            }
                            break;
                    }
                }
                return undefined;
            }
            function entryToAccessExpression(entry) {
                if (entry.node.parent) {
                    var reference = entry.node;
                    var parent = reference.parent;
                    switch (parent.kind) {
                        // `C.foo`
                        case 194 /* PropertyAccessExpression */:
                            var propertyAccessExpression = ts.tryCast(parent, ts.isPropertyAccessExpression);
                            if (propertyAccessExpression && propertyAccessExpression.expression === reference) {
                                return propertyAccessExpression;
                            }
                            break;
                        // `C["foo"]`
                        case 195 /* ElementAccessExpression */:
                            var elementAccessExpression = ts.tryCast(parent, ts.isElementAccessExpression);
                            if (elementAccessExpression && elementAccessExpression.expression === reference) {
                                return elementAccessExpression;
                            }
                            break;
                    }
                }
                return undefined;
            }
            function entryToType(entry) {
                var reference = entry.node;
                if (ts.getMeaningFromLocation(reference) === 2 /* Type */ || ts.isExpressionWithTypeArgumentsInClassExtendsClause(reference.parent)) {
                    return reference;
                }
                return undefined;
            }
            function getFunctionDeclarationAtPosition(file, startPosition, checker) {
                var node = ts.getTouchingToken(file, startPosition);
                var functionDeclaration = ts.getContainingFunctionDeclaration(node);
                // don't offer refactor on top-level JSDoc
                if (isTopLevelJSDoc(node))
                    return undefined;
                if (functionDeclaration
                    && isValidFunctionDeclaration(functionDeclaration, checker)
                    && ts.rangeContainsRange(functionDeclaration, node)
                    && !(functionDeclaration.body && ts.rangeContainsRange(functionDeclaration.body, node)))
                    return functionDeclaration;
                return undefined;
            }
            function isTopLevelJSDoc(node) {
                var containingJSDoc = ts.findAncestor(node, ts.isJSDocNode);
                if (containingJSDoc) {
                    var containingNonJSDoc = ts.findAncestor(containingJSDoc, function (n) { return !ts.isJSDocNode(n); });
                    return !!containingNonJSDoc && ts.isFunctionLikeDeclaration(containingNonJSDoc);
                }
                return false;
            }
            function isValidFunctionDeclaration(functionDeclaration, checker) {
                if (!isValidParameterNodeArray(functionDeclaration.parameters, checker))
                    return false;
                switch (functionDeclaration.kind) {
                    case 244 /* FunctionDeclaration */:
                        return hasNameOrDefault(functionDeclaration) && isSingleImplementation(functionDeclaration, checker);
                    case 161 /* MethodDeclaration */:
                        return isSingleImplementation(functionDeclaration, checker);
                    case 162 /* Constructor */:
                        if (ts.isClassDeclaration(functionDeclaration.parent)) {
                            return hasNameOrDefault(functionDeclaration.parent) && isSingleImplementation(functionDeclaration, checker);
                        }
                        else {
                            return isValidVariableDeclaration(functionDeclaration.parent.parent)
                                && isSingleImplementation(functionDeclaration, checker);
                        }
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                        return isValidVariableDeclaration(functionDeclaration.parent);
                }
                return false;
            }
            function isSingleImplementation(functionDeclaration, checker) {
                return !!functionDeclaration.body && !checker.isImplementationOfOverload(functionDeclaration);
            }
            function hasNameOrDefault(functionOrClassDeclaration) {
                if (!functionOrClassDeclaration.name) {
                    var defaultKeyword = ts.findModifier(functionOrClassDeclaration, 84 /* DefaultKeyword */);
                    return !!defaultKeyword;
                }
                return true;
            }
            function isValidParameterNodeArray(parameters, checker) {
                return getRefactorableParametersLength(parameters) >= minimumParameterLength
                    && ts.every(parameters, /*callback*/ function (/*callback*/ paramDecl) { return isValidParameterDeclaration(paramDecl, checker); });
            }
            function isValidParameterDeclaration(parameterDeclaration, checker) {
                if (ts.isRestParameter(parameterDeclaration)) {
                    var type = checker.getTypeAtLocation(parameterDeclaration);
                    if (!checker.isArrayType(type) && !checker.isTupleType(type))
                        return false;
                }
                return !parameterDeclaration.modifiers && !parameterDeclaration.decorators && ts.isIdentifier(parameterDeclaration.name);
            }
            function isValidVariableDeclaration(node) {
                return ts.isVariableDeclaration(node) && ts.isVarConst(node) && ts.isIdentifier(node.name) && !node.type; // TODO: GH#30113
            }
            function hasThisParameter(parameters) {
                return parameters.length > 0 && ts.isThis(parameters[0].name);
            }
            function getRefactorableParametersLength(parameters) {
                if (hasThisParameter(parameters)) {
                    return parameters.length - 1;
                }
                return parameters.length;
            }
            function getRefactorableParameters(parameters) {
                if (hasThisParameter(parameters)) {
                    parameters = ts.createNodeArray(parameters.slice(1), parameters.hasTrailingComma);
                }
                return parameters;
            }
            function createPropertyOrShorthandAssignment(name, initializer) {
                if (ts.isIdentifier(initializer) && ts.getTextOfIdentifierOrLiteral(initializer) === name) {
                    return ts.createShorthandPropertyAssignment(name);
                }
                return ts.createPropertyAssignment(name, initializer);
            }
            function createNewArgument(functionDeclaration, functionArguments) {
                var parameters = getRefactorableParameters(functionDeclaration.parameters);
                var hasRestParameter = ts.isRestParameter(ts.last(parameters));
                var nonRestArguments = hasRestParameter ? functionArguments.slice(0, parameters.length - 1) : functionArguments;
                var properties = ts.map(nonRestArguments, function (arg, i) {
                    var parameterName = getParameterName(parameters[i]);
                    var property = createPropertyOrShorthandAssignment(parameterName, arg);
                    ts.suppressLeadingAndTrailingTrivia(property.name);
                    if (ts.isPropertyAssignment(property))
                        ts.suppressLeadingAndTrailingTrivia(property.initializer);
                    ts.copyComments(arg, property);
                    return property;
                });
                if (hasRestParameter && functionArguments.length >= parameters.length) {
                    var restArguments = functionArguments.slice(parameters.length - 1);
                    var restProperty = ts.createPropertyAssignment(getParameterName(ts.last(parameters)), ts.createArrayLiteral(restArguments));
                    properties.push(restProperty);
                }
                var objectLiteral = ts.createObjectLiteral(properties, /*multiLine*/ false);
                return objectLiteral;
            }
            function createNewParameters(functionDeclaration, program, host) {
                var checker = program.getTypeChecker();
                var refactorableParameters = getRefactorableParameters(functionDeclaration.parameters);
                var bindingElements = ts.map(refactorableParameters, createBindingElementFromParameterDeclaration);
                var objectParameterName = ts.createObjectBindingPattern(bindingElements);
                var objectParameterType = createParameterTypeNode(refactorableParameters);
                var objectInitializer;
                // If every parameter in the original function was optional, add an empty object initializer to the new object parameter
                if (ts.every(refactorableParameters, isOptionalParameter)) {
                    objectInitializer = ts.createObjectLiteral();
                }
                var objectParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, objectParameterName, 
                /*questionToken*/ undefined, objectParameterType, objectInitializer);
                if (hasThisParameter(functionDeclaration.parameters)) {
                    var thisParameter = functionDeclaration.parameters[0];
                    var newThisParameter = ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, thisParameter.name, 
                    /*questionToken*/ undefined, thisParameter.type);
                    ts.suppressLeadingAndTrailingTrivia(newThisParameter.name);
                    ts.copyComments(thisParameter.name, newThisParameter.name);
                    if (thisParameter.type) {
                        ts.suppressLeadingAndTrailingTrivia(newThisParameter.type);
                        ts.copyComments(thisParameter.type, newThisParameter.type);
                    }
                    return ts.createNodeArray([newThisParameter, objectParameter]);
                }
                return ts.createNodeArray([objectParameter]);
                function createBindingElementFromParameterDeclaration(parameterDeclaration) {
                    var element = ts.createBindingElement(
                    /*dotDotDotToken*/ undefined, 
                    /*propertyName*/ undefined, getParameterName(parameterDeclaration), ts.isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? ts.createArrayLiteral() : parameterDeclaration.initializer);
                    ts.suppressLeadingAndTrailingTrivia(element);
                    if (parameterDeclaration.initializer && element.initializer) {
                        ts.copyComments(parameterDeclaration.initializer, element.initializer);
                    }
                    return element;
                }
                function createParameterTypeNode(parameters) {
                    var members = ts.map(parameters, createPropertySignatureFromParameterDeclaration);
                    var typeNode = ts.addEmitFlags(ts.createTypeLiteralNode(members), 1 /* SingleLine */);
                    return typeNode;
                }
                function createPropertySignatureFromParameterDeclaration(parameterDeclaration) {
                    var parameterType = parameterDeclaration.type;
                    if (!parameterType && (parameterDeclaration.initializer || ts.isRestParameter(parameterDeclaration))) {
                        parameterType = getTypeNode(parameterDeclaration);
                    }
                    var propertySignature = ts.createPropertySignature(
                    /*modifiers*/ undefined, getParameterName(parameterDeclaration), isOptionalParameter(parameterDeclaration) ? ts.createToken(57 /* QuestionToken */) : parameterDeclaration.questionToken, parameterType, 
                    /*initializer*/ undefined);
                    ts.suppressLeadingAndTrailingTrivia(propertySignature);
                    ts.copyComments(parameterDeclaration.name, propertySignature.name);
                    if (parameterDeclaration.type && propertySignature.type) {
                        ts.copyComments(parameterDeclaration.type, propertySignature.type);
                    }
                    return propertySignature;
                }
                function getTypeNode(node) {
                    var type = checker.getTypeAtLocation(node);
                    return ts.getTypeNodeIfAccessible(type, node, program, host);
                }
                function isOptionalParameter(parameterDeclaration) {
                    if (ts.isRestParameter(parameterDeclaration)) {
                        var type = checker.getTypeAtLocation(parameterDeclaration);
                        return !checker.isTupleType(type);
                    }
                    return checker.isOptionalParameter(parameterDeclaration);
                }
            }
            function getParameterName(paramDeclaration) {
                return ts.getTextOfIdentifierOrLiteral(paramDeclaration.name);
            }
            function getClassNames(constructorDeclaration) {
                switch (constructorDeclaration.parent.kind) {
                    case 245 /* ClassDeclaration */:
                        var classDeclaration = constructorDeclaration.parent;
                        if (classDeclaration.name)
                            return [classDeclaration.name];
                        // If the class declaration doesn't have a name, it should have a default modifier.
                        // We validated this in `isValidFunctionDeclaration` through `hasNameOrDefault`
                        var defaultModifier = ts.Debug.checkDefined(ts.findModifier(classDeclaration, 84 /* DefaultKeyword */), "Nameless class declaration should be a default export");
                        return [defaultModifier];
                    case 214 /* ClassExpression */:
                        var classExpression = constructorDeclaration.parent;
                        var variableDeclaration = constructorDeclaration.parent.parent;
                        var className = classExpression.name;
                        if (className)
                            return [className, variableDeclaration.name];
                        return [variableDeclaration.name];
                }
            }
            function getFunctionNames(functionDeclaration) {
                switch (functionDeclaration.kind) {
                    case 244 /* FunctionDeclaration */:
                        if (functionDeclaration.name)
                            return [functionDeclaration.name];
                        // If the function declaration doesn't have a name, it should have a default modifier.
                        // We validated this in `isValidFunctionDeclaration` through `hasNameOrDefault`
                        var defaultModifier = ts.Debug.checkDefined(ts.findModifier(functionDeclaration, 84 /* DefaultKeyword */), "Nameless function declaration should be a default export");
                        return [defaultModifier];
                    case 161 /* MethodDeclaration */:
                        return [functionDeclaration.name];
                    case 162 /* Constructor */:
                        var ctrKeyword = ts.Debug.checkDefined(ts.findChildOfKind(functionDeclaration, 129 /* ConstructorKeyword */, functionDeclaration.getSourceFile()), "Constructor declaration should have constructor keyword");
                        if (functionDeclaration.parent.kind === 214 /* ClassExpression */) {
                            var variableDeclaration = functionDeclaration.parent.parent;
                            return [variableDeclaration.name, ctrKeyword];
                        }
                        return [ctrKeyword];
                    case 202 /* ArrowFunction */:
                        return [functionDeclaration.parent.name];
                    case 201 /* FunctionExpression */:
                        if (functionDeclaration.name)
                            return [functionDeclaration.name, functionDeclaration.parent.name];
                        return [functionDeclaration.parent.name];
                    default:
                        return ts.Debug.assertNever(functionDeclaration, "Unexpected function declaration kind " + functionDeclaration.kind);
                }
            }
        })(convertParamsToDestructuredObject = refactor.convertParamsToDestructuredObject || (refactor.convertParamsToDestructuredObject = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var refactor;
    (function (refactor) {
        var convertStringOrTemplateLiteral;
        (function (convertStringOrTemplateLiteral) {
            var refactorName = "Convert to template string";
            var refactorDescription = ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_to_template_string);
            refactor.registerRefactor(refactorName, { getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions });
            function getAvailableActions(context) {
                var file = context.file, startPosition = context.startPosition;
                var node = getNodeOrParentOfParentheses(file, startPosition);
                var maybeBinary = getParentBinaryExpression(node);
                var refactorInfo = { name: refactorName, description: refactorDescription, actions: [] };
                if (ts.isBinaryExpression(maybeBinary) && isStringConcatenationValid(maybeBinary)) {
                    refactorInfo.actions.push({ name: refactorName, description: refactorDescription });
                    return [refactorInfo];
                }
                return ts.emptyArray;
            }
            function getNodeOrParentOfParentheses(file, startPosition) {
                var node = ts.getTokenAtPosition(file, startPosition);
                var nestedBinary = getParentBinaryExpression(node);
                var isNonStringBinary = !isStringConcatenationValid(nestedBinary);
                if (isNonStringBinary &&
                    ts.isParenthesizedExpression(nestedBinary.parent) &&
                    ts.isBinaryExpression(nestedBinary.parent.parent)) {
                    return nestedBinary.parent.parent;
                }
                return node;
            }
            function getEditsForAction(context, actionName) {
                var file = context.file, startPosition = context.startPosition;
                var node = getNodeOrParentOfParentheses(file, startPosition);
                switch (actionName) {
                    case refactorDescription:
                        return { edits: getEditsForToTemplateLiteral(context, node) };
                    default:
                        return ts.Debug.fail("invalid action");
                }
            }
            function getEditsForToTemplateLiteral(context, node) {
                var maybeBinary = getParentBinaryExpression(node);
                var file = context.file;
                var templateLiteral = nodesToTemplate(treeToArray(maybeBinary), file);
                var trailingCommentRanges = ts.getTrailingCommentRanges(file.text, maybeBinary.end);
                if (trailingCommentRanges) {
                    var lastComment = trailingCommentRanges[trailingCommentRanges.length - 1];
                    var trailingRange_1 = { pos: trailingCommentRanges[0].pos, end: lastComment.end };
                    // since suppressTrailingTrivia(maybeBinary) does not work, the trailing comment is removed manually
                    // otherwise it would have the trailing comment twice
                    return ts.textChanges.ChangeTracker.with(context, function (t) {
                        t.deleteRange(file, trailingRange_1);
                        t.replaceNode(file, maybeBinary, templateLiteral);
                    });
                }
                else {
                    return ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(file, maybeBinary, templateLiteral); });
                }
            }
            function isNotEqualsOperator(node) {
                return node.operatorToken.kind !== 62 /* EqualsToken */;
            }
            function getParentBinaryExpression(expr) {
                while (ts.isBinaryExpression(expr.parent) && isNotEqualsOperator(expr.parent)) {
                    expr = expr.parent;
                }
                return expr;
            }
            function isStringConcatenationValid(node) {
                var _a = treeToArray(node), containsString = _a.containsString, areOperatorsValid = _a.areOperatorsValid;
                return containsString && areOperatorsValid;
            }
            function treeToArray(current) {
                if (ts.isBinaryExpression(current)) {
                    var _a = treeToArray(current.left), nodes = _a.nodes, operators = _a.operators, leftHasString = _a.containsString, leftOperatorValid = _a.areOperatorsValid;
                    if (!leftHasString && !ts.isStringLiteral(current.right)) {
                        return { nodes: [current], operators: [], containsString: false, areOperatorsValid: true };
                    }
                    var currentOperatorValid = current.operatorToken.kind === 39 /* PlusToken */;
                    var areOperatorsValid = leftOperatorValid && currentOperatorValid;
                    nodes.push(current.right);
                    operators.push(current.operatorToken);
                    return { nodes: nodes, operators: operators, containsString: true, areOperatorsValid: areOperatorsValid };
                }
                return { nodes: [current], operators: [], containsString: ts.isStringLiteral(current), areOperatorsValid: true };
            }
            // to copy comments following the operator
            // "foo" + /* comment */ "bar"
            var copyTrailingOperatorComments = function (operators, file) { return function (index, targetNode) {
                if (index < operators.length) {
                    ts.copyTrailingComments(operators[index], targetNode, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ false);
                }
            }; };
            // to copy comments following the string
            // "foo" /* comment */ + "bar" /* comment */ + "bar2"
            var copyCommentFromMultiNode = function (nodes, file, copyOperatorComments) {
                return function (indexes, targetNode) {
                    while (indexes.length > 0) {
                        var index = indexes.shift();
                        ts.copyTrailingComments(nodes[index], targetNode, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ false);
                        copyOperatorComments(index, targetNode);
                    }
                };
            };
            function concatConsecutiveString(index, nodes) {
                var text = "";
                var indexes = [];
                while (index < nodes.length && ts.isStringLiteral(nodes[index])) {
                    var stringNode = nodes[index];
                    text = text + stringNode.text;
                    indexes.push(index);
                    index++;
                }
                return [index, text, indexes];
            }
            function nodesToTemplate(_a, file) {
                var nodes = _a.nodes, operators = _a.operators;
                var copyOperatorComments = copyTrailingOperatorComments(operators, file);
                var copyCommentFromStringLiterals = copyCommentFromMultiNode(nodes, file, copyOperatorComments);
                var _b = concatConsecutiveString(0, nodes), begin = _b[0], headText = _b[1], headIndexes = _b[2];
                if (begin === nodes.length) {
                    var noSubstitutionTemplateLiteral = ts.createNoSubstitutionTemplateLiteral(headText);
                    copyCommentFromStringLiterals(headIndexes, noSubstitutionTemplateLiteral);
                    return noSubstitutionTemplateLiteral;
                }
                var templateSpans = [];
                var templateHead = ts.createTemplateHead(headText);
                copyCommentFromStringLiterals(headIndexes, templateHead);
                for (var i = begin; i < nodes.length; i++) {
                    var currentNode = getExpressionFromParenthesesOrExpression(nodes[i]);
                    copyOperatorComments(i, currentNode);
                    var _c = concatConsecutiveString(i + 1, nodes), newIndex = _c[0], subsequentText = _c[1], stringIndexes = _c[2];
                    i = newIndex - 1;
                    var templatePart = i === nodes.length - 1 ? ts.createTemplateTail(subsequentText) : ts.createTemplateMiddle(subsequentText);
                    copyCommentFromStringLiterals(stringIndexes, templatePart);
                    templateSpans.push(ts.createTemplateSpan(currentNode, templatePart));
                }
                return ts.createTemplateExpression(templateHead, templateSpans);
            }
            // to copy comments following the opening & closing parentheses
            // "foo" + ( /* comment */ 5 + 5 ) /* comment */ + "bar"
            function copyCommentsWhenParenthesized(node) {
                var file = node.getSourceFile();
                ts.copyTrailingComments(node, node.expression, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ false);
                ts.copyTrailingAsLeadingComments(node.expression, node.expression, file, 3 /* MultiLineCommentTrivia */, /* hasTrailingNewLine */ false);
            }
            function getExpressionFromParenthesesOrExpression(node) {
                if (ts.isParenthesizedExpression(node)) {
                    copyCommentsWhenParenthesized(node);
                    node = node.expression;
                }
                return node;
            }
        })(convertStringOrTemplateLiteral = refactor.convertStringOrTemplateLiteral || (refactor.convertStringOrTemplateLiteral = {}));
    })(refactor = ts.refactor || (ts.refactor = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    /** The version of the language service API */
    ts.servicesVersion = "0.8";
    function createNode(kind, pos, end, parent) {
        var node = ts.isNodeKind(kind) ? new NodeObject(kind, pos, end) :
            kind === 75 /* Identifier */ ? new IdentifierObject(75 /* Identifier */, pos, end) :
                kind === 76 /* PrivateIdentifier */ ? new PrivateIdentifierObject(76 /* PrivateIdentifier */, pos, end) :
                    new TokenObject(kind, pos, end);
        node.parent = parent;
        node.flags = parent.flags & 25358336 /* ContextFlags */;
        return node;
    }
    var NodeObject = /** @class */ (function () {
        function NodeObject(kind, pos, end) {
            this.pos = pos;
            this.end = end;
            this.flags = 0 /* None */;
            this.modifierFlagsCache = 0 /* None */;
            this.transformFlags = 0 /* None */;
            this.parent = undefined;
            this.kind = kind;
        }
        NodeObject.prototype.assertHasRealPosition = function (message) {
            // eslint-disable-next-line debug-assert
            ts.Debug.assert(!ts.positionIsSynthesized(this.pos) && !ts.positionIsSynthesized(this.end), message || "Node must have a real position for this operation");
        };
        NodeObject.prototype.getSourceFile = function () {
            return ts.getSourceFileOfNode(this);
        };
        NodeObject.prototype.getStart = function (sourceFile, includeJsDocComment) {
            this.assertHasRealPosition();
            return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment);
        };
        NodeObject.prototype.getFullStart = function () {
            this.assertHasRealPosition();
            return this.pos;
        };
        NodeObject.prototype.getEnd = function () {
            this.assertHasRealPosition();
            return this.end;
        };
        NodeObject.prototype.getWidth = function (sourceFile) {
            this.assertHasRealPosition();
            return this.getEnd() - this.getStart(sourceFile);
        };
        NodeObject.prototype.getFullWidth = function () {
            this.assertHasRealPosition();
            return this.end - this.pos;
        };
        NodeObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
            this.assertHasRealPosition();
            return this.getStart(sourceFile) - this.pos;
        };
        NodeObject.prototype.getFullText = function (sourceFile) {
            this.assertHasRealPosition();
            return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
        };
        NodeObject.prototype.getText = function (sourceFile) {
            this.assertHasRealPosition();
            if (!sourceFile) {
                sourceFile = this.getSourceFile();
            }
            return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
        };
        NodeObject.prototype.getChildCount = function (sourceFile) {
            return this.getChildren(sourceFile).length;
        };
        NodeObject.prototype.getChildAt = function (index, sourceFile) {
            return this.getChildren(sourceFile)[index];
        };
        NodeObject.prototype.getChildren = function (sourceFile) {
            this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine");
            return this._children || (this._children = createChildren(this, sourceFile));
        };
        NodeObject.prototype.getFirstToken = function (sourceFile) {
            this.assertHasRealPosition();
            var children = this.getChildren(sourceFile);
            if (!children.length) {
                return undefined;
            }
            var child = ts.find(children, function (kid) { return kid.kind < 294 /* FirstJSDocNode */ || kid.kind > 323 /* LastJSDocNode */; });
            return child.kind < 153 /* FirstNode */ ?
                child :
                child.getFirstToken(sourceFile);
        };
        NodeObject.prototype.getLastToken = function (sourceFile) {
            this.assertHasRealPosition();
            var children = this.getChildren(sourceFile);
            var child = ts.lastOrUndefined(children);
            if (!child) {
                return undefined;
            }
            return child.kind < 153 /* FirstNode */ ? child : child.getLastToken(sourceFile);
        };
        NodeObject.prototype.forEachChild = function (cbNode, cbNodeArray) {
            return ts.forEachChild(this, cbNode, cbNodeArray);
        };
        return NodeObject;
    }());
    function createChildren(node, sourceFile) {
        if (!ts.isNodeKind(node.kind)) {
            return ts.emptyArray;
        }
        var children = [];
        if (ts.isJSDocCommentContainingNode(node)) {
            /** Don't add trivia for "tokens" since this is in a comment. */
            node.forEachChild(function (child) { children.push(child); });
            return children;
        }
        ts.scanner.setText((sourceFile || node.getSourceFile()).text);
        var pos = node.pos;
        var processNode = function (child) {
            addSyntheticNodes(children, pos, child.pos, node);
            children.push(child);
            pos = child.end;
        };
        var processNodes = function (nodes) {
            addSyntheticNodes(children, pos, nodes.pos, node);
            children.push(createSyntaxList(nodes, node));
            pos = nodes.end;
        };
        // jsDocComments need to be the first children
        ts.forEach(node.jsDoc, processNode);
        // For syntactic classifications, all trivia are classified together, including jsdoc comments.
        // For that to work, the jsdoc comments should still be the leading trivia of the first child.
        // Restoring the scanner position ensures that.
        pos = node.pos;
        node.forEachChild(processNode, processNodes);
        addSyntheticNodes(children, pos, node.end, node);
        ts.scanner.setText(undefined);
        return children;
    }
    function addSyntheticNodes(nodes, pos, end, parent) {
        ts.scanner.setTextPos(pos);
        while (pos < end) {
            var token = ts.scanner.scan();
            var textPos = ts.scanner.getTextPos();
            if (textPos <= end) {
                if (token === 75 /* Identifier */) {
                    ts.Debug.fail("Did not expect " + ts.Debug.formatSyntaxKind(parent.kind) + " to have an Identifier in its trivia");
                }
                nodes.push(createNode(token, pos, textPos, parent));
            }
            pos = textPos;
            if (token === 1 /* EndOfFileToken */) {
                break;
            }
        }
    }
    function createSyntaxList(nodes, parent) {
        var list = createNode(324 /* SyntaxList */, nodes.pos, nodes.end, parent);
        list._children = [];
        var pos = nodes.pos;
        for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
            var node = nodes_1[_i];
            addSyntheticNodes(list._children, pos, node.pos, parent);
            list._children.push(node);
            pos = node.end;
        }
        addSyntheticNodes(list._children, pos, nodes.end, parent);
        return list;
    }
    var TokenOrIdentifierObject = /** @class */ (function () {
        function TokenOrIdentifierObject(pos, end) {
            // Set properties in same order as NodeObject
            this.pos = pos;
            this.end = end;
            this.flags = 0 /* None */;
            this.modifierFlagsCache = 0 /* None */;
            this.transformFlags = 0 /* None */;
            this.parent = undefined;
        }
        TokenOrIdentifierObject.prototype.getSourceFile = function () {
            return ts.getSourceFileOfNode(this);
        };
        TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) {
            return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment);
        };
        TokenOrIdentifierObject.prototype.getFullStart = function () {
            return this.pos;
        };
        TokenOrIdentifierObject.prototype.getEnd = function () {
            return this.end;
        };
        TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) {
            return this.getEnd() - this.getStart(sourceFile);
        };
        TokenOrIdentifierObject.prototype.getFullWidth = function () {
            return this.end - this.pos;
        };
        TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
            return this.getStart(sourceFile) - this.pos;
        };
        TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) {
            return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
        };
        TokenOrIdentifierObject.prototype.getText = function (sourceFile) {
            if (!sourceFile) {
                sourceFile = this.getSourceFile();
            }
            return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
        };
        TokenOrIdentifierObject.prototype.getChildCount = function () {
            return 0;
        };
        TokenOrIdentifierObject.prototype.getChildAt = function () {
            return undefined; // TODO: GH#18217
        };
        TokenOrIdentifierObject.prototype.getChildren = function () {
            return this.kind === 1 /* EndOfFileToken */ ? this.jsDoc || ts.emptyArray : ts.emptyArray;
        };
        TokenOrIdentifierObject.prototype.getFirstToken = function () {
            return undefined;
        };
        TokenOrIdentifierObject.prototype.getLastToken = function () {
            return undefined;
        };
        TokenOrIdentifierObject.prototype.forEachChild = function () {
            return undefined;
        };
        return TokenOrIdentifierObject;
    }());
    var SymbolObject = /** @class */ (function () {
        function SymbolObject(flags, name) {
            this.flags = flags;
            this.escapedName = name;
        }
        SymbolObject.prototype.getFlags = function () {
            return this.flags;
        };
        Object.defineProperty(SymbolObject.prototype, "name", {
            get: function () {
                return ts.symbolName(this);
            },
            enumerable: false,
            configurable: true
        });
        SymbolObject.prototype.getEscapedName = function () {
            return this.escapedName;
        };
        SymbolObject.prototype.getName = function () {
            return this.name;
        };
        SymbolObject.prototype.getDeclarations = function () {
            return this.declarations;
        };
        SymbolObject.prototype.getDocumentationComment = function (checker) {
            if (!this.documentationComment) {
                this.documentationComment = ts.emptyArray; // Set temporarily to avoid an infinite loop finding inherited docs
                this.documentationComment = getDocumentationComment(this.declarations, checker);
            }
            return this.documentationComment;
        };
        SymbolObject.prototype.getJsDocTags = function () {
            if (this.tags === undefined) {
                this.tags = ts.JsDoc.getJsDocTagsFromDeclarations(this.declarations);
            }
            return this.tags;
        };
        return SymbolObject;
    }());
    var TokenObject = /** @class */ (function (_super) {
        __extends(TokenObject, _super);
        function TokenObject(kind, pos, end) {
            var _this = _super.call(this, pos, end) || this;
            _this.kind = kind;
            return _this;
        }
        return TokenObject;
    }(TokenOrIdentifierObject));
    var IdentifierObject = /** @class */ (function (_super) {
        __extends(IdentifierObject, _super);
        function IdentifierObject(_kind, pos, end) {
            var _this = _super.call(this, pos, end) || this;
            _this.kind = 75 /* Identifier */;
            return _this;
        }
        Object.defineProperty(IdentifierObject.prototype, "text", {
            get: function () {
                return ts.idText(this);
            },
            enumerable: false,
            configurable: true
        });
        return IdentifierObject;
    }(TokenOrIdentifierObject));
    IdentifierObject.prototype.kind = 75 /* Identifier */;
    var PrivateIdentifierObject = /** @class */ (function (_super) {
        __extends(PrivateIdentifierObject, _super);
        function PrivateIdentifierObject(_kind, pos, end) {
            return _super.call(this, pos, end) || this;
        }
        Object.defineProperty(PrivateIdentifierObject.prototype, "text", {
            get: function () {
                return ts.idText(this);
            },
            enumerable: false,
            configurable: true
        });
        return PrivateIdentifierObject;
    }(TokenOrIdentifierObject));
    PrivateIdentifierObject.prototype.kind = 76 /* PrivateIdentifier */;
    var TypeObject = /** @class */ (function () {
        function TypeObject(checker, flags) {
            this.checker = checker;
            this.flags = flags;
        }
        TypeObject.prototype.getFlags = function () {
            return this.flags;
        };
        TypeObject.prototype.getSymbol = function () {
            return this.symbol;
        };
        TypeObject.prototype.getProperties = function () {
            return this.checker.getPropertiesOfType(this);
        };
        TypeObject.prototype.getProperty = function (propertyName) {
            return this.checker.getPropertyOfType(this, propertyName);
        };
        TypeObject.prototype.getApparentProperties = function () {
            return this.checker.getAugmentedPropertiesOfType(this);
        };
        TypeObject.prototype.getCallSignatures = function () {
            return this.checker.getSignaturesOfType(this, 0 /* Call */);
        };
        TypeObject.prototype.getConstructSignatures = function () {
            return this.checker.getSignaturesOfType(this, 1 /* Construct */);
        };
        TypeObject.prototype.getStringIndexType = function () {
            return this.checker.getIndexTypeOfType(this, 0 /* String */);
        };
        TypeObject.prototype.getNumberIndexType = function () {
            return this.checker.getIndexTypeOfType(this, 1 /* Number */);
        };
        TypeObject.prototype.getBaseTypes = function () {
            return this.isClassOrInterface() ? this.checker.getBaseTypes(this) : undefined;
        };
        TypeObject.prototype.isNullableType = function () {
            return this.checker.isNullableType(this);
        };
        TypeObject.prototype.getNonNullableType = function () {
            return this.checker.getNonNullableType(this);
        };
        TypeObject.prototype.getNonOptionalType = function () {
            return this.checker.getNonOptionalType(this);
        };
        TypeObject.prototype.getConstraint = function () {
            return this.checker.getBaseConstraintOfType(this);
        };
        TypeObject.prototype.getDefault = function () {
            return this.checker.getDefaultFromTypeParameter(this);
        };
        TypeObject.prototype.isUnion = function () {
            return !!(this.flags & 1048576 /* Union */);
        };
        TypeObject.prototype.isIntersection = function () {
            return !!(this.flags & 2097152 /* Intersection */);
        };
        TypeObject.prototype.isUnionOrIntersection = function () {
            return !!(this.flags & 3145728 /* UnionOrIntersection */);
        };
        TypeObject.prototype.isLiteral = function () {
            return !!(this.flags & 384 /* StringOrNumberLiteral */);
        };
        TypeObject.prototype.isStringLiteral = function () {
            return !!(this.flags & 128 /* StringLiteral */);
        };
        TypeObject.prototype.isNumberLiteral = function () {
            return !!(this.flags & 256 /* NumberLiteral */);
        };
        TypeObject.prototype.isTypeParameter = function () {
            return !!(this.flags & 262144 /* TypeParameter */);
        };
        TypeObject.prototype.isClassOrInterface = function () {
            return !!(ts.getObjectFlags(this) & 3 /* ClassOrInterface */);
        };
        TypeObject.prototype.isClass = function () {
            return !!(ts.getObjectFlags(this) & 1 /* Class */);
        };
        Object.defineProperty(TypeObject.prototype, "typeArguments", {
            /**
             * This polyfills `referenceType.typeArguments` for API consumers
             */
            get: function () {
                if (ts.getObjectFlags(this) & 4 /* Reference */) {
                    return this.checker.getTypeArguments(this);
                }
                return undefined;
            },
            enumerable: false,
            configurable: true
        });
        return TypeObject;
    }());
    var SignatureObject = /** @class */ (function () {
        function SignatureObject(checker, flags) {
            this.checker = checker;
            this.flags = flags;
        }
        SignatureObject.prototype.getDeclaration = function () {
            return this.declaration;
        };
        SignatureObject.prototype.getTypeParameters = function () {
            return this.typeParameters;
        };
        SignatureObject.prototype.getParameters = function () {
            return this.parameters;
        };
        SignatureObject.prototype.getReturnType = function () {
            return this.checker.getReturnTypeOfSignature(this);
        };
        SignatureObject.prototype.getDocumentationComment = function () {
            return this.documentationComment || (this.documentationComment = getDocumentationComment(ts.singleElementArray(this.declaration), this.checker));
        };
        SignatureObject.prototype.getJsDocTags = function () {
            if (this.jsDocTags === undefined) {
                this.jsDocTags = this.declaration ? ts.JsDoc.getJsDocTagsFromDeclarations([this.declaration]) : [];
            }
            return this.jsDocTags;
        };
        return SignatureObject;
    }());
    /**
     * Returns whether or not the given node has a JSDoc "inheritDoc" tag on it.
     * @param node the Node in question.
     * @returns `true` if `node` has a JSDoc "inheritDoc" tag on it, otherwise `false`.
     */
    function hasJSDocInheritDocTag(node) {
        return ts.getJSDocTags(node).some(function (tag) { return tag.tagName.text === "inheritDoc"; });
    }
    function getDocumentationComment(declarations, checker) {
        if (!declarations)
            return ts.emptyArray;
        var doc = ts.JsDoc.getJsDocCommentsFromDeclarations(declarations);
        if (doc.length === 0 || declarations.some(hasJSDocInheritDocTag)) {
            ts.forEachUnique(declarations, function (declaration) {
                var inheritedDocs = findInheritedJSDocComments(declaration, declaration.symbol.name, checker); // TODO: GH#18217
                // TODO: GH#16312 Return a ReadonlyArray, avoid copying inheritedDocs
                if (inheritedDocs)
                    doc = doc.length === 0 ? inheritedDocs.slice() : inheritedDocs.concat(ts.lineBreakPart(), doc);
            });
        }
        return doc;
    }
    /**
     * Attempts to find JSDoc comments for possibly-inherited properties.  Checks superclasses then traverses
     * implemented interfaces until a symbol is found with the same name and with documentation.
     * @param declaration The possibly-inherited declaration to find comments for.
     * @param propertyName The name of the possibly-inherited property.
     * @param typeChecker A TypeChecker, used to find inherited properties.
     * @returns A filled array of documentation comments if any were found, otherwise an empty array.
     */
    function findInheritedJSDocComments(declaration, propertyName, typeChecker) {
        return ts.firstDefined(declaration.parent ? ts.getAllSuperTypeNodes(declaration.parent) : ts.emptyArray, function (superTypeNode) {
            var superType = typeChecker.getTypeAtLocation(superTypeNode);
            var baseProperty = superType && typeChecker.getPropertyOfType(superType, propertyName);
            var inheritedDocs = baseProperty && baseProperty.getDocumentationComment(typeChecker);
            return inheritedDocs && inheritedDocs.length ? inheritedDocs : undefined;
        });
    }
    var SourceFileObject = /** @class */ (function (_super) {
        __extends(SourceFileObject, _super);
        function SourceFileObject(kind, pos, end) {
            var _this = _super.call(this, kind, pos, end) || this;
            _this.kind = 290 /* SourceFile */;
            return _this;
        }
        SourceFileObject.prototype.update = function (newText, textChangeRange) {
            return ts.updateSourceFile(this, newText, textChangeRange);
        };
        SourceFileObject.prototype.getLineAndCharacterOfPosition = function (position) {
            return ts.getLineAndCharacterOfPosition(this, position);
        };
        SourceFileObject.prototype.getLineStarts = function () {
            return ts.getLineStarts(this);
        };
        SourceFileObject.prototype.getPositionOfLineAndCharacter = function (line, character, allowEdits) {
            return ts.computePositionOfLineAndCharacter(ts.getLineStarts(this), line, character, this.text, allowEdits);
        };
        SourceFileObject.prototype.getLineEndOfPosition = function (pos) {
            var line = this.getLineAndCharacterOfPosition(pos).line;
            var lineStarts = this.getLineStarts();
            var lastCharPos;
            if (line + 1 >= lineStarts.length) {
                lastCharPos = this.getEnd();
            }
            if (!lastCharPos) {
                lastCharPos = lineStarts[line + 1] - 1;
            }
            var fullText = this.getFullText();
            // if the new line is "\r\n", we should return the last non-new-line-character position
            return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos;
        };
        SourceFileObject.prototype.getNamedDeclarations = function () {
            if (!this.namedDeclarations) {
                this.namedDeclarations = this.computeNamedDeclarations();
            }
            return this.namedDeclarations;
        };
        SourceFileObject.prototype.computeNamedDeclarations = function () {
            var result = ts.createMultiMap();
            this.forEachChild(visit);
            return result;
            function addDeclaration(declaration) {
                var name = getDeclarationName(declaration);
                if (name) {
                    result.add(name, declaration);
                }
            }
            function getDeclarations(name) {
                var declarations = result.get(name);
                if (!declarations) {
                    result.set(name, declarations = []);
                }
                return declarations;
            }
            function getDeclarationName(declaration) {
                var name = ts.getNonAssignedNameOfDeclaration(declaration);
                return name && (ts.isComputedPropertyName(name) && ts.isPropertyAccessExpression(name.expression) ? name.expression.name.text
                    : ts.isPropertyName(name) ? ts.getNameFromPropertyName(name) : undefined);
            }
            function visit(node) {
                switch (node.kind) {
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                    case 161 /* MethodDeclaration */:
                    case 160 /* MethodSignature */:
                        var functionDeclaration = node;
                        var declarationName = getDeclarationName(functionDeclaration);
                        if (declarationName) {
                            var declarations = getDeclarations(declarationName);
                            var lastDeclaration = ts.lastOrUndefined(declarations);
                            // Check whether this declaration belongs to an "overload group".
                            if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) {
                                // Overwrite the last declaration if it was an overload
                                // and this one is an implementation.
                                if (functionDeclaration.body && !lastDeclaration.body) {
                                    declarations[declarations.length - 1] = functionDeclaration;
                                }
                            }
                            else {
                                declarations.push(functionDeclaration);
                            }
                        }
                        ts.forEachChild(node, visit);
                        break;
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                    case 248 /* EnumDeclaration */:
                    case 249 /* ModuleDeclaration */:
                    case 253 /* ImportEqualsDeclaration */:
                    case 263 /* ExportSpecifier */:
                    case 258 /* ImportSpecifier */:
                    case 255 /* ImportClause */:
                    case 256 /* NamespaceImport */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 173 /* TypeLiteral */:
                        addDeclaration(node);
                        ts.forEachChild(node, visit);
                        break;
                    case 156 /* Parameter */:
                        // Only consider parameter properties
                        if (!ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
                            break;
                        }
                    // falls through
                    case 242 /* VariableDeclaration */:
                    case 191 /* BindingElement */: {
                        var decl = node;
                        if (ts.isBindingPattern(decl.name)) {
                            ts.forEachChild(decl.name, visit);
                            break;
                        }
                        if (decl.initializer) {
                            visit(decl.initializer);
                        }
                    }
                    // falls through
                    case 284 /* EnumMember */:
                    case 159 /* PropertyDeclaration */:
                    case 158 /* PropertySignature */:
                        addDeclaration(node);
                        break;
                    case 260 /* ExportDeclaration */:
                        // Handle named exports case e.g.:
                        //    export {a, b as B} from "mod";
                        var exportDeclaration = node;
                        if (exportDeclaration.exportClause) {
                            if (ts.isNamedExports(exportDeclaration.exportClause)) {
                                ts.forEach(exportDeclaration.exportClause.elements, visit);
                            }
                            else {
                                visit(exportDeclaration.exportClause.name);
                            }
                        }
                        break;
                    case 254 /* ImportDeclaration */:
                        var importClause = node.importClause;
                        if (importClause) {
                            // Handle default import case e.g.:
                            //    import d from "mod";
                            if (importClause.name) {
                                addDeclaration(importClause.name);
                            }
                            // Handle named bindings in imports e.g.:
                            //    import * as NS from "mod";
                            //    import {a, b as B} from "mod";
                            if (importClause.namedBindings) {
                                if (importClause.namedBindings.kind === 256 /* NamespaceImport */) {
                                    addDeclaration(importClause.namedBindings);
                                }
                                else {
                                    ts.forEach(importClause.namedBindings.elements, visit);
                                }
                            }
                        }
                        break;
                    case 209 /* BinaryExpression */:
                        if (ts.getAssignmentDeclarationKind(node) !== 0 /* None */) {
                            addDeclaration(node);
                        }
                    // falls through
                    default:
                        ts.forEachChild(node, visit);
                }
            }
        };
        return SourceFileObject;
    }(NodeObject));
    var SourceMapSourceObject = /** @class */ (function () {
        function SourceMapSourceObject(fileName, text, skipTrivia) {
            this.fileName = fileName;
            this.text = text;
            this.skipTrivia = skipTrivia;
        }
        SourceMapSourceObject.prototype.getLineAndCharacterOfPosition = function (pos) {
            return ts.getLineAndCharacterOfPosition(this, pos);
        };
        return SourceMapSourceObject;
    }());
    function getServicesObjectAllocator() {
        return {
            getNodeConstructor: function () { return NodeObject; },
            getTokenConstructor: function () { return TokenObject; },
            getIdentifierConstructor: function () { return IdentifierObject; },
            getPrivateIdentifierConstructor: function () { return PrivateIdentifierObject; },
            getSourceFileConstructor: function () { return SourceFileObject; },
            getSymbolConstructor: function () { return SymbolObject; },
            getTypeConstructor: function () { return TypeObject; },
            getSignatureConstructor: function () { return SignatureObject; },
            getSourceMapSourceConstructor: function () { return SourceMapSourceObject; },
        };
    }
    function toEditorSettings(optionsAsMap) {
        var allPropertiesAreCamelCased = true;
        for (var key in optionsAsMap) {
            if (ts.hasProperty(optionsAsMap, key) && !isCamelCase(key)) {
                allPropertiesAreCamelCased = false;
                break;
            }
        }
        if (allPropertiesAreCamelCased) {
            return optionsAsMap;
        }
        var settings = {};
        for (var key in optionsAsMap) {
            if (ts.hasProperty(optionsAsMap, key)) {
                var newKey = isCamelCase(key) ? key : key.charAt(0).toLowerCase() + key.substr(1);
                settings[newKey] = optionsAsMap[key];
            }
        }
        return settings;
    }
    ts.toEditorSettings = toEditorSettings;
    function isCamelCase(s) {
        return !s.length || s.charAt(0) === s.charAt(0).toLowerCase();
    }
    function displayPartsToString(displayParts) {
        if (displayParts) {
            return ts.map(displayParts, function (displayPart) { return displayPart.text; }).join("");
        }
        return "";
    }
    ts.displayPartsToString = displayPartsToString;
    function getDefaultCompilerOptions() {
        // Always default to "ScriptTarget.ES5" for the language service
        return {
            target: 1 /* ES5 */,
            jsx: 1 /* Preserve */
        };
    }
    ts.getDefaultCompilerOptions = getDefaultCompilerOptions;
    function getSupportedCodeFixes() {
        return ts.codefix.getSupportedErrorCodes();
    }
    ts.getSupportedCodeFixes = getSupportedCodeFixes;
    // Cache host information about script Should be refreshed
    // at each language service public entry point, since we don't know when
    // the set of scripts handled by the host changes.
    var HostCache = /** @class */ (function () {
        function HostCache(host, getCanonicalFileName) {
            this.host = host;
            // script id => script index
            this.currentDirectory = host.getCurrentDirectory();
            this.fileNameToEntry = ts.createMap();
            // Initialize the list with the root file names
            var rootFileNames = host.getScriptFileNames();
            for (var _i = 0, rootFileNames_1 = rootFileNames; _i < rootFileNames_1.length; _i++) {
                var fileName = rootFileNames_1[_i];
                this.createEntry(fileName, ts.toPath(fileName, this.currentDirectory, getCanonicalFileName));
            }
            // store the compilation settings
            this._compilationSettings = host.getCompilationSettings() || getDefaultCompilerOptions();
        }
        HostCache.prototype.compilationSettings = function () {
            return this._compilationSettings;
        };
        HostCache.prototype.getProjectReferences = function () {
            return this.host.getProjectReferences && this.host.getProjectReferences();
        };
        HostCache.prototype.createEntry = function (fileName, path) {
            var entry;
            var scriptSnapshot = this.host.getScriptSnapshot(fileName);
            if (scriptSnapshot) {
                entry = {
                    hostFileName: fileName,
                    version: this.host.getScriptVersion(fileName),
                    scriptSnapshot: scriptSnapshot,
                    scriptKind: ts.getScriptKind(fileName, this.host)
                };
            }
            else {
                entry = fileName;
            }
            this.fileNameToEntry.set(path, entry);
            return entry;
        };
        HostCache.prototype.getEntryByPath = function (path) {
            return this.fileNameToEntry.get(path);
        };
        HostCache.prototype.getHostFileInformation = function (path) {
            var entry = this.fileNameToEntry.get(path);
            return !ts.isString(entry) ? entry : undefined;
        };
        HostCache.prototype.getOrCreateEntryByPath = function (fileName, path) {
            var info = this.getEntryByPath(path) || this.createEntry(fileName, path);
            return ts.isString(info) ? undefined : info; // TODO: GH#18217
        };
        HostCache.prototype.getRootFileNames = function () {
            var names = [];
            this.fileNameToEntry.forEach(function (entry) {
                if (ts.isString(entry)) {
                    names.push(entry);
                }
                else {
                    names.push(entry.hostFileName);
                }
            });
            return names;
        };
        HostCache.prototype.getScriptSnapshot = function (path) {
            var file = this.getHostFileInformation(path);
            return (file && file.scriptSnapshot); // TODO: GH#18217
        };
        return HostCache;
    }());
    var SyntaxTreeCache = /** @class */ (function () {
        function SyntaxTreeCache(host) {
            this.host = host;
        }
        SyntaxTreeCache.prototype.getCurrentSourceFile = function (fileName) {
            var scriptSnapshot = this.host.getScriptSnapshot(fileName);
            if (!scriptSnapshot) {
                // The host does not know about this file.
                throw new Error("Could not find file: '" + fileName + "'.");
            }
            var scriptKind = ts.getScriptKind(fileName, this.host);
            var version = this.host.getScriptVersion(fileName);
            var sourceFile;
            if (this.currentFileName !== fileName) {
                // This is a new file, just parse it
                sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, 99 /* Latest */, version, /*setNodeParents*/ true, scriptKind);
            }
            else if (this.currentFileVersion !== version) {
                // This is the same file, just a newer version. Incrementally parse the file.
                var editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot);
                sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange);
            }
            if (sourceFile) {
                // All done, ensure state is up to date
                this.currentFileVersion = version;
                this.currentFileName = fileName;
                this.currentFileScriptSnapshot = scriptSnapshot;
                this.currentSourceFile = sourceFile;
            }
            return this.currentSourceFile;
        };
        return SyntaxTreeCache;
    }());
    function setSourceFileFields(sourceFile, scriptSnapshot, version) {
        sourceFile.version = version;
        sourceFile.scriptSnapshot = scriptSnapshot;
    }
    function createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, setNodeParents, scriptKind) {
        var sourceFile = ts.createSourceFile(fileName, ts.getSnapshotText(scriptSnapshot), scriptTarget, setNodeParents, scriptKind);
        setSourceFileFields(sourceFile, scriptSnapshot, version);
        return sourceFile;
    }
    ts.createLanguageServiceSourceFile = createLanguageServiceSourceFile;
    function updateLanguageServiceSourceFile(sourceFile, scriptSnapshot, version, textChangeRange, aggressiveChecks) {
        // If we were given a text change range, and our version or open-ness changed, then
        // incrementally parse this file.
        if (textChangeRange) {
            if (version !== sourceFile.version) {
                var newText = void 0;
                // grab the fragment from the beginning of the original text to the beginning of the span
                var prefix = textChangeRange.span.start !== 0
                    ? sourceFile.text.substr(0, textChangeRange.span.start)
                    : "";
                // grab the fragment from the end of the span till the end of the original text
                var suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length
                    ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span))
                    : "";
                if (textChangeRange.newLength === 0) {
                    // edit was a deletion - just combine prefix and suffix
                    newText = prefix && suffix ? prefix + suffix : prefix || suffix;
                }
                else {
                    // it was actual edit, fetch the fragment of new text that correspond to new span
                    var changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength);
                    // combine prefix, changed text and suffix
                    newText = prefix && suffix
                        ? prefix + changedText + suffix
                        : prefix
                            ? (prefix + changedText)
                            : (changedText + suffix);
                }
                var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
                setSourceFileFields(newSourceFile, scriptSnapshot, version);
                // after incremental parsing nameTable might not be up-to-date
                // drop it so it can be lazily recreated later
                newSourceFile.nameTable = undefined;
                // dispose all resources held by old script snapshot
                if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) {
                    if (sourceFile.scriptSnapshot.dispose) {
                        sourceFile.scriptSnapshot.dispose();
                    }
                    sourceFile.scriptSnapshot = undefined;
                }
                return newSourceFile;
            }
        }
        // Otherwise, just create a new source file.
        return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, sourceFile.scriptKind);
    }
    ts.updateLanguageServiceSourceFile = updateLanguageServiceSourceFile;
    var CancellationTokenObject = /** @class */ (function () {
        function CancellationTokenObject(cancellationToken) {
            this.cancellationToken = cancellationToken;
        }
        CancellationTokenObject.prototype.isCancellationRequested = function () {
            return !!this.cancellationToken && this.cancellationToken.isCancellationRequested();
        };
        CancellationTokenObject.prototype.throwIfCancellationRequested = function () {
            if (this.isCancellationRequested()) {
                throw new ts.OperationCanceledException();
            }
        };
        return CancellationTokenObject;
    }());
    /* @internal */
    /** A cancellation that throttles calls to the host */
    var ThrottledCancellationToken = /** @class */ (function () {
        function ThrottledCancellationToken(hostCancellationToken, throttleWaitMilliseconds) {
            if (throttleWaitMilliseconds === void 0) { throttleWaitMilliseconds = 20; }
            this.hostCancellationToken = hostCancellationToken;
            this.throttleWaitMilliseconds = throttleWaitMilliseconds;
            // Store when we last tried to cancel.  Checking cancellation can be expensive (as we have
            // to marshall over to the host layer).  So we only bother actually checking once enough
            // time has passed.
            this.lastCancellationCheckTime = 0;
        }
        ThrottledCancellationToken.prototype.isCancellationRequested = function () {
            var time = ts.timestamp();
            var duration = Math.abs(time - this.lastCancellationCheckTime);
            if (duration >= this.throttleWaitMilliseconds) {
                // Check no more than once every throttle wait milliseconds
                this.lastCancellationCheckTime = time;
                return this.hostCancellationToken.isCancellationRequested();
            }
            return false;
        };
        ThrottledCancellationToken.prototype.throwIfCancellationRequested = function () {
            if (this.isCancellationRequested()) {
                throw new ts.OperationCanceledException();
            }
        };
        return ThrottledCancellationToken;
    }());
    ts.ThrottledCancellationToken = ThrottledCancellationToken;
    function createLanguageService(host, documentRegistry, syntaxOnly) {
        var _a;
        if (documentRegistry === void 0) { documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); }
        if (syntaxOnly === void 0) { syntaxOnly = false; }
        var syntaxTreeCache = new SyntaxTreeCache(host);
        var program;
        var lastProjectVersion;
        var lastTypesRootVersion = 0;
        var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken());
        var currentDirectory = host.getCurrentDirectory();
        // Check if the localized messages json is set, otherwise query the host for it
        if (!ts.localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) {
            ts.setLocalizedDiagnosticMessages(host.getLocalizedDiagnosticMessages());
        }
        function log(message) {
            if (host.log) {
                host.log(message);
            }
        }
        var useCaseSensitiveFileNames = ts.hostUsesCaseSensitiveFileNames(host);
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        var sourceMapper = ts.getSourceMapper({
            useCaseSensitiveFileNames: function () { return useCaseSensitiveFileNames; },
            getCurrentDirectory: function () { return currentDirectory; },
            getProgram: getProgram,
            fileExists: ts.maybeBind(host, host.fileExists),
            readFile: ts.maybeBind(host, host.readFile),
            getDocumentPositionMapper: ts.maybeBind(host, host.getDocumentPositionMapper),
            getSourceFileLike: ts.maybeBind(host, host.getSourceFileLike),
            log: log
        });
        function getValidSourceFile(fileName) {
            var sourceFile = program.getSourceFile(fileName);
            if (!sourceFile) {
                var error = new Error("Could not find source file: '" + fileName + "'.");
                // We've been having trouble debugging this, so attach sidecar data for the tsserver log.
                // See https://github.com/microsoft/TypeScript/issues/30180.
                error.ProgramFiles = program.getSourceFiles().map(function (f) { return f.fileName; });
                throw error;
            }
            return sourceFile;
        }
        function synchronizeHostData() {
            var _a;
            ts.Debug.assert(!syntaxOnly);
            // perform fast check if host supports it
            if (host.getProjectVersion) {
                var hostProjectVersion = host.getProjectVersion();
                if (hostProjectVersion) {
                    if (lastProjectVersion === hostProjectVersion && !host.hasChangedAutomaticTypeDirectiveNames) {
                        return;
                    }
                    lastProjectVersion = hostProjectVersion;
                }
            }
            var typeRootsVersion = host.getTypeRootsVersion ? host.getTypeRootsVersion() : 0;
            if (lastTypesRootVersion !== typeRootsVersion) {
                log("TypeRoots version has changed; provide new program");
                program = undefined; // TODO: GH#18217
                lastTypesRootVersion = typeRootsVersion;
            }
            // Get a fresh cache of the host information
            var hostCache = new HostCache(host, getCanonicalFileName);
            var rootFileNames = hostCache.getRootFileNames();
            var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
            var projectReferences = hostCache.getProjectReferences();
            // If the program is already up-to-date, we can reuse it
            if (ts.isProgramUptoDate(program, rootFileNames, hostCache.compilationSettings(), function (_path, fileName) { return host.getScriptVersion(fileName); }, fileExists, hasInvalidatedResolution, !!host.hasChangedAutomaticTypeDirectiveNames, projectReferences)) {
                return;
            }
            // IMPORTANT - It is critical from this moment onward that we do not check
            // cancellation tokens.  We are about to mutate source files from a previous program
            // instance.  If we cancel midway through, we may end up in an inconsistent state where
            // the program points to old source files that have been invalidated because of
            // incremental parsing.
            var newSettings = hostCache.compilationSettings();
            // Now create a new compiler
            var compilerHost = {
                getSourceFile: getOrCreateSourceFile,
                getSourceFileByPath: getOrCreateSourceFileByPath,
                getCancellationToken: function () { return cancellationToken; },
                getCanonicalFileName: getCanonicalFileName,
                useCaseSensitiveFileNames: function () { return useCaseSensitiveFileNames; },
                getNewLine: function () { return ts.getNewLineCharacter(newSettings, function () { return ts.getNewLineOrDefaultFromHost(host); }); },
                getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); },
                writeFile: ts.noop,
                getCurrentDirectory: function () { return currentDirectory; },
                fileExists: fileExists,
                readFile: readFile,
                realpath: host.realpath && (function (path) { return host.realpath(path); }),
                directoryExists: function (directoryName) {
                    return ts.directoryProbablyExists(directoryName, host);
                },
                getDirectories: function (path) {
                    return host.getDirectories ? host.getDirectories(path) : [];
                },
                readDirectory: function (path, extensions, exclude, include, depth) {
                    ts.Debug.checkDefined(host.readDirectory, "'LanguageServiceHost.readDirectory' must be implemented to correctly process 'projectReferences'");
                    return host.readDirectory(path, extensions, exclude, include, depth);
                },
                onReleaseOldSourceFile: onReleaseOldSourceFile,
                hasInvalidatedResolution: hasInvalidatedResolution,
                hasChangedAutomaticTypeDirectiveNames: host.hasChangedAutomaticTypeDirectiveNames
            };
            if (host.trace) {
                compilerHost.trace = function (message) { return host.trace(message); };
            }
            if (host.resolveModuleNames) {
                compilerHost.resolveModuleNames = function () {
                    var args = [];
                    for (var _i = 0; _i < arguments.length; _i++) {
                        args[_i] = arguments[_i];
                    }
                    return host.resolveModuleNames.apply(host, args);
                };
            }
            if (host.resolveTypeReferenceDirectives) {
                compilerHost.resolveTypeReferenceDirectives = function () {
                    var args = [];
                    for (var _i = 0; _i < arguments.length; _i++) {
                        args[_i] = arguments[_i];
                    }
                    return host.resolveTypeReferenceDirectives.apply(host, args);
                };
            }
            if (host.useSourceOfProjectReferenceRedirect) {
                compilerHost.useSourceOfProjectReferenceRedirect = function () { return host.useSourceOfProjectReferenceRedirect(); };
            }
            (_a = host.setCompilerHost) === null || _a === void 0 ? void 0 : _a.call(host, compilerHost);
            var documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
            var options = {
                rootNames: rootFileNames,
                options: newSettings,
                host: compilerHost,
                oldProgram: program,
                projectReferences: projectReferences
            };
            program = ts.createProgram(options);
            // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point.
            // It needs to be cleared to allow all collected snapshots to be released
            hostCache = undefined;
            // We reset this cache on structure invalidation so we don't hold on to outdated files for long; however we can't use the `compilerHost` above,
            // Because it only functions until `hostCache` is cleared, while we'll potentially need the functionality to lazily read sourcemap files during
            // the course of whatever called `synchronizeHostData`
            sourceMapper.clearCache();
            // Make sure all the nodes in the program are both bound, and have their parent
            // pointers set property.
            program.getTypeChecker();
            return;
            function fileExists(fileName) {
                var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
                var entry = hostCache && hostCache.getEntryByPath(path);
                return entry ?
                    !ts.isString(entry) :
                    (!!host.fileExists && host.fileExists(fileName));
            }
            function readFile(fileName) {
                // stub missing host functionality
                var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
                var entry = hostCache && hostCache.getEntryByPath(path);
                if (entry) {
                    return ts.isString(entry) ? undefined : ts.getSnapshotText(entry.scriptSnapshot);
                }
                return host.readFile && host.readFile(fileName);
            }
            // Release any files we have acquired in the old program but are
            // not part of the new program.
            function onReleaseOldSourceFile(oldSourceFile, oldOptions) {
                var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldOptions);
                documentRegistry.releaseDocumentWithKey(oldSourceFile.resolvedPath, oldSettingsKey);
            }
            function getOrCreateSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
                return getOrCreateSourceFileByPath(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName), languageVersion, onError, shouldCreateNewSourceFile);
            }
            function getOrCreateSourceFileByPath(fileName, path, _languageVersion, _onError, shouldCreateNewSourceFile) {
                ts.Debug.assert(hostCache !== undefined, "getOrCreateSourceFileByPath called after typical CompilerHost lifetime, check the callstack something with a reference to an old host.");
                // The program is asking for this file, check first if the host can locate it.
                // If the host can not locate the file, then it does not exist. return undefined
                // to the program to allow reporting of errors for missing files.
                var hostFileInformation = hostCache && hostCache.getOrCreateEntryByPath(fileName, path);
                if (!hostFileInformation) {
                    return undefined;
                }
                // Check if the language version has changed since we last created a program; if they are the same,
                // it is safe to reuse the sourceFiles; if not, then the shape of the AST can change, and the oldSourceFile
                // can not be reused. we have to dump all syntax trees and create new ones.
                if (!shouldCreateNewSourceFile) {
                    // Check if the old program had this file already
                    var oldSourceFile = program && program.getSourceFileByPath(path);
                    if (oldSourceFile) {
                        // We already had a source file for this file name.  Go to the registry to
                        // ensure that we get the right up to date version of it.  We need this to
                        // address the following race-condition.  Specifically, say we have the following:
                        //
                        //      LS1
                        //          \
                        //           DocumentRegistry
                        //          /
                        //      LS2
                        //
                        // Each LS has a reference to file 'foo.ts' at version 1.  LS2 then updates
                        // it's version of 'foo.ts' to version 2.  This will cause LS2 and the
                        // DocumentRegistry to have version 2 of the document.  HOwever, LS1 will
                        // have version 1.  And *importantly* this source file will be *corrupt*.
                        // The act of creating version 2 of the file irrevocably damages the version
                        // 1 file.
                        //
                        // So, later when we call into LS1, we need to make sure that it doesn't use
                        // it's source file any more, and instead defers to DocumentRegistry to get
                        // either version 1, version 2 (or some other version) depending on what the
                        // host says should be used.
                        // We do not support the scenario where a host can modify a registered
                        // file's script kind, i.e. in one project some file is treated as ".ts"
                        // and in another as ".js"
                        ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.");
                        return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
                    }
                    // We didn't already have the file.  Fall through and acquire it from the registry.
                }
                // Could not find this file in the old program, create a new SourceFile for it.
                return documentRegistry.acquireDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
            }
        }
        // TODO: GH#18217 frequently asserted as defined
        function getProgram() {
            if (syntaxOnly) {
                ts.Debug.assert(program === undefined);
                return undefined;
            }
            synchronizeHostData();
            return program;
        }
        function cleanupSemanticCache() {
            program = undefined; // TODO: GH#18217
        }
        function dispose() {
            if (program) {
                // Use paths to ensure we are using correct key and paths as document registry could bre created with different current directory than host
                var key_1 = documentRegistry.getKeyForCompilationSettings(program.getCompilerOptions());
                ts.forEach(program.getSourceFiles(), function (f) {
                    return documentRegistry.releaseDocumentWithKey(f.resolvedPath, key_1);
                });
                program = undefined; // TODO: GH#18217
            }
            host = undefined;
        }
        /// Diagnostics
        function getSyntacticDiagnostics(fileName) {
            synchronizeHostData();
            return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice();
        }
        /**
         * getSemanticDiagnostics return array of Diagnostics. If '-d' is not enabled, only report semantic errors
         * If '-d' enabled, report both semantic and emitter errors
         */
        function getSemanticDiagnostics(fileName) {
            synchronizeHostData();
            var targetSourceFile = getValidSourceFile(fileName);
            // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
            // Therefore only get diagnostics for given file.
            var semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
            if (!ts.getEmitDeclarations(program.getCompilerOptions())) {
                return semanticDiagnostics.slice();
            }
            // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
            var declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken);
            return __spreadArrays(semanticDiagnostics, declarationDiagnostics);
        }
        function getSuggestionDiagnostics(fileName) {
            synchronizeHostData();
            return ts.computeSuggestionDiagnostics(getValidSourceFile(fileName), program, cancellationToken);
        }
        function getCompilerOptionsDiagnostics() {
            synchronizeHostData();
            return __spreadArrays(program.getOptionsDiagnostics(cancellationToken), program.getGlobalDiagnostics(cancellationToken));
        }
        function getCompletionsAtPosition(fileName, position, options) {
            if (options === void 0) { options = ts.emptyOptions; }
            // Convert from deprecated options names to new names
            var fullPreferences = __assign(__assign({}, ts.identity(options)), { includeCompletionsForModuleExports: options.includeCompletionsForModuleExports || options.includeExternalModuleExports, includeCompletionsWithInsertText: options.includeCompletionsWithInsertText || options.includeInsertTextCompletions });
            synchronizeHostData();
            return ts.Completions.getCompletionsAtPosition(host, program, log, getValidSourceFile(fileName), position, fullPreferences, options.triggerCharacter);
        }
        function getCompletionEntryDetails(fileName, position, name, formattingOptions, source, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            return ts.Completions.getCompletionEntryDetails(program, log, getValidSourceFile(fileName), position, { name: name, source: source }, host, (formattingOptions && ts.formatting.getFormatContext(formattingOptions, host)), // TODO: GH#18217
            preferences, cancellationToken);
        }
        function getCompletionEntrySymbol(fileName, position, name, source, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            return ts.Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name: name, source: source }, host, preferences);
        }
        function getQuickInfoAtPosition(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                // Avoid giving quickInfo for the sourceFile as a whole.
                return undefined;
            }
            var typeChecker = program.getTypeChecker();
            var nodeForQuickInfo = getNodeForQuickInfo(node);
            var symbol = getSymbolAtLocationForQuickInfo(nodeForQuickInfo, typeChecker);
            if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
                var type_2 = shouldGetType(sourceFile, nodeForQuickInfo, position) ? typeChecker.getTypeAtLocation(nodeForQuickInfo) : undefined;
                return type_2 && {
                    kind: "" /* unknown */,
                    kindModifiers: "" /* none */,
                    textSpan: ts.createTextSpanFromNode(nodeForQuickInfo, sourceFile),
                    displayParts: typeChecker.runWithCancellationToken(cancellationToken, function (typeChecker) { return ts.typeToDisplayParts(typeChecker, type_2, ts.getContainerNode(nodeForQuickInfo)); }),
                    documentation: type_2.symbol ? type_2.symbol.getDocumentationComment(typeChecker) : undefined,
                    tags: type_2.symbol ? type_2.symbol.getJsDocTags() : undefined
                };
            }
            var _a = typeChecker.runWithCancellationToken(cancellationToken, function (typeChecker) {
                return ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, ts.getContainerNode(nodeForQuickInfo), nodeForQuickInfo);
            }), symbolKind = _a.symbolKind, displayParts = _a.displayParts, documentation = _a.documentation, tags = _a.tags;
            return {
                kind: symbolKind,
                kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol),
                textSpan: ts.createTextSpanFromNode(nodeForQuickInfo, sourceFile),
                displayParts: displayParts,
                documentation: documentation,
                tags: tags,
            };
        }
        function getNodeForQuickInfo(node) {
            if (ts.isNewExpression(node.parent) && node.pos === node.parent.pos) {
                return node.parent.expression;
            }
            return node;
        }
        function shouldGetType(sourceFile, node, position) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return !ts.isLabelName(node) && !ts.isTagName(node);
                case 194 /* PropertyAccessExpression */:
                case 153 /* QualifiedName */:
                    // Don't return quickInfo if inside the comment in `a/**/.b`
                    return !ts.isInComment(sourceFile, position);
                case 104 /* ThisKeyword */:
                case 183 /* ThisType */:
                case 102 /* SuperKeyword */:
                    return true;
                default:
                    return false;
            }
        }
        /// Goto definition
        function getDefinitionAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position);
        }
        function getDefinitionAndBoundSpan(fileName, position) {
            synchronizeHostData();
            return ts.GoToDefinition.getDefinitionAndBoundSpan(program, getValidSourceFile(fileName), position);
        }
        function getTypeDefinitionAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position);
        }
        /// Goto implementation
        function getImplementationAtPosition(fileName, position) {
            synchronizeHostData();
            return ts.FindAllReferences.getImplementationsAtPosition(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position);
        }
        /// References and Occurrences
        function getOccurrencesAtPosition(fileName, position) {
            return ts.flatMap(getDocumentHighlights(fileName, position, [fileName]), function (entry) { return entry.highlightSpans.map(function (highlightSpan) { return (__assign(__assign({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, isWriteAccess: highlightSpan.kind === "writtenReference" /* writtenReference */, isDefinition: false }, highlightSpan.isInString && { isInString: true }), highlightSpan.contextSpan && { contextSpan: highlightSpan.contextSpan })); }); });
        }
        function getDocumentHighlights(fileName, position, filesToSearch) {
            var normalizedFileName = ts.normalizePath(fileName);
            ts.Debug.assert(filesToSearch.some(function (f) { return ts.normalizePath(f) === normalizedFileName; }));
            synchronizeHostData();
            var sourceFilesToSearch = ts.mapDefined(filesToSearch, function (fileName) { return program.getSourceFile(fileName); });
            var sourceFile = getValidSourceFile(fileName);
            return ts.DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch);
        }
        function findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var node = ts.getAdjustedRenameLocation(ts.getTouchingPropertyName(sourceFile, position));
            if (ts.isIdentifier(node) && (ts.isJsxOpeningElement(node.parent) || ts.isJsxClosingElement(node.parent)) && ts.isIntrinsicJsxName(node.escapedText)) {
                var _a = node.parent.parent, openingElement = _a.openingElement, closingElement = _a.closingElement;
                return [openingElement, closingElement].map(function (node) {
                    var textSpan = ts.createTextSpanFromNode(node.tagName, sourceFile);
                    return __assign({ fileName: sourceFile.fileName, textSpan: textSpan }, ts.FindAllReferences.toContextSpan(textSpan, sourceFile, node.parent));
                });
            }
            else {
                return getReferencesWorker(node, position, { findInStrings: findInStrings, findInComments: findInComments, providePrefixAndSuffixTextForRename: providePrefixAndSuffixTextForRename, use: 2 /* Rename */ }, function (entry, originalNode, checker) { return ts.FindAllReferences.toRenameLocation(entry, originalNode, checker, providePrefixAndSuffixTextForRename || false); });
            }
        }
        function getReferencesAtPosition(fileName, position) {
            synchronizeHostData();
            return getReferencesWorker(ts.getTouchingPropertyName(getValidSourceFile(fileName), position), position, { use: 1 /* References */ }, ts.FindAllReferences.toReferenceEntry);
        }
        function getReferencesWorker(node, position, options, cb) {
            synchronizeHostData();
            // Exclude default library when renaming as commonly user don't want to change that file.
            var sourceFiles = options && options.use === 2 /* Rename */
                ? program.getSourceFiles().filter(function (sourceFile) { return !program.isSourceFileDefaultLibrary(sourceFile); })
                : program.getSourceFiles();
            return ts.FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, sourceFiles, node, position, options, cb);
        }
        function findReferences(fileName, position) {
            synchronizeHostData();
            return ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position);
        }
        function getNavigateToItems(searchValue, maxResultCount, fileName, excludeDtsFiles) {
            if (excludeDtsFiles === void 0) { excludeDtsFiles = false; }
            synchronizeHostData();
            var sourceFiles = fileName ? [getValidSourceFile(fileName)] : program.getSourceFiles();
            return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles);
        }
        function getEmitOutput(fileName, emitOnlyDtsFiles, forceDtsEmit) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var customTransformers = host.getCustomTransformers && host.getCustomTransformers();
            return ts.getFileEmitOutput(program, sourceFile, !!emitOnlyDtsFiles, cancellationToken, customTransformers, forceDtsEmit);
        }
        // Signature help
        /**
         * This is a semantic operation.
         */
        function getSignatureHelpItems(fileName, position, _a) {
            var triggerReason = (_a === void 0 ? ts.emptyOptions : _a).triggerReason;
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            return ts.SignatureHelp.getSignatureHelpItems(program, sourceFile, position, triggerReason, cancellationToken);
        }
        /// Syntactic features
        function getNonBoundSourceFile(fileName) {
            return syntaxTreeCache.getCurrentSourceFile(fileName);
        }
        function getNameOrDottedNameSpan(fileName, startPos, _endPos) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            // Get node at the location
            var node = ts.getTouchingPropertyName(sourceFile, startPos);
            if (node === sourceFile) {
                return undefined;
            }
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                case 153 /* QualifiedName */:
                case 10 /* StringLiteral */:
                case 91 /* FalseKeyword */:
                case 106 /* TrueKeyword */:
                case 100 /* NullKeyword */:
                case 102 /* SuperKeyword */:
                case 104 /* ThisKeyword */:
                case 183 /* ThisType */:
                case 75 /* Identifier */:
                    break;
                // Cant create the text span
                default:
                    return undefined;
            }
            var nodeForStartPos = node;
            while (true) {
                if (ts.isRightSideOfPropertyAccess(nodeForStartPos) || ts.isRightSideOfQualifiedName(nodeForStartPos)) {
                    // If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node
                    nodeForStartPos = nodeForStartPos.parent;
                }
                else if (ts.isNameOfModuleDeclaration(nodeForStartPos)) {
                    // If this is name of a module declarations, check if this is right side of dotted module name
                    // If parent of the module declaration which is parent of this node is module declaration and its body is the module declaration that this node is name of
                    // Then this name is name from dotted module
                    if (nodeForStartPos.parent.parent.kind === 249 /* ModuleDeclaration */ &&
                        nodeForStartPos.parent.parent.body === nodeForStartPos.parent) {
                        // Use parent module declarations name for start pos
                        nodeForStartPos = nodeForStartPos.parent.parent.name;
                    }
                    else {
                        // We have to use this name for start pos
                        break;
                    }
                }
                else {
                    // Is not a member expression so we have found the node for start pos
                    break;
                }
            }
            return ts.createTextSpanFromBounds(nodeForStartPos.getStart(), node.getEnd());
        }
        function getBreakpointStatementAtPosition(fileName, position) {
            // doesn't use compiler - no need to synchronize with host
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position);
        }
        function getNavigationBarItems(fileName) {
            return ts.NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
        }
        function getNavigationTree(fileName) {
            return ts.NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
        }
        function isTsOrTsxFile(fileName) {
            var kind = ts.getScriptKind(fileName, host);
            return kind === 3 /* TS */ || kind === 4 /* TSX */;
        }
        function getSemanticClassifications(fileName, span) {
            if (!isTsOrTsxFile(fileName)) {
                // do not run semantic classification on non-ts-or-tsx files
                return [];
            }
            synchronizeHostData();
            return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
        }
        function getEncodedSemanticClassifications(fileName, span) {
            if (!isTsOrTsxFile(fileName)) {
                // do not run semantic classification on non-ts-or-tsx files
                return { spans: [], endOfLineState: 0 /* None */ };
            }
            synchronizeHostData();
            return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
        }
        function getSyntacticClassifications(fileName, span) {
            // doesn't use compiler - no need to synchronize with host
            return ts.getSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span);
        }
        function getEncodedSyntacticClassifications(fileName, span) {
            // doesn't use compiler - no need to synchronize with host
            return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span);
        }
        function getOutliningSpans(fileName) {
            // doesn't use compiler - no need to synchronize with host
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken);
        }
        var braceMatching = ts.createMapFromTemplate((_a = {},
            _a[18 /* OpenBraceToken */] = 19 /* CloseBraceToken */,
            _a[20 /* OpenParenToken */] = 21 /* CloseParenToken */,
            _a[22 /* OpenBracketToken */] = 23 /* CloseBracketToken */,
            _a[31 /* GreaterThanToken */] = 29 /* LessThanToken */,
            _a));
        braceMatching.forEach(function (value, key) { return braceMatching.set(value.toString(), Number(key)); });
        function getBraceMatchingAtPosition(fileName, position) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var token = ts.getTouchingToken(sourceFile, position);
            var matchKind = token.getStart(sourceFile) === position ? braceMatching.get(token.kind.toString()) : undefined;
            var match = matchKind && ts.findChildOfKind(token.parent, matchKind, sourceFile);
            // We want to order the braces when we return the result.
            return match ? [ts.createTextSpanFromNode(token, sourceFile), ts.createTextSpanFromNode(match, sourceFile)].sort(function (a, b) { return a.start - b.start; }) : ts.emptyArray;
        }
        function getIndentationAtPosition(fileName, position, editorOptions) {
            var start = ts.timestamp();
            var settings = toEditorSettings(editorOptions);
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            log("getIndentationAtPosition: getCurrentSourceFile: " + (ts.timestamp() - start));
            start = ts.timestamp();
            var result = ts.formatting.SmartIndenter.getIndentation(position, sourceFile, settings);
            log("getIndentationAtPosition: computeIndentation  : " + (ts.timestamp() - start));
            return result;
        }
        function getFormattingEditsForRange(fileName, start, end, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.formatting.formatSelection(start, end, sourceFile, ts.formatting.getFormatContext(toEditorSettings(options), host));
        }
        function getFormattingEditsForDocument(fileName, options) {
            return ts.formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), ts.formatting.getFormatContext(toEditorSettings(options), host));
        }
        function getFormattingEditsAfterKeystroke(fileName, position, key, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var formatContext = ts.formatting.getFormatContext(toEditorSettings(options), host);
            if (!ts.isInComment(sourceFile, position)) {
                switch (key) {
                    case "{":
                        return ts.formatting.formatOnOpeningCurly(position, sourceFile, formatContext);
                    case "}":
                        return ts.formatting.formatOnClosingCurly(position, sourceFile, formatContext);
                    case ";":
                        return ts.formatting.formatOnSemicolon(position, sourceFile, formatContext);
                    case "\n":
                        return ts.formatting.formatOnEnter(position, sourceFile, formatContext);
                }
            }
            return [];
        }
        function getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var span = ts.createTextSpanFromBounds(start, end);
            var formatContext = ts.formatting.getFormatContext(formatOptions, host);
            return ts.flatMap(ts.deduplicate(errorCodes, ts.equateValues, ts.compareValues), function (errorCode) {
                cancellationToken.throwIfCancellationRequested();
                return ts.codefix.getFixes({ errorCode: errorCode, sourceFile: sourceFile, span: span, program: program, host: host, cancellationToken: cancellationToken, formatContext: formatContext, preferences: preferences });
            });
        }
        function getCombinedCodeFix(scope, fixId, formatOptions, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            ts.Debug.assert(scope.type === "file");
            var sourceFile = getValidSourceFile(scope.fileName);
            var formatContext = ts.formatting.getFormatContext(formatOptions, host);
            return ts.codefix.getAllFixes({ fixId: fixId, sourceFile: sourceFile, program: program, host: host, cancellationToken: cancellationToken, formatContext: formatContext, preferences: preferences });
        }
        function organizeImports(scope, formatOptions, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            ts.Debug.assert(scope.type === "file");
            var sourceFile = getValidSourceFile(scope.fileName);
            var formatContext = ts.formatting.getFormatContext(formatOptions, host);
            return ts.OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences);
        }
        function getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            return ts.getEditsForFileRename(getProgram(), oldFilePath, newFilePath, host, ts.formatting.getFormatContext(formatOptions, host), preferences, sourceMapper);
        }
        function applyCodeActionCommand(fileName, actionOrFormatSettingsOrUndefined) {
            var action = typeof fileName === "string" ? actionOrFormatSettingsOrUndefined : fileName;
            return ts.isArray(action) ? Promise.all(action.map(function (a) { return applySingleCodeActionCommand(a); })) : applySingleCodeActionCommand(action);
        }
        function applySingleCodeActionCommand(action) {
            var getPath = function (path) { return ts.toPath(path, currentDirectory, getCanonicalFileName); };
            ts.Debug.assertEqual(action.type, "install package");
            return host.installPackage
                ? host.installPackage({ fileName: getPath(action.file), packageName: action.packageName })
                : Promise.reject("Host does not implement `installPackage`");
        }
        function getDocCommentTemplateAtPosition(fileName, position) {
            return ts.JsDoc.getDocCommentTemplateAtPosition(ts.getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position);
        }
        function isValidBraceCompletionAtPosition(fileName, position, openingBrace) {
            // '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too
            // expensive to do during typing scenarios
            // i.e. whether we're dealing with:
            //      var x = new foo<| ( with class foo<T>{} )
            // or
            //      var y = 3 <|
            if (openingBrace === 60 /* lessThan */) {
                return false;
            }
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            // Check if in a context where we don't want to perform any insertion
            if (ts.isInString(sourceFile, position)) {
                return false;
            }
            if (ts.isInsideJsxElementOrAttribute(sourceFile, position)) {
                return openingBrace === 123 /* openBrace */;
            }
            if (ts.isInTemplateString(sourceFile, position)) {
                return false;
            }
            switch (openingBrace) {
                case 39 /* singleQuote */:
                case 34 /* doubleQuote */:
                case 96 /* backtick */:
                    return !ts.isInComment(sourceFile, position);
            }
            return true;
        }
        function getJsxClosingTagAtPosition(fileName, position) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var token = ts.findPrecedingToken(position, sourceFile);
            if (!token)
                return undefined;
            var element = token.kind === 31 /* GreaterThanToken */ && ts.isJsxOpeningElement(token.parent) ? token.parent.parent
                : ts.isJsxText(token) ? token.parent : undefined;
            if (element && isUnclosedTag(element)) {
                return { newText: "</" + element.openingElement.tagName.getText(sourceFile) + ">" };
            }
        }
        function isUnclosedTag(_a) {
            var openingElement = _a.openingElement, closingElement = _a.closingElement, parent = _a.parent;
            return !ts.tagNamesAreEquivalent(openingElement.tagName, closingElement.tagName) ||
                ts.isJsxElement(parent) && ts.tagNamesAreEquivalent(openingElement.tagName, parent.openingElement.tagName) && isUnclosedTag(parent);
        }
        function getSpanOfEnclosingComment(fileName, position, onlyMultiLine) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var range = ts.formatting.getRangeOfEnclosingComment(sourceFile, position);
            return range && (!onlyMultiLine || range.kind === 3 /* MultiLineCommentTrivia */) ? ts.createTextSpanFromRange(range) : undefined;
        }
        function getTodoComments(fileName, descriptors) {
            // Note: while getting todo comments seems like a syntactic operation, we actually
            // treat it as a semantic operation here.  This is because we expect our host to call
            // this on every single file.  If we treat this syntactically, then that will cause
            // us to populate and throw away the tree in our syntax tree cache for each file.  By
            // treating this as a semantic operation, we can access any tree without throwing
            // anything away.
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            cancellationToken.throwIfCancellationRequested();
            var fileContents = sourceFile.text;
            var result = [];
            // Exclude node_modules files as we don't want to show the todos of external libraries.
            if (descriptors.length > 0 && !isNodeModulesFile(sourceFile.fileName)) {
                var regExp = getTodoCommentsRegExp();
                var matchArray = void 0;
                while (matchArray = regExp.exec(fileContents)) {
                    cancellationToken.throwIfCancellationRequested();
                    // If we got a match, here is what the match array will look like.  Say the source text is:
                    //
                    //      "    // hack   1"
                    //
                    // The result array with the regexp:    will be:
                    //
                    //      ["// hack   1", "// ", "hack   1", undefined, "hack"]
                    //
                    // Here are the relevant capture groups:
                    //  0) The full match for the entire regexp.
                    //  1) The preamble to the message portion.
                    //  2) The message portion.
                    //  3...N) The descriptor that was matched - by index.  'undefined' for each
                    //         descriptor that didn't match.  an actual value if it did match.
                    //
                    //  i.e. 'undefined' in position 3 above means TODO(jason) didn't match.
                    //       "hack"      in position 4 means HACK did match.
                    var firstDescriptorCaptureIndex = 3;
                    ts.Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex);
                    var preamble = matchArray[1];
                    var matchPosition = matchArray.index + preamble.length;
                    // OK, we have found a match in the file.  This is only an acceptable match if
                    // it is contained within a comment.
                    if (!ts.isInComment(sourceFile, matchPosition)) {
                        continue;
                    }
                    var descriptor = void 0;
                    for (var i = 0; i < descriptors.length; i++) {
                        if (matchArray[i + firstDescriptorCaptureIndex]) {
                            descriptor = descriptors[i];
                        }
                    }
                    if (descriptor === undefined)
                        return ts.Debug.fail();
                    // We don't want to match something like 'TODOBY', so we make sure a non
                    // letter/digit follows the match.
                    if (isLetterOrDigit(fileContents.charCodeAt(matchPosition + descriptor.text.length))) {
                        continue;
                    }
                    var message = matchArray[2];
                    result.push({ descriptor: descriptor, message: message, position: matchPosition });
                }
            }
            return result;
            function escapeRegExp(str) {
                return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
            }
            function getTodoCommentsRegExp() {
                // NOTE: `?:` means 'non-capture group'.  It allows us to have groups without having to
                // filter them out later in the final result array.
                // TODO comments can appear in one of the following forms:
                //
                //  1)      // TODO     or  /////////// TODO
                //
                //  2)      /* TODO     or  /********** TODO
                //
                //  3)      /*
                //           *   TODO
                //           */
                //
                // The following three regexps are used to match the start of the text up to the TODO
                // comment portion.
                var singleLineCommentStart = /(?:\/\/+\s*)/.source;
                var multiLineCommentStart = /(?:\/\*+\s*)/.source;
                var anyNumberOfSpacesAndAsterisksAtStartOfLine = /(?:^(?:\s|\*)*)/.source;
                // Match any of the above three TODO comment start regexps.
                // Note that the outermost group *is* a capture group.  We want to capture the preamble
                // so that we can determine the starting position of the TODO comment match.
                var preamble = "(" + anyNumberOfSpacesAndAsterisksAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")";
                // Takes the descriptors and forms a regexp that matches them as if they were literals.
                // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be:
                //
                //      (?:(TODO\(jason\))|(HACK))
                //
                // Note that the outermost group is *not* a capture group, but the innermost groups
                // *are* capture groups.  By capturing the inner literals we can determine after
                // matching which descriptor we are dealing with.
                var literals = "(?:" + ts.map(descriptors, function (d) { return "(" + escapeRegExp(d.text) + ")"; }).join("|") + ")";
                // After matching a descriptor literal, the following regexp matches the rest of the
                // text up to the end of the line (or */).
                var endOfLineOrEndOfComment = /(?:$|\*\/)/.source;
                var messageRemainder = /(?:.*?)/.source;
                // This is the portion of the match we'll return as part of the TODO comment result. We
                // match the literal portion up to the end of the line or end of comment.
                var messagePortion = "(" + literals + messageRemainder + ")";
                var regExpString = preamble + messagePortion + endOfLineOrEndOfComment;
                // The final regexp will look like this:
                // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim
                // The flags of the regexp are important here.
                //  'g' is so that we are doing a global search and can find matches several times
                //  in the input.
                //
                //  'i' is for case insensitivity (We do this to match C# TODO comment code).
                //
                //  'm' is so we can find matches in a multi-line input.
                return new RegExp(regExpString, "gim");
            }
            function isLetterOrDigit(char) {
                return (char >= 97 /* a */ && char <= 122 /* z */) ||
                    (char >= 65 /* A */ && char <= 90 /* Z */) ||
                    (char >= 48 /* _0 */ && char <= 57 /* _9 */);
            }
            function isNodeModulesFile(path) {
                return ts.stringContains(path, "/node_modules/");
            }
        }
        function getRenameInfo(fileName, position, options) {
            synchronizeHostData();
            return ts.Rename.getRenameInfo(program, getValidSourceFile(fileName), position, options);
        }
        function getRefactorContext(file, positionOrRange, preferences, formatOptions) {
            var _a = typeof positionOrRange === "number" ? [positionOrRange, undefined] : [positionOrRange.pos, positionOrRange.end], startPosition = _a[0], endPosition = _a[1];
            return {
                file: file,
                startPosition: startPosition,
                endPosition: endPosition,
                program: getProgram(),
                host: host,
                formatContext: ts.formatting.getFormatContext(formatOptions, host),
                cancellationToken: cancellationToken,
                preferences: preferences,
            };
        }
        function getSmartSelectionRange(fileName, position) {
            return ts.SmartSelectionRange.getSmartSelectionRange(position, syntaxTreeCache.getCurrentSourceFile(fileName));
        }
        function getApplicableRefactors(fileName, positionOrRange, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            var file = getValidSourceFile(fileName);
            return ts.refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange, preferences));
        }
        function getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName, preferences) {
            if (preferences === void 0) { preferences = ts.emptyOptions; }
            synchronizeHostData();
            var file = getValidSourceFile(fileName);
            return ts.refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, preferences, formatOptions), refactorName, actionName);
        }
        function prepareCallHierarchy(fileName, position) {
            synchronizeHostData();
            var declarations = ts.CallHierarchy.resolveCallHierarchyDeclaration(program, ts.getTouchingPropertyName(getValidSourceFile(fileName), position));
            return declarations && ts.mapOneOrMany(declarations, function (declaration) { return ts.CallHierarchy.createCallHierarchyItem(program, declaration); });
        }
        function provideCallHierarchyIncomingCalls(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var declaration = ts.firstOrOnly(ts.CallHierarchy.resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : ts.getTouchingPropertyName(sourceFile, position)));
            return declaration ? ts.CallHierarchy.getIncomingCalls(program, declaration, cancellationToken) : [];
        }
        function provideCallHierarchyOutgoingCalls(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var declaration = ts.firstOrOnly(ts.CallHierarchy.resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : ts.getTouchingPropertyName(sourceFile, position)));
            return declaration ? ts.CallHierarchy.getOutgoingCalls(program, declaration) : [];
        }
        return {
            dispose: dispose,
            cleanupSemanticCache: cleanupSemanticCache,
            getSyntacticDiagnostics: getSyntacticDiagnostics,
            getSemanticDiagnostics: getSemanticDiagnostics,
            getSuggestionDiagnostics: getSuggestionDiagnostics,
            getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics,
            getSyntacticClassifications: getSyntacticClassifications,
            getSemanticClassifications: getSemanticClassifications,
            getEncodedSyntacticClassifications: getEncodedSyntacticClassifications,
            getEncodedSemanticClassifications: getEncodedSemanticClassifications,
            getCompletionsAtPosition: getCompletionsAtPosition,
            getCompletionEntryDetails: getCompletionEntryDetails,
            getCompletionEntrySymbol: getCompletionEntrySymbol,
            getSignatureHelpItems: getSignatureHelpItems,
            getQuickInfoAtPosition: getQuickInfoAtPosition,
            getDefinitionAtPosition: getDefinitionAtPosition,
            getDefinitionAndBoundSpan: getDefinitionAndBoundSpan,
            getImplementationAtPosition: getImplementationAtPosition,
            getTypeDefinitionAtPosition: getTypeDefinitionAtPosition,
            getReferencesAtPosition: getReferencesAtPosition,
            findReferences: findReferences,
            getOccurrencesAtPosition: getOccurrencesAtPosition,
            getDocumentHighlights: getDocumentHighlights,
            getNameOrDottedNameSpan: getNameOrDottedNameSpan,
            getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
            getNavigateToItems: getNavigateToItems,
            getRenameInfo: getRenameInfo,
            getSmartSelectionRange: getSmartSelectionRange,
            findRenameLocations: findRenameLocations,
            getNavigationBarItems: getNavigationBarItems,
            getNavigationTree: getNavigationTree,
            getOutliningSpans: getOutliningSpans,
            getTodoComments: getTodoComments,
            getBraceMatchingAtPosition: getBraceMatchingAtPosition,
            getIndentationAtPosition: getIndentationAtPosition,
            getFormattingEditsForRange: getFormattingEditsForRange,
            getFormattingEditsForDocument: getFormattingEditsForDocument,
            getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke,
            getDocCommentTemplateAtPosition: getDocCommentTemplateAtPosition,
            isValidBraceCompletionAtPosition: isValidBraceCompletionAtPosition,
            getJsxClosingTagAtPosition: getJsxClosingTagAtPosition,
            getSpanOfEnclosingComment: getSpanOfEnclosingComment,
            getCodeFixesAtPosition: getCodeFixesAtPosition,
            getCombinedCodeFix: getCombinedCodeFix,
            applyCodeActionCommand: applyCodeActionCommand,
            organizeImports: organizeImports,
            getEditsForFileRename: getEditsForFileRename,
            getEmitOutput: getEmitOutput,
            getNonBoundSourceFile: getNonBoundSourceFile,
            getProgram: getProgram,
            getApplicableRefactors: getApplicableRefactors,
            getEditsForRefactor: getEditsForRefactor,
            toLineColumnOffset: sourceMapper.toLineColumnOffset,
            getSourceMapper: function () { return sourceMapper; },
            clearSourceMapperCache: function () { return sourceMapper.clearCache(); },
            prepareCallHierarchy: prepareCallHierarchy,
            provideCallHierarchyIncomingCalls: provideCallHierarchyIncomingCalls,
            provideCallHierarchyOutgoingCalls: provideCallHierarchyOutgoingCalls
        };
    }
    ts.createLanguageService = createLanguageService;
    /* @internal */
    /** Names in the name table are escaped, so an identifier `__foo` will have a name table entry `___foo`. */
    function getNameTable(sourceFile) {
        if (!sourceFile.nameTable) {
            initializeNameTable(sourceFile);
        }
        return sourceFile.nameTable; // TODO: GH#18217
    }
    ts.getNameTable = getNameTable;
    function initializeNameTable(sourceFile) {
        var nameTable = sourceFile.nameTable = ts.createUnderscoreEscapedMap();
        sourceFile.forEachChild(function walk(node) {
            if (ts.isIdentifier(node) && !ts.isTagName(node) && node.escapedText || ts.isStringOrNumericLiteralLike(node) && literalIsName(node)) {
                var text = ts.getEscapedTextOfIdentifierOrLiteral(node);
                nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
            }
            else if (ts.isPrivateIdentifier(node)) {
                var text = node.escapedText;
                nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
            }
            ts.forEachChild(node, walk);
            if (ts.hasJSDocNodes(node)) {
                for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                    var jsDoc = _a[_i];
                    ts.forEachChild(jsDoc, walk);
                }
            }
        });
    }
    /**
     * We want to store any numbers/strings if they were a name that could be
     * related to a declaration.  So, if we have 'import x = require("something")'
     * then we want 'something' to be in the name table.  Similarly, if we have
     * "a['propname']" then we want to store "propname" in the name table.
     */
    function literalIsName(node) {
        return ts.isDeclarationName(node) ||
            node.parent.kind === 265 /* ExternalModuleReference */ ||
            isArgumentOfElementAccessExpression(node) ||
            ts.isLiteralComputedPropertyDeclarationName(node);
    }
    /**
     * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
     */
    /* @internal */
    function getContainingObjectLiteralElement(node) {
        var element = getContainingObjectLiteralElementWorker(node);
        return element && (ts.isObjectLiteralExpression(element.parent) || ts.isJsxAttributes(element.parent)) ? element : undefined;
    }
    ts.getContainingObjectLiteralElement = getContainingObjectLiteralElement;
    function getContainingObjectLiteralElementWorker(node) {
        switch (node.kind) {
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 8 /* NumericLiteral */:
                if (node.parent.kind === 154 /* ComputedPropertyName */) {
                    return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
                }
            // falls through
            case 75 /* Identifier */:
                return ts.isObjectLiteralElement(node.parent) &&
                    (node.parent.parent.kind === 193 /* ObjectLiteralExpression */ || node.parent.parent.kind === 274 /* JsxAttributes */) &&
                    node.parent.name === node ? node.parent : undefined;
        }
        return undefined;
    }
    function getSymbolAtLocationForQuickInfo(node, checker) {
        var object = getContainingObjectLiteralElement(node);
        if (object) {
            var contextualType = checker.getContextualType(object.parent);
            var properties = contextualType && getPropertySymbolsFromContextualType(object, checker, contextualType, /*unionSymbolOk*/ false);
            if (properties && properties.length === 1) {
                return ts.first(properties);
            }
        }
        return checker.getSymbolAtLocation(node);
    }
    /** Gets all symbols for one property. Does not get symbols for every property. */
    /* @internal */
    function getPropertySymbolsFromContextualType(node, checker, contextualType, unionSymbolOk) {
        var name = ts.getNameFromPropertyName(node.name);
        if (!name)
            return ts.emptyArray;
        if (!contextualType.isUnion()) {
            var symbol = contextualType.getProperty(name);
            return symbol ? [symbol] : ts.emptyArray;
        }
        var discriminatedPropertySymbols = ts.mapDefined(contextualType.types, function (t) { return ts.isObjectLiteralExpression(node.parent) && checker.isTypeInvalidDueToUnionDiscriminant(t, node.parent) ? undefined : t.getProperty(name); });
        if (unionSymbolOk && (discriminatedPropertySymbols.length === 0 || discriminatedPropertySymbols.length === contextualType.types.length)) {
            var symbol = contextualType.getProperty(name);
            if (symbol)
                return [symbol];
        }
        if (discriminatedPropertySymbols.length === 0) {
            // Bad discriminant -- do again without discriminating
            return ts.mapDefined(contextualType.types, function (t) { return t.getProperty(name); });
        }
        return discriminatedPropertySymbols;
    }
    ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType;
    function isArgumentOfElementAccessExpression(node) {
        return node &&
            node.parent &&
            node.parent.kind === 195 /* ElementAccessExpression */ &&
            node.parent.argumentExpression === node;
    }
    /**
     * Get the path of the default library files (lib.d.ts) as distributed with the typescript
     * node package.
     * The functionality is not supported if the ts module is consumed outside of a node module.
     */
    function getDefaultLibFilePath(options) {
        // Check __dirname is defined and that we are on a node.js system.
        if (typeof __dirname !== "undefined") {
            return __dirname + ts.directorySeparator + ts.getDefaultLibFileName(options);
        }
        throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. ");
    }
    ts.getDefaultLibFilePath = getDefaultLibFilePath;
    ts.setObjectAllocator(getServicesObjectAllocator());
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var BreakpointResolver;
    (function (BreakpointResolver) {
        /**
         * Get the breakpoint span in given sourceFile
         */
        function spanInSourceFileAtLocation(sourceFile, position) {
            // Cannot set breakpoint in dts file
            if (sourceFile.isDeclarationFile) {
                return undefined;
            }
            var tokenAtLocation = ts.getTokenAtPosition(sourceFile, position);
            var lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
            if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
                // Get previous token if the token is returned starts on new line
                // eg: let x =10; |--- cursor is here
                //     let y = 10;
                // token at position will return let keyword on second line as the token but we would like to use
                // token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line
                var preceding = ts.findPrecedingToken(tokenAtLocation.pos, sourceFile);
                // It's a blank line
                if (!preceding || sourceFile.getLineAndCharacterOfPosition(preceding.getEnd()).line !== lineOfPosition) {
                    return undefined;
                }
                tokenAtLocation = preceding;
            }
            // Cannot set breakpoint in ambient declarations
            if (tokenAtLocation.flags & 8388608 /* Ambient */) {
                return undefined;
            }
            // Get the span in the node based on its syntax
            return spanInNode(tokenAtLocation);
            function textSpan(startNode, endNode) {
                var start = startNode.decorators ?
                    ts.skipTrivia(sourceFile.text, startNode.decorators.end) :
                    startNode.getStart(sourceFile);
                return ts.createTextSpanFromBounds(start, (endNode || startNode).getEnd());
            }
            function textSpanEndingAtNextToken(startNode, previousTokenToFindNextEndToken) {
                return textSpan(startNode, ts.findNextToken(previousTokenToFindNextEndToken, previousTokenToFindNextEndToken.parent, sourceFile));
            }
            function spanInNodeIfStartsOnSameLine(node, otherwiseOnNode) {
                if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line) {
                    return spanInNode(node);
                }
                return spanInNode(otherwiseOnNode);
            }
            function spanInNodeArray(nodeArray) {
                return ts.createTextSpanFromBounds(ts.skipTrivia(sourceFile.text, nodeArray.pos), nodeArray.end);
            }
            function spanInPreviousNode(node) {
                return spanInNode(ts.findPrecedingToken(node.pos, sourceFile));
            }
            function spanInNextNode(node) {
                return spanInNode(ts.findNextToken(node, node.parent, sourceFile));
            }
            function spanInNode(node) {
                if (node) {
                    var parent = node.parent;
                    switch (node.kind) {
                        case 225 /* VariableStatement */:
                            // Span on first variable declaration
                            return spanInVariableDeclaration(node.declarationList.declarations[0]);
                        case 242 /* VariableDeclaration */:
                        case 159 /* PropertyDeclaration */:
                        case 158 /* PropertySignature */:
                            return spanInVariableDeclaration(node);
                        case 156 /* Parameter */:
                            return spanInParameterDeclaration(node);
                        case 244 /* FunctionDeclaration */:
                        case 161 /* MethodDeclaration */:
                        case 160 /* MethodSignature */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                        case 162 /* Constructor */:
                        case 201 /* FunctionExpression */:
                        case 202 /* ArrowFunction */:
                            return spanInFunctionDeclaration(node);
                        case 223 /* Block */:
                            if (ts.isFunctionBlock(node)) {
                                return spanInFunctionBlock(node);
                            }
                        // falls through
                        case 250 /* ModuleBlock */:
                            return spanInBlock(node);
                        case 280 /* CatchClause */:
                            return spanInBlock(node.block);
                        case 226 /* ExpressionStatement */:
                            // span on the expression
                            return textSpan(node.expression);
                        case 235 /* ReturnStatement */:
                            // span on return keyword and expression if present
                            return textSpan(node.getChildAt(0), node.expression);
                        case 229 /* WhileStatement */:
                            // Span on while(...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 228 /* DoStatement */:
                            // span in statement of the do statement
                            return spanInNode(node.statement);
                        case 241 /* DebuggerStatement */:
                            // span on debugger keyword
                            return textSpan(node.getChildAt(0));
                        case 227 /* IfStatement */:
                            // set on if(..) span
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 238 /* LabeledStatement */:
                            // span in statement
                            return spanInNode(node.statement);
                        case 234 /* BreakStatement */:
                        case 233 /* ContinueStatement */:
                            // On break or continue keyword and label if present
                            return textSpan(node.getChildAt(0), node.label);
                        case 230 /* ForStatement */:
                            return spanInForStatement(node);
                        case 231 /* ForInStatement */:
                            // span of for (a in ...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 232 /* ForOfStatement */:
                            // span in initializer
                            return spanInInitializerOfForLike(node);
                        case 237 /* SwitchStatement */:
                            // span on switch(...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 277 /* CaseClause */:
                        case 278 /* DefaultClause */:
                            // span in first statement of the clause
                            return spanInNode(node.statements[0]);
                        case 240 /* TryStatement */:
                            // span in try block
                            return spanInBlock(node.tryBlock);
                        case 239 /* ThrowStatement */:
                            // span in throw ...
                            return textSpan(node, node.expression);
                        case 259 /* ExportAssignment */:
                            // span on export = id
                            return textSpan(node, node.expression);
                        case 253 /* ImportEqualsDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleReference);
                        case 254 /* ImportDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleSpecifier);
                        case 260 /* ExportDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleSpecifier);
                        case 249 /* ModuleDeclaration */:
                            // span on complete module if it is instantiated
                            if (ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // falls through
                        case 245 /* ClassDeclaration */:
                        case 248 /* EnumDeclaration */:
                        case 284 /* EnumMember */:
                        case 191 /* BindingElement */:
                            // span on complete node
                            return textSpan(node);
                        case 236 /* WithStatement */:
                            // span in statement
                            return spanInNode(node.statement);
                        case 157 /* Decorator */:
                            return spanInNodeArray(parent.decorators);
                        case 189 /* ObjectBindingPattern */:
                        case 190 /* ArrayBindingPattern */:
                            return spanInBindingPattern(node);
                        // No breakpoint in interface, type alias
                        case 246 /* InterfaceDeclaration */:
                        case 247 /* TypeAliasDeclaration */:
                            return undefined;
                        // Tokens:
                        case 26 /* SemicolonToken */:
                        case 1 /* EndOfFileToken */:
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile));
                        case 27 /* CommaToken */:
                            return spanInPreviousNode(node);
                        case 18 /* OpenBraceToken */:
                            return spanInOpenBraceToken(node);
                        case 19 /* CloseBraceToken */:
                            return spanInCloseBraceToken(node);
                        case 23 /* CloseBracketToken */:
                            return spanInCloseBracketToken(node);
                        case 20 /* OpenParenToken */:
                            return spanInOpenParenToken(node);
                        case 21 /* CloseParenToken */:
                            return spanInCloseParenToken(node);
                        case 58 /* ColonToken */:
                            return spanInColonToken(node);
                        case 31 /* GreaterThanToken */:
                        case 29 /* LessThanToken */:
                            return spanInGreaterThanOrLessThanToken(node);
                        // Keywords:
                        case 111 /* WhileKeyword */:
                            return spanInWhileKeyword(node);
                        case 87 /* ElseKeyword */:
                        case 79 /* CatchKeyword */:
                        case 92 /* FinallyKeyword */:
                            return spanInNextNode(node);
                        case 152 /* OfKeyword */:
                            return spanInOfKeyword(node);
                        default:
                            // Destructuring pattern in destructuring assignment
                            // [a, b, c] of
                            // [a, b, c] = expression
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node)) {
                                return spanInArrayLiteralOrObjectLiteralDestructuringPattern(node);
                            }
                            // Set breakpoint on identifier element of destructuring pattern
                            // `a` or `...c` or `d: x` from
                            // `[a, b, ...c]` or `{ a, b }` or `{ d: x }` from destructuring pattern
                            if ((node.kind === 75 /* Identifier */ ||
                                node.kind === 213 /* SpreadElement */ ||
                                node.kind === 281 /* PropertyAssignment */ ||
                                node.kind === 282 /* ShorthandPropertyAssignment */) &&
                                ts.isArrayLiteralOrObjectLiteralDestructuringPattern(parent)) {
                                return textSpan(node);
                            }
                            if (node.kind === 209 /* BinaryExpression */) {
                                var _a = node, left = _a.left, operatorToken = _a.operatorToken;
                                // Set breakpoint in destructuring pattern if its destructuring assignment
                                // [a, b, c] or {a, b, c} of
                                // [a, b, c] = expression or
                                // {a, b, c} = expression
                                if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(left)) {
                                    return spanInArrayLiteralOrObjectLiteralDestructuringPattern(left);
                                }
                                if (operatorToken.kind === 62 /* EqualsToken */ && ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                    // Set breakpoint on assignment expression element of destructuring pattern
                                    // a = expression of
                                    // [a = expression, b, c] = someExpression or
                                    // { a = expression, b, c } = someExpression
                                    return textSpan(node);
                                }
                                if (operatorToken.kind === 27 /* CommaToken */) {
                                    return spanInNode(left);
                                }
                            }
                            if (ts.isExpressionNode(node)) {
                                switch (parent.kind) {
                                    case 228 /* DoStatement */:
                                        // Set span as if on while keyword
                                        return spanInPreviousNode(node);
                                    case 157 /* Decorator */:
                                        // Set breakpoint on the decorator emit
                                        return spanInNode(node.parent);
                                    case 230 /* ForStatement */:
                                    case 232 /* ForOfStatement */:
                                        return textSpan(node);
                                    case 209 /* BinaryExpression */:
                                        if (node.parent.operatorToken.kind === 27 /* CommaToken */) {
                                            // If this is a comma expression, the breakpoint is possible in this expression
                                            return textSpan(node);
                                        }
                                        break;
                                    case 202 /* ArrowFunction */:
                                        if (node.parent.body === node) {
                                            // If this is body of arrow function, it is allowed to have the breakpoint
                                            return textSpan(node);
                                        }
                                        break;
                                }
                            }
                            switch (node.parent.kind) {
                                case 281 /* PropertyAssignment */:
                                    // If this is name of property assignment, set breakpoint in the initializer
                                    if (node.parent.name === node &&
                                        !ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.parent)) {
                                        return spanInNode(node.parent.initializer);
                                    }
                                    break;
                                case 199 /* TypeAssertionExpression */:
                                    // Breakpoint in type assertion goes to its operand
                                    if (node.parent.type === node) {
                                        return spanInNextNode(node.parent.type);
                                    }
                                    break;
                                case 242 /* VariableDeclaration */:
                                case 156 /* Parameter */: {
                                    // initializer of variable/parameter declaration go to previous node
                                    var _b = node.parent, initializer = _b.initializer, type = _b.type;
                                    if (initializer === node || type === node || ts.isAssignmentOperator(node.kind)) {
                                        return spanInPreviousNode(node);
                                    }
                                    break;
                                }
                                case 209 /* BinaryExpression */: {
                                    var left = node.parent.left;
                                    if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(left) && node !== left) {
                                        // If initializer of destructuring assignment move to previous token
                                        return spanInPreviousNode(node);
                                    }
                                    break;
                                }
                                default:
                                    // return type of function go to previous token
                                    if (ts.isFunctionLike(node.parent) && node.parent.type === node) {
                                        return spanInPreviousNode(node);
                                    }
                            }
                            // Default go to parent to set the breakpoint
                            return spanInNode(node.parent);
                    }
                }
                function textSpanFromVariableDeclaration(variableDeclaration) {
                    if (ts.isVariableDeclarationList(variableDeclaration.parent) && variableDeclaration.parent.declarations[0] === variableDeclaration) {
                        // First declaration - include let keyword
                        return textSpan(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
                    }
                    else {
                        // Span only on this declaration
                        return textSpan(variableDeclaration);
                    }
                }
                function spanInVariableDeclaration(variableDeclaration) {
                    // If declaration of for in statement, just set the span in parent
                    if (variableDeclaration.parent.parent.kind === 231 /* ForInStatement */) {
                        return spanInNode(variableDeclaration.parent.parent);
                    }
                    var parent = variableDeclaration.parent;
                    // If this is a destructuring pattern, set breakpoint in binding pattern
                    if (ts.isBindingPattern(variableDeclaration.name)) {
                        return spanInBindingPattern(variableDeclaration.name);
                    }
                    // Breakpoint is possible in variableDeclaration only if there is initialization
                    // or its declaration from 'for of'
                    if (variableDeclaration.initializer ||
                        ts.hasModifier(variableDeclaration, 1 /* Export */) ||
                        parent.parent.kind === 232 /* ForOfStatement */) {
                        return textSpanFromVariableDeclaration(variableDeclaration);
                    }
                    if (ts.isVariableDeclarationList(variableDeclaration.parent) &&
                        variableDeclaration.parent.declarations[0] !== variableDeclaration) {
                        // If we cannot set breakpoint on this declaration, set it on previous one
                        // Because the variable declaration may be binding pattern and
                        // we would like to set breakpoint in last binding element if that's the case,
                        // use preceding token instead
                        return spanInNode(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent));
                    }
                }
                function canHaveSpanInParameterDeclaration(parameter) {
                    // Breakpoint is possible on parameter only if it has initializer, is a rest parameter, or has public or private modifier
                    return !!parameter.initializer || parameter.dotDotDotToken !== undefined ||
                        ts.hasModifier(parameter, 4 /* Public */ | 8 /* Private */);
                }
                function spanInParameterDeclaration(parameter) {
                    if (ts.isBindingPattern(parameter.name)) {
                        // Set breakpoint in binding pattern
                        return spanInBindingPattern(parameter.name);
                    }
                    else if (canHaveSpanInParameterDeclaration(parameter)) {
                        return textSpan(parameter);
                    }
                    else {
                        var functionDeclaration = parameter.parent;
                        var indexOfParameter = functionDeclaration.parameters.indexOf(parameter);
                        ts.Debug.assert(indexOfParameter !== -1);
                        if (indexOfParameter !== 0) {
                            // Not a first parameter, go to previous parameter
                            return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]);
                        }
                        else {
                            // Set breakpoint in the function declaration body
                            return spanInNode(functionDeclaration.body);
                        }
                    }
                }
                function canFunctionHaveSpanInWholeDeclaration(functionDeclaration) {
                    return ts.hasModifier(functionDeclaration, 1 /* Export */) ||
                        (functionDeclaration.parent.kind === 245 /* ClassDeclaration */ && functionDeclaration.kind !== 162 /* Constructor */);
                }
                function spanInFunctionDeclaration(functionDeclaration) {
                    // No breakpoints in the function signature
                    if (!functionDeclaration.body) {
                        return undefined;
                    }
                    if (canFunctionHaveSpanInWholeDeclaration(functionDeclaration)) {
                        // Set the span on whole function declaration
                        return textSpan(functionDeclaration);
                    }
                    // Set span in function body
                    return spanInNode(functionDeclaration.body);
                }
                function spanInFunctionBlock(block) {
                    var nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken();
                    if (canFunctionHaveSpanInWholeDeclaration(block.parent)) {
                        return spanInNodeIfStartsOnSameLine(block.parent, nodeForSpanInBlock);
                    }
                    return spanInNode(nodeForSpanInBlock);
                }
                function spanInBlock(block) {
                    switch (block.parent.kind) {
                        case 249 /* ModuleDeclaration */:
                            if (ts.getModuleInstanceState(block.parent) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // Set on parent if on same line otherwise on first statement
                        // falls through
                        case 229 /* WhileStatement */:
                        case 227 /* IfStatement */:
                        case 231 /* ForInStatement */:
                            return spanInNodeIfStartsOnSameLine(block.parent, block.statements[0]);
                        // Set span on previous token if it starts on same line otherwise on the first statement of the block
                        case 230 /* ForStatement */:
                        case 232 /* ForOfStatement */:
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(block.pos, sourceFile, block.parent), block.statements[0]);
                    }
                    // Default action is to set on first statement
                    return spanInNode(block.statements[0]);
                }
                function spanInInitializerOfForLike(forLikeStatement) {
                    if (forLikeStatement.initializer.kind === 243 /* VariableDeclarationList */) {
                        // Declaration list - set breakpoint in first declaration
                        var variableDeclarationList = forLikeStatement.initializer;
                        if (variableDeclarationList.declarations.length > 0) {
                            return spanInNode(variableDeclarationList.declarations[0]);
                        }
                    }
                    else {
                        // Expression - set breakpoint in it
                        return spanInNode(forLikeStatement.initializer);
                    }
                }
                function spanInForStatement(forStatement) {
                    if (forStatement.initializer) {
                        return spanInInitializerOfForLike(forStatement);
                    }
                    if (forStatement.condition) {
                        return textSpan(forStatement.condition);
                    }
                    if (forStatement.incrementor) {
                        return textSpan(forStatement.incrementor);
                    }
                }
                function spanInBindingPattern(bindingPattern) {
                    // Set breakpoint in first binding element
                    var firstBindingElement = ts.forEach(bindingPattern.elements, function (element) { return element.kind !== 215 /* OmittedExpression */ ? element : undefined; });
                    if (firstBindingElement) {
                        return spanInNode(firstBindingElement);
                    }
                    // Empty binding pattern of binding element, set breakpoint on binding element
                    if (bindingPattern.parent.kind === 191 /* BindingElement */) {
                        return textSpan(bindingPattern.parent);
                    }
                    // Variable declaration is used as the span
                    return textSpanFromVariableDeclaration(bindingPattern.parent);
                }
                function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node) {
                    ts.Debug.assert(node.kind !== 190 /* ArrayBindingPattern */ && node.kind !== 189 /* ObjectBindingPattern */);
                    var elements = node.kind === 192 /* ArrayLiteralExpression */ ? node.elements : node.properties;
                    var firstBindingElement = ts.forEach(elements, function (element) { return element.kind !== 215 /* OmittedExpression */ ? element : undefined; });
                    if (firstBindingElement) {
                        return spanInNode(firstBindingElement);
                    }
                    // Could be ArrayLiteral from destructuring assignment or
                    // just nested element in another destructuring assignment
                    // set breakpoint on assignment when parent is destructuring assignment
                    // Otherwise set breakpoint for this element
                    return textSpan(node.parent.kind === 209 /* BinaryExpression */ ? node.parent : node);
                }
                // Tokens:
                function spanInOpenBraceToken(node) {
                    switch (node.parent.kind) {
                        case 248 /* EnumDeclaration */:
                            var enumDeclaration = node.parent;
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), enumDeclaration.members.length ? enumDeclaration.members[0] : enumDeclaration.getLastToken(sourceFile));
                        case 245 /* ClassDeclaration */:
                            var classDeclaration = node.parent;
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile));
                        case 251 /* CaseBlock */:
                            return spanInNodeIfStartsOnSameLine(node.parent.parent, node.parent.clauses[0]);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInCloseBraceToken(node) {
                    switch (node.parent.kind) {
                        case 250 /* ModuleBlock */:
                            // If this is not an instantiated module block, no bp span
                            if (ts.getModuleInstanceState(node.parent.parent) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // falls through
                        case 248 /* EnumDeclaration */:
                        case 245 /* ClassDeclaration */:
                            // Span on close brace token
                            return textSpan(node);
                        case 223 /* Block */:
                            if (ts.isFunctionBlock(node.parent)) {
                                // Span on close brace token
                                return textSpan(node);
                            }
                        // falls through
                        case 280 /* CatchClause */:
                            return spanInNode(ts.lastOrUndefined(node.parent.statements));
                        case 251 /* CaseBlock */:
                            // breakpoint in last statement of the last clause
                            var caseBlock = node.parent;
                            var lastClause = ts.lastOrUndefined(caseBlock.clauses);
                            if (lastClause) {
                                return spanInNode(ts.lastOrUndefined(lastClause.statements));
                            }
                            return undefined;
                        case 189 /* ObjectBindingPattern */:
                            // Breakpoint in last binding element or binding pattern if it contains no elements
                            var bindingPattern = node.parent;
                            return spanInNode(ts.lastOrUndefined(bindingPattern.elements) || bindingPattern);
                        // Default to parent node
                        default:
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                // Breakpoint in last binding element or binding pattern if it contains no elements
                                var objectLiteral = node.parent;
                                return textSpan(ts.lastOrUndefined(objectLiteral.properties) || objectLiteral);
                            }
                            return spanInNode(node.parent);
                    }
                }
                function spanInCloseBracketToken(node) {
                    switch (node.parent.kind) {
                        case 190 /* ArrayBindingPattern */:
                            // Breakpoint in last binding element or binding pattern if it contains no elements
                            var bindingPattern = node.parent;
                            return textSpan(ts.lastOrUndefined(bindingPattern.elements) || bindingPattern);
                        default:
                            if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                // Breakpoint in last binding element or binding pattern if it contains no elements
                                var arrayLiteral = node.parent;
                                return textSpan(ts.lastOrUndefined(arrayLiteral.elements) || arrayLiteral);
                            }
                            // Default to parent node
                            return spanInNode(node.parent);
                    }
                }
                function spanInOpenParenToken(node) {
                    if (node.parent.kind === 228 /* DoStatement */ || // Go to while keyword and do action instead
                        node.parent.kind === 196 /* CallExpression */ ||
                        node.parent.kind === 197 /* NewExpression */) {
                        return spanInPreviousNode(node);
                    }
                    if (node.parent.kind === 200 /* ParenthesizedExpression */) {
                        return spanInNextNode(node);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInCloseParenToken(node) {
                    // Is this close paren token of parameter list, set span in previous token
                    switch (node.parent.kind) {
                        case 201 /* FunctionExpression */:
                        case 244 /* FunctionDeclaration */:
                        case 202 /* ArrowFunction */:
                        case 161 /* MethodDeclaration */:
                        case 160 /* MethodSignature */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                        case 162 /* Constructor */:
                        case 229 /* WhileStatement */:
                        case 228 /* DoStatement */:
                        case 230 /* ForStatement */:
                        case 232 /* ForOfStatement */:
                        case 196 /* CallExpression */:
                        case 197 /* NewExpression */:
                        case 200 /* ParenthesizedExpression */:
                            return spanInPreviousNode(node);
                        // Default to parent node
                        default:
                            return spanInNode(node.parent);
                    }
                }
                function spanInColonToken(node) {
                    // Is this : specifying return annotation of the function declaration
                    if (ts.isFunctionLike(node.parent) ||
                        node.parent.kind === 281 /* PropertyAssignment */ ||
                        node.parent.kind === 156 /* Parameter */) {
                        return spanInPreviousNode(node);
                    }
                    return spanInNode(node.parent);
                }
                function spanInGreaterThanOrLessThanToken(node) {
                    if (node.parent.kind === 199 /* TypeAssertionExpression */) {
                        return spanInNextNode(node);
                    }
                    return spanInNode(node.parent);
                }
                function spanInWhileKeyword(node) {
                    if (node.parent.kind === 228 /* DoStatement */) {
                        // Set span on while expression
                        return textSpanEndingAtNextToken(node, node.parent.expression);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
                function spanInOfKeyword(node) {
                    if (node.parent.kind === 232 /* ForOfStatement */) {
                        // Set using next token
                        return spanInNextNode(node);
                    }
                    // Default to parent node
                    return spanInNode(node.parent);
                }
            }
        }
        BreakpointResolver.spanInSourceFileAtLocation = spanInSourceFileAtLocation;
    })(BreakpointResolver = ts.BreakpointResolver || (ts.BreakpointResolver = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    /**
     * Transform one or more nodes using the supplied transformers.
     * @param source A single `Node` or an array of `Node` objects.
     * @param transformers An array of `TransformerFactory` callbacks used to process the transformation.
     * @param compilerOptions Optional compiler options.
     */
    function transform(source, transformers, compilerOptions) {
        var diagnostics = [];
        compilerOptions = ts.fixupCompilerOptions(compilerOptions, diagnostics); // TODO: GH#18217
        var nodes = ts.isArray(source) ? source : [source];
        var result = ts.transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true);
        result.diagnostics = ts.concatenate(result.diagnostics, diagnostics);
        return result;
    }
    ts.transform = transform;
})(ts || (ts = {}));
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/* @internal */
var debugObjectHost = (function () { return this; })(); // eslint-disable-line prefer-const
// We need to use 'null' to interface with the managed side.
/* eslint-disable no-in-operator */
/* @internal */
var ts;
(function (ts) {
    function logInternalError(logger, err) {
        if (logger) {
            logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message);
        }
    }
    var ScriptSnapshotShimAdapter = /** @class */ (function () {
        function ScriptSnapshotShimAdapter(scriptSnapshotShim) {
            this.scriptSnapshotShim = scriptSnapshotShim;
        }
        ScriptSnapshotShimAdapter.prototype.getText = function (start, end) {
            return this.scriptSnapshotShim.getText(start, end);
        };
        ScriptSnapshotShimAdapter.prototype.getLength = function () {
            return this.scriptSnapshotShim.getLength();
        };
        ScriptSnapshotShimAdapter.prototype.getChangeRange = function (oldSnapshot) {
            var oldSnapshotShim = oldSnapshot;
            var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim);
            /* eslint-disable no-null/no-null */
            if (encoded === null) {
                return null; // TODO: GH#18217
            }
            /* eslint-enable no-null/no-null */
            var decoded = JSON.parse(encoded); // TODO: GH#18217
            return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength);
        };
        ScriptSnapshotShimAdapter.prototype.dispose = function () {
            // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments
            // 'in' does not have this effect
            if ("dispose" in this.scriptSnapshotShim) {
                this.scriptSnapshotShim.dispose(); // TODO: GH#18217 Can we just use `if (this.scriptSnapshotShim.dispose)`?
            }
        };
        return ScriptSnapshotShimAdapter;
    }());
    var LanguageServiceShimHostAdapter = /** @class */ (function () {
        function LanguageServiceShimHostAdapter(shimHost) {
            var _this = this;
            this.shimHost = shimHost;
            this.loggingEnabled = false;
            this.tracingEnabled = false;
            // if shimHost is a COM object then property check will become method call with no arguments.
            // 'in' does not have this effect.
            if ("getModuleResolutionsForFile" in this.shimHost) {
                this.resolveModuleNames = function (moduleNames, containingFile) {
                    var resolutionsInFile = JSON.parse(_this.shimHost.getModuleResolutionsForFile(containingFile)); // TODO: GH#18217
                    return ts.map(moduleNames, function (name) {
                        var result = ts.getProperty(resolutionsInFile, name);
                        return result ? { resolvedFileName: result, extension: ts.extensionFromPath(result), isExternalLibraryImport: false } : undefined;
                    });
                };
            }
            if ("directoryExists" in this.shimHost) {
                this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); };
            }
            if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) {
                this.resolveTypeReferenceDirectives = function (typeDirectiveNames, containingFile) {
                    var typeDirectivesForFile = JSON.parse(_this.shimHost.getTypeReferenceDirectiveResolutionsForFile(containingFile)); // TODO: GH#18217
                    return ts.map(typeDirectiveNames, function (name) { return ts.getProperty(typeDirectivesForFile, name); });
                };
            }
        }
        LanguageServiceShimHostAdapter.prototype.log = function (s) {
            if (this.loggingEnabled) {
                this.shimHost.log(s);
            }
        };
        LanguageServiceShimHostAdapter.prototype.trace = function (s) {
            if (this.tracingEnabled) {
                this.shimHost.trace(s);
            }
        };
        LanguageServiceShimHostAdapter.prototype.error = function (s) {
            this.shimHost.error(s);
        };
        LanguageServiceShimHostAdapter.prototype.getProjectVersion = function () {
            if (!this.shimHost.getProjectVersion) {
                // shimmed host does not support getProjectVersion
                return undefined; // TODO: GH#18217
            }
            return this.shimHost.getProjectVersion();
        };
        LanguageServiceShimHostAdapter.prototype.getTypeRootsVersion = function () {
            if (!this.shimHost.getTypeRootsVersion) {
                return 0;
            }
            return this.shimHost.getTypeRootsVersion();
        };
        LanguageServiceShimHostAdapter.prototype.useCaseSensitiveFileNames = function () {
            return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
        };
        LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () {
            var settingsJson = this.shimHost.getCompilationSettings();
            // eslint-disable-next-line no-null/no-null
            if (settingsJson === null || settingsJson === "") {
                throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
            }
            var compilerOptions = JSON.parse(settingsJson);
            // permit language service to handle all files (filtering should be performed on the host side)
            compilerOptions.allowNonTsExtensions = true;
            return compilerOptions;
        };
        LanguageServiceShimHostAdapter.prototype.getScriptFileNames = function () {
            var encoded = this.shimHost.getScriptFileNames();
            return JSON.parse(encoded);
        };
        LanguageServiceShimHostAdapter.prototype.getScriptSnapshot = function (fileName) {
            var scriptSnapshot = this.shimHost.getScriptSnapshot(fileName);
            return scriptSnapshot && new ScriptSnapshotShimAdapter(scriptSnapshot);
        };
        LanguageServiceShimHostAdapter.prototype.getScriptKind = function (fileName) {
            if ("getScriptKind" in this.shimHost) {
                return this.shimHost.getScriptKind(fileName); // TODO: GH#18217
            }
            else {
                return 0 /* Unknown */;
            }
        };
        LanguageServiceShimHostAdapter.prototype.getScriptVersion = function (fileName) {
            return this.shimHost.getScriptVersion(fileName);
        };
        LanguageServiceShimHostAdapter.prototype.getLocalizedDiagnosticMessages = function () {
            /* eslint-disable no-null/no-null */
            var diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages();
            if (diagnosticMessagesJson === null || diagnosticMessagesJson === "") {
                return null;
            }
            try {
                return JSON.parse(diagnosticMessagesJson);
            }
            catch (e) {
                this.log(e.description || "diagnosticMessages.generated.json has invalid JSON format");
                return null;
            }
            /* eslint-enable no-null/no-null */
        };
        LanguageServiceShimHostAdapter.prototype.getCancellationToken = function () {
            var hostCancellationToken = this.shimHost.getCancellationToken();
            return new ts.ThrottledCancellationToken(hostCancellationToken);
        };
        LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () {
            return this.shimHost.getCurrentDirectory();
        };
        LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) {
            return JSON.parse(this.shimHost.getDirectories(path));
        };
        LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) {
            return this.shimHost.getDefaultLibFileName(JSON.stringify(options));
        };
        LanguageServiceShimHostAdapter.prototype.readDirectory = function (path, extensions, exclude, include, depth) {
            var pattern = ts.getFileMatcherPatterns(path, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory()); // TODO: GH#18217
            return JSON.parse(this.shimHost.readDirectory(path, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth));
        };
        LanguageServiceShimHostAdapter.prototype.readFile = function (path, encoding) {
            return this.shimHost.readFile(path, encoding);
        };
        LanguageServiceShimHostAdapter.prototype.fileExists = function (path) {
            return this.shimHost.fileExists(path);
        };
        return LanguageServiceShimHostAdapter;
    }());
    ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter;
    var CoreServicesShimHostAdapter = /** @class */ (function () {
        function CoreServicesShimHostAdapter(shimHost) {
            var _this = this;
            this.shimHost = shimHost;
            this.useCaseSensitiveFileNames = this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
            if ("directoryExists" in this.shimHost) {
                this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); };
            }
            else {
                this.directoryExists = undefined; // TODO: GH#18217
            }
            if ("realpath" in this.shimHost) {
                this.realpath = function (path) { return _this.shimHost.realpath(path); }; // TODO: GH#18217
            }
            else {
                this.realpath = undefined; // TODO: GH#18217
            }
        }
        CoreServicesShimHostAdapter.prototype.readDirectory = function (rootDir, extensions, exclude, include, depth) {
            var pattern = ts.getFileMatcherPatterns(rootDir, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory()); // TODO: GH#18217
            return JSON.parse(this.shimHost.readDirectory(rootDir, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth));
        };
        CoreServicesShimHostAdapter.prototype.fileExists = function (fileName) {
            return this.shimHost.fileExists(fileName);
        };
        CoreServicesShimHostAdapter.prototype.readFile = function (fileName) {
            return this.shimHost.readFile(fileName);
        };
        CoreServicesShimHostAdapter.prototype.getDirectories = function (path) {
            return JSON.parse(this.shimHost.getDirectories(path));
        };
        return CoreServicesShimHostAdapter;
    }());
    ts.CoreServicesShimHostAdapter = CoreServicesShimHostAdapter;
    function simpleForwardCall(logger, actionDescription, action, logPerformance) {
        var start;
        if (logPerformance) {
            logger.log(actionDescription);
            start = ts.timestamp();
        }
        var result = action();
        if (logPerformance) {
            var end = ts.timestamp();
            logger.log(actionDescription + " completed in " + (end - start) + " msec");
            if (ts.isString(result)) {
                var str = result;
                if (str.length > 128) {
                    str = str.substring(0, 128) + "...";
                }
                logger.log("  result.length=" + str.length + ", result='" + JSON.stringify(str) + "'");
            }
        }
        return result;
    }
    function forwardJSONCall(logger, actionDescription, action, logPerformance) {
        return forwardCall(logger, actionDescription, /*returnJson*/ true, action, logPerformance);
    }
    function forwardCall(logger, actionDescription, returnJson, action, logPerformance) {
        try {
            var result = simpleForwardCall(logger, actionDescription, action, logPerformance);
            return returnJson ? JSON.stringify({ result: result }) : result;
        }
        catch (err) {
            if (err instanceof ts.OperationCanceledException) {
                return JSON.stringify({ canceled: true });
            }
            logInternalError(logger, err);
            err.description = actionDescription;
            return JSON.stringify({ error: err });
        }
    }
    var ShimBase = /** @class */ (function () {
        function ShimBase(factory) {
            this.factory = factory;
            factory.registerShim(this);
        }
        ShimBase.prototype.dispose = function (_dummy) {
            this.factory.unregisterShim(this);
        };
        return ShimBase;
    }());
    function realizeDiagnostics(diagnostics, newLine) {
        return diagnostics.map(function (d) { return realizeDiagnostic(d, newLine); });
    }
    ts.realizeDiagnostics = realizeDiagnostics;
    function realizeDiagnostic(diagnostic, newLine) {
        return {
            message: ts.flattenDiagnosticMessageText(diagnostic.messageText, newLine),
            start: diagnostic.start,
            length: diagnostic.length,
            category: ts.diagnosticCategoryName(diagnostic),
            code: diagnostic.code,
            reportsUnnecessary: diagnostic.reportsUnnecessary,
        };
    }
    var LanguageServiceShimObject = /** @class */ (function (_super) {
        __extends(LanguageServiceShimObject, _super);
        function LanguageServiceShimObject(factory, host, languageService) {
            var _this = _super.call(this, factory) || this;
            _this.host = host;
            _this.languageService = languageService;
            _this.logPerformance = false;
            _this.logger = _this.host;
            return _this;
        }
        LanguageServiceShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
            return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
        };
        /// DISPOSE
        /**
         * Ensure (almost) deterministic release of internal Javascript resources when
         * some external native objects holds onto us (e.g. Com/Interop).
         */
        LanguageServiceShimObject.prototype.dispose = function (dummy) {
            this.logger.log("dispose()");
            this.languageService.dispose();
            this.languageService = null; // eslint-disable-line no-null/no-null
            // force a GC
            if (debugObjectHost && debugObjectHost.CollectGarbage) {
                debugObjectHost.CollectGarbage();
                this.logger.log("CollectGarbage()");
            }
            this.logger = null; // eslint-disable-line no-null/no-null
            _super.prototype.dispose.call(this, dummy);
        };
        /// REFRESH
        /**
         * Update the list of scripts known to the compiler
         */
        LanguageServiceShimObject.prototype.refresh = function (throwOnError) {
            this.forwardJSONCall("refresh(" + throwOnError + ")", function () { return null; } // eslint-disable-line no-null/no-null
            );
        };
        LanguageServiceShimObject.prototype.cleanupSemanticCache = function () {
            var _this = this;
            this.forwardJSONCall("cleanupSemanticCache()", function () {
                _this.languageService.cleanupSemanticCache();
                return null; // eslint-disable-line no-null/no-null
            });
        };
        LanguageServiceShimObject.prototype.realizeDiagnostics = function (diagnostics) {
            var newLine = ts.getNewLineOrDefaultFromHost(this.host);
            return realizeDiagnostics(diagnostics, newLine);
        };
        LanguageServiceShimObject.prototype.getSyntacticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSyntacticClassifications(fileName, ts.createTextSpan(start, length)); });
        };
        LanguageServiceShimObject.prototype.getSemanticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSemanticClassifications(fileName, ts.createTextSpan(start, length)); });
        };
        LanguageServiceShimObject.prototype.getEncodedSyntacticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getEncodedSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", 
            // directly serialize the spans out to a string.  This is much faster to decode
            // on the managed side versus a full JSON array.
            function () { return convertClassifications(_this.languageService.getEncodedSyntacticClassifications(fileName, ts.createTextSpan(start, length))); });
        };
        LanguageServiceShimObject.prototype.getEncodedSemanticClassifications = function (fileName, start, length) {
            var _this = this;
            return this.forwardJSONCall("getEncodedSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", 
            // directly serialize the spans out to a string.  This is much faster to decode
            // on the managed side versus a full JSON array.
            function () { return convertClassifications(_this.languageService.getEncodedSemanticClassifications(fileName, ts.createTextSpan(start, length))); });
        };
        LanguageServiceShimObject.prototype.getSyntacticDiagnostics = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getSyntacticDiagnostics('" + fileName + "')", function () {
                var diagnostics = _this.languageService.getSyntacticDiagnostics(fileName);
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        LanguageServiceShimObject.prototype.getSemanticDiagnostics = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getSemanticDiagnostics('" + fileName + "')", function () {
                var diagnostics = _this.languageService.getSemanticDiagnostics(fileName);
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        LanguageServiceShimObject.prototype.getSuggestionDiagnostics = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getSuggestionDiagnostics('" + fileName + "')", function () { return _this.realizeDiagnostics(_this.languageService.getSuggestionDiagnostics(fileName)); });
        };
        LanguageServiceShimObject.prototype.getCompilerOptionsDiagnostics = function () {
            var _this = this;
            return this.forwardJSONCall("getCompilerOptionsDiagnostics()", function () {
                var diagnostics = _this.languageService.getCompilerOptionsDiagnostics();
                return _this.realizeDiagnostics(diagnostics);
            });
        };
        /// QUICKINFO
        /**
         * Computes a string representation of the type at the requested position
         * in the active file.
         */
        LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); });
        };
        /// NAMEORDOTTEDNAMESPAN
        /**
         * Computes span information of the name or dotted name at the requested position
         * in the active file.
         */
        LanguageServiceShimObject.prototype.getNameOrDottedNameSpan = function (fileName, startPos, endPos) {
            var _this = this;
            return this.forwardJSONCall("getNameOrDottedNameSpan('" + fileName + "', " + startPos + ", " + endPos + ")", function () { return _this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos); });
        };
        /**
         * STATEMENTSPAN
         * Computes span information of statement at the requested position in the active file.
         */
        LanguageServiceShimObject.prototype.getBreakpointStatementAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getBreakpointStatementAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBreakpointStatementAtPosition(fileName, position); });
        };
        /// SIGNATUREHELP
        LanguageServiceShimObject.prototype.getSignatureHelpItems = function (fileName, position, options) {
            var _this = this;
            return this.forwardJSONCall("getSignatureHelpItems('" + fileName + "', " + position + ")", function () { return _this.languageService.getSignatureHelpItems(fileName, position, options); });
        };
        /// GOTO DEFINITION
        /**
         * Computes the definition location and file for the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getDefinitionAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDefinitionAtPosition(fileName, position); });
        };
        /**
         * Computes the definition location and file for the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getDefinitionAndBoundSpan = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getDefinitionAndBoundSpan('" + fileName + "', " + position + ")", function () { return _this.languageService.getDefinitionAndBoundSpan(fileName, position); });
        };
        /// GOTO Type
        /**
         * Computes the definition location of the type of the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getTypeDefinitionAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getTypeDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getTypeDefinitionAtPosition(fileName, position); });
        };
        /// GOTO Implementation
        /**
         * Computes the implementation location of the symbol
         * at the requested position.
         */
        LanguageServiceShimObject.prototype.getImplementationAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getImplementationAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getImplementationAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getRenameInfo = function (fileName, position, options) {
            var _this = this;
            return this.forwardJSONCall("getRenameInfo('" + fileName + "', " + position + ")", function () { return _this.languageService.getRenameInfo(fileName, position, options); });
        };
        LanguageServiceShimObject.prototype.getSmartSelectionRange = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getSmartSelectionRange('" + fileName + "', " + position + ")", function () { return _this.languageService.getSmartSelectionRange(fileName, position); });
        };
        LanguageServiceShimObject.prototype.findRenameLocations = function (fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename) {
            var _this = this;
            return this.forwardJSONCall("findRenameLocations('" + fileName + "', " + position + ", " + findInStrings + ", " + findInComments + ", " + providePrefixAndSuffixTextForRename + ")", function () { return _this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename); });
        };
        /// GET BRACE MATCHING
        LanguageServiceShimObject.prototype.getBraceMatchingAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getBraceMatchingAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBraceMatchingAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.isValidBraceCompletionAtPosition = function (fileName, position, openingBrace) {
            var _this = this;
            return this.forwardJSONCall("isValidBraceCompletionAtPosition('" + fileName + "', " + position + ", " + openingBrace + ")", function () { return _this.languageService.isValidBraceCompletionAtPosition(fileName, position, openingBrace); });
        };
        LanguageServiceShimObject.prototype.getSpanOfEnclosingComment = function (fileName, position, onlyMultiLine) {
            var _this = this;
            return this.forwardJSONCall("getSpanOfEnclosingComment('" + fileName + "', " + position + ")", function () { return _this.languageService.getSpanOfEnclosingComment(fileName, position, onlyMultiLine); });
        };
        /// GET SMART INDENT
        LanguageServiceShimObject.prototype.getIndentationAtPosition = function (fileName, position, options /*Services.EditorOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getIndentationAtPosition('" + fileName + "', " + position + ")", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getIndentationAtPosition(fileName, position, localOptions);
            });
        };
        /// GET REFERENCES
        LanguageServiceShimObject.prototype.getReferencesAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getReferencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getReferencesAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.findReferences = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("findReferences('" + fileName + "', " + position + ")", function () { return _this.languageService.findReferences(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getOccurrencesAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getOccurrencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getOccurrencesAtPosition(fileName, position); });
        };
        LanguageServiceShimObject.prototype.getDocumentHighlights = function (fileName, position, filesToSearch) {
            var _this = this;
            return this.forwardJSONCall("getDocumentHighlights('" + fileName + "', " + position + ")", function () {
                var results = _this.languageService.getDocumentHighlights(fileName, position, JSON.parse(filesToSearch));
                // workaround for VS document highlighting issue - keep only items from the initial file
                var normalizedName = ts.toFileNameLowerCase(ts.normalizeSlashes(fileName));
                return ts.filter(results, function (r) { return ts.toFileNameLowerCase(ts.normalizeSlashes(r.fileName)) === normalizedName; });
            });
        };
        /// COMPLETION LISTS
        /**
         * Get a string based representation of the completions
         * to provide at the given source position and providing a member completion
         * list if requested.
         */
        LanguageServiceShimObject.prototype.getCompletionsAtPosition = function (fileName, position, preferences) {
            var _this = this;
            return this.forwardJSONCall("getCompletionsAtPosition('" + fileName + "', " + position + ", " + preferences + ")", function () { return _this.languageService.getCompletionsAtPosition(fileName, position, preferences); });
        };
        /** Get a string based representation of a completion list entry details */
        LanguageServiceShimObject.prototype.getCompletionEntryDetails = function (fileName, position, entryName, formatOptions, source, preferences) {
            var _this = this;
            return this.forwardJSONCall("getCompletionEntryDetails('" + fileName + "', " + position + ", '" + entryName + "')", function () {
                var localOptions = formatOptions === undefined ? undefined : JSON.parse(formatOptions);
                return _this.languageService.getCompletionEntryDetails(fileName, position, entryName, localOptions, source, preferences);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsForRange = function (fileName, start, end, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsForRange('" + fileName + "', " + start + ", " + end + ")", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsForRange(fileName, start, end, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsForDocument = function (fileName, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsForDocument('" + fileName + "')", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsForDocument(fileName, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getFormattingEditsAfterKeystroke = function (fileName, position, key, options /*Services.FormatCodeOptions*/) {
            var _this = this;
            return this.forwardJSONCall("getFormattingEditsAfterKeystroke('" + fileName + "', " + position + ", '" + key + "')", function () {
                var localOptions = JSON.parse(options);
                return _this.languageService.getFormattingEditsAfterKeystroke(fileName, position, key, localOptions);
            });
        };
        LanguageServiceShimObject.prototype.getDocCommentTemplateAtPosition = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("getDocCommentTemplateAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDocCommentTemplateAtPosition(fileName, position); });
        };
        /// NAVIGATE TO
        /** Return a list of symbols that are interesting to navigate to */
        LanguageServiceShimObject.prototype.getNavigateToItems = function (searchValue, maxResultCount, fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigateToItems('" + searchValue + "', " + maxResultCount + ", " + fileName + ")", function () { return _this.languageService.getNavigateToItems(searchValue, maxResultCount, fileName); });
        };
        LanguageServiceShimObject.prototype.getNavigationBarItems = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigationBarItems('" + fileName + "')", function () { return _this.languageService.getNavigationBarItems(fileName); });
        };
        LanguageServiceShimObject.prototype.getNavigationTree = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); });
        };
        LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); });
        };
        LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) {
            var _this = this;
            return this.forwardJSONCall("getTodoComments('" + fileName + "')", function () { return _this.languageService.getTodoComments(fileName, JSON.parse(descriptors)); });
        };
        /// CALL HIERARCHY
        LanguageServiceShimObject.prototype.prepareCallHierarchy = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("prepareCallHierarchy('" + fileName + "', " + position + ")", function () { return _this.languageService.prepareCallHierarchy(fileName, position); });
        };
        LanguageServiceShimObject.prototype.provideCallHierarchyIncomingCalls = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("provideCallHierarchyIncomingCalls('" + fileName + "', " + position + ")", function () { return _this.languageService.provideCallHierarchyIncomingCalls(fileName, position); });
        };
        LanguageServiceShimObject.prototype.provideCallHierarchyOutgoingCalls = function (fileName, position) {
            var _this = this;
            return this.forwardJSONCall("provideCallHierarchyOutgoingCalls('" + fileName + "', " + position + ")", function () { return _this.languageService.provideCallHierarchyOutgoingCalls(fileName, position); });
        };
        /// Emit
        LanguageServiceShimObject.prototype.getEmitOutput = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getEmitOutput('" + fileName + "')", function () {
                var _a = _this.languageService.getEmitOutput(fileName), diagnostics = _a.diagnostics, rest = __rest(_a, ["diagnostics"]);
                return __assign(__assign({}, rest), { diagnostics: _this.realizeDiagnostics(diagnostics) });
            });
        };
        LanguageServiceShimObject.prototype.getEmitOutputObject = function (fileName) {
            var _this = this;
            return forwardCall(this.logger, "getEmitOutput('" + fileName + "')", 
            /*returnJson*/ false, function () { return _this.languageService.getEmitOutput(fileName); }, this.logPerformance);
        };
        return LanguageServiceShimObject;
    }(ShimBase));
    function convertClassifications(classifications) {
        return { spans: classifications.spans.join(","), endOfLineState: classifications.endOfLineState };
    }
    var ClassifierShimObject = /** @class */ (function (_super) {
        __extends(ClassifierShimObject, _super);
        function ClassifierShimObject(factory, logger) {
            var _this = _super.call(this, factory) || this;
            _this.logger = logger;
            _this.logPerformance = false;
            _this.classifier = ts.createClassifier();
            return _this;
        }
        ClassifierShimObject.prototype.getEncodedLexicalClassifications = function (text, lexState, syntacticClassifierAbsent) {
            var _this = this;
            if (syntacticClassifierAbsent === void 0) { syntacticClassifierAbsent = false; }
            return forwardJSONCall(this.logger, "getEncodedLexicalClassifications", function () { return convertClassifications(_this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)); }, this.logPerformance);
        };
        /// COLORIZATION
        ClassifierShimObject.prototype.getClassificationsForLine = function (text, lexState, classifyKeywordsInGenerics) {
            if (classifyKeywordsInGenerics === void 0) { classifyKeywordsInGenerics = false; }
            var classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics);
            var result = "";
            for (var _i = 0, _a = classification.entries; _i < _a.length; _i++) {
                var item = _a[_i];
                result += item.length + "\n";
                result += item.classification + "\n";
            }
            result += classification.finalLexState;
            return result;
        };
        return ClassifierShimObject;
    }(ShimBase));
    var CoreServicesShimObject = /** @class */ (function (_super) {
        __extends(CoreServicesShimObject, _super);
        function CoreServicesShimObject(factory, logger, host) {
            var _this = _super.call(this, factory) || this;
            _this.logger = logger;
            _this.host = host;
            _this.logPerformance = false;
            return _this;
        }
        CoreServicesShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
            return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
        };
        CoreServicesShimObject.prototype.resolveModuleName = function (fileName, moduleName, compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("resolveModuleName('" + fileName + "')", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                var result = ts.resolveModuleName(moduleName, ts.normalizeSlashes(fileName), compilerOptions, _this.host);
                var resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined;
                if (result.resolvedModule && result.resolvedModule.extension !== ".ts" /* Ts */ && result.resolvedModule.extension !== ".tsx" /* Tsx */ && result.resolvedModule.extension !== ".d.ts" /* Dts */) {
                    resolvedFileName = undefined;
                }
                return {
                    resolvedFileName: resolvedFileName,
                    failedLookupLocations: result.failedLookupLocations
                };
            });
        };
        CoreServicesShimObject.prototype.resolveTypeReferenceDirective = function (fileName, typeReferenceDirective, compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("resolveTypeReferenceDirective(" + fileName + ")", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                var result = ts.resolveTypeReferenceDirective(typeReferenceDirective, ts.normalizeSlashes(fileName), compilerOptions, _this.host);
                return {
                    resolvedFileName: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.resolvedFileName : undefined,
                    primary: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.primary : true,
                    failedLookupLocations: result.failedLookupLocations
                };
            });
        };
        CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) {
            var _this = this;
            return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () {
                // for now treat files as JavaScript
                var result = ts.preProcessFile(ts.getSnapshotText(sourceTextSnapshot), /* readImportFiles */ true, /* detectJavaScriptImports */ true);
                return {
                    referencedFiles: _this.convertFileReferences(result.referencedFiles),
                    importedFiles: _this.convertFileReferences(result.importedFiles),
                    ambientExternalModules: result.ambientExternalModules,
                    isLibFile: result.isLibFile,
                    typeReferenceDirectives: _this.convertFileReferences(result.typeReferenceDirectives),
                    libReferenceDirectives: _this.convertFileReferences(result.libReferenceDirectives)
                };
            });
        };
        CoreServicesShimObject.prototype.getAutomaticTypeDirectiveNames = function (compilerOptionsJson) {
            var _this = this;
            return this.forwardJSONCall("getAutomaticTypeDirectiveNames('" + compilerOptionsJson + "')", function () {
                var compilerOptions = JSON.parse(compilerOptionsJson);
                return ts.getAutomaticTypeDirectiveNames(compilerOptions, _this.host);
            });
        };
        CoreServicesShimObject.prototype.convertFileReferences = function (refs) {
            if (!refs) {
                return undefined;
            }
            var result = [];
            for (var _i = 0, refs_1 = refs; _i < refs_1.length; _i++) {
                var ref = refs_1[_i];
                result.push({
                    path: ts.normalizeSlashes(ref.fileName),
                    position: ref.pos,
                    length: ref.end - ref.pos
                });
            }
            return result;
        };
        CoreServicesShimObject.prototype.getTSConfigFileInfo = function (fileName, sourceTextSnapshot) {
            var _this = this;
            return this.forwardJSONCall("getTSConfigFileInfo('" + fileName + "')", function () {
                var result = ts.parseJsonText(fileName, ts.getSnapshotText(sourceTextSnapshot));
                var normalizedFileName = ts.normalizeSlashes(fileName);
                var configFile = ts.parseJsonSourceFileConfigFileContent(result, _this.host, ts.getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
                return {
                    options: configFile.options,
                    typeAcquisition: configFile.typeAcquisition,
                    files: configFile.fileNames,
                    raw: configFile.raw,
                    errors: realizeDiagnostics(__spreadArrays(result.parseDiagnostics, configFile.errors), "\r\n")
                };
            });
        };
        CoreServicesShimObject.prototype.getDefaultCompilationSettings = function () {
            return this.forwardJSONCall("getDefaultCompilationSettings()", function () { return ts.getDefaultCompilerOptions(); });
        };
        CoreServicesShimObject.prototype.discoverTypings = function (discoverTypingsJson) {
            var _this = this;
            var getCanonicalFileName = ts.createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false);
            return this.forwardJSONCall("discoverTypings()", function () {
                var info = JSON.parse(discoverTypingsJson);
                if (_this.safeList === undefined) {
                    _this.safeList = ts.JsTyping.loadSafeList(_this.host, ts.toPath(info.safeListPath, info.safeListPath, getCanonicalFileName));
                }
                return ts.JsTyping.discoverTypings(_this.host, function (msg) { return _this.logger.log(msg); }, info.fileNames, ts.toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName), _this.safeList, info.packageNameToTypingLocation, info.typeAcquisition, info.unresolvedImports, info.typesRegistry);
            });
        };
        return CoreServicesShimObject;
    }(ShimBase));
    var TypeScriptServicesFactory = /** @class */ (function () {
        function TypeScriptServicesFactory() {
            this._shims = [];
        }
        /*
         * Returns script API version.
         */
        TypeScriptServicesFactory.prototype.getServicesVersion = function () {
            return ts.servicesVersion;
        };
        TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) {
            try {
                if (this.documentRegistry === undefined) {
                    this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory());
                }
                var hostAdapter = new LanguageServiceShimHostAdapter(host);
                var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry, /*syntaxOnly*/ false);
                return new LanguageServiceShimObject(this, host, languageService);
            }
            catch (err) {
                logInternalError(host, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.createClassifierShim = function (logger) {
            try {
                return new ClassifierShimObject(this, logger);
            }
            catch (err) {
                logInternalError(logger, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.createCoreServicesShim = function (host) {
            try {
                var adapter = new CoreServicesShimHostAdapter(host);
                return new CoreServicesShimObject(this, host, adapter);
            }
            catch (err) {
                logInternalError(host, err);
                throw err;
            }
        };
        TypeScriptServicesFactory.prototype.close = function () {
            // Forget all the registered shims
            ts.clear(this._shims);
            this.documentRegistry = undefined;
        };
        TypeScriptServicesFactory.prototype.registerShim = function (shim) {
            this._shims.push(shim);
        };
        TypeScriptServicesFactory.prototype.unregisterShim = function (shim) {
            for (var i = 0; i < this._shims.length; i++) {
                if (this._shims[i] === shim) {
                    delete this._shims[i];
                    return;
                }
            }
            throw new Error("Invalid operation");
        };
        return TypeScriptServicesFactory;
    }());
    ts.TypeScriptServicesFactory = TypeScriptServicesFactory;
})(ts || (ts = {}));
/* eslint-enable no-in-operator */
// We polyfill `globalThis` here so re can reliably patch the global scope
// in the contexts we want to in the same way across script and module formats
/* eslint-enable no-var */
((function () {
    if (typeof globalThis === "object")
        return;
    try {
        Object.defineProperty(Object.prototype, "__magic__", {
            get: function () {
                return this;
            },
            configurable: true
        });
        //@ts-ignore
        __magic__.globalThis = __magic__;
        // The previous line should have made `globalThis` globally
        // available, but it fails in Internet Explorer 10 and older.
        // Detect this failure and fall back.
        if (typeof globalThis === "undefined") {
            // Assume `window` exists.
            //@ts-ignore
            window.globalThis = window;
        }
        //@ts-ignore
        delete Object.prototype.__magic__;
    }
    catch (error) {
        // In IE8, Object.defineProperty only works on DOM objects.
        // If we hit this code path, assume `window` exists.
        //@ts-ignore
        window.globalThis = window;
    }
})());
// #endregion The polyfill ends here.
// if `process` is undefined, we're probably not running in node - patch legacy members onto the global scope
// @ts-ignore
if (typeof process === "undefined" || process.browser) {
    /// TODO: this is used by VS, clean this up on both sides of the interface
    //@ts-ignore
    globalThis.TypeScript = globalThis.TypeScript || {};
    //@ts-ignore
    globalThis.TypeScript.Services = globalThis.TypeScript.Services || {};
    //@ts-ignore
    globalThis.TypeScript.Services.TypeScriptServicesFactory = ts.TypeScriptServicesFactory;
    // 'toolsVersion' gets consumed by the managed side, so it's not unused.
    // TODO: it should be moved into a namespace though.
    //@ts-ignore
    globalThis.toolsVersion = ts.versionMajorMinor;
}
if (typeof module !== "undefined" && module.exports) {
    module.exports = ts;
}


//# sourceMappingURL=typescript.js.map
